@bitgo-beta/abstract-eth 1.0.2-beta.234 → 1.0.2-beta.2341

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 (187) 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 +938 -0
  5. package/dist/src/abstractEthLikeNewCoins.d.ts.map +1 -0
  6. package/dist/src/abstractEthLikeNewCoins.js +2891 -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 +292 -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 +173 -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 +388 -0
  59. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  60. package/dist/src/lib/transactionBuilder.js +1120 -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 +386 -0
  83. package/dist/src/lib/utils.d.ts.map +1 -0
  84. package/dist/src/lib/utils.js +1026 -0
  85. package/dist/src/lib/walletUtil.d.ts +46 -0
  86. package/dist/src/lib/walletUtil.d.ts.map +1 -0
  87. package/dist/src/lib/walletUtil.js +53 -0
  88. package/dist/src/lib/zamaUtils.d.ts +257 -0
  89. package/dist/src/lib/zamaUtils.d.ts.map +1 -0
  90. package/dist/src/lib/zamaUtils.js +527 -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/finalizeUnwrapERC7984.d.ts +3 -0
  152. package/dist/test/unit/transactionBuilder/finalizeUnwrapERC7984.d.ts.map +1 -0
  153. package/dist/test/unit/transactionBuilder/finalizeUnwrapERC7984.js +127 -0
  154. package/dist/test/unit/transactionBuilder/flushERC7984.d.ts +3 -0
  155. package/dist/test/unit/transactionBuilder/flushERC7984.d.ts.map +1 -0
  156. package/dist/test/unit/transactionBuilder/flushERC7984.js +292 -0
  157. package/dist/test/unit/transactionBuilder/flushNft.d.ts +2 -0
  158. package/dist/test/unit/transactionBuilder/flushNft.d.ts.map +1 -0
  159. package/dist/test/unit/transactionBuilder/flushNft.js +381 -0
  160. package/dist/test/unit/transactionBuilder/index.d.ts +10 -0
  161. package/dist/test/unit/transactionBuilder/index.d.ts.map +1 -0
  162. package/dist/test/unit/transactionBuilder/index.js +26 -0
  163. package/dist/test/unit/transactionBuilder/send.d.ts +3 -0
  164. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  165. package/dist/test/unit/transactionBuilder/send.js +197 -0
  166. package/dist/test/unit/transactionBuilder/unwrapERC7984.d.ts +3 -0
  167. package/dist/test/unit/transactionBuilder/unwrapERC7984.d.ts.map +1 -0
  168. package/dist/test/unit/transactionBuilder/unwrapERC7984.js +134 -0
  169. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +11 -0
  170. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  171. package/dist/test/unit/transactionBuilder/walletInitialization.js +137 -0
  172. package/dist/test/unit/transactionBuilder/wrapERC7984.d.ts +3 -0
  173. package/dist/test/unit/transactionBuilder/wrapERC7984.d.ts.map +1 -0
  174. package/dist/test/unit/transactionBuilder/wrapERC7984.js +140 -0
  175. package/dist/test/unit/transferBuilder.d.ts +2 -0
  176. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  177. package/dist/test/unit/transferBuilder.js +76 -0
  178. package/dist/test/unit/utils.d.ts +2 -0
  179. package/dist/test/unit/utils.d.ts.map +1 -0
  180. package/dist/test/unit/utils.js +214 -0
  181. package/dist/test/unit/zamaUtils.d.ts +2 -0
  182. package/dist/test/unit/zamaUtils.d.ts.map +1 -0
  183. package/dist/test/unit/zamaUtils.js +616 -0
  184. package/dist/tsconfig.tsbuildinfo +1 -8442
  185. package/package.json +34 -10
  186. package/.eslintignore +0 -5
  187. package/CHANGELOG.md +0 -178
@@ -0,0 +1,616 @@
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
+ const walletUtil_1 = require("../../src/lib/walletUtil");
10
+ describe('Zama Utils', () => {
11
+ const ACL_ADDRESS = '0xf0Ffdc93b7E186bC2f8CB3dAA75D86d1930A433D';
12
+ const DELEGATE_ADDRESS = '0x1111111111111111111111111111111111111111';
13
+ const TOKEN_ADDRESS = '0x94167129172A35ab093B44b8b96213DDbc3cD387';
14
+ const TOKEN_ADDRESS_2 = '0x4E7B06D78965594eB5EF5414c357ca21E1554491';
15
+ const TOKEN_ADDRESS_3 = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
16
+ const FORWARDER_ADDRESS = '0xDeADbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF';
17
+ // Hoodi hteth:cusdt wrapper (spender for exact-amount approve)
18
+ const WRAPPER_ADDRESS = '0x2debbe0487ef921df4457f9e36ed05be2df1ac75';
19
+ const EXPIRY = Math.floor(Date.now() / 1000) + 365 * 86400;
20
+ // Helper: decode a delegateForUserDecryption call
21
+ function decodeDelegationCall(calldata) {
22
+ const payload = Buffer.from(calldata.slice(10), 'hex');
23
+ const decoded = ethereumjs_abi_1.default.rawDecode(['address', 'address', 'uint64'], payload);
24
+ return [decoded[0].toString('hex'), decoded[1].toString('hex'), Number(decoded[2])];
25
+ }
26
+ // -------------------------------------------------------------------------
27
+ describe('Method IDs', () => {
28
+ it('should have correct selector for delegateForUserDecryption(address,address,uint64)', () => {
29
+ zamaUtils_1.delegateForUserDecryptionMethodId.should.equal('0x04f61a95');
30
+ });
31
+ it('should have correct selector for multicall(bytes[])', () => {
32
+ zamaUtils_1.aclMulticallMethodId.should.equal('0xac9650d8');
33
+ });
34
+ it('should have correct selector for callFromParent(address,uint256,bytes)', () => {
35
+ zamaUtils_1.callFromParentMethodId.should.equal('0x77e60b35');
36
+ });
37
+ it('should have correct selector for approve(address,uint256)', () => {
38
+ zamaUtils_1.approveMethodId.should.equal('0x095ea7b3');
39
+ });
40
+ it('should have correct selector for wrap(address,uint256)', () => {
41
+ zamaUtils_1.wrapMethodId.should.equal('0xbf376c7a');
42
+ });
43
+ it('should have correct selector for unwrap(address,address,bytes32,bytes)', () => {
44
+ zamaUtils_1.unwrapMethodId.should.equal('0x5bf4ef06');
45
+ });
46
+ it('should have correct selector for finalizeUnwrap(bytes32,uint64,bytes)', () => {
47
+ zamaUtils_1.finalizeUnwrapMethodId.should.equal('0x5bb67a05');
48
+ });
49
+ it('method IDs should all be distinct', () => {
50
+ const ids = new Set([
51
+ zamaUtils_1.delegateForUserDecryptionMethodId,
52
+ zamaUtils_1.aclMulticallMethodId,
53
+ zamaUtils_1.callFromParentMethodId,
54
+ zamaUtils_1.approveMethodId,
55
+ zamaUtils_1.wrapMethodId,
56
+ zamaUtils_1.unwrapMethodId,
57
+ zamaUtils_1.finalizeUnwrapMethodId,
58
+ ]);
59
+ ids.size.should.equal(7);
60
+ });
61
+ });
62
+ // -------------------------------------------------------------------------
63
+ describe('buildApproveCalldata', () => {
64
+ const EXACT_AMOUNT = '1000000'; // 1 USDT (6 decimals)
65
+ describe('output format', () => {
66
+ it('should produce a 0x-prefixed hex string', () => {
67
+ const calldata = (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, EXACT_AMOUNT);
68
+ calldata.should.be.a.String();
69
+ calldata.should.startWith('0x');
70
+ });
71
+ it('should have exact length: 4-byte selector + 2 × 32-byte ABI words = 68 bytes (138 chars)', () => {
72
+ const calldata = (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, EXACT_AMOUNT);
73
+ calldata.length.should.equal(138); // '0x' + 136 hex chars
74
+ });
75
+ it('should start with approve selector 0x095ea7b3', () => {
76
+ const calldata = (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, EXACT_AMOUNT);
77
+ calldata.slice(0, 10).should.equal(zamaUtils_1.approveMethodId);
78
+ calldata.slice(0, 10).should.equal('0x095ea7b3');
79
+ });
80
+ });
81
+ describe('ABI parameter encoding', () => {
82
+ it('should encode wrapper as spender in the first ABI word', () => {
83
+ const calldata = (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, EXACT_AMOUNT);
84
+ const word1 = calldata.slice(10, 74);
85
+ word1.should.equal(WRAPPER_ADDRESS.slice(2).toLowerCase().padStart(64, '0'));
86
+ });
87
+ it('should encode exact amount in the second ABI word', () => {
88
+ const calldata = (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, EXACT_AMOUNT);
89
+ const word2 = calldata.slice(74, 138);
90
+ word2.should.equal(BigInt(EXACT_AMOUNT).toString(16).padStart(64, '0'));
91
+ });
92
+ it('should encode approve(0) reset when amount is 0', () => {
93
+ const calldata = (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, 0);
94
+ calldata.slice(0, 10).should.equal(zamaUtils_1.approveMethodId);
95
+ calldata.slice(74, 138).should.equal('0'.repeat(64));
96
+ });
97
+ it('should accept amount as bigint', () => {
98
+ const calldata = (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, 1000000n);
99
+ calldata.slice(74, 138).should.equal(BigInt(EXACT_AMOUNT).toString(16).padStart(64, '0'));
100
+ });
101
+ it('should accept amount as number', () => {
102
+ const calldata = (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, 1000000);
103
+ calldata.slice(74, 138).should.equal(BigInt(EXACT_AMOUNT).toString(16).padStart(64, '0'));
104
+ });
105
+ });
106
+ describe('validation', () => {
107
+ it('should reject an invalid wrapper address', () => {
108
+ (() => (0, zamaUtils_1.buildApproveCalldata)('not-an-address', EXACT_AMOUNT)).should.throw(/invalid wrapper address/);
109
+ });
110
+ it('should reject a bad EIP-55 checksum', () => {
111
+ // Mixed case that does not match the correct checksum
112
+ const badChecksum = '0x2Debbe0487ef921df4457f9e36ed05be2df1ac75';
113
+ (() => (0, zamaUtils_1.buildApproveCalldata)(badChecksum, EXACT_AMOUNT)).should.throw(/invalid wrapper address/);
114
+ });
115
+ it('should accept all-lowercase addresses', () => {
116
+ const calldata = (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS.toLowerCase(), EXACT_AMOUNT);
117
+ calldata.slice(0, 10).should.equal(zamaUtils_1.approveMethodId);
118
+ });
119
+ it('should reject a negative amount', () => {
120
+ (() => (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, -1)).should.throw(/amount must be >= 0/);
121
+ });
122
+ it('should reject a non-numeric amount string', () => {
123
+ (() => (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, 'abc')).should.throw(/invalid amount/);
124
+ });
125
+ });
126
+ });
127
+ // -------------------------------------------------------------------------
128
+ describe('decodeApproveCalldata', () => {
129
+ it('should round-trip buildApproveCalldata with a checksummed spender', () => {
130
+ const decoded = (0, zamaUtils_1.decodeApproveCalldata)((0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, '1000000'));
131
+ decoded.spender.should.equal('0x2dEBbe0487Ef921dF4457F9E36eD05Be2df1AC75');
132
+ decoded.amount.should.equal('1000000');
133
+ });
134
+ it('should decode amount 0 and the uint256 max', () => {
135
+ (0, zamaUtils_1.decodeApproveCalldata)((0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, 0)).amount.should.equal('0');
136
+ const max = (2n ** 256n - 1n).toString();
137
+ (0, zamaUtils_1.decodeApproveCalldata)((0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, max)).amount.should.equal(max);
138
+ });
139
+ it('should reject a non-approve selector', () => {
140
+ should_1.default.throws(() => (0, zamaUtils_1.decodeApproveCalldata)((0, zamaUtils_1.buildWrapCalldata)(WRAPPER_ADDRESS, '1')), /expected approve selector/);
141
+ });
142
+ it('should reject truncated calldata and trailing bytes', () => {
143
+ const valid = (0, zamaUtils_1.buildApproveCalldata)(WRAPPER_ADDRESS, '1');
144
+ should_1.default.throws(() => (0, zamaUtils_1.decodeApproveCalldata)(valid.slice(0, -2)), /expected 68 bytes/);
145
+ should_1.default.throws(() => (0, zamaUtils_1.decodeApproveCalldata)(valid + '00'), /expected 68 bytes/);
146
+ });
147
+ });
148
+ // -------------------------------------------------------------------------
149
+ describe('buildWrapCalldata', () => {
150
+ const RECIPIENT = '0x1111111111111111111111111111111111111111';
151
+ const EXACT_AMOUNT = '1000000';
152
+ const RATE_ONE = '1';
153
+ const RATE_1E12 = '1000000000000'; // hteth:ctest1
154
+ describe('output format', () => {
155
+ it('should produce a 0x-prefixed hex string', () => {
156
+ const calldata = (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, EXACT_AMOUNT, RATE_ONE);
157
+ calldata.should.be.a.String();
158
+ calldata.should.startWith('0x');
159
+ });
160
+ it('should have exact length: 4-byte selector + 2 × 32-byte ABI words = 68 bytes (138 chars)', () => {
161
+ const calldata = (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, EXACT_AMOUNT, RATE_ONE);
162
+ calldata.length.should.equal(138);
163
+ });
164
+ it('should start with wrap selector 0xbf376c7a', () => {
165
+ const calldata = (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, EXACT_AMOUNT, RATE_ONE);
166
+ calldata.slice(0, 10).should.equal(zamaUtils_1.wrapMethodId);
167
+ calldata.slice(0, 10).should.equal('0xbf376c7a');
168
+ });
169
+ });
170
+ describe('ABI parameter encoding', () => {
171
+ it('should encode recipient in the first ABI word', () => {
172
+ const calldata = (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, EXACT_AMOUNT, RATE_ONE);
173
+ const word1 = calldata.slice(10, 74);
174
+ word1.should.equal(RECIPIENT.slice(2).toLowerCase().padStart(64, '0'));
175
+ });
176
+ it('should encode amount in the second ABI word', () => {
177
+ const calldata = (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, EXACT_AMOUNT, RATE_ONE);
178
+ const word2 = calldata.slice(74, 138);
179
+ word2.should.equal(BigInt(EXACT_AMOUNT).toString(16).padStart(64, '0'));
180
+ });
181
+ it('should round-trip through decodeWrapCalldata', () => {
182
+ const calldata = (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, EXACT_AMOUNT, RATE_ONE);
183
+ const decoded = (0, zamaUtils_1.decodeWrapCalldata)(calldata);
184
+ decoded.to.toLowerCase().should.equal(RECIPIENT.toLowerCase());
185
+ decoded.amount.should.equal(EXACT_AMOUNT);
186
+ });
187
+ });
188
+ describe('validation', () => {
189
+ it('should reject an invalid to address', () => {
190
+ (() => (0, zamaUtils_1.buildWrapCalldata)('not-an-address', EXACT_AMOUNT, RATE_ONE)).should.throw(/invalid to address/);
191
+ });
192
+ it('should reject a bad EIP-55 checksum', () => {
193
+ // Mixed case that does not match the correct checksum (same pattern as approve tests)
194
+ const badChecksum = '0x2Debbe0487ef921df4457f9e36ed05be2df1ac75';
195
+ (() => (0, zamaUtils_1.buildWrapCalldata)(badChecksum, EXACT_AMOUNT, RATE_ONE)).should.throw(/invalid to address/);
196
+ });
197
+ it('should reject amount 0', () => {
198
+ (() => (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, 0, RATE_ONE)).should.throw(/amount must be > 0/);
199
+ });
200
+ it('should reject a negative amount', () => {
201
+ (() => (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, -1, RATE_ONE)).should.throw(/amount must be > 0/);
202
+ });
203
+ it('should accept 1 full 18-decimal underlying token for rate 1e12 (mints 1e6)', () => {
204
+ const calldata = (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, '1000000000000000000', RATE_1E12);
205
+ calldata.slice(0, 10).should.equal(zamaUtils_1.wrapMethodId);
206
+ });
207
+ it('should accept the largest amount whose floor(amount / rate) is UINT64_MAX', () => {
208
+ const largest = (zamaUtils_1.UINT64_MAX * BigInt(RATE_1E12) + BigInt(RATE_1E12) - 1n).toString();
209
+ const calldata = (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, largest, RATE_1E12);
210
+ calldata.slice(0, 10).should.equal(zamaUtils_1.wrapMethodId);
211
+ });
212
+ it('should reject the smallest amount whose floor(amount / rate) exceeds uint64', () => {
213
+ const tooLarge = ((zamaUtils_1.UINT64_MAX + 1n) * BigInt(RATE_1E12)).toString();
214
+ (() => (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, tooLarge, RATE_1E12)).should.throw(/amount \/ rate exceeds uint64/);
215
+ });
216
+ it('should reject amount above uint64 for rate 1', () => {
217
+ const tooLarge = (zamaUtils_1.UINT64_MAX + 1n).toString();
218
+ (() => (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, tooLarge, RATE_ONE)).should.throw(/amount \/ rate exceeds uint64/);
219
+ });
220
+ it('should encode without rate when rate is omitted (deserialize path)', () => {
221
+ const calldata = (0, zamaUtils_1.buildWrapCalldata)(RECIPIENT, EXACT_AMOUNT);
222
+ calldata.slice(0, 10).should.equal(zamaUtils_1.wrapMethodId);
223
+ });
224
+ });
225
+ });
226
+ describe('buildUnwrapCalldata', () => {
227
+ const FROM = '0x1111111111111111111111111111111111111111';
228
+ const TO = '0x1111111111111111111111111111111111111111';
229
+ const ENCRYPTED_AMOUNT = '0x' + 'ab'.repeat(32);
230
+ const INPUT_PROOF = '0x' + 'cd'.repeat(64);
231
+ describe('output format', () => {
232
+ it('should produce a 0x-prefixed hex string starting with unwrap selector', () => {
233
+ const calldata = (0, zamaUtils_1.buildUnwrapCalldata)(FROM, TO, ENCRYPTED_AMOUNT, INPUT_PROOF);
234
+ calldata.should.be.a.String();
235
+ calldata.should.startWith(zamaUtils_1.unwrapMethodId);
236
+ calldata.slice(0, 10).should.equal('0x5bf4ef06');
237
+ });
238
+ it('should round-trip through decodeUnwrapCalldata', () => {
239
+ const calldata = (0, zamaUtils_1.buildUnwrapCalldata)(FROM, TO, ENCRYPTED_AMOUNT, INPUT_PROOF);
240
+ const decoded = (0, zamaUtils_1.decodeUnwrapCalldata)(calldata);
241
+ decoded.from.toLowerCase().should.equal(FROM.toLowerCase());
242
+ decoded.to.toLowerCase().should.equal(TO.toLowerCase());
243
+ decoded.encryptedAmount.should.equal(ENCRYPTED_AMOUNT);
244
+ decoded.inputProof.should.equal(INPUT_PROOF);
245
+ });
246
+ });
247
+ describe('validation', () => {
248
+ it('should reject an invalid from address', () => {
249
+ (() => (0, zamaUtils_1.buildUnwrapCalldata)('not-an-address', TO, ENCRYPTED_AMOUNT, INPUT_PROOF)).should.throw(/invalid from address/);
250
+ });
251
+ it('should reject an invalid to address', () => {
252
+ (() => (0, zamaUtils_1.buildUnwrapCalldata)(FROM, 'not-an-address', ENCRYPTED_AMOUNT, INPUT_PROOF)).should.throw(/invalid to address/);
253
+ });
254
+ it('should reject a bad EIP-55 checksum', () => {
255
+ const badChecksum = '0x2Debbe0487ef921df4457f9e36ed05be2df1ac75';
256
+ (() => (0, zamaUtils_1.buildUnwrapCalldata)(badChecksum, TO, ENCRYPTED_AMOUNT, INPUT_PROOF)).should.throw(/invalid from address/);
257
+ });
258
+ it('should reject a non-32-byte encryptedAmount', () => {
259
+ (() => (0, zamaUtils_1.buildUnwrapCalldata)(FROM, TO, '0xabcd', INPUT_PROOF)).should.throw(/encryptedAmount must be a 32-byte/);
260
+ });
261
+ it('should reject an empty inputProof', () => {
262
+ (() => (0, zamaUtils_1.buildUnwrapCalldata)(FROM, TO, ENCRYPTED_AMOUNT, '0x')).should.throw(/inputProof must be a non-empty/);
263
+ });
264
+ });
265
+ });
266
+ describe('buildFinalizeUnwrapCalldata', () => {
267
+ const REQUEST_ID = '0x' + '11'.repeat(32);
268
+ const CLEARTEXT_AMOUNT = '1000000';
269
+ const DECRYPTION_PROOF = '0x' + 'ee'.repeat(64);
270
+ describe('output format', () => {
271
+ it('should produce a 0x-prefixed hex string starting with finalizeUnwrap selector', () => {
272
+ const calldata = (0, zamaUtils_1.buildFinalizeUnwrapCalldata)(REQUEST_ID, CLEARTEXT_AMOUNT, DECRYPTION_PROOF);
273
+ calldata.should.be.a.String();
274
+ calldata.should.startWith(zamaUtils_1.finalizeUnwrapMethodId);
275
+ calldata.slice(0, 10).should.equal('0x5bb67a05');
276
+ });
277
+ it('should round-trip through decodeFinalizeUnwrapCalldata', () => {
278
+ const calldata = (0, zamaUtils_1.buildFinalizeUnwrapCalldata)(REQUEST_ID, CLEARTEXT_AMOUNT, DECRYPTION_PROOF);
279
+ const decoded = (0, zamaUtils_1.decodeFinalizeUnwrapCalldata)(calldata);
280
+ decoded.requestId.should.equal(REQUEST_ID);
281
+ decoded.cleartextAmount.should.equal(CLEARTEXT_AMOUNT);
282
+ decoded.decryptionProof.should.equal(DECRYPTION_PROOF);
283
+ });
284
+ });
285
+ describe('validation', () => {
286
+ it('should reject a non-32-byte requestId', () => {
287
+ (() => (0, zamaUtils_1.buildFinalizeUnwrapCalldata)('0xabcd', CLEARTEXT_AMOUNT, DECRYPTION_PROOF)).should.throw(/requestId must be a 32-byte/);
288
+ });
289
+ it('should reject cleartextAmount of 0', () => {
290
+ (() => (0, zamaUtils_1.buildFinalizeUnwrapCalldata)(REQUEST_ID, '0', DECRYPTION_PROOF)).should.throw(/cleartextAmount must be > 0/);
291
+ });
292
+ it('should reject cleartextAmount exceeding uint64', () => {
293
+ (() => (0, zamaUtils_1.buildFinalizeUnwrapCalldata)(REQUEST_ID, (zamaUtils_1.UINT64_MAX + 1n).toString(), DECRYPTION_PROOF)).should.throw(/cleartextAmount exceeds uint64/);
294
+ });
295
+ it('should accept cleartextAmount equal to UINT64_MAX', () => {
296
+ const calldata = (0, zamaUtils_1.buildFinalizeUnwrapCalldata)(REQUEST_ID, zamaUtils_1.UINT64_MAX.toString(), DECRYPTION_PROOF);
297
+ (0, zamaUtils_1.decodeFinalizeUnwrapCalldata)(calldata).cleartextAmount.should.equal(zamaUtils_1.UINT64_MAX.toString());
298
+ });
299
+ it('should reject an empty decryptionProof', () => {
300
+ (() => (0, zamaUtils_1.buildFinalizeUnwrapCalldata)(REQUEST_ID, CLEARTEXT_AMOUNT, '0x')).should.throw(/decryptionProof must be a non-empty/);
301
+ });
302
+ });
303
+ });
304
+ // -------------------------------------------------------------------------
305
+ describe('buildDelegationCalldata', () => {
306
+ describe('output format', () => {
307
+ it('should produce a 0x-prefixed hex string', () => {
308
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
309
+ calldata.should.be.a.String();
310
+ calldata.should.startWith('0x');
311
+ });
312
+ it('should have exact length: 4-byte selector + 3 × 32-byte ABI words = 100 bytes (202 chars)', () => {
313
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
314
+ calldata.length.should.equal(202); // '0x' + 200 hex chars
315
+ });
316
+ it('should start with delegateForUserDecryption selector', () => {
317
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
318
+ calldata.slice(0, 10).should.equal(zamaUtils_1.delegateForUserDecryptionMethodId);
319
+ });
320
+ });
321
+ describe('ABI parameter encoding — position and value', () => {
322
+ it('should encode delegate address as first ABI word (bytes 4–35)', () => {
323
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
324
+ // First 32-byte word after 4-byte selector = hex chars 10–74
325
+ const word1 = calldata.slice(10, 74);
326
+ word1.should.equal(DELEGATE_ADDRESS.slice(2).toLowerCase().padStart(64, '0'));
327
+ });
328
+ it('should encode token address as second ABI word (bytes 36–67)', () => {
329
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
330
+ const word2 = calldata.slice(74, 138);
331
+ word2.should.equal(TOKEN_ADDRESS.slice(2).toLowerCase().padStart(64, '0'));
332
+ });
333
+ it('should encode expiry timestamp as third ABI word (bytes 68–99)', () => {
334
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
335
+ const word3 = calldata.slice(138, 202);
336
+ const encodedExpiry = EXPIRY.toString(16).padStart(64, '0');
337
+ word3.should.equal(encodedExpiry);
338
+ });
339
+ it('should round-trip decode to original parameters', () => {
340
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
341
+ const [delegate, token, expiry] = decodeDelegationCall(calldata);
342
+ delegate.should.equal(DELEGATE_ADDRESS.slice(2).toLowerCase());
343
+ token.should.equal(TOKEN_ADDRESS.slice(2).toLowerCase());
344
+ expiry.should.equal(EXPIRY);
345
+ });
346
+ });
347
+ describe('parameter isolation', () => {
348
+ it('different delegate addresses should produce different calldata', () => {
349
+ const DELEGATE_2 = '0x2222222222222222222222222222222222222222';
350
+ const c1 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
351
+ const c2 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_2, TOKEN_ADDRESS, EXPIRY);
352
+ c1.should.not.equal(c2);
353
+ // Only first word differs
354
+ c1.slice(10, 74).should.not.equal(c2.slice(10, 74));
355
+ c1.slice(74).should.equal(c2.slice(74)); // token and expiry unchanged
356
+ });
357
+ it('different token addresses should produce different calldata', () => {
358
+ const c1 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
359
+ const c2 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS_2, EXPIRY);
360
+ c1.should.not.equal(c2);
361
+ // Only second word differs
362
+ c1.slice(10, 74).should.equal(c2.slice(10, 74)); // delegate unchanged
363
+ c1.slice(74, 138).should.not.equal(c2.slice(74, 138));
364
+ c1.slice(138).should.equal(c2.slice(138)); // expiry unchanged
365
+ });
366
+ it('different expiry timestamps should produce different calldata', () => {
367
+ const c1 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
368
+ const c2 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY + 86400);
369
+ c1.should.not.equal(c2);
370
+ // Only third word differs
371
+ c1.slice(10, 138).should.equal(c2.slice(10, 138)); // delegate + token unchanged
372
+ c1.slice(138).should.not.equal(c2.slice(138));
373
+ });
374
+ });
375
+ describe('address case handling', () => {
376
+ it('should normalise checksummed (mixed-case) addresses to lowercase in encoding', () => {
377
+ // TOKEN_ADDRESS_3 is EIP-55 checksummed: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
378
+ const calldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS_3, EXPIRY);
379
+ const word2 = calldata.slice(74, 138);
380
+ word2.should.equal(TOKEN_ADDRESS_3.slice(2).toLowerCase().padStart(64, '0'));
381
+ });
382
+ });
383
+ });
384
+ // -------------------------------------------------------------------------
385
+ describe('buildMulticallDelegationCalldata', () => {
386
+ describe('output format', () => {
387
+ it('should produce a 0x-prefixed hex string', () => {
388
+ const calldata = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS], EXPIRY);
389
+ calldata.should.be.a.String();
390
+ calldata.should.startWith('0x');
391
+ });
392
+ it('should start with multicall selector', () => {
393
+ const calldata = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS], EXPIRY);
394
+ calldata.slice(0, 10).should.equal(zamaUtils_1.aclMulticallMethodId);
395
+ });
396
+ });
397
+ describe('inner call correctness', () => {
398
+ // Strategy: build expected inner calls independently, then verify they are
399
+ // embedded in the multicall payload. This avoids decoding the complex bytes[]
400
+ // ABI structure and directly verifies what matters: the right calls are present.
401
+ it('should contain the expected inner delegation call for each token', () => {
402
+ const inner1 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY).slice(2);
403
+ const inner2 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS_2, EXPIRY).slice(2);
404
+ const inner3 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS_3, EXPIRY).slice(2);
405
+ const calldata = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2, TOKEN_ADDRESS_3], EXPIRY);
406
+ calldata.should.containEql(inner1);
407
+ calldata.should.containEql(inner2);
408
+ calldata.should.containEql(inner3);
409
+ });
410
+ it('single-token multicall should contain its inner call but not others', () => {
411
+ const inner1 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY).slice(2);
412
+ const inner2 = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS_2, EXPIRY).slice(2);
413
+ const single = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS], EXPIRY);
414
+ single.should.containEql(inner1);
415
+ single.should.not.containEql(inner2);
416
+ });
417
+ it('each inner call should start with delegateForUserDecryption selector', () => {
418
+ const tokens = [TOKEN_ADDRESS, TOKEN_ADDRESS_2, TOKEN_ADDRESS_3];
419
+ const calldata = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, tokens, EXPIRY);
420
+ for (const token of tokens) {
421
+ const expectedInner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, token, EXPIRY).slice(2);
422
+ // Each inner call starts with delegateForUserDecryption selector
423
+ expectedInner.should.startWith(zamaUtils_1.delegateForUserDecryptionMethodId.slice(2));
424
+ calldata.should.containEql(expectedInner);
425
+ }
426
+ });
427
+ it('different expiry timestamps change all inner calls', () => {
428
+ const c1 = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2], EXPIRY);
429
+ const c2 = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2], EXPIRY + 86400);
430
+ // Inner calls with old expiry should NOT appear in the new multicall
431
+ const inner1Old = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY).slice(2);
432
+ c2.should.not.containEql(inner1Old);
433
+ // And vice versa
434
+ const inner1New = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY + 86400).slice(2);
435
+ c1.should.not.containEql(inner1New);
436
+ });
437
+ it('should produce longer calldata for more tokens', () => {
438
+ const single = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS], EXPIRY);
439
+ const double = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2], EXPIRY);
440
+ const triple = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2, TOKEN_ADDRESS_3], EXPIRY);
441
+ double.length.should.be.greaterThan(single.length);
442
+ triple.length.should.be.greaterThan(double.length);
443
+ });
444
+ it('different token orderings should produce different calldata', () => {
445
+ const c1 = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2], EXPIRY);
446
+ const c2 = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS_2, TOKEN_ADDRESS], EXPIRY);
447
+ c1.should.not.equal(c2);
448
+ });
449
+ });
450
+ describe('error handling', () => {
451
+ it('should throw when given an empty token array', () => {
452
+ should_1.default.throws(() => (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [], EXPIRY), /tokenContractAddresses must not be empty/);
453
+ });
454
+ });
455
+ });
456
+ // -------------------------------------------------------------------------
457
+ describe('wrapInCallFromParent', () => {
458
+ describe('output format', () => {
459
+ it('should produce a 0x-prefixed hex string', () => {
460
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
461
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
462
+ wrapped.should.be.a.String();
463
+ wrapped.should.startWith('0x');
464
+ });
465
+ it('should start with callFromParent selector', () => {
466
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
467
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
468
+ wrapped.slice(0, 10).should.equal(zamaUtils_1.callFromParentMethodId);
469
+ });
470
+ it('should produce longer calldata than the inner calldata', () => {
471
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
472
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(FORWARDER_ADDRESS, inner);
473
+ wrapped.length.should.be.greaterThan(inner.length);
474
+ });
475
+ });
476
+ describe('ABI parameter decoding', () => {
477
+ it('should decode target address correctly', () => {
478
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
479
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
480
+ const payload = Buffer.from(wrapped.slice(10), 'hex');
481
+ const [target] = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
482
+ target.toString('hex').should.equal(ACL_ADDRESS.slice(2).toLowerCase());
483
+ });
484
+ it('should encode value as 0 (no ETH transfer)', () => {
485
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
486
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
487
+ const payload = Buffer.from(wrapped.slice(10), 'hex');
488
+ const [, value] = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
489
+ value.toString().should.equal('0');
490
+ });
491
+ it('should preserve inner calldata exactly', () => {
492
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
493
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
494
+ const payload = Buffer.from(wrapped.slice(10), 'hex');
495
+ const [, , data] = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
496
+ ('0x' + data.toString('hex')).should.equal(inner);
497
+ });
498
+ it('should preserve multicall inner calldata exactly', () => {
499
+ const inner = (0, zamaUtils_1.buildMulticallDelegationCalldata)(DELEGATE_ADDRESS, [TOKEN_ADDRESS, TOKEN_ADDRESS_2], EXPIRY);
500
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
501
+ const payload = Buffer.from(wrapped.slice(10), 'hex');
502
+ const [, , data] = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
503
+ ('0x' + data.toString('hex')).should.equal(inner);
504
+ });
505
+ });
506
+ describe('target address isolation', () => {
507
+ it('different target addresses should produce different calldata', () => {
508
+ const inner = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
509
+ const w1 = (0, zamaUtils_1.wrapInCallFromParent)(ACL_ADDRESS, inner);
510
+ const w2 = (0, zamaUtils_1.wrapInCallFromParent)(FORWARDER_ADDRESS, inner);
511
+ w1.should.not.equal(w2);
512
+ });
513
+ });
514
+ });
515
+ // -------------------------------------------------------------------------
516
+ describe('buildConfidentialTransferByHandleCalldata', () => {
517
+ const HANDLE = '0x' + 'ab'.repeat(32); // 32-byte mock handle
518
+ it('should return a 0x-prefixed hex string', () => {
519
+ const result = (0, zamaUtils_1.buildConfidentialTransferByHandleCalldata)(DELEGATE_ADDRESS, HANDLE);
520
+ result.should.be.a.String();
521
+ result.should.startWith('0x');
522
+ });
523
+ it('should start with the confidentialTransferNoProof selector (0x5bebed7e)', () => {
524
+ const result = (0, zamaUtils_1.buildConfidentialTransferByHandleCalldata)(DELEGATE_ADDRESS, HANDLE);
525
+ result.should.startWith(walletUtil_1.confidentialTransferNoProofMethodId);
526
+ });
527
+ it('should encode the recipient address correctly', () => {
528
+ const result = (0, zamaUtils_1.buildConfidentialTransferByHandleCalldata)(DELEGATE_ADDRESS, HANDLE);
529
+ const payload = Buffer.from(result.slice(10), 'hex');
530
+ const decoded = ethereumjs_abi_1.default.rawDecode(['address', 'bytes32'], payload);
531
+ ('0x' + decoded[0].toString('hex')).toLowerCase().should.equal(DELEGATE_ADDRESS.toLowerCase());
532
+ });
533
+ it('should encode the encrypted handle correctly', () => {
534
+ const result = (0, zamaUtils_1.buildConfidentialTransferByHandleCalldata)(DELEGATE_ADDRESS, HANDLE);
535
+ const payload = Buffer.from(result.slice(10), 'hex');
536
+ const decoded = ethereumjs_abi_1.default.rawDecode(['address', 'bytes32'], payload);
537
+ ('0x' + decoded[1].toString('hex')).should.equal(HANDLE);
538
+ });
539
+ it('different handles should produce different calldata', () => {
540
+ const h1 = '0x' + '01'.repeat(32);
541
+ const h2 = '0x' + '02'.repeat(32);
542
+ (0, zamaUtils_1.buildConfidentialTransferByHandleCalldata)(DELEGATE_ADDRESS, h1).should.not.equal((0, zamaUtils_1.buildConfidentialTransferByHandleCalldata)(DELEGATE_ADDRESS, h2));
543
+ });
544
+ it('different recipient addresses should produce different calldata', () => {
545
+ (0, zamaUtils_1.buildConfidentialTransferByHandleCalldata)(DELEGATE_ADDRESS, HANDLE).should.not.equal((0, zamaUtils_1.buildConfidentialTransferByHandleCalldata)(TOKEN_ADDRESS, HANDLE));
546
+ });
547
+ });
548
+ // -------------------------------------------------------------------------
549
+ describe('buildFlushERC7984ForwarderTokenCalldata', () => {
550
+ const PARENT_ADDRESS = '0x2222222222222222222222222222222222222222';
551
+ const HANDLE = '0x' + 'cd'.repeat(32);
552
+ it('should return a 0x-prefixed hex string', () => {
553
+ const result = (0, zamaUtils_1.buildFlushERC7984ForwarderTokenCalldata)(TOKEN_ADDRESS, PARENT_ADDRESS, HANDLE);
554
+ result.should.be.a.String();
555
+ result.should.startWith('0x');
556
+ });
557
+ it('should start with the callFromParent selector', () => {
558
+ const result = (0, zamaUtils_1.buildFlushERC7984ForwarderTokenCalldata)(TOKEN_ADDRESS, PARENT_ADDRESS, HANDLE);
559
+ result.should.startWith(zamaUtils_1.callFromParentMethodId);
560
+ });
561
+ it('inner calldata should start with confidentialTransferNoProof selector', () => {
562
+ const result = (0, zamaUtils_1.buildFlushERC7984ForwarderTokenCalldata)(TOKEN_ADDRESS, PARENT_ADDRESS, HANDLE);
563
+ const payload = Buffer.from(result.slice(10), 'hex');
564
+ const decoded = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
565
+ const innerCalldata = '0x' + decoded[2].toString('hex');
566
+ innerCalldata.should.startWith(walletUtil_1.confidentialTransferNoProofMethodId);
567
+ });
568
+ it('outer target address should equal the token contract address', () => {
569
+ const result = (0, zamaUtils_1.buildFlushERC7984ForwarderTokenCalldata)(TOKEN_ADDRESS, PARENT_ADDRESS, HANDLE);
570
+ const payload = Buffer.from(result.slice(10), 'hex');
571
+ const decoded = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
572
+ ('0x' + decoded[0].toString('hex')).toLowerCase().should.equal(TOKEN_ADDRESS.toLowerCase());
573
+ });
574
+ it('inner recipient should equal the parent address', () => {
575
+ const result = (0, zamaUtils_1.buildFlushERC7984ForwarderTokenCalldata)(TOKEN_ADDRESS, PARENT_ADDRESS, HANDLE);
576
+ const payload = Buffer.from(result.slice(10), 'hex');
577
+ const decoded = ethereumjs_abi_1.default.rawDecode(['address', 'uint256', 'bytes'], payload);
578
+ const innerCalldata = '0x' + decoded[2].toString('hex');
579
+ const innerPayload = Buffer.from(innerCalldata.slice(10), 'hex');
580
+ const innerDecoded = ethereumjs_abi_1.default.rawDecode(['address', 'bytes32'], innerPayload);
581
+ ('0x' + innerDecoded[0].toString('hex')).toLowerCase().should.equal(PARENT_ADDRESS.toLowerCase());
582
+ });
583
+ it('different token addresses should produce different calldata', () => {
584
+ (0, zamaUtils_1.buildFlushERC7984ForwarderTokenCalldata)(TOKEN_ADDRESS, PARENT_ADDRESS, HANDLE).should.not.equal((0, zamaUtils_1.buildFlushERC7984ForwarderTokenCalldata)(TOKEN_ADDRESS_2, PARENT_ADDRESS, HANDLE));
585
+ });
586
+ });
587
+ // -------------------------------------------------------------------------
588
+ describe('decodeFlushERC7984ForwarderTokenCalldata', () => {
589
+ const PARENT_ADDRESS = '0x2222222222222222222222222222222222222222';
590
+ const HANDLE = '0x' + 'ef'.repeat(32);
591
+ it('should round-trip encode and decode correctly', () => {
592
+ const encoded = (0, zamaUtils_1.buildFlushERC7984ForwarderTokenCalldata)(TOKEN_ADDRESS, PARENT_ADDRESS, HANDLE);
593
+ const decoded = (0, zamaUtils_1.decodeFlushERC7984ForwarderTokenCalldata)(encoded);
594
+ decoded.tokenContractAddress.toLowerCase().should.equal(TOKEN_ADDRESS.toLowerCase());
595
+ decoded.parentAddress.toLowerCase().should.equal(PARENT_ADDRESS.toLowerCase());
596
+ decoded.encryptedHandle.should.equal(HANDLE);
597
+ });
598
+ it('should throw for calldata with wrong outer selector', () => {
599
+ const bad = '0xdeadbeef' + '00'.repeat(64);
600
+ should_1.default.throws(() => (0, zamaUtils_1.decodeFlushERC7984ForwarderTokenCalldata)(bad), /Invalid FlushERC7984ForwarderToken calldata/);
601
+ });
602
+ it('should throw for calldata with correct outer but wrong inner selector', () => {
603
+ // Wrap delegation calldata in callFromParent — inner starts with 0x04f61a95, not 0x5bebed7e
604
+ const innerCalldata = (0, zamaUtils_1.buildDelegationCalldata)(DELEGATE_ADDRESS, TOKEN_ADDRESS, EXPIRY);
605
+ const wrapped = (0, zamaUtils_1.wrapInCallFromParent)(TOKEN_ADDRESS, innerCalldata);
606
+ should_1.default.throws(() => (0, zamaUtils_1.decodeFlushERC7984ForwarderTokenCalldata)(wrapped), /Invalid FlushERC7984ForwarderToken inner calldata/);
607
+ });
608
+ it('decoded tokenContractAddress should be checksummed or lowercase consistently', () => {
609
+ const encoded = (0, zamaUtils_1.buildFlushERC7984ForwarderTokenCalldata)(TOKEN_ADDRESS, PARENT_ADDRESS, HANDLE);
610
+ const decoded = (0, zamaUtils_1.decodeFlushERC7984ForwarderTokenCalldata)(encoded);
611
+ should_1.default.exist(decoded.tokenContractAddress);
612
+ decoded.tokenContractAddress.should.be.a.String();
613
+ });
614
+ });
615
+ });
616
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiemFtYVV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L3phbWFVdGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG9EQUE0QjtBQUM1QixvRUFBeUM7QUFDekMsdURBdUJpQztBQUNqQyx5REFBK0U7QUFFL0UsUUFBUSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUU7SUFDMUIsTUFBTSxXQUFXLEdBQUcsNENBQTRDLENBQUM7SUFDakUsTUFBTSxnQkFBZ0IsR0FBRyw0Q0FBNEMsQ0FBQztJQUN0RSxNQUFNLGFBQWEsR0FBRyw0Q0FBNEMsQ0FBQztJQUNuRSxNQUFNLGVBQWUsR0FBRyw0Q0FBNEMsQ0FBQztJQUNyRSxNQUFNLGVBQWUsR0FBRyw0Q0FBNEMsQ0FBQztJQUNyRSxNQUFNLGlCQUFpQixHQUFHLDRDQUE0QyxDQUFDO0lBQ3ZFLCtEQUErRDtJQUMvRCxNQUFNLGVBQWUsR0FBRyw0Q0FBNEMsQ0FBQztJQUNyRSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDO0lBRTNELGtEQUFrRDtJQUNsRCxTQUFTLG9CQUFvQixDQUFDLFFBQWdCO1FBQzVDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN2RCxNQUFNLE9BQU8sR0FBRyx3QkFBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDakYsT0FBTyxDQUFFLE9BQU8sQ0FBQyxDQUFDLENBQVksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUcsT0FBTyxDQUFDLENBQUMsQ0FBWSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5RyxDQUFDO0lBRUQsNEVBQTRFO0lBQzVFLFFBQVEsQ0FBQyxZQUFZLEVBQUUsR0FBRyxFQUFFO1FBQzFCLEVBQUUsQ0FBQyxvRkFBb0YsRUFBRSxHQUFHLEVBQUU7WUFDNUYsNkNBQWlDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMvRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxxREFBcUQsRUFBRSxHQUFHLEVBQUU7WUFDN0QsZ0NBQW9CLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx3RUFBd0UsRUFBRSxHQUFHLEVBQUU7WUFDaEYsa0NBQXNCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyREFBMkQsRUFBRSxHQUFHLEVBQUU7WUFDbkUsMkJBQWUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHdEQUF3RCxFQUFFLEdBQUcsRUFBRTtZQUNoRSx3QkFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0VBQXdFLEVBQUUsR0FBRyxFQUFFO1lBQ2hGLDBCQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM1QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1RUFBdUUsRUFBRSxHQUFHLEVBQUU7WUFDL0Usa0NBQXNCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxtQ0FBbUMsRUFBRSxHQUFHLEVBQUU7WUFDM0MsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7Z0JBQ2xCLDZDQUFpQztnQkFDakMsZ0NBQW9CO2dCQUNwQixrQ0FBc0I7Z0JBQ3RCLDJCQUFlO2dCQUNmLHdCQUFZO2dCQUNaLDBCQUFjO2dCQUNkLGtDQUFzQjthQUN2QixDQUFDLENBQUM7WUFDSCxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILDRFQUE0RTtJQUM1RSxRQUFRLENBQUMsc0JBQXNCLEVBQUUsR0FBRyxFQUFFO1FBQ3BDLE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQyxDQUFDLHNCQUFzQjtRQUV0RCxRQUFRLENBQUMsZUFBZSxFQUFFLEdBQUcsRUFBRTtZQUM3QixFQUFFLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO2dCQUNqRCxNQUFNLFFBQVEsR0FBRyxJQUFBLGdDQUFvQixFQUFDLGVBQWUsRUFBRSxZQUFZLENBQUMsQ0FBQztnQkFDckUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUM5QixRQUFRLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQywwRkFBMEYsRUFBRSxHQUFHLEVBQUU7Z0JBQ2xHLE1BQU0sUUFBUSxHQUFHLElBQUEsZ0NBQW9CLEVBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUNyRSxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyx1QkFBdUI7WUFDNUQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsK0NBQStDLEVBQUUsR0FBRyxFQUFFO2dCQUN2RCxNQUFNLFFBQVEsR0FBRyxJQUFBLGdDQUFvQixFQUFDLGVBQWUsRUFBRSxZQUFZLENBQUMsQ0FBQztnQkFDckUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBZSxDQUFDLENBQUM7Z0JBQ3BELFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDbkQsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLEVBQUU7WUFDdEMsRUFBRSxDQUFDLHdEQUF3RCxFQUFFLEdBQUcsRUFBRTtnQkFDaEUsTUFBTSxRQUFRLEdBQUcsSUFBQSxnQ0FBb0IsRUFBQyxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0JBQ3JFLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUNyQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUMvRSxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxtREFBbUQsRUFBRSxHQUFHLEVBQUU7Z0JBQzNELE1BQU0sUUFBUSxHQUFHLElBQUEsZ0NBQW9CLEVBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUNyRSxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDdEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDMUUsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsaURBQWlELEVBQUUsR0FBRyxFQUFFO2dCQUN6RCxNQUFNLFFBQVEsR0FBRyxJQUFBLGdDQUFvQixFQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDMUQsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBZSxDQUFDLENBQUM7Z0JBQ3BELFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEdBQUcsRUFBRTtnQkFDeEMsTUFBTSxRQUFRLEdBQUcsSUFBQSxnQ0FBb0IsRUFBQyxlQUFlLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQ2pFLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDNUYsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsR0FBRyxFQUFFO2dCQUN4QyxNQUFNLFFBQVEsR0FBRyxJQUFBLGdDQUFvQixFQUFDLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDaEUsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUM1RixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUU7WUFDMUIsRUFBRSxDQUFDLDBDQUEwQyxFQUFFLEdBQUcsRUFBRTtnQkFDbEQsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFBLGdDQUFvQixFQUFDLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1lBQ3ZHLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHFDQUFxQyxFQUFFLEdBQUcsRUFBRTtnQkFDN0Msc0RBQXNEO2dCQUN0RCxNQUFNLFdBQVcsR0FBRyw0Q0FBNEMsQ0FBQztnQkFDakUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFBLGdDQUFvQixFQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztZQUNsRyxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRSxHQUFHLEVBQUU7Z0JBQy9DLE1BQU0sUUFBUSxHQUFHLElBQUEsZ0NBQW9CLEVBQUMsZUFBZSxDQUFDLFdBQVcsRUFBRSxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUNuRixRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDJCQUFlLENBQUMsQ0FBQztZQUN0RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxpQ0FBaUMsRUFBRSxHQUFHLEVBQUU7Z0JBQ3pDLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSxnQ0FBb0IsRUFBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUN4RixDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQywyQ0FBMkMsRUFBRSxHQUFHLEVBQUU7Z0JBQ25ELENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSxnQ0FBb0IsRUFBQyxlQUFlLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDdEYsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsNEVBQTRFO0lBQzVFLFFBQVEsQ0FBQyx1QkFBdUIsRUFBRSxHQUFHLEVBQUU7UUFDckMsRUFBRSxDQUFDLG1FQUFtRSxFQUFFLEdBQUcsRUFBRTtZQUMzRSxNQUFNLE9BQU8sR0FBRyxJQUFBLGlDQUFxQixFQUFDLElBQUEsZ0NBQW9CLEVBQUMsZUFBZSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDeEYsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDRDQUE0QyxDQUFDLENBQUM7WUFDM0UsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFLEdBQUcsRUFBRTtZQUNwRCxJQUFBLGlDQUFxQixFQUFDLElBQUEsZ0NBQW9CLEVBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDekYsTUFBTSxHQUFHLEdBQUcsQ0FBQyxFQUFFLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3pDLElBQUEsaUNBQXFCLEVBQUMsSUFBQSxnQ0FBb0IsRUFBQyxlQUFlLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3RixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUU7WUFDOUMsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSxpQ0FBcUIsRUFBQyxJQUFBLDZCQUFpQixFQUFDLGVBQWUsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLDJCQUEyQixDQUFDLENBQUM7UUFDbkgsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscURBQXFELEVBQUUsR0FBRyxFQUFFO1lBQzdELE1BQU0sS0FBSyxHQUFHLElBQUEsZ0NBQW9CLEVBQUMsZUFBZSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3pELGdCQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUEsaUNBQXFCLEVBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLG1CQUFtQixDQUFDLENBQUM7WUFDcEYsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSxpQ0FBcUIsRUFBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztRQUNoRixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsNEVBQTRFO0lBQzVFLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLEVBQUU7UUFDakMsTUFBTSxTQUFTLEdBQUcsNENBQTRDLENBQUM7UUFDL0QsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDO1FBQy9CLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQztRQUNyQixNQUFNLFNBQVMsR0FBRyxlQUFlLENBQUMsQ0FBQyxlQUFlO1FBRWxELFFBQVEsQ0FBQyxlQUFlLEVBQUUsR0FBRyxFQUFFO1lBQzdCLEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7Z0JBQ2pELE1BQU0sUUFBUSxHQUFHLElBQUEsNkJBQWlCLEVBQUMsU0FBUyxFQUFFLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDdEUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUM5QixRQUFRLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQywwRkFBMEYsRUFBRSxHQUFHLEVBQUU7Z0JBQ2xHLE1BQU0sUUFBUSxHQUFHLElBQUEsNkJBQWlCLEVBQUMsU0FBUyxFQUFFLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDdEUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BDLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFLEdBQUcsRUFBRTtnQkFDcEQsTUFBTSxRQUFRLEdBQUcsSUFBQSw2QkFBaUIsRUFBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUN0RSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHdCQUFZLENBQUMsQ0FBQztnQkFDakQsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNuRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLHdCQUF3QixFQUFFLEdBQUcsRUFBRTtZQUN0QyxFQUFFLENBQUMsK0NBQStDLEVBQUUsR0FBRyxFQUFFO2dCQUN2RCxNQUFNLFFBQVEsR0FBRyxJQUFBLDZCQUFpQixFQUFDLFNBQVMsRUFBRSxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQ3RFLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUNyQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN6RSxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyw2Q0FBNkMsRUFBRSxHQUFHLEVBQUU7Z0JBQ3JELE1BQU0sUUFBUSxHQUFHLElBQUEsNkJBQWlCLEVBQUMsU0FBUyxFQUFFLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDdEUsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3RDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzFFLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDhDQUE4QyxFQUFFLEdBQUcsRUFBRTtnQkFDdEQsTUFBTSxRQUFRLEdBQUcsSUFBQSw2QkFBaUIsRUFBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUN0RSxNQUFNLE9BQU8sR0FBRyxJQUFBLDhCQUFrQixFQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUM3QyxPQUFPLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7Z0JBQy9ELE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM1QyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUU7WUFDMUIsRUFBRSxDQUFDLHFDQUFxQyxFQUFFLEdBQUcsRUFBRTtnQkFDN0MsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFBLDZCQUFpQixFQUFDLGdCQUFnQixFQUFFLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUN6RyxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxxQ0FBcUMsRUFBRSxHQUFHLEVBQUU7Z0JBQzdDLHNGQUFzRjtnQkFDdEYsTUFBTSxXQUFXLEdBQUcsNENBQTRDLENBQUM7Z0JBQ2pFLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSw2QkFBaUIsRUFBQyxXQUFXLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBQ3BHLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHdCQUF3QixFQUFFLEdBQUcsRUFBRTtnQkFDaEMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFBLDZCQUFpQixFQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUM7WUFDdkYsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsaUNBQWlDLEVBQUUsR0FBRyxFQUFFO2dCQUN6QyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUEsNkJBQWlCLEVBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBQ3hGLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDRFQUE0RSxFQUFFLEdBQUcsRUFBRTtnQkFDcEYsTUFBTSxRQUFRLEdBQUcsSUFBQSw2QkFBaUIsRUFBQyxTQUFTLEVBQUUscUJBQXFCLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQ2hGLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsd0JBQVksQ0FBQyxDQUFDO1lBQ25ELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDJFQUEyRSxFQUFFLEdBQUcsRUFBRTtnQkFDbkYsTUFBTSxPQUFPLEdBQUcsQ0FBQyxzQkFBVSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3JGLE1BQU0sUUFBUSxHQUFHLElBQUEsNkJBQWlCLEVBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDbEUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx3QkFBWSxDQUFDLENBQUM7WUFDbkQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsNkVBQTZFLEVBQUUsR0FBRyxFQUFFO2dCQUNyRixNQUFNLFFBQVEsR0FBRyxDQUFDLENBQUMsc0JBQVUsR0FBRyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDcEUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFBLDZCQUFpQixFQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixDQUFDLENBQUM7WUFDMUcsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsOENBQThDLEVBQUUsR0FBRyxFQUFFO2dCQUN0RCxNQUFNLFFBQVEsR0FBRyxDQUFDLHNCQUFVLEdBQUcsRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQzlDLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSw2QkFBaUIsRUFBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1lBQ3pHLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLG9FQUFvRSxFQUFFLEdBQUcsRUFBRTtnQkFDNUUsTUFBTSxRQUFRLEdBQUcsSUFBQSw2QkFBaUIsRUFBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0JBQzVELFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsd0JBQVksQ0FBQyxDQUFDO1lBQ25ELENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSxHQUFHLEVBQUU7UUFDbkMsTUFBTSxJQUFJLEdBQUcsNENBQTRDLENBQUM7UUFDMUQsTUFBTSxFQUFFLEdBQUcsNENBQTRDLENBQUM7UUFDeEQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNoRCxNQUFNLFdBQVcsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUUzQyxRQUFRLENBQUMsZUFBZSxFQUFFLEdBQUcsRUFBRTtZQUM3QixFQUFFLENBQUMsdUVBQXVFLEVBQUUsR0FBRyxFQUFFO2dCQUMvRSxNQUFNLFFBQVEsR0FBRyxJQUFBLCtCQUFtQixFQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxDQUFDLENBQUM7Z0JBQzlFLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDOUIsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsMEJBQWMsQ0FBQyxDQUFDO2dCQUMxQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ25ELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLGdEQUFnRCxFQUFFLEdBQUcsRUFBRTtnQkFDeEQsTUFBTSxRQUFRLEdBQUcsSUFBQSwrQkFBbUIsRUFBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLGdCQUFnQixFQUFFLFdBQVcsQ0FBQyxDQUFDO2dCQUM5RSxNQUFNLE9BQU8sR0FBRyxJQUFBLGdDQUFvQixFQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUMvQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7Z0JBQzVELE9BQU8sQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztnQkFDeEQsT0FBTyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQ3ZELE9BQU8sQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUMvQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUU7WUFDMUIsRUFBRSxDQUFDLHVDQUF1QyxFQUFFLEdBQUcsRUFBRTtnQkFDL0MsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFBLCtCQUFtQixFQUFDLGdCQUFnQixFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQzNGLHNCQUFzQixDQUN2QixDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMscUNBQXFDLEVBQUUsR0FBRyxFQUFFO2dCQUM3QyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUEsK0JBQW1CLEVBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDN0Ysb0JBQW9CLENBQ3JCLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxxQ0FBcUMsRUFBRSxHQUFHLEVBQUU7Z0JBQzdDLE1BQU0sV0FBVyxHQUFHLDRDQUE0QyxDQUFDO2dCQUNqRSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUEsK0JBQW1CLEVBQUMsV0FBVyxFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ3RGLHNCQUFzQixDQUN2QixDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsNkNBQTZDLEVBQUUsR0FBRyxFQUFFO2dCQUNyRCxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUEsK0JBQW1CLEVBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7WUFDakgsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxFQUFFO2dCQUMzQyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUEsK0JBQW1CLEVBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztZQUMvRyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsNkJBQTZCLEVBQUUsR0FBRyxFQUFFO1FBQzNDLE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sZ0JBQWdCLEdBQUcsU0FBUyxDQUFDO1FBQ25DLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFaEQsUUFBUSxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7WUFDN0IsRUFBRSxDQUFDLCtFQUErRSxFQUFFLEdBQUcsRUFBRTtnQkFDdkYsTUFBTSxRQUFRLEdBQUcsSUFBQSx1Q0FBMkIsRUFBQyxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztnQkFDN0YsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUM5QixRQUFRLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxrQ0FBc0IsQ0FBQyxDQUFDO2dCQUNsRCxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ25ELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHdEQUF3RCxFQUFFLEdBQUcsRUFBRTtnQkFDaEUsTUFBTSxRQUFRLEdBQUcsSUFBQSx1Q0FBMkIsRUFBQyxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztnQkFDN0YsTUFBTSxPQUFPLEdBQUcsSUFBQSx3Q0FBNEIsRUFBQyxRQUFRLENBQUMsQ0FBQztnQkFDdkQsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUMzQyxPQUFPLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDdkQsT0FBTyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDekQsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILFFBQVEsQ0FBQyxZQUFZLEVBQUUsR0FBRyxFQUFFO1lBQzFCLEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRSxHQUFHLEVBQUU7Z0JBQy9DLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSx1Q0FBMkIsRUFBQyxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQzVGLDZCQUE2QixDQUM5QixDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsb0NBQW9DLEVBQUUsR0FBRyxFQUFFO2dCQUM1QyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUEsdUNBQTJCLEVBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDakYsNkJBQTZCLENBQzlCLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxnREFBZ0QsRUFBRSxHQUFHLEVBQUU7Z0JBQ3hELENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSx1Q0FBMkIsRUFBQyxVQUFVLEVBQUUsQ0FBQyxzQkFBVSxHQUFHLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUMxRyxnQ0FBZ0MsQ0FDakMsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLG1EQUFtRCxFQUFFLEdBQUcsRUFBRTtnQkFDM0QsTUFBTSxRQUFRLEdBQUcsSUFBQSx1Q0FBMkIsRUFBQyxVQUFVLEVBQUUsc0JBQVUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUNsRyxJQUFBLHdDQUE0QixFQUFDLFFBQVEsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHNCQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUM3RixDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRSxHQUFHLEVBQUU7Z0JBQ2hELENBQUMsR0FBRyxFQUFFLENBQUMsSUFBQSx1Q0FBMkIsRUFBQyxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNsRixxQ0FBcUMsQ0FDdEMsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILDRFQUE0RTtJQUM1RSxRQUFRLENBQUMseUJBQXlCLEVBQUUsR0FBRyxFQUFFO1FBQ3ZDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsR0FBRyxFQUFFO1lBQzdCLEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7Z0JBQ2pELE1BQU0sUUFBUSxHQUFHLElBQUEsbUNBQXVCLEVBQUMsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUNsRixRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQzlCLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xDLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDJGQUEyRixFQUFFLEdBQUcsRUFBRTtnQkFDbkcsTUFBTSxRQUFRLEdBQUcsSUFBQSxtQ0FBdUIsRUFBQyxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ2xGLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLHVCQUF1QjtZQUM1RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxzREFBc0QsRUFBRSxHQUFHLEVBQUU7Z0JBQzlELE1BQU0sUUFBUSxHQUFHLElBQUEsbUNBQXVCLEVBQUMsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUNsRixRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDZDQUFpQyxDQUFDLENBQUM7WUFDeEUsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILFFBQVEsQ0FBQyw2Q0FBNkMsRUFBRSxHQUFHLEVBQUU7WUFDM0QsRUFBRSxDQUFDLCtEQUErRCxFQUFFLEdBQUcsRUFBRTtnQkFDdkUsTUFBTSxRQUFRLEdBQUcsSUFBQSxtQ0FBdUIsRUFBQyxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ2xGLDZEQUE2RDtnQkFDN0QsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ3JDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDaEYsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsOERBQThELEVBQUUsR0FBRyxFQUFFO2dCQUN0RSxNQUFNLFFBQVEsR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDbEYsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3RDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzdFLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLGdFQUFnRSxFQUFFLEdBQUcsRUFBRTtnQkFDeEUsTUFBTSxRQUFRLEdBQUcsSUFBQSxtQ0FBdUIsRUFBQyxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ2xGLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUN2QyxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzVELEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3BDLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLGlEQUFpRCxFQUFFLEdBQUcsRUFBRTtnQkFDekQsTUFBTSxRQUFRLEdBQUcsSUFBQSxtQ0FBdUIsRUFBQyxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ2xGLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxHQUFHLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNqRSxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztnQkFDL0QsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO2dCQUN6RCxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM5QixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLHFCQUFxQixFQUFFLEdBQUcsRUFBRTtZQUNuQyxFQUFFLENBQUMsZ0VBQWdFLEVBQUUsR0FBRyxFQUFFO2dCQUN4RSxNQUFNLFVBQVUsR0FBRyw0Q0FBNEMsQ0FBQztnQkFDaEUsTUFBTSxFQUFFLEdBQUcsSUFBQSxtQ0FBdUIsRUFBQyxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzVFLE1BQU0sRUFBRSxHQUFHLElBQUEsbUNBQXVCLEVBQUMsVUFBVSxFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDdEUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUN4QiwwQkFBMEI7Z0JBQzFCLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BELEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyw2QkFBNkI7WUFDeEUsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsNkRBQTZELEVBQUUsR0FBRyxFQUFFO2dCQUNyRSxNQUFNLEVBQUUsR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDNUUsTUFBTSxFQUFFLEdBQUcsSUFBQSxtQ0FBdUIsRUFBQyxnQkFBZ0IsRUFBRSxlQUFlLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzlFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDeEIsMkJBQTJCO2dCQUMzQixFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxxQkFBcUI7Z0JBQ3RFLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RELEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUI7WUFDaEUsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsK0RBQStELEVBQUUsR0FBRyxFQUFFO2dCQUN2RSxNQUFNLEVBQUUsR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDNUUsTUFBTSxFQUFFLEdBQUcsSUFBQSxtQ0FBdUIsRUFBQyxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDO2dCQUNwRixFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3hCLDBCQUEwQjtnQkFDMUIsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsNkJBQTZCO2dCQUNoRixFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNoRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLHVCQUF1QixFQUFFLEdBQUcsRUFBRTtZQUNyQyxFQUFFLENBQUMsOEVBQThFLEVBQUUsR0FBRyxFQUFFO2dCQUN0RixvRkFBb0Y7Z0JBQ3BGLE1BQU0sUUFBUSxHQUFHLElBQUEsbUNBQXVCLEVBQUMsZ0JBQWdCLEVBQUUsZUFBZSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUNwRixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDdEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDL0UsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsNEVBQTRFO0lBQzVFLFFBQVEsQ0FBQyxrQ0FBa0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsUUFBUSxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7WUFDN0IsRUFBRSxDQUFDLHlDQUF5QyxFQUFFLEdBQUcsRUFBRTtnQkFDakQsTUFBTSxRQUFRLEdBQUcsSUFBQSw0Q0FBZ0MsRUFBQyxnQkFBZ0IsRUFBRSxDQUFDLGFBQWEsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUM3RixRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQzlCLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xDLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHNDQUFzQyxFQUFFLEdBQUcsRUFBRTtnQkFDOUMsTUFBTSxRQUFRLEdBQUcsSUFBQSw0Q0FBZ0MsRUFBQyxnQkFBZ0IsRUFBRSxDQUFDLGFBQWEsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUM3RixRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdDQUFvQixDQUFDLENBQUM7WUFDM0QsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLEVBQUU7WUFDdEMsMkVBQTJFO1lBQzNFLDhFQUE4RTtZQUM5RSxpRkFBaUY7WUFFakYsRUFBRSxDQUFDLGtFQUFrRSxFQUFFLEdBQUcsRUFBRTtnQkFDMUUsTUFBTSxNQUFNLEdBQUcsSUFBQSxtQ0FBdUIsRUFBQyxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN6RixNQUFNLE1BQU0sR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNGLE1BQU0sTUFBTSxHQUFHLElBQUEsbUNBQXVCLEVBQUMsZ0JBQWdCLEVBQUUsZUFBZSxFQUFFLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFM0YsTUFBTSxRQUFRLEdBQUcsSUFBQSw0Q0FBZ0MsRUFDL0MsZ0JBQWdCLEVBQ2hCLENBQUMsYUFBYSxFQUFFLGVBQWUsRUFBRSxlQUFlLENBQUMsRUFDakQsTUFBTSxDQUNQLENBQUM7Z0JBRUYsUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ25DLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNuQyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyQyxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxxRUFBcUUsRUFBRSxHQUFHLEVBQUU7Z0JBQzdFLE1BQU0sTUFBTSxHQUFHLElBQUEsbUNBQXVCLEVBQUMsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDekYsTUFBTSxNQUFNLEdBQUcsSUFBQSxtQ0FBdUIsRUFBQyxnQkFBZ0IsRUFBRSxlQUFlLEVBQUUsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUUzRixNQUFNLE1BQU0sR0FBRyxJQUFBLDRDQUFnQyxFQUFDLGdCQUFnQixFQUFFLENBQUMsYUFBYSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBRTNGLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNqQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdkMsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsc0VBQXNFLEVBQUUsR0FBRyxFQUFFO2dCQUM5RSxNQUFNLE1BQU0sR0FBRyxDQUFDLGFBQWEsRUFBRSxlQUFlLEVBQUUsZUFBZSxDQUFDLENBQUM7Z0JBQ2pFLE1BQU0sUUFBUSxHQUFHLElBQUEsNENBQWdDLEVBQUMsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUVwRixLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO29CQUMzQixNQUFNLGFBQWEsR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3hGLGlFQUFpRTtvQkFDakUsYUFBYSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsNkNBQWlDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQzNFLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUM1QyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsb0RBQW9ELEVBQUUsR0FBRyxFQUFFO2dCQUM1RCxNQUFNLEVBQUUsR0FBRyxJQUFBLDRDQUFnQyxFQUFDLGdCQUFnQixFQUFFLENBQUMsYUFBYSxFQUFFLGVBQWUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUN4RyxNQUFNLEVBQUUsR0FBRyxJQUFBLDRDQUFnQyxFQUFDLGdCQUFnQixFQUFFLENBQUMsYUFBYSxFQUFFLGVBQWUsQ0FBQyxFQUFFLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQztnQkFFaEgscUVBQXFFO2dCQUNyRSxNQUFNLFNBQVMsR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzVGLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFcEMsaUJBQWlCO2dCQUNqQixNQUFNLFNBQVMsR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNwRyxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDdEMsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsZ0RBQWdELEVBQUUsR0FBRyxFQUFFO2dCQUN4RCxNQUFNLE1BQU0sR0FBRyxJQUFBLDRDQUFnQyxFQUFDLGdCQUFnQixFQUFFLENBQUMsYUFBYSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzNGLE1BQU0sTUFBTSxHQUFHLElBQUEsNENBQWdDLEVBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLEVBQUUsZUFBZSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzVHLE1BQU0sTUFBTSxHQUFHLElBQUEsNENBQWdDLEVBQzdDLGdCQUFnQixFQUNoQixDQUFDLGFBQWEsRUFBRSxlQUFlLEVBQUUsZUFBZSxDQUFDLEVBQ2pELE1BQU0sQ0FDUCxDQUFDO2dCQUNGLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNuRCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyRCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyw2REFBNkQsRUFBRSxHQUFHLEVBQUU7Z0JBQ3JFLE1BQU0sRUFBRSxHQUFHLElBQUEsNENBQWdDLEVBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLEVBQUUsZUFBZSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3hHLE1BQU0sRUFBRSxHQUFHLElBQUEsNENBQWdDLEVBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxlQUFlLEVBQUUsYUFBYSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3hHLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMxQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtZQUM5QixFQUFFLENBQUMsOENBQThDLEVBQUUsR0FBRyxFQUFFO2dCQUN0RCxnQkFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFBLDRDQUFnQyxFQUFDLGdCQUFnQixFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsRUFDcEUsMENBQTBDLENBQzNDLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCw0RUFBNEU7SUFDNUUsUUFBUSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsRUFBRTtRQUNwQyxRQUFRLENBQUMsZUFBZSxFQUFFLEdBQUcsRUFBRTtZQUM3QixFQUFFLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO2dCQUNqRCxNQUFNLEtBQUssR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDL0UsTUFBTSxPQUFPLEdBQUcsSUFBQSxnQ0FBb0IsRUFBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ3pELE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDN0IsT0FBTyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDakMsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsMkNBQTJDLEVBQUUsR0FBRyxFQUFFO2dCQUNuRCxNQUFNLEtBQUssR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDL0UsTUFBTSxPQUFPLEdBQUcsSUFBQSxnQ0FBb0IsRUFBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ3pELE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0NBQXNCLENBQUMsQ0FBQztZQUM1RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyx3REFBd0QsRUFBRSxHQUFHLEVBQUU7Z0JBQ2hFLE1BQU0sS0FBSyxHQUFHLElBQUEsbUNBQXVCLEVBQUMsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUMvRSxNQUFNLE9BQU8sR0FBRyxJQUFBLGdDQUFvQixFQUFDLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUMvRCxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLHdCQUF3QixFQUFFLEdBQUcsRUFBRTtZQUN0QyxFQUFFLENBQUMsd0NBQXdDLEVBQUUsR0FBRyxFQUFFO2dCQUNoRCxNQUFNLEtBQUssR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDL0UsTUFBTSxPQUFPLEdBQUcsSUFBQSxnQ0FBb0IsRUFBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ3pELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDdEQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLHdCQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDaEYsTUFBaUIsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7WUFDdEYsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO2dCQUNwRCxNQUFNLEtBQUssR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDL0UsTUFBTSxPQUFPLEdBQUcsSUFBQSxnQ0FBb0IsRUFBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ3pELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDdEQsTUFBTSxDQUFDLEVBQUUsS0FBSyxDQUFDLEdBQUcsd0JBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUNsRixLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNyQyxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRSxHQUFHLEVBQUU7Z0JBQ2hELE1BQU0sS0FBSyxHQUFHLElBQUEsbUNBQXVCLEVBQUMsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUMvRSxNQUFNLE9BQU8sR0FBRyxJQUFBLGdDQUFvQixFQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDekQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUN0RCxNQUFNLENBQUMsRUFBRSxBQUFELEVBQUcsSUFBSSxDQUFDLEdBQUcsd0JBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUNuRixDQUFDLElBQUksR0FBSSxJQUFlLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNoRSxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRSxHQUFHLEVBQUU7Z0JBQzFELE1BQU0sS0FBSyxHQUFHLElBQUEsNENBQWdDLEVBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLEVBQUUsZUFBZSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzNHLE1BQU0sT0FBTyxHQUFHLElBQUEsZ0NBQW9CLEVBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUN6RCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ3RELE1BQU0sQ0FBQyxFQUFFLEFBQUQsRUFBRyxJQUFJLENBQUMsR0FBRyx3QkFBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ25GLENBQUMsSUFBSSxHQUFJLElBQWUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hFLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxRQUFRLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxFQUFFO1lBQ3hDLEVBQUUsQ0FBQyw4REFBOEQsRUFBRSxHQUFHLEVBQUU7Z0JBQ3RFLE1BQU0sS0FBSyxHQUFHLElBQUEsbUNBQXVCLEVBQUMsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUMvRSxNQUFNLEVBQUUsR0FBRyxJQUFBLGdDQUFvQixFQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDcEQsTUFBTSxFQUFFLEdBQUcsSUFBQSxnQ0FBb0IsRUFBQyxpQkFBaUIsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDMUQsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzFCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILDRFQUE0RTtJQUM1RSxRQUFRLENBQUMsMkNBQTJDLEVBQUUsR0FBRyxFQUFFO1FBQ3pELE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsc0JBQXNCO1FBRTdELEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRSxHQUFHLEVBQUU7WUFDaEQsTUFBTSxNQUFNLEdBQUcsSUFBQSxxREFBeUMsRUFBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNuRixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDNUIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMseUVBQXlFLEVBQUUsR0FBRyxFQUFFO1lBQ2pGLE1BQU0sTUFBTSxHQUFHLElBQUEscURBQXlDLEVBQUMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDbkYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsZ0RBQW1DLENBQUMsQ0FBQztRQUMvRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywrQ0FBK0MsRUFBRSxHQUFHLEVBQUU7WUFDdkQsTUFBTSxNQUFNLEdBQUcsSUFBQSxxREFBeUMsRUFBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNuRixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckQsTUFBTSxPQUFPLEdBQUcsd0JBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDdkUsQ0FBQyxJQUFJLEdBQUksT0FBTyxDQUFDLENBQUMsQ0FBWSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUM3RyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRSxHQUFHLEVBQUU7WUFDdEQsTUFBTSxNQUFNLEdBQUcsSUFBQSxxREFBeUMsRUFBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNuRixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckQsTUFBTSxPQUFPLEdBQUcsd0JBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDdkUsQ0FBQyxJQUFJLEdBQUksT0FBTyxDQUFDLENBQUMsQ0FBWSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscURBQXFELEVBQUUsR0FBRyxFQUFFO1lBQzdELE1BQU0sRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2xDLE1BQU0sRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2xDLElBQUEscURBQXlDLEVBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQzlFLElBQUEscURBQXlDLEVBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLENBQ2hFLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxpRUFBaUUsRUFBRSxHQUFHLEVBQUU7WUFDekUsSUFBQSxxREFBeUMsRUFBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDbEYsSUFBQSxxREFBeUMsRUFBQyxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQ2pFLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsNEVBQTRFO0lBQzVFLFFBQVEsQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7UUFDdkQsTUFBTSxjQUFjLEdBQUcsNENBQTRDLENBQUM7UUFDcEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFdEMsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLEdBQUcsRUFBRTtZQUNoRCxNQUFNLE1BQU0sR0FBRyxJQUFBLG1EQUF1QyxFQUFDLGFBQWEsRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDOUYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtDQUErQyxFQUFFLEdBQUcsRUFBRTtZQUN2RCxNQUFNLE1BQU0sR0FBRyxJQUFBLG1EQUF1QyxFQUFDLGFBQWEsRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDOUYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsa0NBQXNCLENBQUMsQ0FBQztRQUNsRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1RUFBdUUsRUFBRSxHQUFHLEVBQUU7WUFDL0UsTUFBTSxNQUFNLEdBQUcsSUFBQSxtREFBdUMsRUFBQyxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzlGLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNyRCxNQUFNLE9BQU8sR0FBRyx3QkFBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDaEYsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFJLE9BQU8sQ0FBQyxDQUFDLENBQVksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEUsYUFBYSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsZ0RBQW1DLENBQUMsQ0FBQztRQUN0RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw4REFBOEQsRUFBRSxHQUFHLEVBQUU7WUFDdEUsTUFBTSxNQUFNLEdBQUcsSUFBQSxtREFBdUMsRUFBQyxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzlGLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNyRCxNQUFNLE9BQU8sR0FBRyx3QkFBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDaEYsQ0FBQyxJQUFJLEdBQUksT0FBTyxDQUFDLENBQUMsQ0FBWSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDMUcsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaURBQWlELEVBQUUsR0FBRyxFQUFFO1lBQ3pELE1BQU0sTUFBTSxHQUFHLElBQUEsbURBQXVDLEVBQUMsYUFBYSxFQUFFLGNBQWMsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM5RixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckQsTUFBTSxPQUFPLEdBQUcsd0JBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ2hGLE1BQU0sYUFBYSxHQUFHLElBQUksR0FBSSxPQUFPLENBQUMsQ0FBQyxDQUFZLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BFLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNqRSxNQUFNLFlBQVksR0FBRyx3QkFBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNqRixDQUFDLElBQUksR0FBSSxZQUFZLENBQUMsQ0FBQyxDQUFZLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNoSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw2REFBNkQsRUFBRSxHQUFHLEVBQUU7WUFDckUsSUFBQSxtREFBdUMsRUFBQyxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUM3RixJQUFBLG1EQUF1QyxFQUFDLGVBQWUsRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLENBQ2pGLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsNEVBQTRFO0lBQzVFLFFBQVEsQ0FBQywwQ0FBMEMsRUFBRSxHQUFHLEVBQUU7UUFDeEQsTUFBTSxjQUFjLEdBQUcsNENBQTRDLENBQUM7UUFDcEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFdEMsRUFBRSxDQUFDLCtDQUErQyxFQUFFLEdBQUcsRUFBRTtZQUN2RCxNQUFNLE9BQU8sR0FBRyxJQUFBLG1EQUF1QyxFQUFDLGFBQWEsRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDL0YsTUFBTSxPQUFPLEdBQUcsSUFBQSxvREFBd0MsRUFBQyxPQUFPLENBQUMsQ0FBQztZQUNsRSxPQUFPLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUNyRixPQUFPLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7WUFDL0UsT0FBTyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHFEQUFxRCxFQUFFLEdBQUcsRUFBRTtZQUM3RCxNQUFNLEdBQUcsR0FBRyxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMzQyxnQkFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFBLG9EQUF3QyxFQUFDLEdBQUcsQ0FBQyxFQUFFLDZDQUE2QyxDQUFDLENBQUM7UUFDcEgsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUVBQXVFLEVBQUUsR0FBRyxFQUFFO1lBQy9FLDRGQUE0RjtZQUM1RixNQUFNLGFBQWEsR0FBRyxJQUFBLG1DQUF1QixFQUFDLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN2RixNQUFNLE9BQU8sR0FBRyxJQUFBLGdDQUFvQixFQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUNuRSxnQkFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFBLG9EQUF3QyxFQUFDLE9BQU8sQ0FBQyxFQUN2RCxtREFBbUQsQ0FDcEQsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDhFQUE4RSxFQUFFLEdBQUcsRUFBRTtZQUN0RixNQUFNLE9BQU8sR0FBRyxJQUFBLG1EQUF1QyxFQUFDLGFBQWEsRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDL0YsTUFBTSxPQUFPLEdBQUcsSUFBQSxvREFBd0MsRUFBQyxPQUFPLENBQUMsQ0FBQztZQUNsRSxnQkFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUMzQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDcEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IEV0aGVyZXVtQWJpIGZyb20gJ2V0aGVyZXVtanMtYWJpJztcbmltcG9ydCB7XG4gIGJ1aWxkQXBwcm92ZUNhbGxkYXRhLFxuICBkZWNvZGVBcHByb3ZlQ2FsbGRhdGEsXG4gIGJ1aWxkV3JhcENhbGxkYXRhLFxuICBkZWNvZGVXcmFwQ2FsbGRhdGEsXG4gIGJ1aWxkVW53cmFwQ2FsbGRhdGEsXG4gIGRlY29kZVVud3JhcENhbGxkYXRhLFxuICBidWlsZEZpbmFsaXplVW53cmFwQ2FsbGRhdGEsXG4gIGRlY29kZUZpbmFsaXplVW53cmFwQ2FsbGRhdGEsXG4gIGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhLFxuICBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YSxcbiAgYnVpbGRDb25maWRlbnRpYWxUcmFuc2ZlckJ5SGFuZGxlQ2FsbGRhdGEsXG4gIGJ1aWxkRmx1c2hFUkM3OTg0Rm9yd2FyZGVyVG9rZW5DYWxsZGF0YSxcbiAgZGVjb2RlRmx1c2hFUkM3OTg0Rm9yd2FyZGVyVG9rZW5DYWxsZGF0YSxcbiAgd3JhcEluQ2FsbEZyb21QYXJlbnQsXG4gIGFwcHJvdmVNZXRob2RJZCxcbiAgd3JhcE1ldGhvZElkLFxuICBVSU5UNjRfTUFYLFxuICB1bndyYXBNZXRob2RJZCxcbiAgZmluYWxpemVVbndyYXBNZXRob2RJZCxcbiAgZGVsZWdhdGVGb3JVc2VyRGVjcnlwdGlvbk1ldGhvZElkLFxuICBhY2xNdWx0aWNhbGxNZXRob2RJZCxcbiAgY2FsbEZyb21QYXJlbnRNZXRob2RJZCxcbn0gZnJvbSAnLi4vLi4vc3JjL2xpYi96YW1hVXRpbHMnO1xuaW1wb3J0IHsgY29uZmlkZW50aWFsVHJhbnNmZXJOb1Byb29mTWV0aG9kSWQgfSBmcm9tICcuLi8uLi9zcmMvbGliL3dhbGxldFV0aWwnO1xuXG5kZXNjcmliZSgnWmFtYSBVdGlscycsICgpID0+IHtcbiAgY29uc3QgQUNMX0FERFJFU1MgPSAnMHhmMEZmZGM5M2I3RTE4NmJDMmY4Q0IzZEFBNzVEODZkMTkzMEE0MzNEJztcbiAgY29uc3QgREVMRUdBVEVfQUREUkVTUyA9ICcweDExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEnO1xuICBjb25zdCBUT0tFTl9BRERSRVNTID0gJzB4OTQxNjcxMjkxNzJBMzVhYjA5M0I0NGI4Yjk2MjEzRERiYzNjRDM4Nyc7XG4gIGNvbnN0IFRPS0VOX0FERFJFU1NfMiA9ICcweDRFN0IwNkQ3ODk2NTU5NGVCNUVGNTQxNGMzNTdjYTIxRTE1NTQ0OTEnO1xuICBjb25zdCBUT0tFTl9BRERSRVNTXzMgPSAnMHhBMGI4Njk5MWM2MjE4YjM2YzFkMTlENGEyZTlFYjBjRTM2MDZlQjQ4JztcbiAgY29uc3QgRk9SV0FSREVSX0FERFJFU1MgPSAnMHhEZUFEYmVlZmRFQWRiZWVmZEVhZGJFRUZkZWFkYmVFRmRFYURiZWVGJztcbiAgLy8gSG9vZGkgaHRldGg6Y3VzZHQgd3JhcHBlciAoc3BlbmRlciBmb3IgZXhhY3QtYW1vdW50IGFwcHJvdmUpXG4gIGNvbnN0IFdSQVBQRVJfQUREUkVTUyA9ICcweDJkZWJiZTA0ODdlZjkyMWRmNDQ1N2Y5ZTM2ZWQwNWJlMmRmMWFjNzUnO1xuICBjb25zdCBFWFBJUlkgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKSArIDM2NSAqIDg2NDAwO1xuXG4gIC8vIEhlbHBlcjogZGVjb2RlIGEgZGVsZWdhdGVGb3JVc2VyRGVjcnlwdGlvbiBjYWxsXG4gIGZ1bmN0aW9uIGRlY29kZURlbGVnYXRpb25DYWxsKGNhbGxkYXRhOiBzdHJpbmcpOiBbc3RyaW5nLCBzdHJpbmcsIG51bWJlcl0ge1xuICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuZnJvbShjYWxsZGF0YS5zbGljZSgxMCksICdoZXgnKTtcbiAgICBjb25zdCBkZWNvZGVkID0gRXRoZXJldW1BYmkucmF3RGVjb2RlKFsnYWRkcmVzcycsICdhZGRyZXNzJywgJ3VpbnQ2NCddLCBwYXlsb2FkKTtcbiAgICByZXR1cm4gWyhkZWNvZGVkWzBdIGFzIEJ1ZmZlcikudG9TdHJpbmcoJ2hleCcpLCAoZGVjb2RlZFsxXSBhcyBCdWZmZXIpLnRvU3RyaW5nKCdoZXgnKSwgTnVtYmVyKGRlY29kZWRbMl0pXTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgZGVzY3JpYmUoJ01ldGhvZCBJRHMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3Qgc2VsZWN0b3IgZm9yIGRlbGVnYXRlRm9yVXNlckRlY3J5cHRpb24oYWRkcmVzcyxhZGRyZXNzLHVpbnQ2NCknLCAoKSA9PiB7XG4gICAgICBkZWxlZ2F0ZUZvclVzZXJEZWNyeXB0aW9uTWV0aG9kSWQuc2hvdWxkLmVxdWFsKCcweDA0ZjYxYTk1Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgY29ycmVjdCBzZWxlY3RvciBmb3IgbXVsdGljYWxsKGJ5dGVzW10pJywgKCkgPT4ge1xuICAgICAgYWNsTXVsdGljYWxsTWV0aG9kSWQuc2hvdWxkLmVxdWFsKCcweGFjOTY1MGQ4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgY29ycmVjdCBzZWxlY3RvciBmb3IgY2FsbEZyb21QYXJlbnQoYWRkcmVzcyx1aW50MjU2LGJ5dGVzKScsICgpID0+IHtcbiAgICAgIGNhbGxGcm9tUGFyZW50TWV0aG9kSWQuc2hvdWxkLmVxdWFsKCcweDc3ZTYwYjM1Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgY29ycmVjdCBzZWxlY3RvciBmb3IgYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgKCkgPT4ge1xuICAgICAgYXBwcm92ZU1ldGhvZElkLnNob3VsZC5lcXVhbCgnMHgwOTVlYTdiMycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3Qgc2VsZWN0b3IgZm9yIHdyYXAoYWRkcmVzcyx1aW50MjU2KScsICgpID0+IHtcbiAgICAgIHdyYXBNZXRob2RJZC5zaG91bGQuZXF1YWwoJzB4YmYzNzZjN2EnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBjb3JyZWN0IHNlbGVjdG9yIGZvciB1bndyYXAoYWRkcmVzcyxhZGRyZXNzLGJ5dGVzMzIsYnl0ZXMpJywgKCkgPT4ge1xuICAgICAgdW53cmFwTWV0aG9kSWQuc2hvdWxkLmVxdWFsKCcweDViZjRlZjA2Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgY29ycmVjdCBzZWxlY3RvciBmb3IgZmluYWxpemVVbndyYXAoYnl0ZXMzMix1aW50NjQsYnl0ZXMpJywgKCkgPT4ge1xuICAgICAgZmluYWxpemVVbndyYXBNZXRob2RJZC5zaG91bGQuZXF1YWwoJzB4NWJiNjdhMDUnKTtcbiAgICB9KTtcblxuICAgIGl0KCdtZXRob2QgSURzIHNob3VsZCBhbGwgYmUgZGlzdGluY3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCBpZHMgPSBuZXcgU2V0KFtcbiAgICAgICAgZGVsZWdhdGVGb3JVc2VyRGVjcnlwdGlvbk1ldGhvZElkLFxuICAgICAgICBhY2xNdWx0aWNhbGxNZXRob2RJZCxcbiAgICAgICAgY2FsbEZyb21QYXJlbnRNZXRob2RJZCxcbiAgICAgICAgYXBwcm92ZU1ldGhvZElkLFxuICAgICAgICB3cmFwTWV0aG9kSWQsXG4gICAgICAgIHVud3JhcE1ldGhvZElkLFxuICAgICAgICBmaW5hbGl6ZVVud3JhcE1ldGhvZElkLFxuICAgICAgXSk7XG4gICAgICBpZHMuc2l6ZS5zaG91bGQuZXF1YWwoNyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgZGVzY3JpYmUoJ2J1aWxkQXBwcm92ZUNhbGxkYXRhJywgKCkgPT4ge1xuICAgIGNvbnN0IEVYQUNUX0FNT1VOVCA9ICcxMDAwMDAwJzsgLy8gMSBVU0RUICg2IGRlY2ltYWxzKVxuXG4gICAgZGVzY3JpYmUoJ291dHB1dCBmb3JtYXQnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHByb2R1Y2UgYSAweC1wcmVmaXhlZCBoZXggc3RyaW5nJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkQXBwcm92ZUNhbGxkYXRhKFdSQVBQRVJfQUREUkVTUywgRVhBQ1RfQU1PVU5UKTtcbiAgICAgICAgY2FsbGRhdGEuc2hvdWxkLmJlLmEuU3RyaW5nKCk7XG4gICAgICAgIGNhbGxkYXRhLnNob3VsZC5zdGFydFdpdGgoJzB4Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYXZlIGV4YWN0IGxlbmd0aDogNC1ieXRlIHNlbGVjdG9yICsgMiDDlyAzMi1ieXRlIEFCSSB3b3JkcyA9IDY4IGJ5dGVzICgxMzggY2hhcnMpJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkQXBwcm92ZUNhbGxkYXRhKFdSQVBQRVJfQUREUkVTUywgRVhBQ1RfQU1PVU5UKTtcbiAgICAgICAgY2FsbGRhdGEubGVuZ3RoLnNob3VsZC5lcXVhbCgxMzgpOyAvLyAnMHgnICsgMTM2IGhleCBjaGFyc1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3RhcnQgd2l0aCBhcHByb3ZlIHNlbGVjdG9yIDB4MDk1ZWE3YjMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRBcHByb3ZlQ2FsbGRhdGEoV1JBUFBFUl9BRERSRVNTLCBFWEFDVF9BTU9VTlQpO1xuICAgICAgICBjYWxsZGF0YS5zbGljZSgwLCAxMCkuc2hvdWxkLmVxdWFsKGFwcHJvdmVNZXRob2RJZCk7XG4gICAgICAgIGNhbGxkYXRhLnNsaWNlKDAsIDEwKS5zaG91bGQuZXF1YWwoJzB4MDk1ZWE3YjMnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0FCSSBwYXJhbWV0ZXIgZW5jb2RpbmcnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGVuY29kZSB3cmFwcGVyIGFzIHNwZW5kZXIgaW4gdGhlIGZpcnN0IEFCSSB3b3JkJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkQXBwcm92ZUNhbGxkYXRhKFdSQVBQRVJfQUREUkVTUywgRVhBQ1RfQU1PVU5UKTtcbiAgICAgICAgY29uc3Qgd29yZDEgPSBjYWxsZGF0YS5zbGljZSgxMCwgNzQpO1xuICAgICAgICB3b3JkMS5zaG91bGQuZXF1YWwoV1JBUFBFUl9BRERSRVNTLnNsaWNlKDIpLnRvTG93ZXJDYXNlKCkucGFkU3RhcnQoNjQsICcwJykpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZW5jb2RlIGV4YWN0IGFtb3VudCBpbiB0aGUgc2Vjb25kIEFCSSB3b3JkJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkQXBwcm92ZUNhbGxkYXRhKFdSQVBQRVJfQUREUkVTUywgRVhBQ1RfQU1PVU5UKTtcbiAgICAgICAgY29uc3Qgd29yZDIgPSBjYWxsZGF0YS5zbGljZSg3NCwgMTM4KTtcbiAgICAgICAgd29yZDIuc2hvdWxkLmVxdWFsKEJpZ0ludChFWEFDVF9BTU9VTlQpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCg2NCwgJzAnKSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBlbmNvZGUgYXBwcm92ZSgwKSByZXNldCB3aGVuIGFtb3VudCBpcyAwJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkQXBwcm92ZUNhbGxkYXRhKFdSQVBQRVJfQUREUkVTUywgMCk7XG4gICAgICAgIGNhbGxkYXRhLnNsaWNlKDAsIDEwKS5zaG91bGQuZXF1YWwoYXBwcm92ZU1ldGhvZElkKTtcbiAgICAgICAgY2FsbGRhdGEuc2xpY2UoNzQsIDEzOCkuc2hvdWxkLmVxdWFsKCcwJy5yZXBlYXQoNjQpKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGFjY2VwdCBhbW91bnQgYXMgYmlnaW50JywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkQXBwcm92ZUNhbGxkYXRhKFdSQVBQRVJfQUREUkVTUywgMTAwMDAwMG4pO1xuICAgICAgICBjYWxsZGF0YS5zbGljZSg3NCwgMTM4KS5zaG91bGQuZXF1YWwoQmlnSW50KEVYQUNUX0FNT1VOVCkudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDY0LCAnMCcpKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGFjY2VwdCBhbW91bnQgYXMgbnVtYmVyJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkQXBwcm92ZUNhbGxkYXRhKFdSQVBQRVJfQUREUkVTUywgMTAwMDAwMCk7XG4gICAgICAgIGNhbGxkYXRhLnNsaWNlKDc0LCAxMzgpLnNob3VsZC5lcXVhbChCaWdJbnQoRVhBQ1RfQU1PVU5UKS50b1N0cmluZygxNikucGFkU3RhcnQoNjQsICcwJykpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgndmFsaWRhdGlvbicsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGFuIGludmFsaWQgd3JhcHBlciBhZGRyZXNzJywgKCkgPT4ge1xuICAgICAgICAoKCkgPT4gYnVpbGRBcHByb3ZlQ2FsbGRhdGEoJ25vdC1hbi1hZGRyZXNzJywgRVhBQ1RfQU1PVU5UKSkuc2hvdWxkLnRocm93KC9pbnZhbGlkIHdyYXBwZXIgYWRkcmVzcy8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgYmFkIEVJUC01NSBjaGVja3N1bScsICgpID0+IHtcbiAgICAgICAgLy8gTWl4ZWQgY2FzZSB0aGF0IGRvZXMgbm90IG1hdGNoIHRoZSBjb3JyZWN0IGNoZWNrc3VtXG4gICAgICAgIGNvbnN0IGJhZENoZWNrc3VtID0gJzB4MkRlYmJlMDQ4N2VmOTIxZGY0NDU3ZjllMzZlZDA1YmUyZGYxYWM3NSc7XG4gICAgICAgICgoKSA9PiBidWlsZEFwcHJvdmVDYWxsZGF0YShiYWRDaGVja3N1bSwgRVhBQ1RfQU1PVU5UKSkuc2hvdWxkLnRocm93KC9pbnZhbGlkIHdyYXBwZXIgYWRkcmVzcy8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYWNjZXB0IGFsbC1sb3dlcmNhc2UgYWRkcmVzc2VzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkQXBwcm92ZUNhbGxkYXRhKFdSQVBQRVJfQUREUkVTUy50b0xvd2VyQ2FzZSgpLCBFWEFDVF9BTU9VTlQpO1xuICAgICAgICBjYWxsZGF0YS5zbGljZSgwLCAxMCkuc2hvdWxkLmVxdWFsKGFwcHJvdmVNZXRob2RJZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgYSBuZWdhdGl2ZSBhbW91bnQnLCAoKSA9PiB7XG4gICAgICAgICgoKSA9PiBidWlsZEFwcHJvdmVDYWxsZGF0YShXUkFQUEVSX0FERFJFU1MsIC0xKSkuc2hvdWxkLnRocm93KC9hbW91bnQgbXVzdCBiZSA+PSAwLyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgYSBub24tbnVtZXJpYyBhbW91bnQgc3RyaW5nJywgKCkgPT4ge1xuICAgICAgICAoKCkgPT4gYnVpbGRBcHByb3ZlQ2FsbGRhdGEoV1JBUFBFUl9BRERSRVNTLCAnYWJjJykpLnNob3VsZC50aHJvdygvaW52YWxpZCBhbW91bnQvKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIGRlc2NyaWJlKCdkZWNvZGVBcHByb3ZlQ2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByb3VuZC10cmlwIGJ1aWxkQXBwcm92ZUNhbGxkYXRhIHdpdGggYSBjaGVja3N1bW1lZCBzcGVuZGVyJywgKCkgPT4ge1xuICAgICAgY29uc3QgZGVjb2RlZCA9IGRlY29kZUFwcHJvdmVDYWxsZGF0YShidWlsZEFwcHJvdmVDYWxsZGF0YShXUkFQUEVSX0FERFJFU1MsICcxMDAwMDAwJykpO1xuICAgICAgZGVjb2RlZC5zcGVuZGVyLnNob3VsZC5lcXVhbCgnMHgyZEVCYmUwNDg3RWY5MjFkRjQ0NTdGOUUzNmVEMDVCZTJkZjFBQzc1Jyk7XG4gICAgICBkZWNvZGVkLmFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwMDAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZGVjb2RlIGFtb3VudCAwIGFuZCB0aGUgdWludDI1NiBtYXgnLCAoKSA9PiB7XG4gICAgICBkZWNvZGVBcHByb3ZlQ2FsbGRhdGEoYnVpbGRBcHByb3ZlQ2FsbGRhdGEoV1JBUFBFUl9BRERSRVNTLCAwKSkuYW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgY29uc3QgbWF4ID0gKDJuICoqIDI1Nm4gLSAxbikudG9TdHJpbmcoKTtcbiAgICAgIGRlY29kZUFwcHJvdmVDYWxsZGF0YShidWlsZEFwcHJvdmVDYWxsZGF0YShXUkFQUEVSX0FERFJFU1MsIG1heCkpLmFtb3VudC5zaG91bGQuZXF1YWwobWF4KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgbm9uLWFwcHJvdmUgc2VsZWN0b3InLCAoKSA9PiB7XG4gICAgICBzaG91bGQudGhyb3dzKCgpID0+IGRlY29kZUFwcHJvdmVDYWxsZGF0YShidWlsZFdyYXBDYWxsZGF0YShXUkFQUEVSX0FERFJFU1MsICcxJykpLCAvZXhwZWN0ZWQgYXBwcm92ZSBzZWxlY3Rvci8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgdHJ1bmNhdGVkIGNhbGxkYXRhIGFuZCB0cmFpbGluZyBieXRlcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkID0gYnVpbGRBcHByb3ZlQ2FsbGRhdGEoV1JBUFBFUl9BRERSRVNTLCAnMScpO1xuICAgICAgc2hvdWxkLnRocm93cygoKSA9PiBkZWNvZGVBcHByb3ZlQ2FsbGRhdGEodmFsaWQuc2xpY2UoMCwgLTIpKSwgL2V4cGVjdGVkIDY4IGJ5dGVzLyk7XG4gICAgICBzaG91bGQudGhyb3dzKCgpID0+IGRlY29kZUFwcHJvdmVDYWxsZGF0YSh2YWxpZCArICcwMCcpLCAvZXhwZWN0ZWQgNjggYnl0ZXMvKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICBkZXNjcmliZSgnYnVpbGRXcmFwQ2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgY29uc3QgUkVDSVBJRU5UID0gJzB4MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMSc7XG4gICAgY29uc3QgRVhBQ1RfQU1PVU5UID0gJzEwMDAwMDAnO1xuICAgIGNvbnN0IFJBVEVfT05FID0gJzEnO1xuICAgIGNvbnN0IFJBVEVfMUUxMiA9ICcxMDAwMDAwMDAwMDAwJzsgLy8gaHRldGg6Y3Rlc3QxXG5cbiAgICBkZXNjcmliZSgnb3V0cHV0IGZvcm1hdCcsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcHJvZHVjZSBhIDB4LXByZWZpeGVkIGhleCBzdHJpbmcnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRXcmFwQ2FsbGRhdGEoUkVDSVBJRU5ULCBFWEFDVF9BTU9VTlQsIFJBVEVfT05FKTtcbiAgICAgICAgY2FsbGRhdGEuc2hvdWxkLmJlLmEuU3RyaW5nKCk7XG4gICAgICAgIGNhbGxkYXRhLnNob3VsZC5zdGFydFdpdGgoJzB4Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYXZlIGV4YWN0IGxlbmd0aDogNC1ieXRlIHNlbGVjdG9yICsgMiDDlyAzMi1ieXRlIEFCSSB3b3JkcyA9IDY4IGJ5dGVzICgxMzggY2hhcnMpJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkV3JhcENhbGxkYXRhKFJFQ0lQSUVOVCwgRVhBQ1RfQU1PVU5ULCBSQVRFX09ORSk7XG4gICAgICAgIGNhbGxkYXRhLmxlbmd0aC5zaG91bGQuZXF1YWwoMTM4KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHN0YXJ0IHdpdGggd3JhcCBzZWxlY3RvciAweGJmMzc2YzdhJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkV3JhcENhbGxkYXRhKFJFQ0lQSUVOVCwgRVhBQ1RfQU1PVU5ULCBSQVRFX09ORSk7XG4gICAgICAgIGNhbGxkYXRhLnNsaWNlKDAsIDEwKS5zaG91bGQuZXF1YWwod3JhcE1ldGhvZElkKTtcbiAgICAgICAgY2FsbGRhdGEuc2xpY2UoMCwgMTApLnNob3VsZC5lcXVhbCgnMHhiZjM3NmM3YScpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQUJJIHBhcmFtZXRlciBlbmNvZGluZycsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgZW5jb2RlIHJlY2lwaWVudCBpbiB0aGUgZmlyc3QgQUJJIHdvcmQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRXcmFwQ2FsbGRhdGEoUkVDSVBJRU5ULCBFWEFDVF9BTU9VTlQsIFJBVEVfT05FKTtcbiAgICAgICAgY29uc3Qgd29yZDEgPSBjYWxsZGF0YS5zbGljZSgxMCwgNzQpO1xuICAgICAgICB3b3JkMS5zaG91bGQuZXF1YWwoUkVDSVBJRU5ULnNsaWNlKDIpLnRvTG93ZXJDYXNlKCkucGFkU3RhcnQoNjQsICcwJykpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZW5jb2RlIGFtb3VudCBpbiB0aGUgc2Vjb25kIEFCSSB3b3JkJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkV3JhcENhbGxkYXRhKFJFQ0lQSUVOVCwgRVhBQ1RfQU1PVU5ULCBSQVRFX09ORSk7XG4gICAgICAgIGNvbnN0IHdvcmQyID0gY2FsbGRhdGEuc2xpY2UoNzQsIDEzOCk7XG4gICAgICAgIHdvcmQyLnNob3VsZC5lcXVhbChCaWdJbnQoRVhBQ1RfQU1PVU5UKS50b1N0cmluZygxNikucGFkU3RhcnQoNjQsICcwJykpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcm91bmQtdHJpcCB0aHJvdWdoIGRlY29kZVdyYXBDYWxsZGF0YScsICgpID0+IHtcbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZFdyYXBDYWxsZGF0YShSRUNJUElFTlQsIEVYQUNUX0FNT1VOVCwgUkFURV9PTkUpO1xuICAgICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlV3JhcENhbGxkYXRhKGNhbGxkYXRhKTtcbiAgICAgICAgZGVjb2RlZC50by50b0xvd2VyQ2FzZSgpLnNob3VsZC5lcXVhbChSRUNJUElFTlQudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgIGRlY29kZWQuYW1vdW50LnNob3VsZC5lcXVhbChFWEFDVF9BTU9VTlQpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgndmFsaWRhdGlvbicsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGFuIGludmFsaWQgdG8gYWRkcmVzcycsICgpID0+IHtcbiAgICAgICAgKCgpID0+IGJ1aWxkV3JhcENhbGxkYXRhKCdub3QtYW4tYWRkcmVzcycsIEVYQUNUX0FNT1VOVCwgUkFURV9PTkUpKS5zaG91bGQudGhyb3coL2ludmFsaWQgdG8gYWRkcmVzcy8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgYmFkIEVJUC01NSBjaGVja3N1bScsICgpID0+IHtcbiAgICAgICAgLy8gTWl4ZWQgY2FzZSB0aGF0IGRvZXMgbm90IG1hdGNoIHRoZSBjb3JyZWN0IGNoZWNrc3VtIChzYW1lIHBhdHRlcm4gYXMgYXBwcm92ZSB0ZXN0cylcbiAgICAgICAgY29uc3QgYmFkQ2hlY2tzdW0gPSAnMHgyRGViYmUwNDg3ZWY5MjFkZjQ0NTdmOWUzNmVkMDViZTJkZjFhYzc1JztcbiAgICAgICAgKCgpID0+IGJ1aWxkV3JhcENhbGxkYXRhKGJhZENoZWNrc3VtLCBFWEFDVF9BTU9VTlQsIFJBVEVfT05FKSkuc2hvdWxkLnRocm93KC9pbnZhbGlkIHRvIGFkZHJlc3MvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhbW91bnQgMCcsICgpID0+IHtcbiAgICAgICAgKCgpID0+IGJ1aWxkV3JhcENhbGxkYXRhKFJFQ0lQSUVOVCwgMCwgUkFURV9PTkUpKS5zaG91bGQudGhyb3coL2Ftb3VudCBtdXN0IGJlID4gMC8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgbmVnYXRpdmUgYW1vdW50JywgKCkgPT4ge1xuICAgICAgICAoKCkgPT4gYnVpbGRXcmFwQ2FsbGRhdGEoUkVDSVBJRU5ULCAtMSwgUkFURV9PTkUpKS5zaG91bGQudGhyb3coL2Ftb3VudCBtdXN0IGJlID4gMC8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYWNjZXB0IDEgZnVsbCAxOC1kZWNpbWFsIHVuZGVybHlpbmcgdG9rZW4gZm9yIHJhdGUgMWUxMiAobWludHMgMWU2KScsICgpID0+IHtcbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZFdyYXBDYWxsZGF0YShSRUNJUElFTlQsICcxMDAwMDAwMDAwMDAwMDAwMDAwJywgUkFURV8xRTEyKTtcbiAgICAgICAgY2FsbGRhdGEuc2xpY2UoMCwgMTApLnNob3VsZC5lcXVhbCh3cmFwTWV0aG9kSWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYWNjZXB0IHRoZSBsYXJnZXN0IGFtb3VudCB3aG9zZSBmbG9vcihhbW91bnQgLyByYXRlKSBpcyBVSU5UNjRfTUFYJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBsYXJnZXN0ID0gKFVJTlQ2NF9NQVggKiBCaWdJbnQoUkFURV8xRTEyKSArIEJpZ0ludChSQVRFXzFFMTIpIC0gMW4pLnRvU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRXcmFwQ2FsbGRhdGEoUkVDSVBJRU5ULCBsYXJnZXN0LCBSQVRFXzFFMTIpO1xuICAgICAgICBjYWxsZGF0YS5zbGljZSgwLCAxMCkuc2hvdWxkLmVxdWFsKHdyYXBNZXRob2RJZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgdGhlIHNtYWxsZXN0IGFtb3VudCB3aG9zZSBmbG9vcihhbW91bnQgLyByYXRlKSBleGNlZWRzIHVpbnQ2NCcsICgpID0+IHtcbiAgICAgICAgY29uc3QgdG9vTGFyZ2UgPSAoKFVJTlQ2NF9NQVggKyAxbikgKiBCaWdJbnQoUkFURV8xRTEyKSkudG9TdHJpbmcoKTtcbiAgICAgICAgKCgpID0+IGJ1aWxkV3JhcENhbGxkYXRhKFJFQ0lQSUVOVCwgdG9vTGFyZ2UsIFJBVEVfMUUxMikpLnNob3VsZC50aHJvdygvYW1vdW50IFxcLyByYXRlIGV4Y2VlZHMgdWludDY0Lyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgYW1vdW50IGFib3ZlIHVpbnQ2NCBmb3IgcmF0ZSAxJywgKCkgPT4ge1xuICAgICAgICBjb25zdCB0b29MYXJnZSA9IChVSU5UNjRfTUFYICsgMW4pLnRvU3RyaW5nKCk7XG4gICAgICAgICgoKSA9PiBidWlsZFdyYXBDYWxsZGF0YShSRUNJUElFTlQsIHRvb0xhcmdlLCBSQVRFX09ORSkpLnNob3VsZC50aHJvdygvYW1vdW50IFxcLyByYXRlIGV4Y2VlZHMgdWludDY0Lyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBlbmNvZGUgd2l0aG91dCByYXRlIHdoZW4gcmF0ZSBpcyBvbWl0dGVkIChkZXNlcmlhbGl6ZSBwYXRoKScsICgpID0+IHtcbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZFdyYXBDYWxsZGF0YShSRUNJUElFTlQsIEVYQUNUX0FNT1VOVCk7XG4gICAgICAgIGNhbGxkYXRhLnNsaWNlKDAsIDEwKS5zaG91bGQuZXF1YWwod3JhcE1ldGhvZElkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYnVpbGRVbndyYXBDYWxsZGF0YScsICgpID0+IHtcbiAgICBjb25zdCBGUk9NID0gJzB4MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMSc7XG4gICAgY29uc3QgVE8gPSAnMHgxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExJztcbiAgICBjb25zdCBFTkNSWVBURURfQU1PVU5UID0gJzB4JyArICdhYicucmVwZWF0KDMyKTtcbiAgICBjb25zdCBJTlBVVF9QUk9PRiA9ICcweCcgKyAnY2QnLnJlcGVhdCg2NCk7XG5cbiAgICBkZXNjcmliZSgnb3V0cHV0IGZvcm1hdCcsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcHJvZHVjZSBhIDB4LXByZWZpeGVkIGhleCBzdHJpbmcgc3RhcnRpbmcgd2l0aCB1bndyYXAgc2VsZWN0b3InLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRVbndyYXBDYWxsZGF0YShGUk9NLCBUTywgRU5DUllQVEVEX0FNT1VOVCwgSU5QVVRfUFJPT0YpO1xuICAgICAgICBjYWxsZGF0YS5zaG91bGQuYmUuYS5TdHJpbmcoKTtcbiAgICAgICAgY2FsbGRhdGEuc2hvdWxkLnN0YXJ0V2l0aCh1bndyYXBNZXRob2RJZCk7XG4gICAgICAgIGNhbGxkYXRhLnNsaWNlKDAsIDEwKS5zaG91bGQuZXF1YWwoJzB4NWJmNGVmMDYnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJvdW5kLXRyaXAgdGhyb3VnaCBkZWNvZGVVbndyYXBDYWxsZGF0YScsICgpID0+IHtcbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZFVud3JhcENhbGxkYXRhKEZST00sIFRPLCBFTkNSWVBURURfQU1PVU5ULCBJTlBVVF9QUk9PRik7XG4gICAgICAgIGNvbnN0IGRlY29kZWQgPSBkZWNvZGVVbndyYXBDYWxsZGF0YShjYWxsZGF0YSk7XG4gICAgICAgIGRlY29kZWQuZnJvbS50b0xvd2VyQ2FzZSgpLnNob3VsZC5lcXVhbChGUk9NLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICBkZWNvZGVkLnRvLnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFsKFRPLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICBkZWNvZGVkLmVuY3J5cHRlZEFtb3VudC5zaG91bGQuZXF1YWwoRU5DUllQVEVEX0FNT1VOVCk7XG4gICAgICAgIGRlY29kZWQuaW5wdXRQcm9vZi5zaG91bGQuZXF1YWwoSU5QVVRfUFJPT0YpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgndmFsaWRhdGlvbicsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGFuIGludmFsaWQgZnJvbSBhZGRyZXNzJywgKCkgPT4ge1xuICAgICAgICAoKCkgPT4gYnVpbGRVbndyYXBDYWxsZGF0YSgnbm90LWFuLWFkZHJlc3MnLCBUTywgRU5DUllQVEVEX0FNT1VOVCwgSU5QVVRfUFJPT0YpKS5zaG91bGQudGhyb3coXG4gICAgICAgICAgL2ludmFsaWQgZnJvbSBhZGRyZXNzL1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGFuIGludmFsaWQgdG8gYWRkcmVzcycsICgpID0+IHtcbiAgICAgICAgKCgpID0+IGJ1aWxkVW53cmFwQ2FsbGRhdGEoRlJPTSwgJ25vdC1hbi1hZGRyZXNzJywgRU5DUllQVEVEX0FNT1VOVCwgSU5QVVRfUFJPT0YpKS5zaG91bGQudGhyb3coXG4gICAgICAgICAgL2ludmFsaWQgdG8gYWRkcmVzcy9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhIGJhZCBFSVAtNTUgY2hlY2tzdW0nLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGJhZENoZWNrc3VtID0gJzB4MkRlYmJlMDQ4N2VmOTIxZGY0NDU3ZjllMzZlZDA1YmUyZGYxYWM3NSc7XG4gICAgICAgICgoKSA9PiBidWlsZFVud3JhcENhbGxkYXRhKGJhZENoZWNrc3VtLCBUTywgRU5DUllQVEVEX0FNT1VOVCwgSU5QVVRfUFJPT0YpKS5zaG91bGQudGhyb3coXG4gICAgICAgICAgL2ludmFsaWQgZnJvbSBhZGRyZXNzL1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgbm9uLTMyLWJ5dGUgZW5jcnlwdGVkQW1vdW50JywgKCkgPT4ge1xuICAgICAgICAoKCkgPT4gYnVpbGRVbndyYXBDYWxsZGF0YShGUk9NLCBUTywgJzB4YWJjZCcsIElOUFVUX1BST09GKSkuc2hvdWxkLnRocm93KC9lbmNyeXB0ZWRBbW91bnQgbXVzdCBiZSBhIDMyLWJ5dGUvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhbiBlbXB0eSBpbnB1dFByb29mJywgKCkgPT4ge1xuICAgICAgICAoKCkgPT4gYnVpbGRVbndyYXBDYWxsZGF0YShGUk9NLCBUTywgRU5DUllQVEVEX0FNT1VOVCwgJzB4JykpLnNob3VsZC50aHJvdygvaW5wdXRQcm9vZiBtdXN0IGJlIGEgbm9uLWVtcHR5Lyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2J1aWxkRmluYWxpemVVbndyYXBDYWxsZGF0YScsICgpID0+IHtcbiAgICBjb25zdCBSRVFVRVNUX0lEID0gJzB4JyArICcxMScucmVwZWF0KDMyKTtcbiAgICBjb25zdCBDTEVBUlRFWFRfQU1PVU5UID0gJzEwMDAwMDAnO1xuICAgIGNvbnN0IERFQ1JZUFRJT05fUFJPT0YgPSAnMHgnICsgJ2VlJy5yZXBlYXQoNjQpO1xuXG4gICAgZGVzY3JpYmUoJ291dHB1dCBmb3JtYXQnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHByb2R1Y2UgYSAweC1wcmVmaXhlZCBoZXggc3RyaW5nIHN0YXJ0aW5nIHdpdGggZmluYWxpemVVbndyYXAgc2VsZWN0b3InLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRGaW5hbGl6ZVVud3JhcENhbGxkYXRhKFJFUVVFU1RfSUQsIENMRUFSVEVYVF9BTU9VTlQsIERFQ1JZUFRJT05fUFJPT0YpO1xuICAgICAgICBjYWxsZGF0YS5zaG91bGQuYmUuYS5TdHJpbmcoKTtcbiAgICAgICAgY2FsbGRhdGEuc2hvdWxkLnN0YXJ0V2l0aChmaW5hbGl6ZVVud3JhcE1ldGhvZElkKTtcbiAgICAgICAgY2FsbGRhdGEuc2xpY2UoMCwgMTApLnNob3VsZC5lcXVhbCgnMHg1YmI2N2EwNScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcm91bmQtdHJpcCB0aHJvdWdoIGRlY29kZUZpbmFsaXplVW53cmFwQ2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRGaW5hbGl6ZVVud3JhcENhbGxkYXRhKFJFUVVFU1RfSUQsIENMRUFSVEVYVF9BTU9VTlQsIERFQ1JZUFRJT05fUFJPT0YpO1xuICAgICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlRmluYWxpemVVbndyYXBDYWxsZGF0YShjYWxsZGF0YSk7XG4gICAgICAgIGRlY29kZWQucmVxdWVzdElkLnNob3VsZC5lcXVhbChSRVFVRVNUX0lEKTtcbiAgICAgICAgZGVjb2RlZC5jbGVhcnRleHRBbW91bnQuc2hvdWxkLmVxdWFsKENMRUFSVEVYVF9BTU9VTlQpO1xuICAgICAgICBkZWNvZGVkLmRlY3J5cHRpb25Qcm9vZi5zaG91bGQuZXF1YWwoREVDUllQVElPTl9QUk9PRik7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd2YWxpZGF0aW9uJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgYSBub24tMzItYnl0ZSByZXF1ZXN0SWQnLCAoKSA9PiB7XG4gICAgICAgICgoKSA9PiBidWlsZEZpbmFsaXplVW53cmFwQ2FsbGRhdGEoJzB4YWJjZCcsIENMRUFSVEVYVF9BTU9VTlQsIERFQ1JZUFRJT05fUFJPT0YpKS5zaG91bGQudGhyb3coXG4gICAgICAgICAgL3JlcXVlc3RJZCBtdXN0IGJlIGEgMzItYnl0ZS9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBjbGVhcnRleHRBbW91bnQgb2YgMCcsICgpID0+IHtcbiAgICAgICAgKCgpID0+IGJ1aWxkRmluYWxpemVVbndyYXBDYWxsZGF0YShSRVFVRVNUX0lELCAnMCcsIERFQ1JZUFRJT05fUFJPT0YpKS5zaG91bGQudGhyb3coXG4gICAgICAgICAgL2NsZWFydGV4dEFtb3VudCBtdXN0IGJlID4gMC9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBjbGVhcnRleHRBbW91bnQgZXhjZWVkaW5nIHVpbnQ2NCcsICgpID0+IHtcbiAgICAgICAgKCgpID0+IGJ1aWxkRmluYWxpemVVbndyYXBDYWxsZGF0YShSRVFVRVNUX0lELCAoVUlOVDY0X01BWCArIDFuKS50b1N0cmluZygpLCBERUNSWVBUSU9OX1BST09GKSkuc2hvdWxkLnRocm93KFxuICAgICAgICAgIC9jbGVhcnRleHRBbW91bnQgZXhjZWVkcyB1aW50NjQvXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBhY2NlcHQgY2xlYXJ0ZXh0QW1vdW50IGVxdWFsIHRvIFVJTlQ2NF9NQVgnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRGaW5hbGl6ZVVud3JhcENhbGxkYXRhKFJFUVVFU1RfSUQsIFVJTlQ2NF9NQVgudG9TdHJpbmcoKSwgREVDUllQVElPTl9QUk9PRik7XG4gICAgICAgIGRlY29kZUZpbmFsaXplVW53cmFwQ2FsbGRhdGEoY2FsbGRhdGEpLmNsZWFydGV4dEFtb3VudC5zaG91bGQuZXF1YWwoVUlOVDY0X01BWC50b1N0cmluZygpKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhbiBlbXB0eSBkZWNyeXB0aW9uUHJvb2YnLCAoKSA9PiB7XG4gICAgICAgICgoKSA9PiBidWlsZEZpbmFsaXplVW53cmFwQ2FsbGRhdGEoUkVRVUVTVF9JRCwgQ0xFQVJURVhUX0FNT1VOVCwgJzB4JykpLnNob3VsZC50aHJvdyhcbiAgICAgICAgICAvZGVjcnlwdGlvblByb29mIG11c3QgYmUgYSBub24tZW1wdHkvXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICBkZXNjcmliZSgnYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgZGVzY3JpYmUoJ291dHB1dCBmb3JtYXQnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHByb2R1Y2UgYSAweC1wcmVmaXhlZCBoZXggc3RyaW5nJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNhbGxkYXRhLnNob3VsZC5iZS5hLlN0cmluZygpO1xuICAgICAgICBjYWxsZGF0YS5zaG91bGQuc3RhcnRXaXRoKCcweCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGF2ZSBleGFjdCBsZW5ndGg6IDQtYnl0ZSBzZWxlY3RvciArIDMgw5cgMzItYnl0ZSBBQkkgd29yZHMgPSAxMDAgYnl0ZXMgKDIwMiBjaGFycyknLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKTtcbiAgICAgICAgY2FsbGRhdGEubGVuZ3RoLnNob3VsZC5lcXVhbCgyMDIpOyAvLyAnMHgnICsgMjAwIGhleCBjaGFyc1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3RhcnQgd2l0aCBkZWxlZ2F0ZUZvclVzZXJEZWNyeXB0aW9uIHNlbGVjdG9yJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNhbGxkYXRhLnNsaWNlKDAsIDEwKS5zaG91bGQuZXF1YWwoZGVsZWdhdGVGb3JVc2VyRGVjcnlwdGlvbk1ldGhvZElkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0FCSSBwYXJhbWV0ZXIgZW5jb2Rpbmcg4oCUIHBvc2l0aW9uIGFuZCB2YWx1ZScsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgZW5jb2RlIGRlbGVnYXRlIGFkZHJlc3MgYXMgZmlyc3QgQUJJIHdvcmQgKGJ5dGVzIDTigJMzNSknLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKTtcbiAgICAgICAgLy8gRmlyc3QgMzItYnl0ZSB3b3JkIGFmdGVyIDQtYnl0ZSBzZWxlY3RvciA9IGhleCBjaGFycyAxMOKAkzc0XG4gICAgICAgIGNvbnN0IHdvcmQxID0gY2FsbGRhdGEuc2xpY2UoMTAsIDc0KTtcbiAgICAgICAgd29yZDEuc2hvdWxkLmVxdWFsKERFTEVHQVRFX0FERFJFU1Muc2xpY2UoMikudG9Mb3dlckNhc2UoKS5wYWRTdGFydCg2NCwgJzAnKSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBlbmNvZGUgdG9rZW4gYWRkcmVzcyBhcyBzZWNvbmQgQUJJIHdvcmQgKGJ5dGVzIDM24oCTNjcpJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IHdvcmQyID0gY2FsbGRhdGEuc2xpY2UoNzQsIDEzOCk7XG4gICAgICAgIHdvcmQyLnNob3VsZC5lcXVhbChUT0tFTl9BRERSRVNTLnNsaWNlKDIpLnRvTG93ZXJDYXNlKCkucGFkU3RhcnQoNjQsICcwJykpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZW5jb2RlIGV4cGlyeSB0aW1lc3RhbXAgYXMgdGhpcmQgQUJJIHdvcmQgKGJ5dGVzIDY44oCTOTkpJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IHdvcmQzID0gY2FsbGRhdGEuc2xpY2UoMTM4LCAyMDIpO1xuICAgICAgICBjb25zdCBlbmNvZGVkRXhwaXJ5ID0gRVhQSVJZLnRvU3RyaW5nKDE2KS5wYWRTdGFydCg2NCwgJzAnKTtcbiAgICAgICAgd29yZDMuc2hvdWxkLmVxdWFsKGVuY29kZWRFeHBpcnkpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcm91bmQtdHJpcCBkZWNvZGUgdG8gb3JpZ2luYWwgcGFyYW1ldGVycycsICgpID0+IHtcbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCBbZGVsZWdhdGUsIHRva2VuLCBleHBpcnldID0gZGVjb2RlRGVsZWdhdGlvbkNhbGwoY2FsbGRhdGEpO1xuICAgICAgICBkZWxlZ2F0ZS5zaG91bGQuZXF1YWwoREVMRUdBVEVfQUREUkVTUy5zbGljZSgyKS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgdG9rZW4uc2hvdWxkLmVxdWFsKFRPS0VOX0FERFJFU1Muc2xpY2UoMikudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgIGV4cGlyeS5zaG91bGQuZXF1YWwoRVhQSVJZKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3BhcmFtZXRlciBpc29sYXRpb24nLCAoKSA9PiB7XG4gICAgICBpdCgnZGlmZmVyZW50IGRlbGVnYXRlIGFkZHJlc3NlcyBzaG91bGQgcHJvZHVjZSBkaWZmZXJlbnQgY2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IERFTEVHQVRFXzIgPSAnMHgyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyJztcbiAgICAgICAgY29uc3QgYzEgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCBjMiA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFXzIsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGMxLnNob3VsZC5ub3QuZXF1YWwoYzIpO1xuICAgICAgICAvLyBPbmx5IGZpcnN0IHdvcmQgZGlmZmVyc1xuICAgICAgICBjMS5zbGljZSgxMCwgNzQpLnNob3VsZC5ub3QuZXF1YWwoYzIuc2xpY2UoMTAsIDc0KSk7XG4gICAgICAgIGMxLnNsaWNlKDc0KS5zaG91bGQuZXF1YWwoYzIuc2xpY2UoNzQpKTsgLy8gdG9rZW4gYW5kIGV4cGlyeSB1bmNoYW5nZWRcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnZGlmZmVyZW50IHRva2VuIGFkZHJlc3NlcyBzaG91bGQgcHJvZHVjZSBkaWZmZXJlbnQgY2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGMxID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKTtcbiAgICAgICAgY29uc3QgYzIgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTXzIsIEVYUElSWSk7XG4gICAgICAgIGMxLnNob3VsZC5ub3QuZXF1YWwoYzIpO1xuICAgICAgICAvLyBPbmx5IHNlY29uZCB3b3JkIGRpZmZlcnNcbiAgICAgICAgYzEuc2xpY2UoMTAsIDc0KS5zaG91bGQuZXF1YWwoYzIuc2xpY2UoMTAsIDc0KSk7IC8vIGRlbGVnYXRlIHVuY2hhbmdlZFxuICAgICAgICBjMS5zbGljZSg3NCwgMTM4KS5zaG91bGQubm90LmVxdWFsKGMyLnNsaWNlKDc0LCAxMzgpKTtcbiAgICAgICAgYzEuc2xpY2UoMTM4KS5zaG91bGQuZXF1YWwoYzIuc2xpY2UoMTM4KSk7IC8vIGV4cGlyeSB1bmNoYW5nZWRcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnZGlmZmVyZW50IGV4cGlyeSB0aW1lc3RhbXBzIHNob3VsZCBwcm9kdWNlIGRpZmZlcmVudCBjYWxsZGF0YScsICgpID0+IHtcbiAgICAgICAgY29uc3QgYzEgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCBjMiA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSArIDg2NDAwKTtcbiAgICAgICAgYzEuc2hvdWxkLm5vdC5lcXVhbChjMik7XG4gICAgICAgIC8vIE9ubHkgdGhpcmQgd29yZCBkaWZmZXJzXG4gICAgICAgIGMxLnNsaWNlKDEwLCAxMzgpLnNob3VsZC5lcXVhbChjMi5zbGljZSgxMCwgMTM4KSk7IC8vIGRlbGVnYXRlICsgdG9rZW4gdW5jaGFuZ2VkXG4gICAgICAgIGMxLnNsaWNlKDEzOCkuc2hvdWxkLm5vdC5lcXVhbChjMi5zbGljZSgxMzgpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2FkZHJlc3MgY2FzZSBoYW5kbGluZycsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgbm9ybWFsaXNlIGNoZWNrc3VtbWVkIChtaXhlZC1jYXNlKSBhZGRyZXNzZXMgdG8gbG93ZXJjYXNlIGluIGVuY29kaW5nJywgKCkgPT4ge1xuICAgICAgICAvLyBUT0tFTl9BRERSRVNTXzMgaXMgRUlQLTU1IGNoZWNrc3VtbWVkOiAweEEwYjg2OTkxYzYyMThiMzZjMWQxOUQ0YTJlOUViMGNFMzYwNmVCNDhcbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTXzMsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IHdvcmQyID0gY2FsbGRhdGEuc2xpY2UoNzQsIDEzOCk7XG4gICAgICAgIHdvcmQyLnNob3VsZC5lcXVhbChUT0tFTl9BRERSRVNTXzMuc2xpY2UoMikudG9Mb3dlckNhc2UoKS5wYWRTdGFydCg2NCwgJzAnKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICBkZXNjcmliZSgnYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgZGVzY3JpYmUoJ291dHB1dCBmb3JtYXQnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHByb2R1Y2UgYSAweC1wcmVmaXhlZCBoZXggc3RyaW5nJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsZGF0YSA9IGJ1aWxkTXVsdGljYWxsRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFtUT0tFTl9BRERSRVNTXSwgRVhQSVJZKTtcbiAgICAgICAgY2FsbGRhdGEuc2hvdWxkLmJlLmEuU3RyaW5nKCk7XG4gICAgICAgIGNhbGxkYXRhLnNob3VsZC5zdGFydFdpdGgoJzB4Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdGFydCB3aXRoIG11bHRpY2FsbCBzZWxlY3RvcicsICgpID0+IHtcbiAgICAgICAgY29uc3QgY2FsbGRhdGEgPSBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBbVE9LRU5fQUREUkVTU10sIEVYUElSWSk7XG4gICAgICAgIGNhbGxkYXRhLnNsaWNlKDAsIDEwKS5zaG91bGQuZXF1YWwoYWNsTXVsdGljYWxsTWV0aG9kSWQpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnaW5uZXIgY2FsbCBjb3JyZWN0bmVzcycsICgpID0+IHtcbiAgICAgIC8vIFN0cmF0ZWd5OiBidWlsZCBleHBlY3RlZCBpbm5lciBjYWxscyBpbmRlcGVuZGVudGx5LCB0aGVuIHZlcmlmeSB0aGV5IGFyZVxuICAgICAgLy8gZW1iZWRkZWQgaW4gdGhlIG11bHRpY2FsbCBwYXlsb2FkLiBUaGlzIGF2b2lkcyBkZWNvZGluZyB0aGUgY29tcGxleCBieXRlc1tdXG4gICAgICAvLyBBQkkgc3RydWN0dXJlIGFuZCBkaXJlY3RseSB2ZXJpZmllcyB3aGF0IG1hdHRlcnM6IHRoZSByaWdodCBjYWxscyBhcmUgcHJlc2VudC5cblxuICAgICAgaXQoJ3Nob3VsZCBjb250YWluIHRoZSBleHBlY3RlZCBpbm5lciBkZWxlZ2F0aW9uIGNhbGwgZm9yIGVhY2ggdG9rZW4nLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlubmVyMSA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSkuc2xpY2UoMik7XG4gICAgICAgIGNvbnN0IGlubmVyMiA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1NfMiwgRVhQSVJZKS5zbGljZSgyKTtcbiAgICAgICAgY29uc3QgaW5uZXIzID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTU18zLCBFWFBJUlkpLnNsaWNlKDIpO1xuXG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEoXG4gICAgICAgICAgREVMRUdBVEVfQUREUkVTUyxcbiAgICAgICAgICBbVE9LRU5fQUREUkVTUywgVE9LRU5fQUREUkVTU18yLCBUT0tFTl9BRERSRVNTXzNdLFxuICAgICAgICAgIEVYUElSWVxuICAgICAgICApO1xuXG4gICAgICAgIGNhbGxkYXRhLnNob3VsZC5jb250YWluRXFsKGlubmVyMSk7XG4gICAgICAgIGNhbGxkYXRhLnNob3VsZC5jb250YWluRXFsKGlubmVyMik7XG4gICAgICAgIGNhbGxkYXRhLnNob3VsZC5jb250YWluRXFsKGlubmVyMyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3NpbmdsZS10b2tlbiBtdWx0aWNhbGwgc2hvdWxkIGNvbnRhaW4gaXRzIGlubmVyIGNhbGwgYnV0IG5vdCBvdGhlcnMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlubmVyMSA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSkuc2xpY2UoMik7XG4gICAgICAgIGNvbnN0IGlubmVyMiA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1NfMiwgRVhQSVJZKS5zbGljZSgyKTtcblxuICAgICAgICBjb25zdCBzaW5nbGUgPSBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBbVE9LRU5fQUREUkVTU10sIEVYUElSWSk7XG5cbiAgICAgICAgc2luZ2xlLnNob3VsZC5jb250YWluRXFsKGlubmVyMSk7XG4gICAgICAgIHNpbmdsZS5zaG91bGQubm90LmNvbnRhaW5FcWwoaW5uZXIyKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnZWFjaCBpbm5lciBjYWxsIHNob3VsZCBzdGFydCB3aXRoIGRlbGVnYXRlRm9yVXNlckRlY3J5cHRpb24gc2VsZWN0b3InLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRva2VucyA9IFtUT0tFTl9BRERSRVNTLCBUT0tFTl9BRERSRVNTXzIsIFRPS0VOX0FERFJFU1NfM107XG4gICAgICAgIGNvbnN0IGNhbGxkYXRhID0gYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgdG9rZW5zLCBFWFBJUlkpO1xuXG4gICAgICAgIGZvciAoY29uc3QgdG9rZW4gb2YgdG9rZW5zKSB7XG4gICAgICAgICAgY29uc3QgZXhwZWN0ZWRJbm5lciA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIHRva2VuLCBFWFBJUlkpLnNsaWNlKDIpO1xuICAgICAgICAgIC8vIEVhY2ggaW5uZXIgY2FsbCBzdGFydHMgd2l0aCBkZWxlZ2F0ZUZvclVzZXJEZWNyeXB0aW9uIHNlbGVjdG9yXG4gICAgICAgICAgZXhwZWN0ZWRJbm5lci5zaG91bGQuc3RhcnRXaXRoKGRlbGVnYXRlRm9yVXNlckRlY3J5cHRpb25NZXRob2RJZC5zbGljZSgyKSk7XG4gICAgICAgICAgY2FsbGRhdGEuc2hvdWxkLmNvbnRhaW5FcWwoZXhwZWN0ZWRJbm5lcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnZGlmZmVyZW50IGV4cGlyeSB0aW1lc3RhbXBzIGNoYW5nZSBhbGwgaW5uZXIgY2FsbHMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGMxID0gYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgW1RPS0VOX0FERFJFU1MsIFRPS0VOX0FERFJFU1NfMl0sIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IGMyID0gYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgW1RPS0VOX0FERFJFU1MsIFRPS0VOX0FERFJFU1NfMl0sIEVYUElSWSArIDg2NDAwKTtcblxuICAgICAgICAvLyBJbm5lciBjYWxscyB3aXRoIG9sZCBleHBpcnkgc2hvdWxkIE5PVCBhcHBlYXIgaW4gdGhlIG5ldyBtdWx0aWNhbGxcbiAgICAgICAgY29uc3QgaW5uZXIxT2xkID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKS5zbGljZSgyKTtcbiAgICAgICAgYzIuc2hvdWxkLm5vdC5jb250YWluRXFsKGlubmVyMU9sZCk7XG5cbiAgICAgICAgLy8gQW5kIHZpY2UgdmVyc2FcbiAgICAgICAgY29uc3QgaW5uZXIxTmV3ID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZICsgODY0MDApLnNsaWNlKDIpO1xuICAgICAgICBjMS5zaG91bGQubm90LmNvbnRhaW5FcWwoaW5uZXIxTmV3KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHByb2R1Y2UgbG9uZ2VyIGNhbGxkYXRhIGZvciBtb3JlIHRva2VucycsICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2luZ2xlID0gYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgW1RPS0VOX0FERFJFU1NdLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCBkb3VibGUgPSBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBbVE9LRU5fQUREUkVTUywgVE9LRU5fQUREUkVTU18yXSwgRVhQSVJZKTtcbiAgICAgICAgY29uc3QgdHJpcGxlID0gYnVpbGRNdWx0aWNhbGxEZWxlZ2F0aW9uQ2FsbGRhdGEoXG4gICAgICAgICAgREVMRUdBVEVfQUREUkVTUyxcbiAgICAgICAgICBbVE9LRU5fQUREUkVTUywgVE9LRU5fQUREUkVTU18yLCBUT0tFTl9BRERSRVNTXzNdLFxuICAgICAgICAgIEVYUElSWVxuICAgICAgICApO1xuICAgICAgICBkb3VibGUubGVuZ3RoLnNob3VsZC5iZS5ncmVhdGVyVGhhbihzaW5nbGUubGVuZ3RoKTtcbiAgICAgICAgdHJpcGxlLmxlbmd0aC5zaG91bGQuYmUuZ3JlYXRlclRoYW4oZG91YmxlLmxlbmd0aCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2RpZmZlcmVudCB0b2tlbiBvcmRlcmluZ3Mgc2hvdWxkIHByb2R1Y2UgZGlmZmVyZW50IGNhbGxkYXRhJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBjMSA9IGJ1aWxkTXVsdGljYWxsRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFtUT0tFTl9BRERSRVNTLCBUT0tFTl9BRERSRVNTXzJdLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCBjMiA9IGJ1aWxkTXVsdGljYWxsRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFtUT0tFTl9BRERSRVNTXzIsIFRPS0VOX0FERFJFU1NdLCBFWFBJUlkpO1xuICAgICAgICBjMS5zaG91bGQubm90LmVxdWFsKGMyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2Vycm9yIGhhbmRsaW5nJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIGdpdmVuIGFuIGVtcHR5IHRva2VuIGFycmF5JywgKCkgPT4ge1xuICAgICAgICBzaG91bGQudGhyb3dzKFxuICAgICAgICAgICgpID0+IGJ1aWxkTXVsdGljYWxsRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFtdLCBFWFBJUlkpLFxuICAgICAgICAgIC90b2tlbkNvbnRyYWN0QWRkcmVzc2VzIG11c3Qgbm90IGJlIGVtcHR5L1xuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgZGVzY3JpYmUoJ3dyYXBJbkNhbGxGcm9tUGFyZW50JywgKCkgPT4ge1xuICAgIGRlc2NyaWJlKCdvdXRwdXQgZm9ybWF0JywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGEgMHgtcHJlZml4ZWQgaGV4IHN0cmluZycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXIgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCB3cmFwcGVkID0gd3JhcEluQ2FsbEZyb21QYXJlbnQoQUNMX0FERFJFU1MsIGlubmVyKTtcbiAgICAgICAgd3JhcHBlZC5zaG91bGQuYmUuYS5TdHJpbmcoKTtcbiAgICAgICAgd3JhcHBlZC5zaG91bGQuc3RhcnRXaXRoKCcweCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3RhcnQgd2l0aCBjYWxsRnJvbVBhcmVudCBzZWxlY3RvcicsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXIgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCB3cmFwcGVkID0gd3JhcEluQ2FsbEZyb21QYXJlbnQoQUNMX0FERFJFU1MsIGlubmVyKTtcbiAgICAgICAgd3JhcHBlZC5zbGljZSgwLCAxMCkuc2hvdWxkLmVxdWFsKGNhbGxGcm9tUGFyZW50TWV0aG9kSWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcHJvZHVjZSBsb25nZXIgY2FsbGRhdGEgdGhhbiB0aGUgaW5uZXIgY2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlubmVyID0gYnVpbGREZWxlZ2F0aW9uQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgVE9LRU5fQUREUkVTUywgRVhQSVJZKTtcbiAgICAgICAgY29uc3Qgd3JhcHBlZCA9IHdyYXBJbkNhbGxGcm9tUGFyZW50KEZPUldBUkRFUl9BRERSRVNTLCBpbm5lcik7XG4gICAgICAgIHdyYXBwZWQubGVuZ3RoLnNob3VsZC5iZS5ncmVhdGVyVGhhbihpbm5lci5sZW5ndGgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQUJJIHBhcmFtZXRlciBkZWNvZGluZycsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgZGVjb2RlIHRhcmdldCBhZGRyZXNzIGNvcnJlY3RseScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXIgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCB3cmFwcGVkID0gd3JhcEluQ2FsbEZyb21QYXJlbnQoQUNMX0FERFJFU1MsIGlubmVyKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IEJ1ZmZlci5mcm9tKHdyYXBwZWQuc2xpY2UoMTApLCAnaGV4Jyk7XG4gICAgICAgIGNvbnN0IFt0YXJnZXRdID0gRXRoZXJldW1BYmkucmF3RGVjb2RlKFsnYWRkcmVzcycsICd1aW50MjU2JywgJ2J5dGVzJ10sIHBheWxvYWQpO1xuICAgICAgICAodGFyZ2V0IGFzIEJ1ZmZlcikudG9TdHJpbmcoJ2hleCcpLnNob3VsZC5lcXVhbChBQ0xfQUREUkVTUy5zbGljZSgyKS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGVuY29kZSB2YWx1ZSBhcyAwIChubyBFVEggdHJhbnNmZXIpJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbm5lciA9IGJ1aWxkRGVsZWdhdGlvbkNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIFRPS0VOX0FERFJFU1MsIEVYUElSWSk7XG4gICAgICAgIGNvbnN0IHdyYXBwZWQgPSB3cmFwSW5DYWxsRnJvbVBhcmVudChBQ0xfQUREUkVTUywgaW5uZXIpO1xuICAgICAgICBjb25zdCBwYXlsb2FkID0gQnVmZmVyLmZyb20od3JhcHBlZC5zbGljZSgxMCksICdoZXgnKTtcbiAgICAgICAgY29uc3QgWywgdmFsdWVdID0gRXRoZXJldW1BYmkucmF3RGVjb2RlKFsnYWRkcmVzcycsICd1aW50MjU2JywgJ2J5dGVzJ10sIHBheWxvYWQpO1xuICAgICAgICB2YWx1ZS50b1N0cmluZygpLnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcHJlc2VydmUgaW5uZXIgY2FsbGRhdGEgZXhhY3RseScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXIgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCB3cmFwcGVkID0gd3JhcEluQ2FsbEZyb21QYXJlbnQoQUNMX0FERFJFU1MsIGlubmVyKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IEJ1ZmZlci5mcm9tKHdyYXBwZWQuc2xpY2UoMTApLCAnaGV4Jyk7XG4gICAgICAgIGNvbnN0IFssICwgZGF0YV0gPSBFdGhlcmV1bUFiaS5yYXdEZWNvZGUoWydhZGRyZXNzJywgJ3VpbnQyNTYnLCAnYnl0ZXMnXSwgcGF5bG9hZCk7XG4gICAgICAgICgnMHgnICsgKGRhdGEgYXMgQnVmZmVyKS50b1N0cmluZygnaGV4JykpLnNob3VsZC5lcXVhbChpbm5lcik7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBwcmVzZXJ2ZSBtdWx0aWNhbGwgaW5uZXIgY2FsbGRhdGEgZXhhY3RseScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXIgPSBidWlsZE11bHRpY2FsbERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBbVE9LRU5fQUREUkVTUywgVE9LRU5fQUREUkVTU18yXSwgRVhQSVJZKTtcbiAgICAgICAgY29uc3Qgd3JhcHBlZCA9IHdyYXBJbkNhbGxGcm9tUGFyZW50KEFDTF9BRERSRVNTLCBpbm5lcik7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuZnJvbSh3cmFwcGVkLnNsaWNlKDEwKSwgJ2hleCcpO1xuICAgICAgICBjb25zdCBbLCAsIGRhdGFdID0gRXRoZXJldW1BYmkucmF3RGVjb2RlKFsnYWRkcmVzcycsICd1aW50MjU2JywgJ2J5dGVzJ10sIHBheWxvYWQpO1xuICAgICAgICAoJzB4JyArIChkYXRhIGFzIEJ1ZmZlcikudG9TdHJpbmcoJ2hleCcpKS5zaG91bGQuZXF1YWwoaW5uZXIpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgndGFyZ2V0IGFkZHJlc3MgaXNvbGF0aW9uJywgKCkgPT4ge1xuICAgICAgaXQoJ2RpZmZlcmVudCB0YXJnZXQgYWRkcmVzc2VzIHNob3VsZCBwcm9kdWNlIGRpZmZlcmVudCBjYWxsZGF0YScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5uZXIgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgICBjb25zdCB3MSA9IHdyYXBJbkNhbGxGcm9tUGFyZW50KEFDTF9BRERSRVNTLCBpbm5lcik7XG4gICAgICAgIGNvbnN0IHcyID0gd3JhcEluQ2FsbEZyb21QYXJlbnQoRk9SV0FSREVSX0FERFJFU1MsIGlubmVyKTtcbiAgICAgICAgdzEuc2hvdWxkLm5vdC5lcXVhbCh3Mik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICBkZXNjcmliZSgnYnVpbGRDb25maWRlbnRpYWxUcmFuc2ZlckJ5SGFuZGxlQ2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgY29uc3QgSEFORExFID0gJzB4JyArICdhYicucmVwZWF0KDMyKTsgLy8gMzItYnl0ZSBtb2NrIGhhbmRsZVxuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSAweC1wcmVmaXhlZCBoZXggc3RyaW5nJywgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYnVpbGRDb25maWRlbnRpYWxUcmFuc2ZlckJ5SGFuZGxlQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgSEFORExFKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuYmUuYS5TdHJpbmcoKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuc3RhcnRXaXRoKCcweCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdGFydCB3aXRoIHRoZSBjb25maWRlbnRpYWxUcmFuc2Zlck5vUHJvb2Ygc2VsZWN0b3IgKDB4NWJlYmVkN2UpJywgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYnVpbGRDb25maWRlbnRpYWxUcmFuc2ZlckJ5SGFuZGxlQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgSEFORExFKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuc3RhcnRXaXRoKGNvbmZpZGVudGlhbFRyYW5zZmVyTm9Qcm9vZk1ldGhvZElkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZW5jb2RlIHRoZSByZWNpcGllbnQgYWRkcmVzcyBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBidWlsZENvbmZpZGVudGlhbFRyYW5zZmVyQnlIYW5kbGVDYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBIQU5ETEUpO1xuICAgICAgY29uc3QgcGF5bG9hZCA9IEJ1ZmZlci5mcm9tKHJlc3VsdC5zbGljZSgxMCksICdoZXgnKTtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBFdGhlcmV1bUFiaS5yYXdEZWNvZGUoWydhZGRyZXNzJywgJ2J5dGVzMzInXSwgcGF5bG9hZCk7XG4gICAgICAoJzB4JyArIChkZWNvZGVkWzBdIGFzIEJ1ZmZlcikudG9TdHJpbmcoJ2hleCcpKS50b0xvd2VyQ2FzZSgpLnNob3VsZC5lcXVhbChERUxFR0FURV9BRERSRVNTLnRvTG93ZXJDYXNlKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgdGhlIGVuY3J5cHRlZCBoYW5kbGUgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYnVpbGRDb25maWRlbnRpYWxUcmFuc2ZlckJ5SGFuZGxlQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgSEFORExFKTtcbiAgICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuZnJvbShyZXN1bHQuc2xpY2UoMTApLCAnaGV4Jyk7XG4gICAgICBjb25zdCBkZWNvZGVkID0gRXRoZXJldW1BYmkucmF3RGVjb2RlKFsnYWRkcmVzcycsICdieXRlczMyJ10sIHBheWxvYWQpO1xuICAgICAgKCcweCcgKyAoZGVjb2RlZFsxXSBhcyBCdWZmZXIpLnRvU3RyaW5nKCdoZXgnKSkuc2hvdWxkLmVxdWFsKEhBTkRMRSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZGlmZmVyZW50IGhhbmRsZXMgc2hvdWxkIHByb2R1Y2UgZGlmZmVyZW50IGNhbGxkYXRhJywgKCkgPT4ge1xuICAgICAgY29uc3QgaDEgPSAnMHgnICsgJzAxJy5yZXBlYXQoMzIpO1xuICAgICAgY29uc3QgaDIgPSAnMHgnICsgJzAyJy5yZXBlYXQoMzIpO1xuICAgICAgYnVpbGRDb25maWRlbnRpYWxUcmFuc2ZlckJ5SGFuZGxlQ2FsbGRhdGEoREVMRUdBVEVfQUREUkVTUywgaDEpLnNob3VsZC5ub3QuZXF1YWwoXG4gICAgICAgIGJ1aWxkQ29uZmlkZW50aWFsVHJhbnNmZXJCeUhhbmRsZUNhbGxkYXRhKERFTEVHQVRFX0FERFJFU1MsIGgyKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdkaWZmZXJlbnQgcmVjaXBpZW50IGFkZHJlc3NlcyBzaG91bGQgcHJvZHVjZSBkaWZmZXJlbnQgY2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgICBidWlsZENvbmZpZGVudGlhbFRyYW5zZmVyQnlIYW5kbGVDYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBIQU5ETEUpLnNob3VsZC5ub3QuZXF1YWwoXG4gICAgICAgIGJ1aWxkQ29uZmlkZW50aWFsVHJhbnNmZXJCeUhhbmRsZUNhbGxkYXRhKFRPS0VOX0FERFJFU1MsIEhBTkRMRSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgZGVzY3JpYmUoJ2J1aWxkRmx1c2hFUkM3OTg0Rm9yd2FyZGVyVG9rZW5DYWxsZGF0YScsICgpID0+IHtcbiAgICBjb25zdCBQQVJFTlRfQUREUkVTUyA9ICcweDIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjInO1xuICAgIGNvbnN0IEhBTkRMRSA9ICcweCcgKyAnY2QnLnJlcGVhdCgzMik7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIDB4LXByZWZpeGVkIGhleCBzdHJpbmcnLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBidWlsZEZsdXNoRVJDNzk4NEZvcndhcmRlclRva2VuQ2FsbGRhdGEoVE9LRU5fQUREUkVTUywgUEFSRU5UX0FERFJFU1MsIEhBTkRMRSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmJlLmEuU3RyaW5nKCk7XG4gICAgICByZXN1bHQuc2hvdWxkLnN0YXJ0V2l0aCgnMHgnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3RhcnQgd2l0aCB0aGUgY2FsbEZyb21QYXJlbnQgc2VsZWN0b3InLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBidWlsZEZsdXNoRVJDNzk4NEZvcndhcmRlclRva2VuQ2FsbGRhdGEoVE9LRU5fQUREUkVTUywgUEFSRU5UX0FERFJFU1MsIEhBTkRMRSk7XG4gICAgICByZXN1bHQuc2hvdWxkLnN0YXJ0V2l0aChjYWxsRnJvbVBhcmVudE1ldGhvZElkKTtcbiAgICB9KTtcblxuICAgIGl0KCdpbm5lciBjYWxsZGF0YSBzaG91bGQgc3RhcnQgd2l0aCBjb25maWRlbnRpYWxUcmFuc2Zlck5vUHJvb2Ygc2VsZWN0b3InLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBidWlsZEZsdXNoRVJDNzk4NEZvcndhcmRlclRva2VuQ2FsbGRhdGEoVE9LRU5fQUREUkVTUywgUEFSRU5UX0FERFJFU1MsIEhBTkRMRSk7XG4gICAgICBjb25zdCBwYXlsb2FkID0gQnVmZmVyLmZyb20ocmVzdWx0LnNsaWNlKDEwKSwgJ2hleCcpO1xuICAgICAgY29uc3QgZGVjb2RlZCA9IEV0aGVyZXVtQWJpLnJhd0RlY29kZShbJ2FkZHJlc3MnLCAndWludDI1NicsICdieXRlcyddLCBwYXlsb2FkKTtcbiAgICAgIGNvbnN0IGlubmVyQ2FsbGRhdGEgPSAnMHgnICsgKGRlY29kZWRbMl0gYXMgQnVmZmVyKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBpbm5lckNhbGxkYXRhLnNob3VsZC5zdGFydFdpdGgoY29uZmlkZW50aWFsVHJhbnNmZXJOb1Byb29mTWV0aG9kSWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ291dGVyIHRhcmdldCBhZGRyZXNzIHNob3VsZCBlcXVhbCB0aGUgdG9rZW4gY29udHJhY3QgYWRkcmVzcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGJ1aWxkRmx1c2hFUkM3OTg0Rm9yd2FyZGVyVG9rZW5DYWxsZGF0YShUT0tFTl9BRERSRVNTLCBQQVJFTlRfQUREUkVTUywgSEFORExFKTtcbiAgICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuZnJvbShyZXN1bHQuc2xpY2UoMTApLCAnaGV4Jyk7XG4gICAgICBjb25zdCBkZWNvZGVkID0gRXRoZXJldW1BYmkucmF3RGVjb2RlKFsnYWRkcmVzcycsICd1aW50MjU2JywgJ2J5dGVzJ10sIHBheWxvYWQpO1xuICAgICAgKCcweCcgKyAoZGVjb2RlZFswXSBhcyBCdWZmZXIpLnRvU3RyaW5nKCdoZXgnKSkudG9Mb3dlckNhc2UoKS5zaG91bGQuZXF1YWwoVE9LRU5fQUREUkVTUy50b0xvd2VyQ2FzZSgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdpbm5lciByZWNpcGllbnQgc2hvdWxkIGVxdWFsIHRoZSBwYXJlbnQgYWRkcmVzcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGJ1aWxkRmx1c2hFUkM3OTg0Rm9yd2FyZGVyVG9rZW5DYWxsZGF0YShUT0tFTl9BRERSRVNTLCBQQVJFTlRfQUREUkVTUywgSEFORExFKTtcbiAgICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuZnJvbShyZXN1bHQuc2xpY2UoMTApLCAnaGV4Jyk7XG4gICAgICBjb25zdCBkZWNvZGVkID0gRXRoZXJldW1BYmkucmF3RGVjb2RlKFsnYWRkcmVzcycsICd1aW50MjU2JywgJ2J5dGVzJ10sIHBheWxvYWQpO1xuICAgICAgY29uc3QgaW5uZXJDYWxsZGF0YSA9ICcweCcgKyAoZGVjb2RlZFsyXSBhcyBCdWZmZXIpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGlubmVyUGF5bG9hZCA9IEJ1ZmZlci5mcm9tKGlubmVyQ2FsbGRhdGEuc2xpY2UoMTApLCAnaGV4Jyk7XG4gICAgICBjb25zdCBpbm5lckRlY29kZWQgPSBFdGhlcmV1bUFiaS5yYXdEZWNvZGUoWydhZGRyZXNzJywgJ2J5dGVzMzInXSwgaW5uZXJQYXlsb2FkKTtcbiAgICAgICgnMHgnICsgKGlubmVyRGVjb2RlZFswXSBhcyBCdWZmZXIpLnRvU3RyaW5nKCdoZXgnKSkudG9Mb3dlckNhc2UoKS5zaG91bGQuZXF1YWwoUEFSRU5UX0FERFJFU1MudG9Mb3dlckNhc2UoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZGlmZmVyZW50IHRva2VuIGFkZHJlc3NlcyBzaG91bGQgcHJvZHVjZSBkaWZmZXJlbnQgY2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgICBidWlsZEZsdXNoRVJDNzk4NEZvcndhcmRlclRva2VuQ2FsbGRhdGEoVE9LRU5fQUREUkVTUywgUEFSRU5UX0FERFJFU1MsIEhBTkRMRSkuc2hvdWxkLm5vdC5lcXVhbChcbiAgICAgICAgYnVpbGRGbHVzaEVSQzc5ODRGb3J3YXJkZXJUb2tlbkNhbGxkYXRhKFRPS0VOX0FERFJFU1NfMiwgUEFSRU5UX0FERFJFU1MsIEhBTkRMRSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgZGVzY3JpYmUoJ2RlY29kZUZsdXNoRVJDNzk4NEZvcndhcmRlclRva2VuQ2FsbGRhdGEnLCAoKSA9PiB7XG4gICAgY29uc3QgUEFSRU5UX0FERFJFU1MgPSAnMHgyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyJztcbiAgICBjb25zdCBIQU5ETEUgPSAnMHgnICsgJ2VmJy5yZXBlYXQoMzIpO1xuXG4gICAgaXQoJ3Nob3VsZCByb3VuZC10cmlwIGVuY29kZSBhbmQgZGVjb2RlIGNvcnJlY3RseScsICgpID0+IHtcbiAgICAgIGNvbnN0IGVuY29kZWQgPSBidWlsZEZsdXNoRVJDNzk4NEZvcndhcmRlclRva2VuQ2FsbGRhdGEoVE9LRU5fQUREUkVTUywgUEFSRU5UX0FERFJFU1MsIEhBTkRMRSk7XG4gICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlRmx1c2hFUkM3OTg0Rm9yd2FyZGVyVG9rZW5DYWxsZGF0YShlbmNvZGVkKTtcbiAgICAgIGRlY29kZWQudG9rZW5Db250cmFjdEFkZHJlc3MudG9Mb3dlckNhc2UoKS5zaG91bGQuZXF1YWwoVE9LRU5fQUREUkVTUy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIGRlY29kZWQucGFyZW50QWRkcmVzcy50b0xvd2VyQ2FzZSgpLnNob3VsZC5lcXVhbChQQVJFTlRfQUREUkVTUy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIGRlY29kZWQuZW5jcnlwdGVkSGFuZGxlLnNob3VsZC5lcXVhbChIQU5ETEUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgY2FsbGRhdGEgd2l0aCB3cm9uZyBvdXRlciBzZWxlY3RvcicsICgpID0+IHtcbiAgICAgIGNvbnN0IGJhZCA9ICcweGRlYWRiZWVmJyArICcwMCcucmVwZWF0KDY0KTtcbiAgICAgIHNob3VsZC50aHJvd3MoKCkgPT4gZGVjb2RlRmx1c2hFUkM3OTg0Rm9yd2FyZGVyVG9rZW5DYWxsZGF0YShiYWQpLCAvSW52YWxpZCBGbHVzaEVSQzc5ODRGb3J3YXJkZXJUb2tlbiBjYWxsZGF0YS8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgY2FsbGRhdGEgd2l0aCBjb3JyZWN0IG91dGVyIGJ1dCB3cm9uZyBpbm5lciBzZWxlY3RvcicsICgpID0+IHtcbiAgICAgIC8vIFdyYXAgZGVsZWdhdGlvbiBjYWxsZGF0YSBpbiBjYWxsRnJvbVBhcmVudCDigJQgaW5uZXIgc3RhcnRzIHdpdGggMHgwNGY2MWE5NSwgbm90IDB4NWJlYmVkN2VcbiAgICAgIGNvbnN0IGlubmVyQ2FsbGRhdGEgPSBidWlsZERlbGVnYXRpb25DYWxsZGF0YShERUxFR0FURV9BRERSRVNTLCBUT0tFTl9BRERSRVNTLCBFWFBJUlkpO1xuICAgICAgY29uc3Qgd3JhcHBlZCA9IHdyYXBJbkNhbGxGcm9tUGFyZW50KFRPS0VOX0FERFJFU1MsIGlubmVyQ2FsbGRhdGEpO1xuICAgICAgc2hvdWxkLnRocm93cyhcbiAgICAgICAgKCkgPT4gZGVjb2RlRmx1c2hFUkM3OTg0Rm9yd2FyZGVyVG9rZW5DYWxsZGF0YSh3cmFwcGVkKSxcbiAgICAgICAgL0ludmFsaWQgRmx1c2hFUkM3OTg0Rm9yd2FyZGVyVG9rZW4gaW5uZXIgY2FsbGRhdGEvXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ2RlY29kZWQgdG9rZW5Db250cmFjdEFkZHJlc3Mgc2hvdWxkIGJlIGNoZWNrc3VtbWVkIG9yIGxvd2VyY2FzZSBjb25zaXN0ZW50bHknLCAoKSA9PiB7XG4gICAgICBjb25zdCBlbmNvZGVkID0gYnVpbGRGbHVzaEVSQzc5ODRGb3J3YXJkZXJUb2tlbkNhbGxkYXRhKFRPS0VOX0FERFJFU1MsIFBBUkVOVF9BRERSRVNTLCBIQU5ETEUpO1xuICAgICAgY29uc3QgZGVjb2RlZCA9IGRlY29kZUZsdXNoRVJDNzk4NEZvcndhcmRlclRva2VuQ2FsbGRhdGEoZW5jb2RlZCk7XG4gICAgICBzaG91bGQuZXhpc3QoZGVjb2RlZC50b2tlbkNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICBkZWNvZGVkLnRva2VuQ29udHJhY3RBZGRyZXNzLnNob3VsZC5iZS5hLlN0cmluZygpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19