@bitgo-beta/abstract-eth 1.0.2-beta.206 → 1.0.2-beta.2061

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 (175) 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 +876 -0
  5. package/dist/src/abstractEthLikeNewCoins.d.ts.map +1 -0
  6. package/dist/src/abstractEthLikeNewCoins.js +2647 -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 +271 -0
  59. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  60. package/dist/src/lib/transactionBuilder.js +837 -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 +5 -0
  68. package/dist/src/lib/transferBuilders/index.d.ts.map +1 -0
  69. package/dist/src/lib/transferBuilders/index.js +21 -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/transferBuilders/transferBuilderERC7984.d.ts +35 -0
  77. package/dist/src/lib/transferBuilders/transferBuilderERC7984.d.ts.map +1 -0
  78. package/dist/src/lib/transferBuilders/transferBuilderERC7984.js +113 -0
  79. package/dist/src/lib/types.d.ts +40 -0
  80. package/dist/src/lib/types.d.ts.map +1 -0
  81. package/dist/src/lib/types.js +140 -0
  82. package/dist/src/lib/utils.d.ts +326 -0
  83. package/dist/src/lib/utils.d.ts.map +1 -0
  84. package/dist/src/lib/utils.js +893 -0
  85. package/dist/src/lib/walletUtil.d.ts +45 -0
  86. package/dist/src/lib/walletUtil.d.ts.map +1 -0
  87. package/dist/src/lib/walletUtil.js +51 -0
  88. package/dist/src/lib/zamaUtils.d.ts +73 -0
  89. package/dist/src/lib/zamaUtils.d.ts.map +1 -0
  90. package/dist/src/lib/zamaUtils.js +159 -0
  91. package/dist/src/types.d.ts +9 -0
  92. package/dist/src/types.d.ts.map +1 -0
  93. package/dist/src/types.js +3 -0
  94. package/dist/test/index.d.ts +2 -0
  95. package/dist/test/index.d.ts.map +1 -0
  96. package/dist/test/index.js +18 -0
  97. package/dist/test/unit/coin.d.ts +8 -0
  98. package/dist/test/unit/coin.d.ts.map +1 -0
  99. package/dist/test/unit/coin.js +577 -0
  100. package/dist/test/unit/decryptionDelegationBuilder.d.ts +2 -0
  101. package/dist/test/unit/decryptionDelegationBuilder.d.ts.map +1 -0
  102. package/dist/test/unit/decryptionDelegationBuilder.js +265 -0
  103. package/dist/test/unit/index.d.ts +8 -0
  104. package/dist/test/unit/index.d.ts.map +1 -0
  105. package/dist/test/unit/index.js +24 -0
  106. package/dist/test/unit/messages/abstractEthMessageBuilderTests.d.ts +3 -0
  107. package/dist/test/unit/messages/abstractEthMessageBuilderTests.d.ts.map +1 -0
  108. package/dist/test/unit/messages/abstractEthMessageBuilderTests.js +110 -0
  109. package/dist/test/unit/messages/abstractEthMessageTestTypes.d.ts +43 -0
  110. package/dist/test/unit/messages/abstractEthMessageTestTypes.d.ts.map +1 -0
  111. package/dist/test/unit/messages/abstractEthMessageTestTypes.js +3 -0
  112. package/dist/test/unit/messages/abstractEthMessagesTests.d.ts +3 -0
  113. package/dist/test/unit/messages/abstractEthMessagesTests.d.ts.map +1 -0
  114. package/dist/test/unit/messages/abstractEthMessagesTests.js +129 -0
  115. package/dist/test/unit/messages/eip191/eip191Message.d.ts +2 -0
  116. package/dist/test/unit/messages/eip191/eip191Message.d.ts.map +1 -0
  117. package/dist/test/unit/messages/eip191/eip191Message.js +15 -0
  118. package/dist/test/unit/messages/eip191/eip191MessageBuilder.d.ts +2 -0
  119. package/dist/test/unit/messages/eip191/eip191MessageBuilder.d.ts.map +1 -0
  120. package/dist/test/unit/messages/eip191/eip191MessageBuilder.js +16 -0
  121. package/dist/test/unit/messages/eip191/fixtures.d.ts +109 -0
  122. package/dist/test/unit/messages/eip191/fixtures.d.ts.map +1 -0
  123. package/dist/test/unit/messages/eip191/fixtures.js +63 -0
  124. package/dist/test/unit/messages/eip712/eip712Message.d.ts +2 -0
  125. package/dist/test/unit/messages/eip712/eip712Message.d.ts.map +1 -0
  126. package/dist/test/unit/messages/eip712/eip712Message.js +15 -0
  127. package/dist/test/unit/messages/eip712/eip712MessageBuilder.d.ts +2 -0
  128. package/dist/test/unit/messages/eip712/eip712MessageBuilder.d.ts.map +1 -0
  129. package/dist/test/unit/messages/eip712/eip712MessageBuilder.js +16 -0
  130. package/dist/test/unit/messages/eip712/fixtures.d.ts +76 -0
  131. package/dist/test/unit/messages/eip712/fixtures.d.ts.map +1 -0
  132. package/dist/test/unit/messages/eip712/fixtures.js +120 -0
  133. package/dist/test/unit/messages/index.d.ts +4 -0
  134. package/dist/test/unit/messages/index.d.ts.map +1 -0
  135. package/dist/test/unit/messages/index.js +20 -0
  136. package/dist/test/unit/messages/messageBuilderFactory.d.ts +2 -0
  137. package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
  138. package/dist/test/unit/messages/messageBuilderFactory.js +52 -0
  139. package/dist/test/unit/token.d.ts +2 -0
  140. package/dist/test/unit/token.d.ts.map +1 -0
  141. package/dist/test/unit/token.js +37 -0
  142. package/dist/test/unit/transaction.d.ts +3 -0
  143. package/dist/test/unit/transaction.d.ts.map +1 -0
  144. package/dist/test/unit/transaction.js +73 -0
  145. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts +8 -0
  146. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts.map +1 -0
  147. package/dist/test/unit/transactionBuilder/addressInitialization.js +95 -0
  148. package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts +3 -0
  149. package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts.map +1 -0
  150. package/dist/test/unit/transactionBuilder/decryptionDelegation.js +161 -0
  151. package/dist/test/unit/transactionBuilder/flushNft.d.ts +2 -0
  152. package/dist/test/unit/transactionBuilder/flushNft.d.ts.map +1 -0
  153. package/dist/test/unit/transactionBuilder/flushNft.js +381 -0
  154. package/dist/test/unit/transactionBuilder/index.d.ts +6 -0
  155. package/dist/test/unit/transactionBuilder/index.d.ts.map +1 -0
  156. package/dist/test/unit/transactionBuilder/index.js +22 -0
  157. package/dist/test/unit/transactionBuilder/send.d.ts +3 -0
  158. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  159. package/dist/test/unit/transactionBuilder/send.js +197 -0
  160. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +11 -0
  161. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  162. package/dist/test/unit/transactionBuilder/walletInitialization.js +137 -0
  163. package/dist/test/unit/transferBuilder.d.ts +2 -0
  164. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  165. package/dist/test/unit/transferBuilder.js +76 -0
  166. package/dist/test/unit/utils.d.ts +2 -0
  167. package/dist/test/unit/utils.d.ts.map +1 -0
  168. package/dist/test/unit/utils.js +214 -0
  169. package/dist/test/unit/zamaUtils.d.ts +2 -0
  170. package/dist/test/unit/zamaUtils.d.ts.map +1 -0
  171. package/dist/test/unit/zamaUtils.js +251 -0
  172. package/dist/tsconfig.tsbuildinfo +1 -8244
  173. package/package.json +34 -10
  174. package/.eslintignore +0 -5
  175. package/CHANGELOG.md +0 -166
@@ -0,0 +1,214 @@
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
+ const should_1 = __importDefault(require("should"));
7
+ const utils_1 = require("../../src/lib/utils");
8
+ const transferBuilderERC721_1 = require("../../src/lib/transferBuilders/transferBuilderERC721");
9
+ const walletUtil_1 = require("../../src/lib/walletUtil");
10
+ describe('Abstract ETH Utils', () => {
11
+ describe('ERC721 Flush Functions', () => {
12
+ it('should encode flush ERC721 data correctly for v0-v3', () => {
13
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
14
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
15
+ const tokenId = '12345';
16
+ const forwarderVersion = 0;
17
+ const encoded = (0, utils_1.flushERC721TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
18
+ should_1.default.exist(encoded);
19
+ encoded.should.startWith('0x5a953d0a'); // flushERC721ForwarderTokens method ID
20
+ encoded.should.be.a.String();
21
+ encoded.length.should.be.greaterThan(10); // method ID + parameters
22
+ });
23
+ it('should encode flush ERC721 data correctly for v4+', () => {
24
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
25
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
26
+ const tokenId = '12345';
27
+ const forwarderVersion = 4;
28
+ const encoded = (0, utils_1.flushERC721TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
29
+ should_1.default.exist(encoded);
30
+ encoded.should.startWith('0x159e44d7'); // flushERC721Token method ID (v5)
31
+ encoded.should.be.a.String();
32
+ });
33
+ it('should decode flush ERC721 data correctly for v0-v3', () => {
34
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
35
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
36
+ const tokenId = '12345';
37
+ const forwarderVersion = 2;
38
+ const encoded = (0, utils_1.flushERC721TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
39
+ const decoded = (0, utils_1.decodeFlushERC721TokensData)(encoded);
40
+ should_1.default.exist(decoded);
41
+ decoded.forwarderAddress.toLowerCase().should.equal(forwarderAddress.toLowerCase());
42
+ decoded.tokenAddress.toLowerCase().should.equal(tokenAddress.toLowerCase());
43
+ decoded.tokenId.should.equal(tokenId);
44
+ should_1.default.not.exist(decoded.forwarderVersion);
45
+ });
46
+ it('should decode flush ERC721 data correctly for v4+', () => {
47
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
48
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
49
+ const tokenId = '12345';
50
+ const forwarderVersion = 4;
51
+ const encoded = (0, utils_1.flushERC721TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
52
+ const decoded = (0, utils_1.decodeFlushERC721TokensData)(encoded, forwarderAddress);
53
+ should_1.default.exist(decoded);
54
+ decoded.forwarderAddress.toLowerCase().should.equal(forwarderAddress.toLowerCase());
55
+ decoded.tokenAddress.toLowerCase().should.equal(tokenAddress.toLowerCase());
56
+ decoded.tokenId.should.equal(tokenId);
57
+ should_1.default.exist(decoded.forwarderVersion);
58
+ should_1.default.equal(decoded.forwarderVersion, 4);
59
+ });
60
+ it('should handle large token IDs for ERC721', () => {
61
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
62
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
63
+ const tokenId = '115792089237316195423570985008687907853269984665640564039457584007913129639935'; // max uint256
64
+ const forwarderVersion = 0;
65
+ const encoded = (0, utils_1.flushERC721TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
66
+ const decoded = (0, utils_1.decodeFlushERC721TokensData)(encoded);
67
+ decoded.tokenId.should.equal(tokenId);
68
+ });
69
+ it('should throw error for invalid flush ERC721 data', () => {
70
+ const invalidData = '0x12345678'; // Wrong method ID
71
+ should_1.default.throws(() => {
72
+ (0, utils_1.decodeFlushERC721TokensData)(invalidData);
73
+ }, /Invalid flush ERC721 bytecode/);
74
+ });
75
+ it('should throw error for missing to address in v4+ decode', () => {
76
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
77
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
78
+ const tokenId = '12345';
79
+ const forwarderVersion = 4;
80
+ const encoded = (0, utils_1.flushERC721TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
81
+ should_1.default.throws(() => {
82
+ (0, utils_1.decodeFlushERC721TokensData)(encoded); // Missing 'to' parameter
83
+ }, /Missing to address/);
84
+ });
85
+ });
86
+ describe('ERC1155 Flush Functions', () => {
87
+ it('should encode flush ERC1155 data correctly for v0-v3', () => {
88
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
89
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
90
+ const tokenId = '99999';
91
+ const forwarderVersion = 0;
92
+ const encoded = (0, utils_1.flushERC1155TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
93
+ should_1.default.exist(encoded);
94
+ encoded.should.startWith('0xe6bd0aa4'); // flushERC1155ForwarderTokens method ID
95
+ encoded.should.be.a.String();
96
+ encoded.length.should.be.greaterThan(10); // method ID + parameters
97
+ });
98
+ it('should encode flush ERC1155 data correctly for v4+', () => {
99
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
100
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
101
+ const tokenId = '99999';
102
+ const forwarderVersion = 4;
103
+ const encoded = (0, utils_1.flushERC1155TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
104
+ should_1.default.exist(encoded);
105
+ encoded.should.startWith('0x8972c17c'); // flushERC1155Tokens method ID (v5)
106
+ encoded.should.be.a.String();
107
+ });
108
+ it('should decode flush ERC1155 data correctly for v0-v3', () => {
109
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
110
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
111
+ const tokenId = '99999';
112
+ const forwarderVersion = 2;
113
+ const encoded = (0, utils_1.flushERC1155TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
114
+ const decoded = (0, utils_1.decodeFlushERC1155TokensData)(encoded);
115
+ should_1.default.exist(decoded);
116
+ decoded.forwarderAddress.toLowerCase().should.equal(forwarderAddress.toLowerCase());
117
+ decoded.tokenAddress.toLowerCase().should.equal(tokenAddress.toLowerCase());
118
+ decoded.tokenId.should.equal(tokenId);
119
+ should_1.default.not.exist(decoded.forwarderVersion);
120
+ });
121
+ it('should decode flush ERC1155 data correctly for v4+', () => {
122
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
123
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
124
+ const tokenId = '99999';
125
+ const forwarderVersion = 4;
126
+ const encoded = (0, utils_1.flushERC1155TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
127
+ const decoded = (0, utils_1.decodeFlushERC1155TokensData)(encoded, forwarderAddress);
128
+ should_1.default.exist(decoded);
129
+ decoded.forwarderAddress.toLowerCase().should.equal(forwarderAddress.toLowerCase());
130
+ decoded.tokenAddress.toLowerCase().should.equal(tokenAddress.toLowerCase());
131
+ decoded.tokenId.should.equal(tokenId);
132
+ should_1.default.exist(decoded.forwarderVersion);
133
+ should_1.default.equal(decoded.forwarderVersion, 4);
134
+ });
135
+ it('should handle token ID 0 for ERC1155', () => {
136
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
137
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
138
+ const tokenId = '0';
139
+ const forwarderVersion = 0;
140
+ const encoded = (0, utils_1.flushERC1155TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
141
+ const decoded = (0, utils_1.decodeFlushERC1155TokensData)(encoded);
142
+ decoded.tokenId.should.equal(tokenId);
143
+ });
144
+ it('should handle large token IDs for ERC1155', () => {
145
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
146
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
147
+ const tokenId = '115792089237316195423570985008687907853269984665640564039457584007913129639935'; // max uint256
148
+ const forwarderVersion = 0;
149
+ const encoded = (0, utils_1.flushERC1155TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
150
+ const decoded = (0, utils_1.decodeFlushERC1155TokensData)(encoded);
151
+ decoded.tokenId.should.equal(tokenId);
152
+ });
153
+ it('should throw error for invalid flush ERC1155 data', () => {
154
+ const invalidData = '0x87654321'; // Wrong method ID
155
+ should_1.default.throws(() => {
156
+ (0, utils_1.decodeFlushERC1155TokensData)(invalidData);
157
+ }, /Invalid flush ERC1155 bytecode/);
158
+ });
159
+ it('should throw error for missing to address in v4+ decode', () => {
160
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
161
+ const tokenAddress = '0xdf7decb1baa8f529f0c8982cbb4be50357195299';
162
+ const tokenId = '99999';
163
+ const forwarderVersion = 4;
164
+ const encoded = (0, utils_1.flushERC1155TokensData)(forwarderAddress, tokenAddress, tokenId, forwarderVersion);
165
+ should_1.default.throws(() => {
166
+ (0, utils_1.decodeFlushERC1155TokensData)(encoded); // Missing 'to' parameter
167
+ }, /Missing to address/);
168
+ });
169
+ });
170
+ describe('ERC721TransferBuilder.buildTransferFrom', () => {
171
+ const owner = '0x19645032c7f1533395d44a629462e751084d3e4d';
172
+ const recipient = '0x19645032c7f1533395d44a629462e751084d3e4c';
173
+ const htsNftAddress = '0x00000000000000000000000000000000007ac203';
174
+ it('should encode transferFrom with selector 0x23b872dd', () => {
175
+ const builder = new transferBuilderERC721_1.ERC721TransferBuilder();
176
+ builder.tokenContractAddress(htsNftAddress).to(recipient).from(owner).tokenId('12');
177
+ const data = builder.buildTransferFrom();
178
+ should_1.default.exist(data);
179
+ data.should.startWith(walletUtil_1.ERC721TransferFromMethodId); // 0x23b872dd
180
+ });
181
+ it('should encode safeTransferFrom with selector 0xb88d4fde via build()', () => {
182
+ const builder = new transferBuilderERC721_1.ERC721TransferBuilder();
183
+ builder.tokenContractAddress(htsNftAddress).to(recipient).from(owner).tokenId('12');
184
+ const data = builder.build();
185
+ should_1.default.exist(data);
186
+ data.should.startWith(walletUtil_1.ERC721SafeTransferTypeMethodId); // 0xb88d4fde
187
+ });
188
+ it('should produce different encodings for build() vs buildTransferFrom()', () => {
189
+ const builder = new transferBuilderERC721_1.ERC721TransferBuilder();
190
+ builder.tokenContractAddress(htsNftAddress).to(recipient).from(owner).tokenId('12');
191
+ const safeTransferData = builder.build();
192
+ const transferFromData = builder.buildTransferFrom();
193
+ safeTransferData.should.not.equal(transferFromData);
194
+ // transferFrom encoding should be shorter (no bytes param)
195
+ transferFromData.length.should.be.lessThan(safeTransferData.length);
196
+ });
197
+ });
198
+ describe('Token Address Validation', () => {
199
+ it('should preserve address format in encoding/decoding', () => {
200
+ const forwarderAddress = '0x8f977e912ef500548a0c3be6ddde9899f1199b81';
201
+ const tokenAddressChecksum = '0xDf7DECb1bAa8F529F0C8982cBB4Be50357195299'; // With checksum
202
+ const tokenId = '12345';
203
+ const forwarderVersion = 0;
204
+ const encoded721 = (0, utils_1.flushERC721TokensData)(forwarderAddress, tokenAddressChecksum, tokenId, forwarderVersion);
205
+ const decoded721 = (0, utils_1.decodeFlushERC721TokensData)(encoded721);
206
+ // Should preserve the address (though may lowercase it)
207
+ decoded721.tokenAddress.toLowerCase().should.equal(tokenAddressChecksum.toLowerCase());
208
+ const encoded1155 = (0, utils_1.flushERC1155TokensData)(forwarderAddress, tokenAddressChecksum, tokenId, forwarderVersion);
209
+ const decoded1155 = (0, utils_1.decodeFlushERC1155TokensData)(encoded1155);
210
+ decoded1155.tokenAddress.toLowerCase().should.equal(tokenAddressChecksum.toLowerCase());
211
+ });
212
+ });
213
+ });
214
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsK0NBSzZCO0FBQzdCLGdHQUE2RjtBQUM3Rix5REFBc0c7QUFFdEcsUUFBUSxDQUFDLG9CQUFvQixFQUFFLEdBQUcsRUFBRTtJQUNsQyxRQUFRLENBQUMsd0JBQXdCLEVBQUUsR0FBRyxFQUFFO1FBQ3RDLEVBQUUsQ0FBQyxxREFBcUQsRUFBRSxHQUFHLEVBQUU7WUFDN0QsTUFBTSxnQkFBZ0IsR0FBRyw0Q0FBNEMsQ0FBQztZQUN0RSxNQUFNLFlBQVksR0FBRyw0Q0FBNEMsQ0FBQztZQUNsRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFDeEIsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7WUFFM0IsTUFBTSxPQUFPLEdBQUcsSUFBQSw2QkFBcUIsRUFBQyxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixDQUFDLENBQUM7WUFFakcsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdEIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyx1Q0FBdUM7WUFDL0UsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzdCLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyx5QkFBeUI7UUFDckUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsbURBQW1ELEVBQUUsR0FBRyxFQUFFO1lBQzNELE1BQU0sZ0JBQWdCLEdBQUcsNENBQTRDLENBQUM7WUFDdEUsTUFBTSxZQUFZLEdBQUcsNENBQTRDLENBQUM7WUFDbEUsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDO1lBQ3hCLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1lBRTNCLE1BQU0sT0FBTyxHQUFHLElBQUEsNkJBQXFCLEVBQUMsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBRWpHLGdCQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLE9BQU8sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsa0NBQWtDO1lBQzFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUMvQixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxxREFBcUQsRUFBRSxHQUFHLEVBQUU7WUFDN0QsTUFBTSxnQkFBZ0IsR0FBRyw0Q0FBNEMsQ0FBQztZQUN0RSxNQUFNLFlBQVksR0FBRyw0Q0FBNEMsQ0FBQztZQUNsRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFDeEIsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7WUFFM0IsTUFBTSxPQUFPLEdBQUcsSUFBQSw2QkFBcUIsRUFBQyxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixDQUFDLENBQUM7WUFDakcsTUFBTSxPQUFPLEdBQUcsSUFBQSxtQ0FBMkIsRUFBQyxPQUFPLENBQUMsQ0FBQztZQUVyRCxnQkFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN0QixPQUFPLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQ3BGLE9BQU8sQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUM1RSxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdEMsZ0JBQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1EQUFtRCxFQUFFLEdBQUcsRUFBRTtZQUMzRCxNQUFNLGdCQUFnQixHQUFHLDRDQUE0QyxDQUFDO1lBQ3RFLE1BQU0sWUFBWSxHQUFHLDRDQUE0QyxDQUFDO1lBQ2xFLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUN4QixNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQztZQUUzQixNQUFNLE9BQU8sR0FBRyxJQUFBLDZCQUFxQixFQUFDLGdCQUFnQixFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUNqRyxNQUFNLE9BQU8sR0FBRyxJQUFBLG1DQUEyQixFQUFDLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBRXZFLGdCQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7WUFDcEYsT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQzVFLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN0QyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUN2QyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMENBQTBDLEVBQUUsR0FBRyxFQUFFO1lBQ2xELE1BQU0sZ0JBQWdCLEdBQUcsNENBQTRDLENBQUM7WUFDdEUsTUFBTSxZQUFZLEdBQUcsNENBQTRDLENBQUM7WUFDbEUsTUFBTSxPQUFPLEdBQUcsZ0ZBQWdGLENBQUMsQ0FBQyxjQUFjO1lBQ2hILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1lBRTNCLE1BQU0sT0FBTyxHQUFHLElBQUEsNkJBQXFCLEVBQUMsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2pHLE1BQU0sT0FBTyxHQUFHLElBQUEsbUNBQTJCLEVBQUMsT0FBTyxDQUFDLENBQUM7WUFFckQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtEQUFrRCxFQUFFLEdBQUcsRUFBRTtZQUMxRCxNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUMsQ0FBQyxrQkFBa0I7WUFFcEQsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFO2dCQUNqQixJQUFBLG1DQUEyQixFQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzNDLENBQUMsRUFBRSwrQkFBK0IsQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHlEQUF5RCxFQUFFLEdBQUcsRUFBRTtZQUNqRSxNQUFNLGdCQUFnQixHQUFHLDRDQUE0QyxDQUFDO1lBQ3RFLE1BQU0sWUFBWSxHQUFHLDRDQUE0QyxDQUFDO1lBQ2xFLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUN4QixNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQztZQUUzQixNQUFNLE9BQU8sR0FBRyxJQUFBLDZCQUFxQixFQUFDLGdCQUFnQixFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUVqRyxnQkFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUU7Z0JBQ2pCLElBQUEsbUNBQTJCLEVBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyx5QkFBeUI7WUFDakUsQ0FBQyxFQUFFLG9CQUFvQixDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyx5QkFBeUIsRUFBRSxHQUFHLEVBQUU7UUFDdkMsRUFBRSxDQUFDLHNEQUFzRCxFQUFFLEdBQUcsRUFBRTtZQUM5RCxNQUFNLGdCQUFnQixHQUFHLDRDQUE0QyxDQUFDO1lBQ3RFLE1BQU0sWUFBWSxHQUFHLDRDQUE0QyxDQUFDO1lBQ2xFLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUN4QixNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQztZQUUzQixNQUFNLE9BQU8sR0FBRyxJQUFBLDhCQUFzQixFQUFDLGdCQUFnQixFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUVsRyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN0QixPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLHdDQUF3QztZQUNoRixPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDN0IsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLHlCQUF5QjtRQUNyRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvREFBb0QsRUFBRSxHQUFHLEVBQUU7WUFDNUQsTUFBTSxnQkFBZ0IsR0FBRyw0Q0FBNEMsQ0FBQztZQUN0RSxNQUFNLFlBQVksR0FBRyw0Q0FBNEMsQ0FBQztZQUNsRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFDeEIsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7WUFFM0IsTUFBTSxPQUFPLEdBQUcsSUFBQSw4QkFBc0IsRUFBQyxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixDQUFDLENBQUM7WUFFbEcsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdEIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxvQ0FBb0M7WUFDNUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQy9CLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNEQUFzRCxFQUFFLEdBQUcsRUFBRTtZQUM5RCxNQUFNLGdCQUFnQixHQUFHLDRDQUE0QyxDQUFDO1lBQ3RFLE1BQU0sWUFBWSxHQUFHLDRDQUE0QyxDQUFDO1lBQ2xFLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUN4QixNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQztZQUUzQixNQUFNLE9BQU8sR0FBRyxJQUFBLDhCQUFzQixFQUFDLGdCQUFnQixFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUNsRyxNQUFNLE9BQU8sR0FBRyxJQUFBLG9DQUE0QixFQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRXRELGdCQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7WUFDcEYsT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQzVFLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN0QyxnQkFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0RBQW9ELEVBQUUsR0FBRyxFQUFFO1lBQzVELE1BQU0sZ0JBQWdCLEdBQUcsNENBQTRDLENBQUM7WUFDdEUsTUFBTSxZQUFZLEdBQUcsNENBQTRDLENBQUM7WUFDbEUsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDO1lBQ3hCLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1lBRTNCLE1BQU0sT0FBTyxHQUFHLElBQUEsOEJBQXNCLEVBQUMsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xHLE1BQU0sT0FBTyxHQUFHLElBQUEsb0NBQTRCLEVBQUMsT0FBTyxFQUFFLGdCQUFnQixDQUFDLENBQUM7WUFFeEUsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdEIsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUNwRixPQUFPLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7WUFDNUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RDLGdCQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3ZDLGdCQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUU7WUFDOUMsTUFBTSxnQkFBZ0IsR0FBRyw0Q0FBNEMsQ0FBQztZQUN0RSxNQUFNLFlBQVksR0FBRyw0Q0FBNEMsQ0FBQztZQUNsRSxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUM7WUFDcEIsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7WUFFM0IsTUFBTSxPQUFPLEdBQUcsSUFBQSw4QkFBc0IsRUFBQyxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixDQUFDLENBQUM7WUFDbEcsTUFBTSxPQUFPLEdBQUcsSUFBQSxvQ0FBNEIsRUFBQyxPQUFPLENBQUMsQ0FBQztZQUV0RCxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMkNBQTJDLEVBQUUsR0FBRyxFQUFFO1lBQ25ELE1BQU0sZ0JBQWdCLEdBQUcsNENBQTRDLENBQUM7WUFDdEUsTUFBTSxZQUFZLEdBQUcsNENBQTRDLENBQUM7WUFDbEUsTUFBTSxPQUFPLEdBQUcsZ0ZBQWdGLENBQUMsQ0FBQyxjQUFjO1lBQ2hILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1lBRTNCLE1BQU0sT0FBTyxHQUFHLElBQUEsOEJBQXNCLEVBQUMsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xHLE1BQU0sT0FBTyxHQUFHLElBQUEsb0NBQTRCLEVBQUMsT0FBTyxDQUFDLENBQUM7WUFFdEQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1EQUFtRCxFQUFFLEdBQUcsRUFBRTtZQUMzRCxNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUMsQ0FBQyxrQkFBa0I7WUFFcEQsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFO2dCQUNqQixJQUFBLG9DQUE0QixFQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzVDLENBQUMsRUFBRSxnQ0FBZ0MsQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHlEQUF5RCxFQUFFLEdBQUcsRUFBRTtZQUNqRSxNQUFNLGdCQUFnQixHQUFHLDRDQUE0QyxDQUFDO1lBQ3RFLE1BQU0sWUFBWSxHQUFHLDRDQUE0QyxDQUFDO1lBQ2xFLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUN4QixNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQztZQUUzQixNQUFNLE9BQU8sR0FBRyxJQUFBLDhCQUFzQixFQUFDLGdCQUFnQixFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUVsRyxnQkFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUU7Z0JBQ2pCLElBQUEsb0NBQTRCLEVBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyx5QkFBeUI7WUFDbEUsQ0FBQyxFQUFFLG9CQUFvQixDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7UUFDdkQsTUFBTSxLQUFLLEdBQUcsNENBQTRDLENBQUM7UUFDM0QsTUFBTSxTQUFTLEdBQUcsNENBQTRDLENBQUM7UUFDL0QsTUFBTSxhQUFhLEdBQUcsNENBQTRDLENBQUM7UUFFbkUsRUFBRSxDQUFDLHFEQUFxRCxFQUFFLEdBQUcsRUFBRTtZQUM3RCxNQUFNLE9BQU8sR0FBRyxJQUFJLDZDQUFxQixFQUFFLENBQUM7WUFDNUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXBGLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBRXpDLGdCQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ25CLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLHVDQUEwQixDQUFDLENBQUMsQ0FBQyxhQUFhO1FBQ2xFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHFFQUFxRSxFQUFFLEdBQUcsRUFBRTtZQUM3RSxNQUFNLE9BQU8sR0FBRyxJQUFJLDZDQUFxQixFQUFFLENBQUM7WUFDNUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXBGLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUU3QixnQkFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuQixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQywyQ0FBOEIsQ0FBQyxDQUFDLENBQUMsYUFBYTtRQUN0RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1RUFBdUUsRUFBRSxHQUFHLEVBQUU7WUFDL0UsTUFBTSxPQUFPLEdBQUcsSUFBSSw2Q0FBcUIsRUFBRSxDQUFDO1lBQzVDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUVwRixNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN6QyxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBRXJELGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDcEQsMkRBQTJEO1lBQzNELGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0RSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLDBCQUEwQixFQUFFLEdBQUcsRUFBRTtRQUN4QyxFQUFFLENBQUMscURBQXFELEVBQUUsR0FBRyxFQUFFO1lBQzdELE1BQU0sZ0JBQWdCLEdBQUcsNENBQTRDLENBQUM7WUFDdEUsTUFBTSxvQkFBb0IsR0FBRyw0Q0FBNEMsQ0FBQyxDQUFDLGdCQUFnQjtZQUMzRixNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFDeEIsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7WUFFM0IsTUFBTSxVQUFVLEdBQUcsSUFBQSw2QkFBcUIsRUFBQyxnQkFBZ0IsRUFBRSxvQkFBb0IsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUM1RyxNQUFNLFVBQVUsR0FBRyxJQUFBLG1DQUEyQixFQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRTNELHdEQUF3RDtZQUN4RCxVQUFVLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUV2RixNQUFNLFdBQVcsR0FBRyxJQUFBLDhCQUFzQixFQUFDLGdCQUFnQixFQUFFLG9CQUFvQixFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBQzlHLE1BQU0sV0FBVyxHQUFHLElBQUEsb0NBQTRCLEVBQUMsV0FBVyxDQUFDLENBQUM7WUFFOUQsV0FBVyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDMUYsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IHtcbiAgZmx1c2hFUkM3MjFUb2tlbnNEYXRhLFxuICBmbHVzaEVSQzExNTVUb2tlbnNEYXRhLFxuICBkZWNvZGVGbHVzaEVSQzcyMVRva2Vuc0RhdGEsXG4gIGRlY29kZUZsdXNoRVJDMTE1NVRva2Vuc0RhdGEsXG59IGZyb20gJy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0IHsgRVJDNzIxVHJhbnNmZXJCdWlsZGVyIH0gZnJvbSAnLi4vLi4vc3JjL2xpYi90cmFuc2ZlckJ1aWxkZXJzL3RyYW5zZmVyQnVpbGRlckVSQzcyMSc7XG5pbXBvcnQgeyBFUkM3MjFUcmFuc2ZlckZyb21NZXRob2RJZCwgRVJDNzIxU2FmZVRyYW5zZmVyVHlwZU1ldGhvZElkIH0gZnJvbSAnLi4vLi4vc3JjL2xpYi93YWxsZXRVdGlsJztcblxuZGVzY3JpYmUoJ0Fic3RyYWN0IEVUSCBVdGlscycsICgpID0+IHtcbiAgZGVzY3JpYmUoJ0VSQzcyMSBGbHVzaCBGdW5jdGlvbnMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgZmx1c2ggRVJDNzIxIGRhdGEgY29ycmVjdGx5IGZvciB2MC12MycsICgpID0+IHtcbiAgICAgIGNvbnN0IGZvcndhcmRlckFkZHJlc3MgPSAnMHg4Zjk3N2U5MTJlZjUwMDU0OGEwYzNiZTZkZGRlOTg5OWYxMTk5YjgxJztcbiAgICAgIGNvbnN0IHRva2VuQWRkcmVzcyA9ICcweGRmN2RlY2IxYmFhOGY1MjlmMGM4OTgyY2JiNGJlNTAzNTcxOTUyOTknO1xuICAgICAgY29uc3QgdG9rZW5JZCA9ICcxMjM0NSc7XG4gICAgICBjb25zdCBmb3J3YXJkZXJWZXJzaW9uID0gMDtcblxuICAgICAgY29uc3QgZW5jb2RlZCA9IGZsdXNoRVJDNzIxVG9rZW5zRGF0YShmb3J3YXJkZXJBZGRyZXNzLCB0b2tlbkFkZHJlc3MsIHRva2VuSWQsIGZvcndhcmRlclZlcnNpb24pO1xuXG4gICAgICBzaG91bGQuZXhpc3QoZW5jb2RlZCk7XG4gICAgICBlbmNvZGVkLnNob3VsZC5zdGFydFdpdGgoJzB4NWE5NTNkMGEnKTsgLy8gZmx1c2hFUkM3MjFGb3J3YXJkZXJUb2tlbnMgbWV0aG9kIElEXG4gICAgICBlbmNvZGVkLnNob3VsZC5iZS5hLlN0cmluZygpO1xuICAgICAgZW5jb2RlZC5sZW5ndGguc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKDEwKTsgLy8gbWV0aG9kIElEICsgcGFyYW1ldGVyc1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgZmx1c2ggRVJDNzIxIGRhdGEgY29ycmVjdGx5IGZvciB2NCsnLCAoKSA9PiB7XG4gICAgICBjb25zdCBmb3J3YXJkZXJBZGRyZXNzID0gJzB4OGY5NzdlOTEyZWY1MDA1NDhhMGMzYmU2ZGRkZTk4OTlmMTE5OWI4MSc7XG4gICAgICBjb25zdCB0b2tlbkFkZHJlc3MgPSAnMHhkZjdkZWNiMWJhYThmNTI5ZjBjODk4MmNiYjRiZTUwMzU3MTk1Mjk5JztcbiAgICAgIGNvbnN0IHRva2VuSWQgPSAnMTIzNDUnO1xuICAgICAgY29uc3QgZm9yd2FyZGVyVmVyc2lvbiA9IDQ7XG5cbiAgICAgIGNvbnN0IGVuY29kZWQgPSBmbHVzaEVSQzcyMVRva2Vuc0RhdGEoZm9yd2FyZGVyQWRkcmVzcywgdG9rZW5BZGRyZXNzLCB0b2tlbklkLCBmb3J3YXJkZXJWZXJzaW9uKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KGVuY29kZWQpO1xuICAgICAgZW5jb2RlZC5zaG91bGQuc3RhcnRXaXRoKCcweDE1OWU0NGQ3Jyk7IC8vIGZsdXNoRVJDNzIxVG9rZW4gbWV0aG9kIElEICh2NSlcbiAgICAgIGVuY29kZWQuc2hvdWxkLmJlLmEuU3RyaW5nKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRlY29kZSBmbHVzaCBFUkM3MjEgZGF0YSBjb3JyZWN0bHkgZm9yIHYwLXYzJywgKCkgPT4ge1xuICAgICAgY29uc3QgZm9yd2FyZGVyQWRkcmVzcyA9ICcweDhmOTc3ZTkxMmVmNTAwNTQ4YTBjM2JlNmRkZGU5ODk5ZjExOTliODEnO1xuICAgICAgY29uc3QgdG9rZW5BZGRyZXNzID0gJzB4ZGY3ZGVjYjFiYWE4ZjUyOWYwYzg5ODJjYmI0YmU1MDM1NzE5NTI5OSc7XG4gICAgICBjb25zdCB0b2tlbklkID0gJzEyMzQ1JztcbiAgICAgIGNvbnN0IGZvcndhcmRlclZlcnNpb24gPSAyO1xuXG4gICAgICBjb25zdCBlbmNvZGVkID0gZmx1c2hFUkM3MjFUb2tlbnNEYXRhKGZvcndhcmRlckFkZHJlc3MsIHRva2VuQWRkcmVzcywgdG9rZW5JZCwgZm9yd2FyZGVyVmVyc2lvbik7XG4gICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlRmx1c2hFUkM3MjFUb2tlbnNEYXRhKGVuY29kZWQpO1xuXG4gICAgICBzaG91bGQuZXhpc3QoZGVjb2RlZCk7XG4gICAgICBkZWNvZGVkLmZvcndhcmRlckFkZHJlc3MudG9Mb3dlckNhc2UoKS5zaG91bGQuZXF1YWwoZm9yd2FyZGVyQWRkcmVzcy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIGRlY29kZWQudG9rZW5BZGRyZXNzLnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFsKHRva2VuQWRkcmVzcy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIGRlY29kZWQudG9rZW5JZC5zaG91bGQuZXF1YWwodG9rZW5JZCk7XG4gICAgICBzaG91bGQubm90LmV4aXN0KGRlY29kZWQuZm9yd2FyZGVyVmVyc2lvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRlY29kZSBmbHVzaCBFUkM3MjEgZGF0YSBjb3JyZWN0bHkgZm9yIHY0KycsICgpID0+IHtcbiAgICAgIGNvbnN0IGZvcndhcmRlckFkZHJlc3MgPSAnMHg4Zjk3N2U5MTJlZjUwMDU0OGEwYzNiZTZkZGRlOTg5OWYxMTk5YjgxJztcbiAgICAgIGNvbnN0IHRva2VuQWRkcmVzcyA9ICcweGRmN2RlY2IxYmFhOGY1MjlmMGM4OTgyY2JiNGJlNTAzNTcxOTUyOTknO1xuICAgICAgY29uc3QgdG9rZW5JZCA9ICcxMjM0NSc7XG4gICAgICBjb25zdCBmb3J3YXJkZXJWZXJzaW9uID0gNDtcblxuICAgICAgY29uc3QgZW5jb2RlZCA9IGZsdXNoRVJDNzIxVG9rZW5zRGF0YShmb3J3YXJkZXJBZGRyZXNzLCB0b2tlbkFkZHJlc3MsIHRva2VuSWQsIGZvcndhcmRlclZlcnNpb24pO1xuICAgICAgY29uc3QgZGVjb2RlZCA9IGRlY29kZUZsdXNoRVJDNzIxVG9rZW5zRGF0YShlbmNvZGVkLCBmb3J3YXJkZXJBZGRyZXNzKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KGRlY29kZWQpO1xuICAgICAgZGVjb2RlZC5mb3J3YXJkZXJBZGRyZXNzLnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFsKGZvcndhcmRlckFkZHJlc3MudG9Mb3dlckNhc2UoKSk7XG4gICAgICBkZWNvZGVkLnRva2VuQWRkcmVzcy50b0xvd2VyQ2FzZSgpLnNob3VsZC5lcXVhbCh0b2tlbkFkZHJlc3MudG9Mb3dlckNhc2UoKSk7XG4gICAgICBkZWNvZGVkLnRva2VuSWQuc2hvdWxkLmVxdWFsKHRva2VuSWQpO1xuICAgICAgc2hvdWxkLmV4aXN0KGRlY29kZWQuZm9yd2FyZGVyVmVyc2lvbik7XG4gICAgICBzaG91bGQuZXF1YWwoZGVjb2RlZC5mb3J3YXJkZXJWZXJzaW9uLCA0KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIGxhcmdlIHRva2VuIElEcyBmb3IgRVJDNzIxJywgKCkgPT4ge1xuICAgICAgY29uc3QgZm9yd2FyZGVyQWRkcmVzcyA9ICcweDhmOTc3ZTkxMmVmNTAwNTQ4YTBjM2JlNmRkZGU5ODk5ZjExOTliODEnO1xuICAgICAgY29uc3QgdG9rZW5BZGRyZXNzID0gJzB4ZGY3ZGVjYjFiYWE4ZjUyOWYwYzg5ODJjYmI0YmU1MDM1NzE5NTI5OSc7XG4gICAgICBjb25zdCB0b2tlbklkID0gJzExNTc5MjA4OTIzNzMxNjE5NTQyMzU3MDk4NTAwODY4NzkwNzg1MzI2OTk4NDY2NTY0MDU2NDAzOTQ1NzU4NDAwNzkxMzEyOTYzOTkzNSc7IC8vIG1heCB1aW50MjU2XG4gICAgICBjb25zdCBmb3J3YXJkZXJWZXJzaW9uID0gMDtcblxuICAgICAgY29uc3QgZW5jb2RlZCA9IGZsdXNoRVJDNzIxVG9rZW5zRGF0YShmb3J3YXJkZXJBZGRyZXNzLCB0b2tlbkFkZHJlc3MsIHRva2VuSWQsIGZvcndhcmRlclZlcnNpb24pO1xuICAgICAgY29uc3QgZGVjb2RlZCA9IGRlY29kZUZsdXNoRVJDNzIxVG9rZW5zRGF0YShlbmNvZGVkKTtcblxuICAgICAgZGVjb2RlZC50b2tlbklkLnNob3VsZC5lcXVhbCh0b2tlbklkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgZmx1c2ggRVJDNzIxIGRhdGEnLCAoKSA9PiB7XG4gICAgICBjb25zdCBpbnZhbGlkRGF0YSA9ICcweDEyMzQ1Njc4JzsgLy8gV3JvbmcgbWV0aG9kIElEXG5cbiAgICAgIHNob3VsZC50aHJvd3MoKCkgPT4ge1xuICAgICAgICBkZWNvZGVGbHVzaEVSQzcyMVRva2Vuc0RhdGEoaW52YWxpZERhdGEpO1xuICAgICAgfSwgL0ludmFsaWQgZmx1c2ggRVJDNzIxIGJ5dGVjb2RlLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBtaXNzaW5nIHRvIGFkZHJlc3MgaW4gdjQrIGRlY29kZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGZvcndhcmRlckFkZHJlc3MgPSAnMHg4Zjk3N2U5MTJlZjUwMDU0OGEwYzNiZTZkZGRlOTg5OWYxMTk5YjgxJztcbiAgICAgIGNvbnN0IHRva2VuQWRkcmVzcyA9ICcweGRmN2RlY2IxYmFhOGY1MjlmMGM4OTgyY2JiNGJlNTAzNTcxOTUyOTknO1xuICAgICAgY29uc3QgdG9rZW5JZCA9ICcxMjM0NSc7XG4gICAgICBjb25zdCBmb3J3YXJkZXJWZXJzaW9uID0gNDtcblxuICAgICAgY29uc3QgZW5jb2RlZCA9IGZsdXNoRVJDNzIxVG9rZW5zRGF0YShmb3J3YXJkZXJBZGRyZXNzLCB0b2tlbkFkZHJlc3MsIHRva2VuSWQsIGZvcndhcmRlclZlcnNpb24pO1xuXG4gICAgICBzaG91bGQudGhyb3dzKCgpID0+IHtcbiAgICAgICAgZGVjb2RlRmx1c2hFUkM3MjFUb2tlbnNEYXRhKGVuY29kZWQpOyAvLyBNaXNzaW5nICd0bycgcGFyYW1ldGVyXG4gICAgICB9LCAvTWlzc2luZyB0byBhZGRyZXNzLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFUkMxMTU1IEZsdXNoIEZ1bmN0aW9ucycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGVuY29kZSBmbHVzaCBFUkMxMTU1IGRhdGEgY29ycmVjdGx5IGZvciB2MC12MycsICgpID0+IHtcbiAgICAgIGNvbnN0IGZvcndhcmRlckFkZHJlc3MgPSAnMHg4Zjk3N2U5MTJlZjUwMDU0OGEwYzNiZTZkZGRlOTg5OWYxMTk5YjgxJztcbiAgICAgIGNvbnN0IHRva2VuQWRkcmVzcyA9ICcweGRmN2RlY2IxYmFhOGY1MjlmMGM4OTgyY2JiNGJlNTAzNTcxOTUyOTknO1xuICAgICAgY29uc3QgdG9rZW5JZCA9ICc5OTk5OSc7XG4gICAgICBjb25zdCBmb3J3YXJkZXJWZXJzaW9uID0gMDtcblxuICAgICAgY29uc3QgZW5jb2RlZCA9IGZsdXNoRVJDMTE1NVRva2Vuc0RhdGEoZm9yd2FyZGVyQWRkcmVzcywgdG9rZW5BZGRyZXNzLCB0b2tlbklkLCBmb3J3YXJkZXJWZXJzaW9uKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KGVuY29kZWQpO1xuICAgICAgZW5jb2RlZC5zaG91bGQuc3RhcnRXaXRoKCcweGU2YmQwYWE0Jyk7IC8vIGZsdXNoRVJDMTE1NUZvcndhcmRlclRva2VucyBtZXRob2QgSURcbiAgICAgIGVuY29kZWQuc2hvdWxkLmJlLmEuU3RyaW5nKCk7XG4gICAgICBlbmNvZGVkLmxlbmd0aC5zaG91bGQuYmUuZ3JlYXRlclRoYW4oMTApOyAvLyBtZXRob2QgSUQgKyBwYXJhbWV0ZXJzXG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGVuY29kZSBmbHVzaCBFUkMxMTU1IGRhdGEgY29ycmVjdGx5IGZvciB2NCsnLCAoKSA9PiB7XG4gICAgICBjb25zdCBmb3J3YXJkZXJBZGRyZXNzID0gJzB4OGY5NzdlOTEyZWY1MDA1NDhhMGMzYmU2ZGRkZTk4OTlmMTE5OWI4MSc7XG4gICAgICBjb25zdCB0b2tlbkFkZHJlc3MgPSAnMHhkZjdkZWNiMWJhYThmNTI5ZjBjODk4MmNiYjRiZTUwMzU3MTk1Mjk5JztcbiAgICAgIGNvbnN0IHRva2VuSWQgPSAnOTk5OTknO1xuICAgICAgY29uc3QgZm9yd2FyZGVyVmVyc2lvbiA9IDQ7XG5cbiAgICAgIGNvbnN0IGVuY29kZWQgPSBmbHVzaEVSQzExNTVUb2tlbnNEYXRhKGZvcndhcmRlckFkZHJlc3MsIHRva2VuQWRkcmVzcywgdG9rZW5JZCwgZm9yd2FyZGVyVmVyc2lvbik7XG5cbiAgICAgIHNob3VsZC5leGlzdChlbmNvZGVkKTtcbiAgICAgIGVuY29kZWQuc2hvdWxkLnN0YXJ0V2l0aCgnMHg4OTcyYzE3YycpOyAvLyBmbHVzaEVSQzExNTVUb2tlbnMgbWV0aG9kIElEICh2NSlcbiAgICAgIGVuY29kZWQuc2hvdWxkLmJlLmEuU3RyaW5nKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRlY29kZSBmbHVzaCBFUkMxMTU1IGRhdGEgY29ycmVjdGx5IGZvciB2MC12MycsICgpID0+IHtcbiAgICAgIGNvbnN0IGZvcndhcmRlckFkZHJlc3MgPSAnMHg4Zjk3N2U5MTJlZjUwMDU0OGEwYzNiZTZkZGRlOTg5OWYxMTk5YjgxJztcbiAgICAgIGNvbnN0IHRva2VuQWRkcmVzcyA9ICcweGRmN2RlY2IxYmFhOGY1MjlmMGM4OTgyY2JiNGJlNTAzNTcxOTUyOTknO1xuICAgICAgY29uc3QgdG9rZW5JZCA9ICc5OTk5OSc7XG4gICAgICBjb25zdCBmb3J3YXJkZXJWZXJzaW9uID0gMjtcblxuICAgICAgY29uc3QgZW5jb2RlZCA9IGZsdXNoRVJDMTE1NVRva2Vuc0RhdGEoZm9yd2FyZGVyQWRkcmVzcywgdG9rZW5BZGRyZXNzLCB0b2tlbklkLCBmb3J3YXJkZXJWZXJzaW9uKTtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBkZWNvZGVGbHVzaEVSQzExNTVUb2tlbnNEYXRhKGVuY29kZWQpO1xuXG4gICAgICBzaG91bGQuZXhpc3QoZGVjb2RlZCk7XG4gICAgICBkZWNvZGVkLmZvcndhcmRlckFkZHJlc3MudG9Mb3dlckNhc2UoKS5zaG91bGQuZXF1YWwoZm9yd2FyZGVyQWRkcmVzcy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIGRlY29kZWQudG9rZW5BZGRyZXNzLnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFsKHRva2VuQWRkcmVzcy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIGRlY29kZWQudG9rZW5JZC5zaG91bGQuZXF1YWwodG9rZW5JZCk7XG4gICAgICBzaG91bGQubm90LmV4aXN0KGRlY29kZWQuZm9yd2FyZGVyVmVyc2lvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRlY29kZSBmbHVzaCBFUkMxMTU1IGRhdGEgY29ycmVjdGx5IGZvciB2NCsnLCAoKSA9PiB7XG4gICAgICBjb25zdCBmb3J3YXJkZXJBZGRyZXNzID0gJzB4OGY5NzdlOTEyZWY1MDA1NDhhMGMzYmU2ZGRkZTk4OTlmMTE5OWI4MSc7XG4gICAgICBjb25zdCB0b2tlbkFkZHJlc3MgPSAnMHhkZjdkZWNiMWJhYThmNTI5ZjBjODk4MmNiYjRiZTUwMzU3MTk1Mjk5JztcbiAgICAgIGNvbnN0IHRva2VuSWQgPSAnOTk5OTknO1xuICAgICAgY29uc3QgZm9yd2FyZGVyVmVyc2lvbiA9IDQ7XG5cbiAgICAgIGNvbnN0IGVuY29kZWQgPSBmbHVzaEVSQzExNTVUb2tlbnNEYXRhKGZvcndhcmRlckFkZHJlc3MsIHRva2VuQWRkcmVzcywgdG9rZW5JZCwgZm9yd2FyZGVyVmVyc2lvbik7XG4gICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlRmx1c2hFUkMxMTU1VG9rZW5zRGF0YShlbmNvZGVkLCBmb3J3YXJkZXJBZGRyZXNzKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KGRlY29kZWQpO1xuICAgICAgZGVjb2RlZC5mb3J3YXJkZXJBZGRyZXNzLnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFsKGZvcndhcmRlckFkZHJlc3MudG9Mb3dlckNhc2UoKSk7XG4gICAgICBkZWNvZGVkLnRva2VuQWRkcmVzcy50b0xvd2VyQ2FzZSgpLnNob3VsZC5lcXVhbCh0b2tlbkFkZHJlc3MudG9Mb3dlckNhc2UoKSk7XG4gICAgICBkZWNvZGVkLnRva2VuSWQuc2hvdWxkLmVxdWFsKHRva2VuSWQpO1xuICAgICAgc2hvdWxkLmV4aXN0KGRlY29kZWQuZm9yd2FyZGVyVmVyc2lvbik7XG4gICAgICBzaG91bGQuZXF1YWwoZGVjb2RlZC5mb3J3YXJkZXJWZXJzaW9uLCA0KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHRva2VuIElEIDAgZm9yIEVSQzExNTUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBmb3J3YXJkZXJBZGRyZXNzID0gJzB4OGY5NzdlOTEyZWY1MDA1NDhhMGMzYmU2ZGRkZTk4OTlmMTE5OWI4MSc7XG4gICAgICBjb25zdCB0b2tlbkFkZHJlc3MgPSAnMHhkZjdkZWNiMWJhYThmNTI5ZjBjODk4MmNiYjRiZTUwMzU3MTk1Mjk5JztcbiAgICAgIGNvbnN0IHRva2VuSWQgPSAnMCc7XG4gICAgICBjb25zdCBmb3J3YXJkZXJWZXJzaW9uID0gMDtcblxuICAgICAgY29uc3QgZW5jb2RlZCA9IGZsdXNoRVJDMTE1NVRva2Vuc0RhdGEoZm9yd2FyZGVyQWRkcmVzcywgdG9rZW5BZGRyZXNzLCB0b2tlbklkLCBmb3J3YXJkZXJWZXJzaW9uKTtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBkZWNvZGVGbHVzaEVSQzExNTVUb2tlbnNEYXRhKGVuY29kZWQpO1xuXG4gICAgICBkZWNvZGVkLnRva2VuSWQuc2hvdWxkLmVxdWFsKHRva2VuSWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgbGFyZ2UgdG9rZW4gSURzIGZvciBFUkMxMTU1JywgKCkgPT4ge1xuICAgICAgY29uc3QgZm9yd2FyZGVyQWRkcmVzcyA9ICcweDhmOTc3ZTkxMmVmNTAwNTQ4YTBjM2JlNmRkZGU5ODk5ZjExOTliODEnO1xuICAgICAgY29uc3QgdG9rZW5BZGRyZXNzID0gJzB4ZGY3ZGVjYjFiYWE4ZjUyOWYwYzg5ODJjYmI0YmU1MDM1NzE5NTI5OSc7XG4gICAgICBjb25zdCB0b2tlbklkID0gJzExNTc5MjA4OTIzNzMxNjE5NTQyMzU3MDk4NTAwODY4NzkwNzg1MzI2OTk4NDY2NTY0MDU2NDAzOTQ1NzU4NDAwNzkxMzEyOTYzOTkzNSc7IC8vIG1heCB1aW50MjU2XG4gICAgICBjb25zdCBmb3J3YXJkZXJWZXJzaW9uID0gMDtcblxuICAgICAgY29uc3QgZW5jb2RlZCA9IGZsdXNoRVJDMTE1NVRva2Vuc0RhdGEoZm9yd2FyZGVyQWRkcmVzcywgdG9rZW5BZGRyZXNzLCB0b2tlbklkLCBmb3J3YXJkZXJWZXJzaW9uKTtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBkZWNvZGVGbHVzaEVSQzExNTVUb2tlbnNEYXRhKGVuY29kZWQpO1xuXG4gICAgICBkZWNvZGVkLnRva2VuSWQuc2hvdWxkLmVxdWFsKHRva2VuSWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaW52YWxpZCBmbHVzaCBFUkMxMTU1IGRhdGEnLCAoKSA9PiB7XG4gICAgICBjb25zdCBpbnZhbGlkRGF0YSA9ICcweDg3NjU0MzIxJzsgLy8gV3JvbmcgbWV0aG9kIElEXG5cbiAgICAgIHNob3VsZC50aHJvd3MoKCkgPT4ge1xuICAgICAgICBkZWNvZGVGbHVzaEVSQzExNTVUb2tlbnNEYXRhKGludmFsaWREYXRhKTtcbiAgICAgIH0sIC9JbnZhbGlkIGZsdXNoIEVSQzExNTUgYnl0ZWNvZGUvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIG1pc3NpbmcgdG8gYWRkcmVzcyBpbiB2NCsgZGVjb2RlJywgKCkgPT4ge1xuICAgICAgY29uc3QgZm9yd2FyZGVyQWRkcmVzcyA9ICcweDhmOTc3ZTkxMmVmNTAwNTQ4YTBjM2JlNmRkZGU5ODk5ZjExOTliODEnO1xuICAgICAgY29uc3QgdG9rZW5BZGRyZXNzID0gJzB4ZGY3ZGVjYjFiYWE4ZjUyOWYwYzg5ODJjYmI0YmU1MDM1NzE5NTI5OSc7XG4gICAgICBjb25zdCB0b2tlbklkID0gJzk5OTk5JztcbiAgICAgIGNvbnN0IGZvcndhcmRlclZlcnNpb24gPSA0O1xuXG4gICAgICBjb25zdCBlbmNvZGVkID0gZmx1c2hFUkMxMTU1VG9rZW5zRGF0YShmb3J3YXJkZXJBZGRyZXNzLCB0b2tlbkFkZHJlc3MsIHRva2VuSWQsIGZvcndhcmRlclZlcnNpb24pO1xuXG4gICAgICBzaG91bGQudGhyb3dzKCgpID0+IHtcbiAgICAgICAgZGVjb2RlRmx1c2hFUkMxMTU1VG9rZW5zRGF0YShlbmNvZGVkKTsgLy8gTWlzc2luZyAndG8nIHBhcmFtZXRlclxuICAgICAgfSwgL01pc3NpbmcgdG8gYWRkcmVzcy8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRVJDNzIxVHJhbnNmZXJCdWlsZGVyLmJ1aWxkVHJhbnNmZXJGcm9tJywgKCkgPT4ge1xuICAgIGNvbnN0IG93bmVyID0gJzB4MTk2NDUwMzJjN2YxNTMzMzk1ZDQ0YTYyOTQ2MmU3NTEwODRkM2U0ZCc7XG4gICAgY29uc3QgcmVjaXBpZW50ID0gJzB4MTk2NDUwMzJjN2YxNTMzMzk1ZDQ0YTYyOTQ2MmU3NTEwODRkM2U0Yyc7XG4gICAgY29uc3QgaHRzTmZ0QWRkcmVzcyA9ICcweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA3YWMyMDMnO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgdHJhbnNmZXJGcm9tIHdpdGggc2VsZWN0b3IgMHgyM2I4NzJkZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBuZXcgRVJDNzIxVHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICBidWlsZGVyLnRva2VuQ29udHJhY3RBZGRyZXNzKGh0c05mdEFkZHJlc3MpLnRvKHJlY2lwaWVudCkuZnJvbShvd25lcikudG9rZW5JZCgnMTInKTtcblxuICAgICAgY29uc3QgZGF0YSA9IGJ1aWxkZXIuYnVpbGRUcmFuc2ZlckZyb20oKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KGRhdGEpO1xuICAgICAgZGF0YS5zaG91bGQuc3RhcnRXaXRoKEVSQzcyMVRyYW5zZmVyRnJvbU1ldGhvZElkKTsgLy8gMHgyM2I4NzJkZFxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgc2FmZVRyYW5zZmVyRnJvbSB3aXRoIHNlbGVjdG9yIDB4Yjg4ZDRmZGUgdmlhIGJ1aWxkKCknLCAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gbmV3IEVSQzcyMVRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgYnVpbGRlci50b2tlbkNvbnRyYWN0QWRkcmVzcyhodHNOZnRBZGRyZXNzKS50byhyZWNpcGllbnQpLmZyb20ob3duZXIpLnRva2VuSWQoJzEyJyk7XG5cbiAgICAgIGNvbnN0IGRhdGEgPSBidWlsZGVyLmJ1aWxkKCk7XG5cbiAgICAgIHNob3VsZC5leGlzdChkYXRhKTtcbiAgICAgIGRhdGEuc2hvdWxkLnN0YXJ0V2l0aChFUkM3MjFTYWZlVHJhbnNmZXJUeXBlTWV0aG9kSWQpOyAvLyAweGI4OGQ0ZmRlXG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgZGlmZmVyZW50IGVuY29kaW5ncyBmb3IgYnVpbGQoKSB2cyBidWlsZFRyYW5zZmVyRnJvbSgpJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IG5ldyBFUkM3MjFUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICAgIGJ1aWxkZXIudG9rZW5Db250cmFjdEFkZHJlc3MoaHRzTmZ0QWRkcmVzcykudG8ocmVjaXBpZW50KS5mcm9tKG93bmVyKS50b2tlbklkKCcxMicpO1xuXG4gICAgICBjb25zdCBzYWZlVHJhbnNmZXJEYXRhID0gYnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHJhbnNmZXJGcm9tRGF0YSA9IGJ1aWxkZXIuYnVpbGRUcmFuc2ZlckZyb20oKTtcblxuICAgICAgc2FmZVRyYW5zZmVyRGF0YS5zaG91bGQubm90LmVxdWFsKHRyYW5zZmVyRnJvbURhdGEpO1xuICAgICAgLy8gdHJhbnNmZXJGcm9tIGVuY29kaW5nIHNob3VsZCBiZSBzaG9ydGVyIChubyBieXRlcyBwYXJhbSlcbiAgICAgIHRyYW5zZmVyRnJvbURhdGEubGVuZ3RoLnNob3VsZC5iZS5sZXNzVGhhbihzYWZlVHJhbnNmZXJEYXRhLmxlbmd0aCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUb2tlbiBBZGRyZXNzIFZhbGlkYXRpb24nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBwcmVzZXJ2ZSBhZGRyZXNzIGZvcm1hdCBpbiBlbmNvZGluZy9kZWNvZGluZycsICgpID0+IHtcbiAgICAgIGNvbnN0IGZvcndhcmRlckFkZHJlc3MgPSAnMHg4Zjk3N2U5MTJlZjUwMDU0OGEwYzNiZTZkZGRlOTg5OWYxMTk5YjgxJztcbiAgICAgIGNvbnN0IHRva2VuQWRkcmVzc0NoZWNrc3VtID0gJzB4RGY3REVDYjFiQWE4RjUyOUYwQzg5ODJjQkI0QmU1MDM1NzE5NTI5OSc7IC8vIFdpdGggY2hlY2tzdW1cbiAgICAgIGNvbnN0IHRva2VuSWQgPSAnMTIzNDUnO1xuICAgICAgY29uc3QgZm9yd2FyZGVyVmVyc2lvbiA9IDA7XG5cbiAgICAgIGNvbnN0IGVuY29kZWQ3MjEgPSBmbHVzaEVSQzcyMVRva2Vuc0RhdGEoZm9yd2FyZGVyQWRkcmVzcywgdG9rZW5BZGRyZXNzQ2hlY2tzdW0sIHRva2VuSWQsIGZvcndhcmRlclZlcnNpb24pO1xuICAgICAgY29uc3QgZGVjb2RlZDcyMSA9IGRlY29kZUZsdXNoRVJDNzIxVG9rZW5zRGF0YShlbmNvZGVkNzIxKTtcblxuICAgICAgLy8gU2hvdWxkIHByZXNlcnZlIHRoZSBhZGRyZXNzICh0aG91Z2ggbWF5IGxvd2VyY2FzZSBpdClcbiAgICAgIGRlY29kZWQ3MjEudG9rZW5BZGRyZXNzLnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFsKHRva2VuQWRkcmVzc0NoZWNrc3VtLnRvTG93ZXJDYXNlKCkpO1xuXG4gICAgICBjb25zdCBlbmNvZGVkMTE1NSA9IGZsdXNoRVJDMTE1NVRva2Vuc0RhdGEoZm9yd2FyZGVyQWRkcmVzcywgdG9rZW5BZGRyZXNzQ2hlY2tzdW0sIHRva2VuSWQsIGZvcndhcmRlclZlcnNpb24pO1xuICAgICAgY29uc3QgZGVjb2RlZDExNTUgPSBkZWNvZGVGbHVzaEVSQzExNTVUb2tlbnNEYXRhKGVuY29kZWQxMTU1KTtcblxuICAgICAgZGVjb2RlZDExNTUudG9rZW5BZGRyZXNzLnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFsKHRva2VuQWRkcmVzc0NoZWNrc3VtLnRvTG93ZXJDYXNlKCkpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=zamaUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zamaUtils.d.ts","sourceRoot":"","sources":["../../../test/unit/zamaUtils.ts"],"names":[],"mappings":""}
@@ -0,0 +1,251 @@
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
+ const should_1 = __importDefault(require("should"));
7
+ const ethereumjs_abi_1 = __importDefault(require("ethereumjs-abi"));
8
+ const zamaUtils_1 = require("../../src/lib/zamaUtils");
9
+ describe('Zama Utils', () => {
10
+ const ACL_ADDRESS = '0xf0Ffdc93b7E186bC2f8CB3dAA75D86d1930A433D';
11
+ const DELEGATE_ADDRESS = '0x1111111111111111111111111111111111111111';
12
+ const TOKEN_ADDRESS = '0x94167129172A35ab093B44b8b96213DDbc3cD387';
13
+ const TOKEN_ADDRESS_2 = '0x4E7B06D78965594eB5EF5414c357ca21E1554491';
14
+ const TOKEN_ADDRESS_3 = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
15
+ const FORWARDER_ADDRESS = '0xDeADbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF';
16
+ const EXPIRY = Math.floor(Date.now() / 1000) + 365 * 86400;
17
+ // Helper: decode a delegateForUserDecryption call
18
+ function decodeDelegationCall(calldata) {
19
+ const payload = Buffer.from(calldata.slice(10), 'hex');
20
+ const decoded = ethereumjs_abi_1.default.rawDecode(['address', 'address', 'uint64'], payload);
21
+ return [decoded[0].toString('hex'), decoded[1].toString('hex'), Number(decoded[2])];
22
+ }
23
+ // -------------------------------------------------------------------------
24
+ describe('Method IDs', () => {
25
+ it('should have correct selector for delegateForUserDecryption(address,address,uint64)', () => {
26
+ zamaUtils_1.delegateForUserDecryptionMethodId.should.equal('0x04f61a95');
27
+ });
28
+ it('should have correct selector for multicall(bytes[])', () => {
29
+ zamaUtils_1.aclMulticallMethodId.should.equal('0xac9650d8');
30
+ });
31
+ it('should have correct selector for callFromParent(address,uint256,bytes)', () => {
32
+ zamaUtils_1.callFromParentMethodId.should.equal('0x77e60b35');
33
+ });
34
+ it('method IDs should all be distinct', () => {
35
+ const ids = new Set([zamaUtils_1.delegateForUserDecryptionMethodId, zamaUtils_1.aclMulticallMethodId, zamaUtils_1.callFromParentMethodId]);
36
+ ids.size.should.equal(3);
37
+ });
38
+ });
39
+ // -------------------------------------------------------------------------
40
+ describe('buildDelegationCalldata', () => {
41
+ describe('output format', () => {
42
+ it('should produce a 0x-prefixed hex string', () => {
43
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
44
+ calldata.should.be.a.String();
45
+ calldata.should.startWith('0x');
46
+ });
47
+ it('should have exact length: 4-byte selector + 3 × 32-byte ABI words = 100 bytes (202 chars)', () => {
48
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
49
+ calldata.length.should.equal(202); // '0x' + 200 hex chars
50
+ });
51
+ it('should start with delegateForUserDecryption selector', () => {
52
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
53
+ calldata.slice(0, 10).should.equal(zamaUtils_1.delegateForUserDecryptionMethodId);
54
+ });
55
+ });
56
+ describe('ABI parameter encoding — position and value', () => {
57
+ it('should encode delegate address as first ABI word (bytes 4–35)', () => {
58
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
59
+ // First 32-byte word after 4-byte selector = hex chars 10–74
60
+ const word1 = calldata.slice(10, 74);
61
+ word1.should.equal(DELEGATE_ADDRESS.slice(2).toLowerCase().padStart(64, '0'));
62
+ });
63
+ it('should encode token address as second ABI word (bytes 36–67)', () => {
64
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
65
+ const word2 = calldata.slice(74, 138);
66
+ word2.should.equal(TOKEN_ADDRESS.slice(2).toLowerCase().padStart(64, '0'));
67
+ });
68
+ it('should encode expiry timestamp as third ABI word (bytes 68–99)', () => {
69
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
70
+ const word3 = calldata.slice(138, 202);
71
+ const encodedExpiry = EXPIRY.toString(16).padStart(64, '0');
72
+ word3.should.equal(encodedExpiry);
73
+ });
74
+ it('should round-trip decode to original parameters', () => {
75
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
76
+ const [delegate, token, expiry] = decodeDelegationCall(calldata);
77
+ delegate.should.equal(DELEGATE_ADDRESS.slice(2).toLowerCase());
78
+ token.should.equal(TOKEN_ADDRESS.slice(2).toLowerCase());
79
+ expiry.should.equal(EXPIRY);
80
+ });
81
+ });
82
+ describe('parameter isolation', () => {
83
+ it('different delegate addresses should produce different calldata', () => {
84
+ const DELEGATE_2 = '0x2222222222222222222222222222222222222222';
85
+ const c1 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
86
+ const c2 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_2, TOKEN_ADDRESS, EXPIRY);
87
+ c1.should.not.equal(c2);
88
+ // Only first word differs
89
+ c1.slice(10, 74).should.not.equal(c2.slice(10, 74));
90
+ c1.slice(74).should.equal(c2.slice(74)); // token and expiry unchanged
91
+ });
92
+ it('different token addresses should produce different calldata', () => {
93
+ const c1 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
94
+ const c2 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS_2, EXPIRY);
95
+ c1.should.not.equal(c2);
96
+ // Only second word differs
97
+ c1.slice(10, 74).should.equal(c2.slice(10, 74)); // delegate unchanged
98
+ c1.slice(74, 138).should.not.equal(c2.slice(74, 138));
99
+ c1.slice(138).should.equal(c2.slice(138)); // expiry unchanged
100
+ });
101
+ it('different expiry timestamps should produce different calldata', () => {
102
+ const c1 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
103
+ const c2 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY + 86400);
104
+ c1.should.not.equal(c2);
105
+ // Only third word differs
106
+ c1.slice(10, 138).should.equal(c2.slice(10, 138)); // delegate + token unchanged
107
+ c1.slice(138).should.not.equal(c2.slice(138));
108
+ });
109
+ });
110
+ describe('address case handling', () => {
111
+ it('should normalise checksummed (mixed-case) addresses to lowercase in encoding', () => {
112
+ // TOKEN_ADDRESS_3 is EIP-55 checksummed: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
113
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS_3, EXPIRY);
114
+ const word2 = calldata.slice(74, 138);
115
+ word2.should.equal(TOKEN_ADDRESS_3.slice(2).toLowerCase().padStart(64, '0'));
116
+ });
117
+ });
118
+ });
119
+ // -------------------------------------------------------------------------
120
+ describe('buildMulticallDelegationCalldata', () => {
121
+ describe('output format', () => {
122
+ it('should produce a 0x-prefixed hex string', () => {
123
+ const calldata = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS], EXPIRY);
124
+ calldata.should.be.a.String();
125
+ calldata.should.startWith('0x');
126
+ });
127
+ it('should start with multicall selector', () => {
128
+ const calldata = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS], EXPIRY);
129
+ calldata.slice(0, 10).should.equal(zamaUtils_1.aclMulticallMethodId);
130
+ });
131
+ });
132
+ describe('inner call correctness', () => {
133
+ // Strategy: build expected inner calls independently, then verify they are
134
+ // embedded in the multicall payload. This avoids decoding the complex bytes[]
135
+ // ABI structure and directly verifies what matters: the right calls are present.
136
+ it('should contain the expected inner delegation call for each token', () => {
137
+ const inner1 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY).slice(2);
138
+ const inner2 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS_2, EXPIRY).slice(2);
139
+ const inner3 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS_3, EXPIRY).slice(2);
140
+ const calldata = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2, TOKEN_ADDRESS_3], EXPIRY);
141
+ calldata.should.containEql(inner1);
142
+ calldata.should.containEql(inner2);
143
+ calldata.should.containEql(inner3);
144
+ });
145
+ it('single-token multicall should contain its inner call but not others', () => {
146
+ const inner1 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY).slice(2);
147
+ const inner2 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS_2, EXPIRY).slice(2);
148
+ const single = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS], EXPIRY);
149
+ single.should.containEql(inner1);
150
+ single.should.not.containEql(inner2);
151
+ });
152
+ it('each inner call should start with delegateForUserDecryption selector', () => {
153
+ const tokens = [TOKEN_ADDRESS, TOKEN_ADDRESS_2, TOKEN_ADDRESS_3];
154
+ const calldata = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, tokens, EXPIRY);
155
+ for (const token of tokens) {
156
+ const expectedInner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, token, EXPIRY).slice(2);
157
+ // Each inner call starts with delegateForUserDecryption selector
158
+ expectedInner.should.startWith(zamaUtils_1.delegateForUserDecryptionMethodId.slice(2));
159
+ calldata.should.containEql(expectedInner);
160
+ }
161
+ });
162
+ it('different expiry timestamps change all inner calls', () => {
163
+ const c1 = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2], EXPIRY);
164
+ const c2 = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2], EXPIRY + 86400);
165
+ // Inner calls with old expiry should NOT appear in the new multicall
166
+ const inner1Old = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY).slice(2);
167
+ c2.should.not.containEql(inner1Old);
168
+ // And vice versa
169
+ const inner1New = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY + 86400).slice(2);
170
+ c1.should.not.containEql(inner1New);
171
+ });
172
+ it('should produce longer calldata for more tokens', () => {
173
+ const single = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS], EXPIRY);
174
+ const double = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2], EXPIRY);
175
+ const triple = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2, TOKEN_ADDRESS_3], EXPIRY);
176
+ double.length.should.be.greaterThan(single.length);
177
+ triple.length.should.be.greaterThan(double.length);
178
+ });
179
+ it('different token orderings should produce different calldata', () => {
180
+ const c1 = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2], EXPIRY);
181
+ const c2 = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS_2, TOKEN_ADDRESS], EXPIRY);
182
+ c1.should.not.equal(c2);
183
+ });
184
+ });
185
+ describe('error handling', () => {
186
+ it('should throw when given an empty token array', () => {
187
+ should_1.default.throws(() => (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [], EXPIRY), /tokenContractAddresses must not be empty/);
188
+ });
189
+ });
190
+ });
191
+ // -------------------------------------------------------------------------
192
+ describe('wrapInCallFromParent', () => {
193
+ describe('output format', () => {
194
+ it('should produce a 0x-prefixed hex string', () => {
195
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
196
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
197
+ wrapped.should.be.a.String();
198
+ wrapped.should.startWith('0x');
199
+ });
200
+ it('should start with callFromParent selector', () => {
201
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
202
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
203
+ wrapped.slice(0, 10).should.equal(zamaUtils_1.callFromParentMethodId);
204
+ });
205
+ it('should produce longer calldata than the inner calldata', () => {
206
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
207
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(FORWARDER_ADDRESS, inner);
208
+ wrapped.length.should.be.greaterThan(inner.length);
209
+ });
210
+ });
211
+ describe('ABI parameter decoding', () => {
212
+ it('should decode target address correctly', () => {
213
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
214
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
215
+ const payload = Buffer.from(wrapped.slice(10), 'hex');
216
+ const [target] = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
217
+ target.toString('hex').should.equal(ACL_ADDRESS.slice(2).toLowerCase());
218
+ });
219
+ it('should encode value as 0 (no ETH transfer)', () => {
220
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
221
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
222
+ const payload = Buffer.from(wrapped.slice(10), 'hex');
223
+ const [, value] = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
224
+ value.toString().should.equal('0');
225
+ });
226
+ it('should preserve inner calldata exactly', () => {
227
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
228
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
229
+ const payload = Buffer.from(wrapped.slice(10), 'hex');
230
+ const [, , data] = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
231
+ ('0x' + data.toString('hex')).should.equal(inner);
232
+ });
233
+ it('should preserve multicall inner calldata exactly', () => {
234
+ const inner = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2], EXPIRY);
235
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
236
+ const payload = Buffer.from(wrapped.slice(10), 'hex');
237
+ const [, , data] = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
238
+ ('0x' + data.toString('hex')).should.equal(inner);
239
+ });
240
+ });
241
+ describe('target address isolation', () => {
242
+ it('different target addresses should produce different calldata', () => {
243
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
244
+ const w1 = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
245
+ const w2 = (0, zamaUtils_1.wrapInCallFromParent)(FORWARDER_ADDRESS, inner);
246
+ w1.should.not.equal(w2);
247
+ });
248
+ });
249
+ });
250
+ });
251
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiemFtYVV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L3phbWFVdGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG9EQUE0QjtBQUM1QixvRUFBeUM7QUFDekMsdURBT2lDO0FBRWpDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsR0FBRyxFQUFFO0lBQzFCLE1BQU0sV0FBVyxHQUFHLDRDQUE0QyxDQUFDO0lBQ2pFLE1BQU0sZ0JBQWdCLEdBQUcsNENBQTRDLENBQUM7SUFDdEUsTUFBTSxhQUFhLEdBQUcsNENBQTRDLENBQUM7SUFDbkUsTUFBTSxlQUFlLEdBQUcsNENBQTRDLENBQUM7SUFDckUsTUFBTSxlQUFlLEdBQUcsNENBQTRDLENBQUM7SUFDckUsTUFBTSxpQkFBaUIsR0FBRyw0Q0FBNEMsQ0FBQztJQUN2RSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDO0lBRTNELGtEQUFrRDtJQUNsRCxTQUFTLG9CQUFvQixDQUFDLFFBQWdCO1FBQzVDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN2RCxNQUFNLE9BQU8sR0FBRyx3QkFBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDakYsT0FBTyxDQUFFLE9BQU8sQ0FBQyxDQUFDLENBQVksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUcsT0FBTyxDQUFDLENBQUMsQ0FBWSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5RyxD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QUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCBFdGhlcmV1bUFiaSBmcm9tICdldGhlcmV1bWpzLWFiaSc7XG5pbXBvcnQge1xuICBidWlsZERlbGVnYXRpb25DYWxsZGF0YSxcbiAgYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEsXG4gIHdyYXBJbkNhbGxGcm9tUGFyZW50LFxuICBkZWxlZ2F0ZUZvclVzZXJEZWNyeXB0aW9uTWV0aG9kSWQsXG4gIGFjbE11bHRpY2FsbE1ldGhvZElkLFxuICBjYWxsRnJvbVBhcmVudE1ldGhvZElkLFxufSBmcm9tICcuLi8uLi9zcmMvbGliL3phbWFVdGlscyc7XG5cbmRlc2NyaWJlKCdaYW1hIFV0aWxzJywgKCkgPT4ge1xuICBjb25zdCBBQ0xfQUREUkVTUyA9ICcweGYwRmZkYzkzYjdFMTg2YkMyZjhDQjNkQUE3NUQ4NmQxOTMwQTQzM0QnO1xuICBjb25zdCBERUxFR0FURV9BRERSRVNTID0gJzB4MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMSc7XG4gIGNvbnN0IFRPS0VOX0FERFJFU1MgPSAnMHg5NDE2NzEyOTE3MkEzNWFiMDkzQjQ0YjhiOTYyMTNERGJjM2NEMzg3JztcbiAgY29uc3QgVE9LRU5fQUREUkVTU18yID0gJzB4NEU3QjA2RDc4OTY1NTk0ZUI1RUY1NDE0YzM1N2NhMjFFMTU1NDQ5MSc7XG4gIGNvbnN0IFRPS0VOX0FERFJFU1NfMyA9ICcweEEwYjg2OTkxYzYyMThiMzZjMWQxOUQ0YTJlOUViMGNFMzYwNmVCNDgnO1xuICBjb25zdCBGT1JXQVJERVJfQUREUkVTUyA9ICcweERlQURiZWVmZEVBZGJlZWZkRWFkYkVFRmRlYWRiZUVGZEVhRGJlZUYnO1xuICBjb25zdCBFWFBJUlkgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKSArIDM2NSAqIDg2NDAwO1xuXG4gIC8vIEhlbHBlcjogZGVjb2RlIGEgZGVsZWdhdGVGb3JVc2VyRGVjcnlwdGlvbiBjYWxsXG4gIGZ1bmN0aW9uIGRlY29kZURlbGVnYXRpb25DYWxsKGNhbGxkYXRhOiBzdHJpbmcpOiBbc3RyaW5nLCBzdHJpbmcsIG51bWJlcl0ge1xuICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuZnJvbShjYWxsZGF0YS5zbGljZSgxMCksICdoZXgnKTtcbiAgICBjb25zdCBkZWNvZGVkID0gRXRoZXJldW1BYmkucmF3RGVjb2RlKFsnYWRkcmVzcycsICdhZGRyZXNzJywgJ3VpbnQ2NCddLCBwYXlsb2FkKTtcbiAgICByZXR1cm4gWyhkZWNvZGVkWzBdIGFzIEJ1ZmZlcikudG9TdHJpbmcoJ2hleCcpLCAoZGVjb2RlZFsxXSBhcyBCdWZmZXIpLnRvU3RyaW5nKCdoZXgnKSwgTnVtYmVyKGRlY29kZWRbMl0pXTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgZGVzY3JpYmUoJ01ldGhvZCBJRHMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3Qgc2VsZWN0b3IgZm9yIGRlbGVnYXRlRm9yVXNlckRlY3J5cHRpb24oYWRkcmVzcyxhZGRyZXNzLHVpbnQ2NCknLCAoKSA9PiB7XG4gICAgICBkZWxlZ2F0ZUZvclVzZXJEZWNyeXB0aW9uTWV0aG9kSWQuc2hvdWxkLmVxdWFsKCcweDA0ZjYxYTk1Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgY29ycmVjdCBzZWxlY3RvciBmb3IgbXVsdGljYWxsKGJ5dGVzW10pJywgKCkgPT4ge1xuICAgICAgYWNsTXVsdGljYWxsTWV0aG9kSWQuc2hvdWxkLmVxdWFsKCcweGFjOTY1MGQ4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgY29ycmVjdCBzZWxlY3RvciBmb3IgY2FsbEZyb21QYXJlbnQoYWRkcmVzcyx1aW50MjU2LGJ5dGVzKScsICgpID0+IHtcbiAgICAgIGNhbGxGcm9tUGFyZW50TWV0aG9kSWQuc2hvdWxkLmVxdWFsKCcweDc3ZTYwYjM1Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnbWV0aG9kIElEcyBzaG91bGQgYWxsIGJlIGRpc3RpbmN0JywgKCkgPT4ge1xuICAgICAgY29uc3QgaWRzID0gbmV3IFNldChbZGVsZWdhdGVGb3JVc2VyRGVjcnlwdGlvbk1ldGhvZElkLCBhY2xNdWx0aWNhbGxNZXRob2RJZCwgY2FsbEZyb21QYXJlbnRNZXRob2RJZF0pO1xuICAgICAgaWRzLnNpemUuc2hvdWxkLmVxdWFsKDMpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIGRlc2NyaWJlKCdidWlsZERlbGVnYXRpb25DYWxsZGF0YScsICgpID0+IHtcbiAgICBkZXNjcmliZSgnb3V0cHV0IGZvcm1hdCcsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcHJvZHVjZSBhIDB4LXByZWZpeGVkIGhleCBzdHJpbmcnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKTtcbiAgICAgICAgY2FsbGRhdGEuc2hvdWxkLmJlLmEuU3RyaW5nKCk7XG4gICAgICAgIGNhbGxkYXRhLnNob3VsZC5zdGFydFdpdGgoJzB4Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYXZlIGV4YWN0IGxlbmd0aDogNC1ieXRlIHNlbGVjdG9yICsgMyDDlyAzMi1ieXRlIEFCSSB3b3JkcyA9IDEwMCBieXRlcyAoMjAyIGNoYXJzKScsICgpID0+IHtcbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjYWxsZGF0YS5sZW5ndGguc2hvdWxkLmVxdWFsKDIwMik7IC8vICcweCcgKyAyMDAgaGV4IGNoYXJzXG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdGFydCB3aXRoIGRlbGVnYXRlRm9yVXNlckRlY3J5cHRpb24gc2VsZWN0b3InLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKTtcbiAgICAgICAgY2FsbGRhdGEuc2xpY2UoMCwgMTApLnNob3VsZC5lcXVhbChkZWxlZ2F0ZUZvclVzZXJEZWNyeXB0aW9uTWV0aG9kSWQpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQUJJIHBhcmFtZXRlciBlbmNvZGluZyDigJQgcG9zaXRpb24gYW5kIHZhbHVlJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBlbmNvZGUgZGVsZWdhdGUgYWRkcmVzcyBhcyBmaXJzdCBBQkkgd29yZCAoYnl0ZXMgNOKAkzM1KScsICgpID0+IHtcbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICAvLyBGaXJzdCAzMi1ieXRlIHdvcmQgYWZ0ZXIgNC1ieXRlIHNlbGVjdG9yID0gaGV4IGNoYXJzIDEw4oCTNzRcbiAgICAgICAgY29uc3Qgd29yZDEgPSBjYWxsZGF0YS5zbGljZSgxMCwgNzQpO1xuICAgICAgICB3b3JkMS5zaG91bGQuZXF1YWwoREVMRUdBVEVfQUREUkVTUy5zbGljZSgyKS50b0xvd2VyQ2FzZSgpLnBhZFN0YXJ0KDY0LCAnMCcpKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGVuY29kZSB0b2tlbiBhZGRyZXNzIGFzIHNlY29uZCBBQkkgd29yZCAoYnl0ZXMgMzbigJM2NyknLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKTtcbiAgICAgICAgY29uc3Qgd29yZDIgPSBjYWxsZGF0YS5zbGljZSg3NCwgMTM4KTtcbiAgICAgICAgd29yZDIuc2hvdWxkLmVxdWFsKFRPS0VOX0FERFJFU1Muc2xpY2UoMikudG9Mb3dlckNhc2UoKS5wYWRTdGFydCg2NCwgJzAnKSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBlbmNvZGUgZXhwaXJ5IHRpbWVzdGFtcCBhcyB0aGlyZCBBQkkgd29yZCAoYnl0ZXMgNjjigJM5OSknLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKTtcbiAgICAgICAgY29uc3Qgd29yZDMgPSBjYWxsZGF0YS5zbGljZSgxMzgsIDIwMik7XG4gICAgICAgIGNvbnN0IGVuY29kZWRFeHBpcnkgPSBFWFBJUlkudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDY0LCAnMCcpO1xuICAgICAgICB3b3JkMy5zaG91bGQuZXF1YWwoZW5jb2RlZEV4cGlyeSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByb3VuZC10cmlwIGRlY29kZSB0byBvcmlnaW5hbCBwYXJhbWV0ZXJzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IFtkZWxlZ2F0ZSwgdG9rZW4sIGV4cGlyeV0gPSBkZWNvZGVEZWxlZ2F0aW9uQ2FsbChjYWxsZGF0YSk7XG4gICAgICAgIGRlbGVnYXRlLnNob3VsZC5lcXVhbChERUxFR0FURV9BRERSRVNTLnNsaWNlKDIpLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICB0b2tlbi5zaG91bGQuZXF1YWwoVE9LRU5fQUREUkVTUy5zbGljZSgyKS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgZXhwaXJ5LnNob3VsZC5lcXVhbChFWFBJUlkpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncGFyYW1ldGVyIGlzb2xhdGlvbicsICgpID0+IHtcbiAgICAgIGl0KCdkaWZmZXJlbnQgZGVsZWdhdGUgYWRkcmVzc2VzIHNob3VsZCBwcm9kdWNlIGRpZmZlcmVudCBjYWxsZGF0YScsICgpID0+IHtcbiAgICAgICAgY29uc3QgREVMRUdBVEVfMiA9ICcweDIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjInO1xuICAgICAgICBjb25zdCBjMSA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IGMyID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfMiwgVE9LRU5fQUREUkVTUywgRVhQSVJZKTtcbiAgICAgICAgYzEuc2hvdWxkLm5vdC5lcXVhbChjMik7XG4gICAgICAgIC8vIE9ubHkgZmlyc3Qgd29yZCBkaWZmZXJzXG4gICAgICAgIGMxLnNsaWNlKDEwLCA3NCkuc2hvdWxkLm5vdC5lcXVhbChjMi5zbGljZSgxMCwgNzQpKTtcbiAgICAgICAgYzEuc2xpY2UoNzQpLnNob3VsZC5lcXVhbChjMi5zbGljZSg3NCkpOyAvLyB0b2tlbiBhbmQgZXhwaXJ5IHVuY2hhbmdlZFxuICAgICAgfSk7XG5cbiAgICAgIGl0KCdkaWZmZXJlbnQgdG9rZW4gYWRkcmVzc2VzIHNob3VsZCBwcm9kdWNlIGRpZmZlcmVudCBjYWxsZGF0YScsICgpID0+IHtcbiAgICAgICAgY29uc3QgYzEgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCBjMiA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1NfMiwgRVhQSVJZKTtcbiAgICAgICAgYzEuc2hvdWxkLm5vdC5lcXVhbChjMik7XG4gICAgICAgIC8vIE9ubHkgc2Vjb25kIHdvcmQgZGlmZmVyc1xuICAgICAgICBjMS5zbGljZSgxMCwgNzQpLnNob3VsZC5lcXVhbChjMi5zbGljZSgxMCwgNzQpKTsgLy8gZGVsZWdhdGUgdW5jaGFuZ2VkXG4gICAgICAgIGMxLnNsaWNlKDc0LCAxMzgpLnNob3VsZC5ub3QuZXF1YWwoYzIuc2xpY2UoNzQsIDEzOCkpO1xuICAgICAgICBjMS5zbGljZSgxMzgpLnNob3VsZC5lcXVhbChjMi5zbGljZSgxMzgpKTsgLy8gZXhwaXJ5IHVuY2hhbmdlZFxuICAgICAgfSk7XG5cbiAgICAgIGl0KCdkaWZmZXJlbnQgZXhwaXJ5IHRpbWVzdGFtcHMgc2hvdWxkIHByb2R1Y2UgZGlmZmVyZW50IGNhbGxkYXRhJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjMSA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IGMyID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZICsgODY0MDApO1xuICAgICAgICBjMS5zaG91bGQubm90LmVxdWFsKGMyKTtcbiAgICAgICAgLy8gT25seSB0aGlyZCB3b3JkIGRpZmZlcnNcbiAgICAgICAgYzEuc2xpY2UoMTAsIDEzOCkuc2hvdWxkLmVxdWFsKGMyLnNsaWNlKDEwLCAxMzgpKTsgLy8gZGVsZWdhdGUgKyB0b2tlbiB1bmNoYW5nZWRcbiAgICAgICAgYzEuc2xpY2UoMTM4KS5zaG91bGQubm90LmVxdWFsKGMyLnNsaWNlKDEzOCkpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnYWRkcmVzcyBjYXNlIGhhbmRsaW5nJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBub3JtYWxpc2UgY2hlY2tzdW1tZWQgKG1peGVkLWNhc2UpIGFkZHJlc3NlcyB0byBsb3dlcmNhc2UgaW4gZW5jb2RpbmcnLCAoKSA9PiB7XG4gICAgICAgIC8vIFRPS0VOX0FERFJFU1NfMyBpcyBFSVAtNTUgY2hlY2tzdW1tZWQ6IDB4QTBiODY5OTFjNjIxOGIzNmMxZDE5RDRhMmU5RWIwY0UzNjA2ZUI0OFxuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1NfMywgRVhQSVJZKTtcbiAgICAgICAgY29uc3Qgd29yZDIgPSBjYWxsZGF0YS5zbGljZSg3NCwgMTM4KTtcbiAgICAgICAgd29yZDIuc2hvdWxkLmVxdWFsKFRPS0VOX0FERFJFU1NfMy5zbGljZSgyKS50b0xvd2VyQ2FzZSgpLnBhZFN0YXJ0KDY0LCAnMCcpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIGRlc2NyaWJlKCdidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YScsICgpID0+IHtcbiAgICBkZXNjcmliZSgnb3V0cHV0IGZvcm1hdCcsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcHJvZHVjZSBhIDB4LXByZWZpeGVkIGhleCBzdHJpbmcnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgW1RPS0VOX0FERFJFU1NdLCBFWFBJUlkpO1xuICAgICAgICBjYWxsZGF0YS5zaG91bGQuYmUuYS5TdHJpbmcoKTtcbiAgICAgICAgY2FsbGRhdGEuc2hvdWxkLnN0YXJ0V2l0aCgnMHgnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHN0YXJ0IHdpdGggbXVsdGljYWxsIHNlbGVjdG9yJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkTXVsdGljYWxsRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFtUT0tFTl9BRERSRVNTXSwgRVhQSVJZKTtcbiAgICAgICAgY2FsbGRhdGEuc2xpY2UoMCwgMTApLnNob3VsZC5lcXVhbChhY2xNdWx0aWNhbGxNZXRob2RJZCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdpbm5lciBjYWxsIGNvcnJlY3RuZXNzJywgKCkgPT4ge1xuICAgICAgLy8gU3RyYXRlZ3k6IGJ1aWxkIGV4cGVjdGVkIGlubmVyIGNhbGxzIGluZGVwZW5kZW50bHksIHRoZW4gdmVyaWZ5IHRoZXkgYXJlXG4gICAgICAvLyBlbWJlZGRlZCBpbiB0aGUgbXVsdGljYWxsIHBheWxvYWQuIFRoaXMgYXZvaWRzIGRlY29kaW5nIHRoZSBjb21wbGV4IGJ5dGVzW11cbiAgICAgIC8vIEFCSSBzdHJ1Y3R1cmUgYW5kIGRpcmVjdGx5IHZlcmlmaWVzIHdoYXQgbWF0dGVyczogdGhlIHJpZ2h0IGNhbGxzIGFyZSBwcmVzZW50LlxuXG4gICAgICBpdCgnc2hvdWxkIGNvbnRhaW4gdGhlIGV4cGVjdGVkIGlubmVyIGRlbGVnYXRpb24gY2FsbCBmb3IgZWFjaCB0b2tlbicsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXIxID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKS5zbGljZSgyKTtcbiAgICAgICAgY29uc3QgaW5uZXIyID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTU18yLCBFWFBJUlkpLnNsaWNlKDIpO1xuICAgICAgICBjb25zdCBpbm5lcjMgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTXzMsIEVYUElSWSkuc2xpY2UoMik7XG5cbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YShcbiAgICAgICAgICBERUxFR0FURV9BRERSRVNTLFxuICAgICAgICAgIFtUT0tFTl9BRERSRVNTLCBUT0tFTl9BRERSRVNTXzIsIFRPS0VOX0FERFJFU1NfM10sXG4gICAgICAgICAgRVhQSVJZXG4gICAgICAgICk7XG5cbiAgICAgICAgY2FsbGRhdGEuc2hvdWxkLmNvbnRhaW5FcWwoaW5uZXIxKTtcbiAgICAgICAgY2FsbGRhdGEuc2hvdWxkLmNvbnRhaW5FcWwoaW5uZXIyKTtcbiAgICAgICAgY2FsbGRhdGEuc2hvdWxkLmNvbnRhaW5FcWwoaW5uZXIzKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2luZ2xlLXRva2VuIG11bHRpY2FsbCBzaG91bGQgY29udGFpbiBpdHMgaW5uZXIgY2FsbCBidXQgbm90IG90aGVycycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXIxID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKS5zbGljZSgyKTtcbiAgICAgICAgY29uc3QgaW5uZXIyID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTU18yLCBFWFBJUlkpLnNsaWNlKDIpO1xuXG4gICAgICAgIGNvbnN0IHNpbmdsZSA9IGJ1aWxkTXVsdGljYWxsRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFtUT0tFTl9BRERSRVNTXSwgRVhQSVJZKTtcblxuICAgICAgICBzaW5nbGUuc2hvdWxkLmNvbnRhaW5FcWwoaW5uZXIxKTtcbiAgICAgICAgc2luZ2xlLnNob3VsZC5ub3QuY29udGFpbkVxbChpbm5lcjIpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdlYWNoIGlubmVyIGNhbGwgc2hvdWxkIHN0YXJ0IHdpdGggZGVsZWdhdGVGb3JVc2VyRGVjcnlwdGlvbiBzZWxlY3RvcicsICgpID0+IHtcbiAgICAgICAgY29uc3QgdG9rZW5zID0gW1RPS0VOX0FERFJFU1MsIFRPS0VOX0FERFJFU1NfMiwgVE9LRU5fQUREUkVTU18zXTtcbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCB0b2tlbnMsIEVYUElSWSk7XG5cbiAgICAgICAgZm9yIChjb25zdCB0b2tlbiBvZiB0b2tlbnMpIHtcbiAgICAgICAgICBjb25zdCBleHBlY3RlZElubmVyID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgdG9rZW4sIEVYUElSWSkuc2xpY2UoMik7XG4gICAgICAgICAgLy8gRWFjaCBpbm5lciBjYWxsIHN0YXJ0cyB3aXRoIGRlbGVnYXRlRm9yVXNlckRlY3J5cHRpb24gc2VsZWN0b3JcbiAgICAgICAgICBleHBlY3RlZElubmVyLnNob3VsZC5zdGFydFdpdGgoZGVsZWdhdGVGb3JVc2VyRGVjcnlwdGlvbk1ldGhvZElkLnNsaWNlKDIpKTtcbiAgICAgICAgICBjYWxsZGF0YS5zaG91bGQuY29udGFpbkVxbChleHBlY3RlZElubmVyKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGl0KCdkaWZmZXJlbnQgZXhwaXJ5IHRpbWVzdGFtcHMgY2hhbmdlIGFsbCBpbm5lciBjYWxscycsICgpID0+IHtcbiAgICAgICAgY29uc3QgYzEgPSBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBbVE9LRU5fQUREUkVTUywgVE9LRU5fQUREUkVTU18yXSwgRVhQSVJZKTtcbiAgICAgICAgY29uc3QgYzIgPSBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBbVE9LRU5fQUREUkVTUywgVE9LRU5fQUREUkVTU18yXSwgRVhQSVJZICsgODY0MDApO1xuXG4gICAgICAgIC8vIElubmVyIGNhbGxzIHdpdGggb2xkIGV4cGlyeSBzaG91bGQgTk9UIGFwcGVhciBpbiB0aGUgbmV3IG11bHRpY2FsbFxuICAgICAgICBjb25zdCBpbm5lcjFPbGQgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpLnNsaWNlKDIpO1xuICAgICAgICBjMi5zaG91bGQubm90LmNvbnRhaW5FcWwoaW5uZXIxT2xkKTtcblxuICAgICAgICAvLyBBbmQgdmljZSB2ZXJzYVxuICAgICAgICBjb25zdCBpbm5lcjFOZXcgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkgKyA4NjQwMCkuc2xpY2UoMik7XG4gICAgICAgIGMxLnNob3VsZC5ub3QuY29udGFpbkVxbChpbm5lcjFOZXcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcHJvZHVjZSBsb25nZXIgY2FsbGRhdGEgZm9yIG1vcmUgdG9rZW5zJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBzaW5nbGUgPSBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBbVE9LRU5fQUREUkVTU10sIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IGRvdWJsZSA9IGJ1aWxkTXVsdGljYWxsRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFtUT0tFTl9BRERSRVNTLCBUT0tFTl9BRERSRVNTXzJdLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCB0cmlwbGUgPSBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YShcbiAgICAgICAgICBERUxFR0FURV9BRERSRVNTLFxuICAgICAgICAgIFtUT0tFTl9BRERSRVNTLCBUT0tFTl9BRERSRVNTXzIsIFRPS0VOX0FERFJFU1NfM10sXG4gICAgICAgICAgRVhQSVJZXG4gICAgICAgICk7XG4gICAgICAgIGRvdWJsZS5sZW5ndGguc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKHNpbmdsZS5sZW5ndGgpO1xuICAgICAgICB0cmlwbGUubGVuZ3RoLnNob3VsZC5iZS5ncmVhdGVyVGhhbihkb3VibGUubGVuZ3RoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnZGlmZmVyZW50IHRva2VuIG9yZGVyaW5ncyBzaG91bGQgcHJvZHVjZSBkaWZmZXJlbnQgY2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGMxID0gYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgW1RPS0VOX0FERFJFU1MsIFRPS0VOX0FERFJFU1NfMl0sIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IGMyID0gYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgW1RPS0VOX0FERFJFU1NfMiwgVE9LRU5fQUREUkVTU10sIEVYUElSWSk7XG4gICAgICAgIGMxLnNob3VsZC5ub3QuZXF1YWwoYzIpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZXJyb3IgaGFuZGxpbmcnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gZ2l2ZW4gYW4gZW1wdHkgdG9rZW4gYXJyYXknLCAoKSA9PiB7XG4gICAgICAgIHNob3VsZC50aHJvd3MoXG4gICAgICAgICAgKCkgPT4gYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgW10sIEVYUElSWSksXG4gICAgICAgICAgL3Rva2VuQ29udHJhY3RBZGRyZXNzZXMgbXVzdCBub3QgYmUgZW1wdHkvXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICBkZXNjcmliZSgnd3JhcEluQ2FsbEZyb21QYXJlbnQnLCAoKSA9PiB7XG4gICAgZGVzY3JpYmUoJ291dHB1dCBmb3JtYXQnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHByb2R1Y2UgYSAweC1wcmVmaXhlZCBoZXggc3RyaW5nJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbm5lciA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IHdyYXBwZWQgPSB3cmFwSW5DYWxsRnJvbVBhcmVudChBQ0xfQUREUkVTUywgaW5uZXIpO1xuICAgICAgICB3cmFwcGVkLnNob3VsZC5iZS5hLlN0cmluZygpO1xuICAgICAgICB3cmFwcGVkLnNob3VsZC5zdGFydFdpdGgoJzB4Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdGFydCB3aXRoIGNhbGxGcm9tUGFyZW50IHNlbGVjdG9yJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbm5lciA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IHdyYXBwZWQgPSB3cmFwSW5DYWxsRnJvbVBhcmVudChBQ0xfQUREUkVTUywgaW5uZXIpO1xuICAgICAgICB3cmFwcGVkLnNsaWNlKDAsIDEwKS5zaG91bGQuZXF1YWwoY2FsbEZyb21QYXJlbnRNZXRob2RJZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGxvbmdlciBjYWxsZGF0YSB0aGFuIHRoZSBpbm5lciBjYWxsZGF0YScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXIgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCB3cmFwcGVkID0gd3JhcEluQ2FsbEZyb21QYXJlbnQoRk9SV0FSREVSX0FERFJFU1MsIGlubmVyKTtcbiAgICAgICAgd3JhcHBlZC5sZW5ndGguc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKGlubmVyLmxlbmd0aCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdBQkkgcGFyYW1ldGVyIGRlY29kaW5nJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBkZWNvZGUgdGFyZ2V0IGFkZHJlc3MgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbm5lciA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IHdyYXBwZWQgPSB3cmFwSW5DYWxsRnJvbVBhcmVudChBQ0xfQUREUkVTUywgaW5uZXIpO1xuICAgICAgICBjb25zdCBwYXlsb2FkID0gQnVmZmVyLmZyb20od3JhcHBlZC5zbGljZSgxMCksICdoZXgnKTtcbiAgICAgICAgY29uc3QgW3RhcmdldF0gPSBFdGhlcmV1bUFiaS5yYXdEZWNvZGUoWydhZGRyZXNzJywgJ3VpbnQyNTYnLCAnYnl0ZXMnXSwgcGF5bG9hZCk7XG4gICAgICAgICh0YXJnZXQgYXMgQnVmZmVyKS50b1N0cmluZygnaGV4Jykuc2hvdWxkLmVxdWFsKEFDTF9BRERSRVNTLnNsaWNlKDIpLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZW5jb2RlIHZhbHVlIGFzIDAgKG5vIEVUSCB0cmFuc2ZlciknLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlubmVyID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKTtcbiAgICAgICAgY29uc3Qgd3JhcHBlZCA9IHdyYXBJbkNhbGxGcm9tUGFyZW50KEFDTF9BRERSRVNTLCBpbm5lcik7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuZnJvbSh3cmFwcGVkLnNsaWNlKDEwKSwgJ2hleCcpO1xuICAgICAgICBjb25zdCBbLCB2YWx1ZV0gPSBFdGhlcmV1bUFiaS5yYXdEZWNvZGUoWydhZGRyZXNzJywgJ3VpbnQyNTYnLCAnYnl0ZXMnXSwgcGF5bG9hZCk7XG4gICAgICAgIHZhbHVlLnRvU3RyaW5nKCkuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBwcmVzZXJ2ZSBpbm5lciBjYWxsZGF0YSBleGFjdGx5JywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbm5lciA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IHdyYXBwZWQgPSB3cmFwSW5DYWxsRnJvbVBhcmVudChBQ0xfQUREUkVTUywgaW5uZXIpO1xuICAgICAgICBjb25zdCBwYXlsb2FkID0gQnVmZmVyLmZyb20od3JhcHBlZC5zbGljZSgxMCksICdoZXgnKTtcbiAgICAgICAgY29uc3QgWywgLCBkYXRhXSA9IEV0aGVyZXVtQWJpLnJhd0RlY29kZShbJ2FkZHJlc3MnLCAndWludDI1NicsICdieXRlcyddLCBwYXlsb2FkKTtcbiAgICAgICAgKCcweCcgKyAoZGF0YSBhcyBCdWZmZXIpLnRvU3RyaW5nKCdoZXgnKSkuc2hvdWxkLmVxdWFsKGlubmVyKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHByZXNlcnZlIG11bHRpY2FsbCBpbm5lciBjYWxsZGF0YSBleGFjdGx5JywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbm5lciA9IGJ1aWxkTXVsdGljYWxsRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFtUT0tFTl9BRERSRVNTLCBUT0tFTl9BRERSRVNTXzJdLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCB3cmFwcGVkID0gd3JhcEluQ2FsbEZyb21QYXJlbnQoQUNMX0FERFJFU1MsIGlubmVyKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IEJ1ZmZlci5mcm9tKHdyYXBwZWQuc2xpY2UoMTApLCAnaGV4Jyk7XG4gICAgICAgIGNvbnN0IFssICwgZGF0YV0gPSBFdGhlcmV1bUFiaS5yYXdEZWNvZGUoWydhZGRyZXNzJywgJ3VpbnQyNTYnLCAnYnl0ZXMnXSwgcGF5bG9hZCk7XG4gICAgICAgICgnMHgnICsgKGRhdGEgYXMgQnVmZmVyKS50b1N0cmluZygnaGV4JykpLnNob3VsZC5lcXVhbChpbm5lcik7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd0YXJnZXQgYWRkcmVzcyBpc29sYXRpb24nLCAoKSA9PiB7XG4gICAgICBpdCgnZGlmZmVyZW50IHRhcmdldCBhZGRyZXNzZXMgc2hvdWxkIHByb2R1Y2UgZGlmZmVyZW50IGNhbGxkYXRhJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbm5lciA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IHcxID0gd3JhcEluQ2FsbEZyb21QYXJlbnQoQUNMX0FERFJFU1MsIGlubmVyKTtcbiAgICAgICAgY29uc3QgdzIgPSB3cmFwSW5DYWxsRnJvbVBhcmVudChGT1JXQVJERVJfQUREUkVTUywgaW5uZXIpO1xuICAgICAgICB3MS5zaG91bGQubm90LmVxdWFsKHcyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19