@bitgo/sdk-coin-flrp 1.7.2 → 1.9.0
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.
- package/dist/src/flrp.d.ts +8 -0
- package/dist/src/flrp.d.ts.map +1 -1
- package/dist/src/flrp.js +43 -1
- package/dist/src/lib/ExportInPTxBuilder.d.ts +14 -1
- package/dist/src/lib/ExportInPTxBuilder.d.ts.map +1 -1
- package/dist/src/lib/ExportInPTxBuilder.js +62 -20
- package/dist/src/lib/ImportInCTxBuilder.d.ts +0 -1
- package/dist/src/lib/ImportInCTxBuilder.d.ts.map +1 -1
- package/dist/src/lib/ImportInCTxBuilder.js +23 -17
- package/dist/src/lib/ImportInPTxBuilder.d.ts +0 -10
- package/dist/src/lib/ImportInPTxBuilder.d.ts.map +1 -1
- package/dist/src/lib/ImportInPTxBuilder.js +22 -30
- package/dist/src/lib/atomicTransactionBuilder.d.ts +29 -27
- package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/atomicTransactionBuilder.js +89 -58
- package/dist/src/lib/iface.d.ts +12 -2
- package/dist/src/lib/iface.d.ts.map +1 -1
- package/dist/src/lib/iface.js +1 -1
- package/dist/src/lib/index.d.ts +1 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +4 -2
- package/dist/src/lib/permissionlessDelegatorTxBuilder.d.ts +108 -0
- package/dist/src/lib/permissionlessDelegatorTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/permissionlessDelegatorTxBuilder.js +268 -0
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +42 -11
- package/dist/src/lib/transactionBuilderFactory.d.ts +6 -0
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +14 -1
- package/dist/src/lib/utils.d.ts +31 -0
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +65 -3
- package/dist/test/resources/account.d.ts +21 -0
- package/dist/test/resources/account.d.ts.map +1 -1
- package/dist/test/resources/account.js +23 -2
- package/dist/test/resources/transactionData/delegatorTx.d.ts +83 -0
- package/dist/test/resources/transactionData/delegatorTx.d.ts.map +1 -0
- package/dist/test/resources/transactionData/delegatorTx.js +77 -0
- package/dist/test/resources/transactionData/exportInP.d.ts.map +1 -1
- package/dist/test/resources/transactionData/exportInP.js +5 -6
- package/dist/test/resources/transactionData/importInC.js +5 -5
- package/dist/test/resources/transactionData/importInP.js +5 -5
- package/dist/test/unit/flrp.js +74 -3
- package/dist/test/unit/lib/exportInPTxBuilder.js +144 -34
- package/dist/test/unit/lib/importInCTxBuilder.js +51 -74
- package/dist/test/unit/lib/importInPTxBuilder.js +48 -182
- package/dist/test/unit/lib/permissionlessDelegatorTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/permissionlessDelegatorTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/permissionlessDelegatorTxBuilder.js +235 -0
- package/dist/test/unit/lib/utils.js +92 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/dist/test/unit/lib/signatureIndex.d.ts +0 -13
- package/dist/test/unit/lib/signatureIndex.d.ts.map +0 -1
- package/dist/test/unit/lib/signatureIndex.js +0 -843
|
@@ -0,0 +1,235 @@
|
|
|
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 assert_1 = __importDefault(require("assert"));
|
|
7
|
+
require("should");
|
|
8
|
+
const statics_1 = require("@bitgo/statics");
|
|
9
|
+
const sdk_core_1 = require("@bitgo/sdk-core");
|
|
10
|
+
const lib_1 = require("../../../src/lib");
|
|
11
|
+
const account_1 = require("../../resources/account");
|
|
12
|
+
const utils_1 = __importDefault(require("../../../src/lib/utils"));
|
|
13
|
+
const delegatorTx_1 = require("../../resources/transactionData/delegatorTx");
|
|
14
|
+
describe('Flrp PermissionlessDelegatorTxBuilder', () => {
|
|
15
|
+
const coinConfig = statics_1.coins.get('tflrp');
|
|
16
|
+
const factory = new lib_1.TransactionBuilderFactory(coinConfig);
|
|
17
|
+
describe('getDelegatorBuilder', () => {
|
|
18
|
+
it('should return a PermissionlessDelegatorTxBuilder instance', () => {
|
|
19
|
+
const builder = factory.getDelegatorBuilder();
|
|
20
|
+
builder.should.be.instanceOf(lib_1.PermissionlessDelegatorTxBuilder);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe('validate nodeID', () => {
|
|
24
|
+
it('should fail when nodeID is missing', () => {
|
|
25
|
+
const builder = factory.getDelegatorBuilder();
|
|
26
|
+
assert_1.default.throws(() => {
|
|
27
|
+
builder.nodeID('');
|
|
28
|
+
}, (e) => e.message === 'Invalid transaction: missing nodeID');
|
|
29
|
+
});
|
|
30
|
+
it('should fail when nodeID has invalid prefix', () => {
|
|
31
|
+
const builder = factory.getDelegatorBuilder();
|
|
32
|
+
assert_1.default.throws(() => {
|
|
33
|
+
builder.nodeID('InvalidPrefix-123456789');
|
|
34
|
+
}, (e) => e.message === 'Invalid transaction: invalid NodeID tag');
|
|
35
|
+
});
|
|
36
|
+
it('should accept valid nodeID format', () => {
|
|
37
|
+
const builder = factory.getDelegatorBuilder();
|
|
38
|
+
const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
|
|
39
|
+
(() => builder.nodeID(validNodeID)).should.not.throw();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe('validate stake duration', () => {
|
|
43
|
+
it('should fail when end time is less than start time', () => {
|
|
44
|
+
const builder = factory.getDelegatorBuilder();
|
|
45
|
+
const startTime = BigInt(Math.floor(Date.now() / 1000) + 60);
|
|
46
|
+
const endTime = BigInt(Math.floor(Date.now() / 1000) - 60);
|
|
47
|
+
builder.startTime(startTime.toString());
|
|
48
|
+
builder.endTime(endTime.toString());
|
|
49
|
+
// The validation happens in buildFlareTransaction, but we can test validateStakeDuration directly
|
|
50
|
+
assert_1.default.throws(() => {
|
|
51
|
+
builder.validateStakeDuration(startTime, endTime);
|
|
52
|
+
}, (e) => e.message === 'End date cannot be less than start date');
|
|
53
|
+
});
|
|
54
|
+
it('should accept valid stake duration', () => {
|
|
55
|
+
const builder = factory.getDelegatorBuilder();
|
|
56
|
+
const startTime = BigInt(Math.floor(Date.now() / 1000) + 60);
|
|
57
|
+
const endTime = BigInt(Math.floor(Date.now() / 1000) + 86400 * 14); // 14 days later
|
|
58
|
+
(() => {
|
|
59
|
+
builder.validateStakeDuration(startTime, endTime);
|
|
60
|
+
}).should.not.throw();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe('builder methods', () => {
|
|
64
|
+
it('should set startTime correctly', () => {
|
|
65
|
+
const builder = factory.getDelegatorBuilder();
|
|
66
|
+
const startTime = Math.floor(Date.now() / 1000) + 60;
|
|
67
|
+
(() => builder.startTime(startTime)).should.not.throw();
|
|
68
|
+
});
|
|
69
|
+
it('should set endTime correctly', () => {
|
|
70
|
+
const builder = factory.getDelegatorBuilder();
|
|
71
|
+
const endTime = Math.floor(Date.now() / 1000) + 86400 * 14;
|
|
72
|
+
(() => builder.endTime(endTime)).should.not.throw();
|
|
73
|
+
});
|
|
74
|
+
it('should set rewardAddress with P-chain address', () => {
|
|
75
|
+
const builder = factory.getDelegatorBuilder();
|
|
76
|
+
// P-chain Bech32 address
|
|
77
|
+
(() => builder.rewardAddress(account_1.SEED_ACCOUNT.addressTestnet)).should.not.throw();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe('build validation', () => {
|
|
81
|
+
it('should fail build when nodeID is not set', async () => {
|
|
82
|
+
const builder = factory.getDelegatorBuilder();
|
|
83
|
+
const now = Math.floor(Date.now() / 1000);
|
|
84
|
+
builder
|
|
85
|
+
.startTime(now + 60)
|
|
86
|
+
.endTime(now + 86400 * 14)
|
|
87
|
+
.stakeAmount(BigInt(50000 * 1e9))
|
|
88
|
+
.fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
|
|
89
|
+
.context(account_1.CONTEXT);
|
|
90
|
+
await builder.build().should.be.rejectedWith('NodeID is required for delegation');
|
|
91
|
+
});
|
|
92
|
+
it('should fail build when start time is not set', async () => {
|
|
93
|
+
const builder = factory.getDelegatorBuilder();
|
|
94
|
+
const now = Math.floor(Date.now() / 1000);
|
|
95
|
+
const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
|
|
96
|
+
builder
|
|
97
|
+
.nodeID(validNodeID)
|
|
98
|
+
.endTime(now + 86400 * 14)
|
|
99
|
+
.stakeAmount(BigInt(50000 * 1e9))
|
|
100
|
+
.fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
|
|
101
|
+
.context(account_1.CONTEXT);
|
|
102
|
+
await builder.build().should.be.rejectedWith('Start time is required for delegation');
|
|
103
|
+
});
|
|
104
|
+
it('should fail build when end time is not set', async () => {
|
|
105
|
+
const builder = factory.getDelegatorBuilder();
|
|
106
|
+
const now = Math.floor(Date.now() / 1000);
|
|
107
|
+
const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
|
|
108
|
+
builder
|
|
109
|
+
.nodeID(validNodeID)
|
|
110
|
+
.startTime(now + 60)
|
|
111
|
+
.stakeAmount(BigInt(50000 * 1e9))
|
|
112
|
+
.fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
|
|
113
|
+
.context(account_1.CONTEXT);
|
|
114
|
+
await builder.build().should.be.rejectedWith('End time is required for delegation');
|
|
115
|
+
});
|
|
116
|
+
it('should fail build when stake amount is not set', async () => {
|
|
117
|
+
const builder = factory.getDelegatorBuilder();
|
|
118
|
+
const now = Math.floor(Date.now() / 1000);
|
|
119
|
+
const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
|
|
120
|
+
builder
|
|
121
|
+
.nodeID(validNodeID)
|
|
122
|
+
.startTime(now + 60)
|
|
123
|
+
.endTime(now + 86400 * 14)
|
|
124
|
+
.fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
|
|
125
|
+
.context(account_1.CONTEXT);
|
|
126
|
+
await builder.build().should.be.rejectedWith('Stake amount is required for delegation');
|
|
127
|
+
});
|
|
128
|
+
it('should fail build when context is not set', async () => {
|
|
129
|
+
const builder = factory.getDelegatorBuilder();
|
|
130
|
+
const now = Math.floor(Date.now() / 1000);
|
|
131
|
+
const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
|
|
132
|
+
builder
|
|
133
|
+
.nodeID(validNodeID)
|
|
134
|
+
.startTime(now + 60)
|
|
135
|
+
.endTime(now + 86400 * 14)
|
|
136
|
+
.stakeAmount(BigInt(50000 * 1e9))
|
|
137
|
+
.fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet]);
|
|
138
|
+
await builder.build().should.be.rejectedWith('Context is required for delegation');
|
|
139
|
+
});
|
|
140
|
+
it('should fail build when from addresses are not set', async () => {
|
|
141
|
+
const builder = factory.getDelegatorBuilder();
|
|
142
|
+
const now = Math.floor(Date.now() / 1000);
|
|
143
|
+
const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
|
|
144
|
+
builder
|
|
145
|
+
.nodeID(validNodeID)
|
|
146
|
+
.startTime(now + 60)
|
|
147
|
+
.endTime(now + 86400 * 14)
|
|
148
|
+
.stakeAmount(BigInt(50000 * 1e9))
|
|
149
|
+
.context(account_1.CONTEXT);
|
|
150
|
+
await builder.build().should.be.rejectedWith('From addresses are required for delegation');
|
|
151
|
+
});
|
|
152
|
+
it('should fail build when fee state is not set', async () => {
|
|
153
|
+
const builder = factory.getDelegatorBuilder();
|
|
154
|
+
const now = Math.floor(Date.now() / 1000);
|
|
155
|
+
const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
|
|
156
|
+
builder
|
|
157
|
+
.nodeID(validNodeID)
|
|
158
|
+
.startTime(now + 60)
|
|
159
|
+
.endTime(now + 86400 * 14)
|
|
160
|
+
.stakeAmount(BigInt(50000 * 1e9))
|
|
161
|
+
.fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
|
|
162
|
+
.context(account_1.CONTEXT);
|
|
163
|
+
await builder.build().should.be.rejectedWith('Fee state is required for delegation');
|
|
164
|
+
});
|
|
165
|
+
it('should fail build when UTXOs are not set', async () => {
|
|
166
|
+
const builder = factory.getDelegatorBuilder();
|
|
167
|
+
const now = Math.floor(Date.now() / 1000);
|
|
168
|
+
const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
|
|
169
|
+
const mockFeeState = { capacity: 100000n, excess: 0n, price: 1000n, timestamp: '1234567890' };
|
|
170
|
+
builder
|
|
171
|
+
.nodeID(validNodeID)
|
|
172
|
+
.startTime(now + 60)
|
|
173
|
+
.endTime(now + 86400 * 14)
|
|
174
|
+
.stakeAmount(BigInt(50000 * 1e9))
|
|
175
|
+
.fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
|
|
176
|
+
.context(account_1.CONTEXT)
|
|
177
|
+
.feeState(mockFeeState);
|
|
178
|
+
await builder.build().should.be.rejectedWith('UTXOs are required for delegation');
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
describe('validate stake amount', () => {
|
|
182
|
+
it('should fail when stake amount is below minimum', () => {
|
|
183
|
+
const builder = factory.getDelegatorBuilder();
|
|
184
|
+
// Minimum is 50000 FLR, so 1000 should fail
|
|
185
|
+
assert_1.default.throws(() => {
|
|
186
|
+
builder.stakeAmount(BigInt(1000 * 1e9));
|
|
187
|
+
}, (e) => e.message.includes('Minimum delegation amount'));
|
|
188
|
+
});
|
|
189
|
+
it('should accept stake amount at or above minimum', () => {
|
|
190
|
+
const builder = factory.getDelegatorBuilder();
|
|
191
|
+
const stakeAmount = BigInt(50000 * 1e9);
|
|
192
|
+
(() => builder.stakeAmount(stakeAmount)).should.not.throw();
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
describe('transaction type support', () => {
|
|
196
|
+
it('should allow setting AddPermissionlessDelegator transaction type', () => {
|
|
197
|
+
const builder = factory.getDelegatorBuilder();
|
|
198
|
+
// The builder should successfully configure with AddPermissionlessDelegator type
|
|
199
|
+
// This verifies transaction.ts setTransactionType accepts the delegation type
|
|
200
|
+
builder.should.be.instanceof(lib_1.PermissionlessDelegatorTxBuilder);
|
|
201
|
+
});
|
|
202
|
+
it('should have correct minimum stake amount constant', () => {
|
|
203
|
+
// Verify the minimum stake amount is 50000 FLR (in nanoFLR)
|
|
204
|
+
const minStakeAmount = BigInt(50000 * 1e9);
|
|
205
|
+
minStakeAmount.should.equal(BigInt('50000000000000'));
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
describe('round-trip deserialization', () => {
|
|
209
|
+
it('should deserialize a signed delegation transaction from hex', async () => {
|
|
210
|
+
const rawTx = utils_1.default.removeHexPrefix(delegatorTx_1.DELEGATION_TX_2.signedHex);
|
|
211
|
+
const tx = (await factory.from(rawTx).build());
|
|
212
|
+
tx.type.should.equal(sdk_core_1.TransactionType.AddPermissionlessDelegator);
|
|
213
|
+
});
|
|
214
|
+
it('should correctly extract delegation parameters from deserialized transaction', async () => {
|
|
215
|
+
const rawTx = utils_1.default.removeHexPrefix(delegatorTx_1.DELEGATION_TX_2.signedHex);
|
|
216
|
+
const tx = (await factory.from(rawTx).build());
|
|
217
|
+
const explanation = tx.explainTransaction();
|
|
218
|
+
explanation.outputs.length.should.be.above(0);
|
|
219
|
+
explanation.outputAmount.should.equal(delegatorTx_1.DELEGATION_TX_2.stakeAmount);
|
|
220
|
+
});
|
|
221
|
+
it('should re-serialize to the same hex (round-trip)', async () => {
|
|
222
|
+
const rawTx = utils_1.default.removeHexPrefix(delegatorTx_1.DELEGATION_TX_2.signedHex);
|
|
223
|
+
const tx = (await factory.from(rawTx).build());
|
|
224
|
+
const reEncodedTx = utils_1.default.removeHexPrefix(tx.toBroadcastFormat());
|
|
225
|
+
reEncodedTx.should.equal(rawTx);
|
|
226
|
+
});
|
|
227
|
+
it('should have correct input/output counts', async () => {
|
|
228
|
+
const rawTx = utils_1.default.removeHexPrefix(delegatorTx_1.DELEGATION_TX_2.signedHex);
|
|
229
|
+
const tx = (await factory.from(rawTx).build());
|
|
230
|
+
tx.inputs.should.have.length(3);
|
|
231
|
+
tx.outputs.length.should.be.above(0);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbmxlc3NEZWxlZ2F0b3JUeEJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3Blcm1pc3Npb25sZXNzRGVsZWdhdG9yVHhCdWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsb0RBQTRCO0FBQzVCLGtCQUFnQjtBQUNoQiw0Q0FBdUM7QUFDdkMsOENBQWtEO0FBQ2xELDBDQUE0RztBQUM1RyxxREFBMkU7QUFDM0UsbUVBQTJDO0FBQzNDLDZFQUE4RTtBQUU5RSxRQUFRLENBQUMsdUNBQXVDLEVBQUUsR0FBRyxFQUFFO0lBQ3JELE1BQU0sVUFBVSxHQUFHLGVBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEMsTUFBTSxPQUFPLEdBQUcsSUFBSSwrQkFBeUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUUxRCxRQUFRLENBQUMscUJBQXFCLEVBQUUsR0FBRyxFQUFFO1FBQ25DLEVBQUUsQ0FBQywyREFBMkQsRUFBRSxHQUFHLEVBQUU7WUFDbkUsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLHNDQUFnQyxDQUFDLENBQUM7UUFDakUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLEVBQUU7UUFDL0IsRUFBRSxDQUFDLG9DQUFvQyxFQUFFLEdBQUcsRUFBRTtZQUM1QyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM5QyxnQkFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUU7Z0JBQ0gsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNyQixDQUFDLEVBQ0QsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENB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QyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0RBQWtELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDaEUsTUFBTSxLQUFLLEdBQUcsZUFBSyxDQUFDLGVBQWUsQ0FBQyw2QkFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9ELE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFnQixDQUFDO1lBQzlELE1BQU0sV0FBVyxHQUFHLGVBQUssQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztZQUVsRSxXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN2RCxNQUFNLEtBQUssR0FBRyxlQUFLLENBQUMsZUFBZSxDQUFDLDZCQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDL0QsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQWdCLENBQUM7WUFDOUQsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoQyxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgJ3Nob3VsZCc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5LCBQZXJtaXNzaW9ubGVzc0RlbGVnYXRvclR4QnVpbGRlciwgVHJhbnNhY3Rpb24gfSBmcm9tICcuLi8uLi8uLi9zcmMvbGliJztcbmltcG9ydCB7IFNFRURfQUNDT1VOVCwgQUNDT1VOVF8xLCBDT05URVhUIH0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL2FjY291bnQnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uLy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0IHsgREVMRUdBVElPTl9UWF8yIH0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL3RyYW5zYWN0aW9uRGF0YS9kZWxlZ2F0b3JUeCc7XG5cbmRlc2NyaWJlKCdGbHJwIFBlcm1pc3Npb25sZXNzRGVsZWdhdG9yVHhCdWlsZGVyJywgKCkgPT4ge1xuICBjb25zdCBjb2luQ29uZmlnID0gY29pbnMuZ2V0KCd0ZmxycCcpO1xuICBjb25zdCBmYWN0b3J5ID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbkNvbmZpZyk7XG5cbiAgZGVzY3JpYmUoJ2dldERlbGVnYXRvckJ1aWxkZXInLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBQZXJtaXNzaW9ubGVzc0RlbGVnYXRvclR4QnVpbGRlciBpbnN0YW5jZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGJ1aWxkZXIuc2hvdWxkLmJlLmluc3RhbmNlT2YoUGVybWlzc2lvbmxlc3NEZWxlZ2F0b3JUeEJ1aWxkZXIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmFsaWRhdGUgbm9kZUlEJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZmFpbCB3aGVuIG5vZGVJRCBpcyBtaXNzaW5nJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGJ1aWxkZXIubm9kZUlEKCcnKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnSW52YWxpZCB0cmFuc2FjdGlvbjogbWlzc2luZyBub2RlSUQnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHdoZW4gbm9kZUlEIGhhcyBpbnZhbGlkIHByZWZpeCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICBidWlsZGVyLm5vZGVJRCgnSW52YWxpZFByZWZpeC0xMjM0NTY3ODknKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnSW52YWxpZCB0cmFuc2FjdGlvbjogaW52YWxpZCBOb2RlSUQgdGFnJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWNjZXB0IHZhbGlkIG5vZGVJRCBmb3JtYXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICBjb25zdCB2YWxpZE5vZGVJRCA9ICdOb2RlSUQtQUs3c1BCc1pNOXJRd3NlMjNhTGhFRUJQSFpENWdrTHJMJztcbiAgICAgICgoKSA9PiBidWlsZGVyLm5vZGVJRCh2YWxpZE5vZGVJRCkpLnNob3VsZC5ub3QudGhyb3coKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZhbGlkYXRlIHN0YWtlIGR1cmF0aW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZmFpbCB3aGVuIGVuZCB0aW1lIGlzIGxlc3MgdGhhbiBzdGFydCB0aW1lJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgY29uc3Qgc3RhcnRUaW1lID0gQmlnSW50KE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApICsgNjApO1xuICAgICAgY29uc3QgZW5kVGltZSA9IEJpZ0ludChNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKSAtIDYwKTtcblxuICAgICAgYnVpbGRlci5zdGFydFRpbWUoc3RhcnRUaW1lLnRvU3RyaW5nKCkpO1xuICAgICAgYnVpbGRlci5lbmRUaW1lKGVuZFRpbWUudG9TdHJpbmcoKSk7XG5cbiAgICAgIC8vIFRoZSB2YWxpZGF0aW9uIGhhcHBlbnMgaW4gYnVpbGRGbGFyZVRyYW5zYWN0aW9uLCBidXQgd2UgY2FuIHRlc3QgdmFsaWRhdGVTdGFrZUR1cmF0aW9uIGRpcmVjdGx5XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgYnVpbGRlci52YWxpZGF0ZVN0YWtlRHVyYXRpb24oc3RhcnRUaW1lLCBlbmRUaW1lKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnRW5kIGRhdGUgY2Fubm90IGJlIGxlc3MgdGhhbiBzdGFydCBkYXRlJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWNjZXB0IHZhbGlkIHN0YWtlIGR1cmF0aW9uJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgY29uc3Qgc3RhcnRUaW1lID0gQmlnSW50KE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApICsgNjApO1xuICAgICAgY29uc3QgZW5kVGltZSA9IEJpZ0ludChNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKSArIDg2NDAwICogMTQpOyAvLyAxNCBkYXlzIGxhdGVyXG5cbiAgICAgICgoKSA9PiB7XG4gICAgICAgIGJ1aWxkZXIudmFsaWRhdGVTdGFrZUR1cmF0aW9uKHN0YXJ0VGltZSwgZW5kVGltZSk7XG4gICAgICB9KS5zaG91bGQubm90LnRocm93KCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdidWlsZGVyIG1ldGhvZHMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBzZXQgc3RhcnRUaW1lIGNvcnJlY3RseScsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApICsgNjA7XG4gICAgICAoKCkgPT4gYnVpbGRlci5zdGFydFRpbWUoc3RhcnRUaW1lKSkuc2hvdWxkLm5vdC50aHJvdygpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgZW5kVGltZSBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICBjb25zdCBlbmRUaW1lID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCkgKyA4NjQwMCAqIDE0O1xuICAgICAgKCgpID0+IGJ1aWxkZXIuZW5kVGltZShlbmRUaW1lKSkuc2hvdWxkLm5vdC50aHJvdygpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgcmV3YXJkQWRkcmVzcyB3aXRoIFAtY2hhaW4gYWRkcmVzcycsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIC8vIFAtY2hhaW4gQmVjaDMyIGFkZHJlc3NcbiAgICAgICgoKSA9PiBidWlsZGVyLnJld2FyZEFkZHJlc3MoU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0KSkuc2hvdWxkLm5vdC50aHJvdygpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYnVpbGQgdmFsaWRhdGlvbicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGZhaWwgYnVpbGQgd2hlbiBub2RlSUQgaXMgbm90IHNldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IG5vdyA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xuXG4gICAgICBidWlsZGVyXG4gICAgICAgIC5zdGFydFRpbWUobm93ICsgNjApXG4gICAgICAgIC5lbmRUaW1lKG5vdyArIDg2NDAwICogMTQpXG4gICAgICAgIC5zdGFrZUFtb3VudChCaWdJbnQoNTAwMDAgKiAxZTkpKVxuICAgICAgICAuZnJvbVB1YktleShbU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0LCBBQ0NPVU5UXzEuYWRkcmVzc1Rlc3RuZXRdKVxuICAgICAgICAuY29udGV4dChDT05URVhUIGFzIGFueSk7XG5cbiAgICAgIGF3YWl0IGJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdOb2RlSUQgaXMgcmVxdWlyZWQgZm9yIGRlbGVnYXRpb24nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBidWlsZCB3aGVuIHN0YXJ0IHRpbWUgaXMgbm90IHNldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IG5vdyA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xuICAgICAgY29uc3QgdmFsaWROb2RlSUQgPSAnTm9kZUlELUFLN3NQQnNaTTlyUXdzZTIzYUxoRUVCUEhaRDVna0xyTCc7XG5cbiAgICAgIGJ1aWxkZXJcbiAgICAgICAgLm5vZGVJRCh2YWxpZE5vZGVJRClcbiAgICAgICAgLmVuZFRpbWUobm93ICsgODY0MDAgKiAxNClcbiAgICAgICAgLnN0YWtlQW1vdW50KEJpZ0ludCg1MDAwMCAqIDFlOSkpXG4gICAgICAgIC5mcm9tUHViS2V5KFtTRUVEX0FDQ09VTlQuYWRkcmVzc1Rlc3RuZXQsIEFDQ09VTlRfMS5hZGRyZXNzVGVzdG5ldF0pXG4gICAgICAgIC5jb250ZXh0KENPTlRFWFQgYXMgYW55KTtcblxuICAgICAgYXdhaXQgYnVpbGRlci5idWlsZCgpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1N0YXJ0IHRpbWUgaXMgcmVxdWlyZWQgZm9yIGRlbGVnYXRpb24nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBidWlsZCB3aGVuIGVuZCB0aW1lIGlzIG5vdCBzZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICBjb25zdCBub3cgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKTtcbiAgICAgIGNvbnN0IHZhbGlkTm9kZUlEID0gJ05vZGVJRC1BSzdzUEJzWk05clF3c2UyM2FMaEVFQlBIWkQ1Z2tMckwnO1xuXG4gICAgICBidWlsZGVyXG4gICAgICAgIC5ub2RlSUQodmFsaWROb2RlSUQpXG4gICAgICAgIC5zdGFydFRpbWUobm93ICsgNjApXG4gICAgICAgIC5zdGFrZUFtb3VudChCaWdJbnQoNTAwMDAgKiAxZTkpKVxuICAgICAgICAuZnJvbVB1YktleShbU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0LCBBQ0NPVU5UXzEuYWRkcmVzc1Rlc3RuZXRdKVxuICAgICAgICAuY29udGV4dChDT05URVhUIGFzIGFueSk7XG5cbiAgICAgIGF3YWl0IGJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFbmQgdGltZSBpcyByZXF1aXJlZCBmb3IgZGVsZWdhdGlvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGJ1aWxkIHdoZW4gc3Rha2UgYW1vdW50IGlzIG5vdCBzZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICBjb25zdCBub3cgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKTtcbiAgICAgIGNvbnN0IHZhbGlkTm9kZUlEID0gJ05vZGVJRC1BSzdzUEJzWk05clF3c2UyM2FMaEVFQlBIWkQ1Z2tMckwnO1xuXG4gICAgICBidWlsZGVyXG4gICAgICAgIC5ub2RlSUQodmFsaWROb2RlSUQpXG4gICAgICAgIC5zdGFydFRpbWUobm93ICsgNjApXG4gICAgICAgIC5lbmRUaW1lKG5vdyArIDg2NDAwICogMTQpXG4gICAgICAgIC5mcm9tUHViS2V5KFtTRUVEX0FDQ09VTlQuYWRkcmVzc1Rlc3RuZXQsIEFDQ09VTlRfMS5hZGRyZXNzVGVzdG5ldF0pXG4gICAgICAgIC5jb250ZXh0KENPTlRFWFQgYXMgYW55KTtcblxuICAgICAgYXdhaXQgYnVpbGRlci5idWlsZCgpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1N0YWtlIGFtb3VudCBpcyByZXF1aXJlZCBmb3IgZGVsZWdhdGlvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGJ1aWxkIHdoZW4gY29udGV4dCBpcyBub3Qgc2V0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgY29uc3Qgbm93ID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XG4gICAgICBjb25zdCB2YWxpZE5vZGVJRCA9ICdOb2RlSUQtQUs3c1BCc1pNOXJRd3NlMjNhTGhFRUJQSFpENWdrTHJMJztcblxuICAgICAgYnVpbGRlclxuICAgICAgICAubm9kZUlEKHZhbGlkTm9kZUlEKVxuICAgICAgICAuc3RhcnRUaW1lKG5vdyArIDYwKVxuICAgICAgICAuZW5kVGltZShub3cgKyA4NjQwMCAqIDE0KVxuICAgICAgICAuc3Rha2VBbW91bnQoQmlnSW50KDUwMDAwICogMWU5KSlcbiAgICAgICAgLmZyb21QdWJLZXkoW1NFRURfQUNDT1VOVC5hZGRyZXNzVGVzdG5ldCwgQUNDT1VOVF8xLmFkZHJlc3NUZXN0bmV0XSk7XG5cbiAgICAgIGF3YWl0IGJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdDb250ZXh0IGlzIHJlcXVpcmVkIGZvciBkZWxlZ2F0aW9uJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgYnVpbGQgd2hlbiBmcm9tIGFkZHJlc3NlcyBhcmUgbm90IHNldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IG5vdyA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xuICAgICAgY29uc3QgdmFsaWROb2RlSUQgPSAnTm9kZUlELUFLN3NQQnNaTTlyUXdzZTIzYUxoRUVCUEhaRDVna0xyTCc7XG5cbiAgICAgIGJ1aWxkZXJcbiAgICAgICAgLm5vZGVJRCh2YWxpZE5vZGVJRClcbiAgICAgICAgLnN0YXJ0VGltZShub3cgKyA2MClcbiAgICAgICAgLmVuZFRpbWUobm93ICsgODY0MDAgKiAxNClcbiAgICAgICAgLnN0YWtlQW1vdW50KEJpZ0ludCg1MDAwMCAqIDFlOSkpXG4gICAgICAgIC5jb250ZXh0KENPTlRFWFQgYXMgYW55KTtcblxuICAgICAgYXdhaXQgYnVpbGRlci5idWlsZCgpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0Zyb20gYWRkcmVzc2VzIGFyZSByZXF1aXJlZCBmb3IgZGVsZWdhdGlvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGJ1aWxkIHdoZW4gZmVlIHN0YXRlIGlzIG5vdCBzZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICBjb25zdCBub3cgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKTtcbiAgICAgIGNvbnN0IHZhbGlkTm9kZUlEID0gJ05vZGVJRC1BSzdzUEJzWk05clF3c2UyM2FMaEVFQlBIWkQ1Z2tMckwnO1xuXG4gICAgICBidWlsZGVyXG4gICAgICAgIC5ub2RlSUQodmFsaWROb2RlSUQpXG4gICAgICAgIC5zdGFydFRpbWUobm93ICsgNjApXG4gICAgICAgIC5lbmRUaW1lKG5vdyArIDg2NDAwICogMTQpXG4gICAgICAgIC5zdGFrZUFtb3VudChCaWdJbnQoNTAwMDAgKiAxZTkpKVxuICAgICAgICAuZnJvbVB1YktleShbU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0LCBBQ0NPVU5UXzEuYWRkcmVzc1Rlc3RuZXRdKVxuICAgICAgICAuY29udGV4dChDT05URVhUIGFzIGFueSk7XG5cbiAgICAgIGF3YWl0IGJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdGZWUgc3RhdGUgaXMgcmVxdWlyZWQgZm9yIGRlbGVnYXRpb24nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBidWlsZCB3aGVuIFVUWE9zIGFyZSBub3Qgc2V0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgY29uc3Qgbm93ID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XG4gICAgICBjb25zdCB2YWxpZE5vZGVJRCA9ICdOb2RlSUQtQUs3c1BCc1pNOXJRd3NlMjNhTGhFRUJQSFpENWdrTHJMJztcbiAgICAgIGNvbnN0IG1vY2tGZWVTdGF0ZSA9IHsgY2FwYWNpdHk6IDEwMDAwMG4sIGV4Y2VzczogMG4sIHByaWNlOiAxMDAwbiwgdGltZXN0YW1wOiAnMTIzNDU2Nzg5MCcgfTtcblxuICAgICAgYnVpbGRlclxuICAgICAgICAubm9kZUlEKHZhbGlkTm9kZUlEKVxuICAgICAgICAuc3RhcnRUaW1lKG5vdyArIDYwKVxuICAgICAgICAuZW5kVGltZShub3cgKyA4NjQwMCAqIDE0KVxuICAgICAgICAuc3Rha2VBbW91bnQoQmlnSW50KDUwMDAwICogMWU5KSlcbiAgICAgICAgLmZyb21QdWJLZXkoW1NFRURfQUNDT1VOVC5hZGRyZXNzVGVzdG5ldCwgQUNDT1VOVF8xLmFkZHJlc3NUZXN0bmV0XSlcbiAgICAgICAgLmNvbnRleHQoQ09OVEVYVCBhcyBhbnkpXG4gICAgICAgIC5mZWVTdGF0ZShtb2NrRmVlU3RhdGUpO1xuXG4gICAgICBhd2FpdCBidWlsZGVyLmJ1aWxkKCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVVRYT3MgYXJlIHJlcXVpcmVkIGZvciBkZWxlZ2F0aW9uJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd2YWxpZGF0ZSBzdGFrZSBhbW91bnQnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBmYWlsIHdoZW4gc3Rha2UgYW1vdW50IGlzIGJlbG93IG1pbmltdW0nLCAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICAvLyBNaW5pbXVtIGlzIDUwMDAwIEZMUiwgc28gMTAwMCBzaG91bGQgZmFpbFxuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGJ1aWxkZXIuc3Rha2VBbW91bnQoQmlnSW50KDEwMDAgKiAxZTkpKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlLmluY2x1ZGVzKCdNaW5pbXVtIGRlbGVnYXRpb24gYW1vdW50JylcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFjY2VwdCBzdGFrZSBhbW91bnQgYXQgb3IgYWJvdmUgbWluaW11bScsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IHN0YWtlQW1vdW50ID0gQmlnSW50KDUwMDAwICogMWU5KTtcbiAgICAgICgoKSA9PiBidWlsZGVyLnN0YWtlQW1vdW50KHN0YWtlQW1vdW50KSkuc2hvdWxkLm5vdC50aHJvdygpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndHJhbnNhY3Rpb24gdHlwZSBzdXBwb3J0JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYWxsb3cgc2V0dGluZyBBZGRQZXJtaXNzaW9ubGVzc0RlbGVnYXRvciB0cmFuc2FjdGlvbiB0eXBlJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgLy8gVGhlIGJ1aWxkZXIgc2hvdWxkIHN1Y2Nlc3NmdWxseSBjb25maWd1cmUgd2l0aCBBZGRQZXJtaXNzaW9ubGVzc0RlbGVnYXRvciB0eXBlXG4gICAgICAvLyBUaGlzIHZlcmlmaWVzIHRyYW5zYWN0aW9uLnRzIHNldFRyYW5zYWN0aW9uVHlwZSBhY2NlcHRzIHRoZSBkZWxlZ2F0aW9uIHR5cGVcbiAgICAgIGJ1aWxkZXIuc2hvdWxkLmJlLmluc3RhbmNlb2YoUGVybWlzc2lvbmxlc3NEZWxlZ2F0b3JUeEJ1aWxkZXIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3QgbWluaW11bSBzdGFrZSBhbW91bnQgY29uc3RhbnQnLCAoKSA9PiB7XG4gICAgICAvLyBWZXJpZnkgdGhlIG1pbmltdW0gc3Rha2UgYW1vdW50IGlzIDUwMDAwIEZMUiAoaW4gbmFub0ZMUilcbiAgICAgIGNvbnN0IG1pblN0YWtlQW1vdW50ID0gQmlnSW50KDUwMDAwICogMWU5KTtcbiAgICAgIG1pblN0YWtlQW1vdW50LnNob3VsZC5lcXVhbChCaWdJbnQoJzUwMDAwMDAwMDAwMDAwJykpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncm91bmQtdHJpcCBkZXNlcmlhbGl6YXRpb24nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBkZXNlcmlhbGl6ZSBhIHNpZ25lZCBkZWxlZ2F0aW9uIHRyYW5zYWN0aW9uIGZyb20gaGV4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmF3VHggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoREVMRUdBVElPTl9UWF8yLnNpZ25lZEhleCk7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBmYWN0b3J5LmZyb20ocmF3VHgpLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgdHgudHlwZS5zaG91bGQuZXF1YWwoVHJhbnNhY3Rpb25UeXBlLkFkZFBlcm1pc3Npb25sZXNzRGVsZWdhdG9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IGV4dHJhY3QgZGVsZWdhdGlvbiBwYXJhbWV0ZXJzIGZyb20gZGVzZXJpYWxpemVkIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmF3VHggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoREVMRUdBVElPTl9UWF8yLnNpZ25lZEhleCk7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBmYWN0b3J5LmZyb20ocmF3VHgpLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgZXhwbGFuYXRpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcbiAgICAgIGV4cGxhbmF0aW9uLm91dHB1dHMubGVuZ3RoLnNob3VsZC5iZS5hYm92ZSgwKTtcbiAgICAgIGV4cGxhbmF0aW9uLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoREVMRUdBVElPTl9UWF8yLnN0YWtlQW1vdW50KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmUtc2VyaWFsaXplIHRvIHRoZSBzYW1lIGhleCAocm91bmQtdHJpcCknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByYXdUeCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChERUxFR0FUSU9OX1RYXzIuc2lnbmVkSGV4KTtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGZhY3RvcnkuZnJvbShyYXdUeCkuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgICBjb25zdCByZUVuY29kZWRUeCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeCh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpKTtcblxuICAgICAgcmVFbmNvZGVkVHguc2hvdWxkLmVxdWFsKHJhd1R4KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBjb3JyZWN0IGlucHV0L291dHB1dCBjb3VudHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByYXdUeCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChERUxFR0FUSU9OX1RYXzIuc2lnbmVkSGV4KTtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGZhY3RvcnkuZnJvbShyYXdUeCkuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgICB0eC5pbnB1dHMuc2hvdWxkLmhhdmUubGVuZ3RoKDMpO1xuICAgICAgdHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmJlLmFib3ZlKDApO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
|