@bitgo-beta/sdk-coin-ada 2.3.14-beta.185 → 2.3.14-beta.1850
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/ada.d.ts +15 -13
- package/dist/src/ada.d.ts.map +1 -1
- package/dist/src/ada.js +124 -42
- package/dist/src/adaToken.d.ts +16 -11
- package/dist/src/adaToken.d.ts.map +1 -1
- package/dist/src/adaToken.js +109 -3
- package/dist/src/index.js +6 -2
- package/dist/src/lib/index.d.ts +3 -1
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +29 -9
- package/dist/src/lib/keyPair.js +29 -16
- package/dist/src/lib/messages/cip8/cip8Message.d.ts +25 -0
- package/dist/src/lib/messages/cip8/cip8Message.d.ts.map +1 -0
- package/dist/src/lib/messages/cip8/cip8Message.js +140 -0
- package/dist/src/lib/messages/cip8/cip8MessageBuilder.d.ts +19 -0
- package/dist/src/lib/messages/cip8/cip8MessageBuilder.d.ts.map +1 -0
- package/dist/src/lib/messages/cip8/cip8MessageBuilder.js +27 -0
- package/dist/src/lib/messages/cip8/index.d.ts +4 -0
- package/dist/src/lib/messages/cip8/index.d.ts.map +1 -0
- package/dist/src/lib/messages/cip8/index.js +20 -0
- package/dist/src/lib/messages/cip8/utils.d.ts +24 -0
- package/dist/src/lib/messages/cip8/utils.d.ts.map +1 -0
- package/dist/src/lib/messages/cip8/utils.js +73 -0
- package/dist/src/lib/messages/index.d.ts +3 -0
- package/dist/src/lib/messages/index.d.ts.map +1 -0
- package/dist/src/lib/messages/index.js +19 -0
- package/dist/src/lib/messages/messageBuilderFactory.d.ts +7 -0
- package/dist/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
- package/dist/src/lib/messages/messageBuilderFactory.js +20 -0
- package/dist/src/lib/stakingActivateBuilder.d.ts +1 -1
- package/dist/src/lib/stakingActivateBuilder.d.ts.map +1 -1
- package/dist/src/lib/stakingActivateBuilder.js +30 -10
- package/dist/src/lib/stakingDeactivateBuilder.js +24 -10
- package/dist/src/lib/transaction.d.ts +24 -7
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +81 -17
- package/dist/src/lib/transactionBuilder.d.ts +114 -3
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +464 -20
- package/dist/src/lib/transactionBuilderFactory.d.ts +2 -0
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +7 -1
- package/dist/src/lib/utils.d.ts +22 -0
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +152 -17
- package/dist/src/lib/voteDelegationBuilder.d.ts +24 -0
- package/dist/src/lib/voteDelegationBuilder.d.ts.map +1 -0
- package/dist/src/lib/voteDelegationBuilder.js +84 -0
- package/dist/test/resources/cip8Resources.d.ts +25 -0
- package/dist/test/resources/cip8Resources.d.ts.map +1 -0
- package/dist/test/resources/cip8Resources.js +76 -0
- package/dist/test/resources/index.d.ts +458 -0
- package/dist/test/resources/index.d.ts.map +1 -0
- package/dist/test/resources/index.js +659 -0
- package/dist/test/unit/StakingActivateBuilder.d.ts +2 -0
- package/dist/test/unit/StakingActivateBuilder.d.ts.map +1 -0
- package/dist/test/unit/StakingActivateBuilder.js +213 -0
- package/dist/test/unit/StakingDeactivateBuilder.d.ts +2 -0
- package/dist/test/unit/StakingDeactivateBuilder.d.ts.map +1 -0
- package/dist/test/unit/StakingDeactivateBuilder.js +158 -0
- package/dist/test/unit/ada.d.ts +5 -0
- package/dist/test/unit/ada.d.ts.map +1 -0
- package/dist/test/unit/ada.js +1430 -0
- package/dist/test/unit/getBuilderFactory.d.ts +3 -0
- package/dist/test/unit/getBuilderFactory.d.ts.map +1 -0
- package/dist/test/unit/getBuilderFactory.js +10 -0
- package/dist/test/unit/index.d.ts +2 -0
- package/dist/test/unit/index.d.ts.map +1 -0
- package/dist/test/unit/index.js +32 -0
- package/dist/test/unit/keyPair.d.ts +2 -0
- package/dist/test/unit/keyPair.d.ts.map +1 -0
- package/dist/test/unit/keyPair.js +88 -0
- package/dist/test/unit/messages/cip8/cip8Message.d.ts +2 -0
- package/dist/test/unit/messages/cip8/cip8Message.d.ts.map +1 -0
- package/dist/test/unit/messages/cip8/cip8Message.js +131 -0
- package/dist/test/unit/messages/cip8/cip8MessageBuilder.d.ts +2 -0
- package/dist/test/unit/messages/cip8/cip8MessageBuilder.d.ts.map +1 -0
- package/dist/test/unit/messages/cip8/cip8MessageBuilder.js +132 -0
- package/dist/test/unit/messages/cip8/utils.d.ts +2 -0
- package/dist/test/unit/messages/cip8/utils.d.ts.map +1 -0
- package/dist/test/unit/messages/cip8/utils.js +127 -0
- package/dist/test/unit/messages/messageBuilderFactory.d.ts +2 -0
- package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
- package/dist/test/unit/messages/messageBuilderFactory.js +35 -0
- package/dist/test/unit/stakingClaimRewardsBuilder.d.ts +2 -0
- package/dist/test/unit/stakingClaimRewardsBuilder.d.ts.map +1 -0
- package/dist/test/unit/stakingClaimRewardsBuilder.js +70 -0
- package/dist/test/unit/stakingPledgeBuilder.d.ts +2 -0
- package/dist/test/unit/stakingPledgeBuilder.d.ts.map +1 -0
- package/dist/test/unit/stakingPledgeBuilder.js +141 -0
- package/dist/test/unit/stakingWithdrawBuilder.d.ts +2 -0
- package/dist/test/unit/stakingWithdrawBuilder.d.ts.map +1 -0
- package/dist/test/unit/stakingWithdrawBuilder.js +167 -0
- package/dist/test/unit/tokenWithdrawal.d.ts +2 -0
- package/dist/test/unit/tokenWithdrawal.d.ts.map +1 -0
- package/dist/test/unit/tokenWithdrawal.js +959 -0
- package/dist/test/unit/transaction.d.ts +2 -0
- package/dist/test/unit/transaction.d.ts.map +1 -0
- package/dist/test/unit/transaction.js +100 -0
- package/dist/test/unit/transactionBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder.js +545 -0
- package/dist/test/unit/utils.d.ts +2 -0
- package/dist/test/unit/utils.d.ts.map +1 -0
- package/dist/test/unit/utils.js +138 -0
- package/dist/test/unit/voteDelegationBuilder.d.ts +2 -0
- package/dist/test/unit/voteDelegationBuilder.d.ts.map +1 -0
- package/dist/test/unit/voteDelegationBuilder.js +96 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +18 -13
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -470
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const should_1 = __importDefault(require("should"));
|
|
40
|
+
const sinon = __importStar(require("sinon"));
|
|
41
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
42
|
+
const testData = __importStar(require("../resources"));
|
|
43
|
+
const src_1 = require("../../src");
|
|
44
|
+
const statics_1 = require("@bitgo-beta/statics");
|
|
45
|
+
const CardanoWasm = __importStar(require("@emurgo/cardano-serialization-lib-nodejs"));
|
|
46
|
+
const transaction_1 = require("../../src/lib/transaction");
|
|
47
|
+
describe('ADA Transaction Builder', async () => {
|
|
48
|
+
const factory = new src_1.TransactionBuilderFactory(statics_1.coins.get('tada'));
|
|
49
|
+
it('start and build an unsigned transfer tx for byron address', async () => {
|
|
50
|
+
const txBuilder = factory.getTransferBuilder();
|
|
51
|
+
txBuilder.input({
|
|
52
|
+
transaction_id: '1b53331e069a6e58fe77919d30c0cf299d13a2f5b3d9970ce473c1a66d71bf03',
|
|
53
|
+
transaction_index: 1,
|
|
54
|
+
});
|
|
55
|
+
const outputAmount = 200000000;
|
|
56
|
+
txBuilder.output({
|
|
57
|
+
address: testData.rawTxByron.outputAddress1.address,
|
|
58
|
+
amount: outputAmount.toString(),
|
|
59
|
+
});
|
|
60
|
+
const totalInput = 999600000;
|
|
61
|
+
txBuilder.changeAddress(testData.rawTxByron.outputAddress2.address, totalInput.toString());
|
|
62
|
+
txBuilder.ttl(800000000);
|
|
63
|
+
// txBuilder.fee('200000');
|
|
64
|
+
const tx = (await txBuilder.build());
|
|
65
|
+
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
|
|
66
|
+
const txData = tx.toJson();
|
|
67
|
+
txData.witnesses.length.should.equal(0);
|
|
68
|
+
txData.certs.length.should.equal(0);
|
|
69
|
+
txData.withdrawals.length.should.equal(0);
|
|
70
|
+
txData.outputs.length.should.equal(2);
|
|
71
|
+
txData.outputs[0].address.should.equal(testData.rawTxByron.outputAddress1.address);
|
|
72
|
+
txData.outputs[1].address.should.equal(testData.rawTxByron.outputAddress2.address);
|
|
73
|
+
const fee = tx.getFee;
|
|
74
|
+
txData.outputs[1].amount.should.equal((totalInput - outputAmount - Number(fee)).toString());
|
|
75
|
+
fee.should.equal('167437');
|
|
76
|
+
txData.id.should.equal(testData.rawTxByron.txHash2);
|
|
77
|
+
const txBroadcast = tx.toBroadcastFormat();
|
|
78
|
+
should_1.default.equal(txBroadcast, testData.rawTxByron.unsignedTx2);
|
|
79
|
+
});
|
|
80
|
+
it('start and build an unsigned transfer tx for shelley address', async () => {
|
|
81
|
+
const txBuilder = factory.getTransferBuilder();
|
|
82
|
+
txBuilder.input({
|
|
83
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
84
|
+
transaction_index: 1,
|
|
85
|
+
});
|
|
86
|
+
const outputAmount = 7823121;
|
|
87
|
+
txBuilder.output({
|
|
88
|
+
address: testData.rawTx.outputAddress1.address,
|
|
89
|
+
amount: outputAmount.toString(),
|
|
90
|
+
});
|
|
91
|
+
const totalInput = 21032023;
|
|
92
|
+
txBuilder.changeAddress(testData.rawTx.outputAddress2.address, totalInput.toString());
|
|
93
|
+
txBuilder.ttl(800000000);
|
|
94
|
+
const tx = (await txBuilder.build());
|
|
95
|
+
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
|
|
96
|
+
const txData = tx.toJson();
|
|
97
|
+
txData.witnesses.length.should.equal(0);
|
|
98
|
+
txData.certs.length.should.equal(0);
|
|
99
|
+
txData.withdrawals.length.should.equal(0);
|
|
100
|
+
txData.outputs.length.should.equal(2);
|
|
101
|
+
txData.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
|
|
102
|
+
txData.outputs[1].address.should.equal(testData.rawTx.outputAddress2.address);
|
|
103
|
+
const fee = tx.getFee;
|
|
104
|
+
txData.outputs[1].amount.should.equal((totalInput - outputAmount - Number(fee)).toString());
|
|
105
|
+
fee.should.equal('167173');
|
|
106
|
+
txData.id.should.equal(testData.rawTx.txHash2);
|
|
107
|
+
const txBroadcast = tx.toBroadcastFormat();
|
|
108
|
+
should_1.default.equal(txBroadcast, testData.rawTx.unsignedTx2);
|
|
109
|
+
});
|
|
110
|
+
it('should build a consolidate tx with no asset', async () => {
|
|
111
|
+
const txBuilder = factory.getTransferBuilder();
|
|
112
|
+
txBuilder.input({
|
|
113
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
114
|
+
transaction_index: 1,
|
|
115
|
+
});
|
|
116
|
+
const outputAmount = 0;
|
|
117
|
+
const totalInput = 20000000;
|
|
118
|
+
txBuilder.changeAddress(testData.rawTx.outputAddress1.address, totalInput.toString());
|
|
119
|
+
txBuilder.ttl(800000000);
|
|
120
|
+
const tx = (await txBuilder.build());
|
|
121
|
+
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
|
|
122
|
+
const txData = tx.toJson();
|
|
123
|
+
txData.witnesses.length.should.equal(0);
|
|
124
|
+
txData.certs.length.should.equal(0);
|
|
125
|
+
txData.withdrawals.length.should.equal(0);
|
|
126
|
+
txData.outputs.length.should.equal(1);
|
|
127
|
+
txData.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
|
|
128
|
+
const fee = tx.getFee;
|
|
129
|
+
txData.outputs[0].amount.should.equal((totalInput - outputAmount - Number(fee)).toString());
|
|
130
|
+
fee.should.equal('165545');
|
|
131
|
+
txData.id.should.equal(testData.rawTx.txHash5);
|
|
132
|
+
const txBroadcast = tx.toBroadcastFormat();
|
|
133
|
+
should_1.default.equal(txBroadcast, testData.rawTx.unsignedTx5);
|
|
134
|
+
});
|
|
135
|
+
it('should initialize and build tx with asset data', async () => {
|
|
136
|
+
const policyId = 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72';
|
|
137
|
+
const assetName = '4d494e';
|
|
138
|
+
const quantity = '2000000';
|
|
139
|
+
const preBuiltTx = new transaction_1.Transaction(statics_1.coins.get('tada'));
|
|
140
|
+
preBuiltTx.fromRawTransaction(testData.rawTx.unsignedTx3);
|
|
141
|
+
const txBuilder = factory.getTransferBuilder();
|
|
142
|
+
txBuilder.initBuilder(preBuiltTx);
|
|
143
|
+
const tx = (await txBuilder.build());
|
|
144
|
+
const txData = tx.toJson();
|
|
145
|
+
const expectedAssetName = CardanoWasm.AssetName.new(Buffer.from(assetName, 'hex'));
|
|
146
|
+
const expectedPolicyId = CardanoWasm.ScriptHash.from_bytes(Buffer.from(policyId, 'hex'));
|
|
147
|
+
txData.outputs[0].should.have.property('multiAssets');
|
|
148
|
+
txData.outputs[0].multiAssets
|
|
149
|
+
.get_asset(expectedPolicyId, expectedAssetName)
|
|
150
|
+
.to_str()
|
|
151
|
+
.should.equal(quantity);
|
|
152
|
+
txData.id.should.equal(testData.rawTx.txHash3);
|
|
153
|
+
const txBroadcast = tx.toBroadcastFormat();
|
|
154
|
+
should_1.default.equal(txBroadcast, testData.rawTx.unsignedTx3);
|
|
155
|
+
});
|
|
156
|
+
it('should build a consolidate tx with single asset', async () => {
|
|
157
|
+
const txBuilder = factory.getTransferBuilder();
|
|
158
|
+
txBuilder.input({
|
|
159
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
160
|
+
transaction_index: 1,
|
|
161
|
+
});
|
|
162
|
+
const outputAmount = 0;
|
|
163
|
+
const policyId = 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72';
|
|
164
|
+
const assetName = '4d494e';
|
|
165
|
+
const quantity = '2000000';
|
|
166
|
+
txBuilder.assets({
|
|
167
|
+
policy_id: policyId,
|
|
168
|
+
asset_name: assetName,
|
|
169
|
+
quantity: quantity,
|
|
170
|
+
});
|
|
171
|
+
const minAmountForSingleAsset = 1500000;
|
|
172
|
+
const totalInput = 20000000;
|
|
173
|
+
txBuilder.changeAddress(testData.rawTx.outputAddress1.address, totalInput.toString());
|
|
174
|
+
txBuilder.ttl(800000000);
|
|
175
|
+
const tx = (await txBuilder.build());
|
|
176
|
+
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
|
|
177
|
+
const txData = tx.toJson();
|
|
178
|
+
txData.witnesses.length.should.equal(0);
|
|
179
|
+
txData.certs.length.should.equal(0);
|
|
180
|
+
txData.withdrawals.length.should.equal(0);
|
|
181
|
+
txData.outputs.length.should.equal(2);
|
|
182
|
+
txData.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
|
|
183
|
+
txData.outputs[1].address.should.equal(testData.rawTx.outputAddress1.address);
|
|
184
|
+
// token assertion
|
|
185
|
+
const expectedAssetName = CardanoWasm.AssetName.new(Buffer.from(assetName, 'hex'));
|
|
186
|
+
const expectedPolicyId = CardanoWasm.ScriptHash.from_bytes(Buffer.from(policyId, 'hex'));
|
|
187
|
+
txData.outputs[0].amount.should.equal(minAmountForSingleAsset.toString());
|
|
188
|
+
txData.outputs[0].should.have.property('multiAssets');
|
|
189
|
+
txData.outputs[0].multiAssets
|
|
190
|
+
.get_asset(expectedPolicyId, expectedAssetName)
|
|
191
|
+
.to_str()
|
|
192
|
+
.should.equal(quantity);
|
|
193
|
+
const fee = tx.getFee;
|
|
194
|
+
txData.outputs[1].amount.should.equal((totalInput - minAmountForSingleAsset - outputAmount - Number(fee)).toString());
|
|
195
|
+
fee.should.equal('170253');
|
|
196
|
+
txData.id.should.equal(testData.rawTx.txHash3);
|
|
197
|
+
const txBroadcast = tx.toBroadcastFormat();
|
|
198
|
+
should_1.default.equal(txBroadcast, testData.rawTx.unsignedTx3);
|
|
199
|
+
});
|
|
200
|
+
it('should build a consolidate tx with multiple assets', async () => {
|
|
201
|
+
const txBuilder = factory.getTransferBuilder();
|
|
202
|
+
txBuilder.input({
|
|
203
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
204
|
+
transaction_index: 1,
|
|
205
|
+
});
|
|
206
|
+
const outputAmount = 0;
|
|
207
|
+
const asset1_policyId = '279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f';
|
|
208
|
+
const asset1_assetName = '534e454b';
|
|
209
|
+
const asset1_quantity = '6000000';
|
|
210
|
+
const asset2_policyId = '1f7a58a1aa1e6b047a42109ade331ce26c9c2cce027d043ff264fb1f';
|
|
211
|
+
const asset2_assetName = '425249434b53';
|
|
212
|
+
const asset2_quantity = '5000000';
|
|
213
|
+
txBuilder.assets({
|
|
214
|
+
policy_id: asset1_policyId,
|
|
215
|
+
asset_name: asset1_assetName,
|
|
216
|
+
quantity: asset1_quantity,
|
|
217
|
+
});
|
|
218
|
+
txBuilder.assets({
|
|
219
|
+
policy_id: asset2_policyId,
|
|
220
|
+
asset_name: asset2_assetName,
|
|
221
|
+
quantity: asset2_quantity,
|
|
222
|
+
});
|
|
223
|
+
const totalInput = 20000000;
|
|
224
|
+
const minAmountForSingleAsset = 1500000;
|
|
225
|
+
txBuilder.changeAddress(testData.rawTx.outputAddress1.address, totalInput.toString());
|
|
226
|
+
txBuilder.ttl(800000000);
|
|
227
|
+
const tx = (await txBuilder.build());
|
|
228
|
+
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
|
|
229
|
+
const txData = tx.toJson();
|
|
230
|
+
txData.witnesses.length.should.equal(0);
|
|
231
|
+
txData.certs.length.should.equal(0);
|
|
232
|
+
txData.withdrawals.length.should.equal(0);
|
|
233
|
+
txData.outputs.length.should.equal(3);
|
|
234
|
+
txData.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
|
|
235
|
+
txData.outputs[1].address.should.equal(testData.rawTx.outputAddress1.address);
|
|
236
|
+
txData.outputs[2].address.should.equal(testData.rawTx.outputAddress1.address);
|
|
237
|
+
// token assertion
|
|
238
|
+
const asset1_expectedAssetName = CardanoWasm.AssetName.new(Buffer.from(asset1_assetName, 'hex'));
|
|
239
|
+
const asset1_expectedPolicyId = CardanoWasm.ScriptHash.from_bytes(Buffer.from(asset1_policyId, 'hex'));
|
|
240
|
+
txData.outputs[0].amount.should.equal(minAmountForSingleAsset.toString());
|
|
241
|
+
txData.outputs[0].should.have.property('multiAssets');
|
|
242
|
+
txData.outputs[0].multiAssets
|
|
243
|
+
.get_asset(asset1_expectedPolicyId, asset1_expectedAssetName)
|
|
244
|
+
.to_str()
|
|
245
|
+
.should.equal(asset1_quantity);
|
|
246
|
+
const asset2_expectedAssetName = CardanoWasm.AssetName.new(Buffer.from(asset2_assetName, 'hex'));
|
|
247
|
+
const asset2_expectedPolicyId = CardanoWasm.ScriptHash.from_bytes(Buffer.from(asset2_policyId, 'hex'));
|
|
248
|
+
txData.outputs[1].amount.should.equal(minAmountForSingleAsset.toString());
|
|
249
|
+
txData.outputs[1].should.have.property('multiAssets');
|
|
250
|
+
txData.outputs[1].multiAssets
|
|
251
|
+
.get_asset(asset2_expectedPolicyId, asset2_expectedAssetName)
|
|
252
|
+
.to_str()
|
|
253
|
+
.should.equal(asset2_quantity);
|
|
254
|
+
const fee = tx.getFee;
|
|
255
|
+
txData.outputs[2].amount.should.equal((totalInput - minAmountForSingleAsset * 2 - outputAmount - Number(fee)).toString());
|
|
256
|
+
fee.should.equal('175137');
|
|
257
|
+
txData.id.should.equal(testData.rawTx.txHash4);
|
|
258
|
+
const txBroadcast = tx.toBroadcastFormat();
|
|
259
|
+
should_1.default.equal(txBroadcast, testData.rawTx.unsignedTx4);
|
|
260
|
+
});
|
|
261
|
+
it('should fail to build a consolidate tx with single asset and insufficient minimum ADA', async () => {
|
|
262
|
+
const txBuilder = factory.getTransferBuilder();
|
|
263
|
+
txBuilder.input({
|
|
264
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
265
|
+
transaction_index: 1,
|
|
266
|
+
});
|
|
267
|
+
const policyId = '279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f';
|
|
268
|
+
const assetName = '534e454b';
|
|
269
|
+
const quantity = '6000000';
|
|
270
|
+
txBuilder.assets({
|
|
271
|
+
policy_id: policyId,
|
|
272
|
+
asset_name: assetName,
|
|
273
|
+
quantity: quantity,
|
|
274
|
+
});
|
|
275
|
+
// change = input amt - fee - output amt => change will be less than 1000000
|
|
276
|
+
// even if one output has less than 1 ADA, tx will fail
|
|
277
|
+
const totalInput = 1000000;
|
|
278
|
+
txBuilder.changeAddress(testData.rawTx.outputAddress1.address, totalInput.toString());
|
|
279
|
+
txBuilder.ttl(800000000);
|
|
280
|
+
await txBuilder
|
|
281
|
+
.build()
|
|
282
|
+
.should.rejectedWith('Insufficient funds: need a minimum of 1.5 ADA per output to construct token consolidation');
|
|
283
|
+
});
|
|
284
|
+
it('build and sign a transfer tx', async () => {
|
|
285
|
+
const txBuilder = factory.getTransferBuilder();
|
|
286
|
+
txBuilder.input({
|
|
287
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
288
|
+
transaction_index: 1,
|
|
289
|
+
});
|
|
290
|
+
const outputAmount = 7823121;
|
|
291
|
+
txBuilder.output({
|
|
292
|
+
address: testData.rawTx.outputAddress1.address,
|
|
293
|
+
amount: outputAmount.toString(),
|
|
294
|
+
});
|
|
295
|
+
const totalInput = 21032023;
|
|
296
|
+
txBuilder.changeAddress(testData.rawTx.outputAddress2.address, totalInput.toString());
|
|
297
|
+
txBuilder.ttl(800000000);
|
|
298
|
+
txBuilder.sign({ key: testData.privateKeys.prvKey4 });
|
|
299
|
+
const tx = (await txBuilder.build());
|
|
300
|
+
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
|
|
301
|
+
const txData = tx.toJson();
|
|
302
|
+
txData.witnesses.length.should.equal(1);
|
|
303
|
+
txData.certs.length.should.equal(0);
|
|
304
|
+
txData.withdrawals.length.should.equal(0);
|
|
305
|
+
txData.outputs.length.should.equal(2);
|
|
306
|
+
txData.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
|
|
307
|
+
txData.outputs[1].address.should.equal(testData.rawTx.outputAddress2.address);
|
|
308
|
+
const fee = tx.getFee;
|
|
309
|
+
txData.outputs[1].amount.should.equal((totalInput - outputAmount - Number(fee)).toString());
|
|
310
|
+
fee.should.equal('167173');
|
|
311
|
+
txData.id.should.equal(testData.rawTx.txHash2);
|
|
312
|
+
const txBroadcast = tx.toBroadcastFormat();
|
|
313
|
+
should_1.default.equal(txBroadcast, testData.rawTx.signedTx2);
|
|
314
|
+
});
|
|
315
|
+
it('should initialize a fee properly, not as zero', async () => {
|
|
316
|
+
const txBuilder = factory.getTransferBuilder();
|
|
317
|
+
txBuilder.input({
|
|
318
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
319
|
+
transaction_index: 1,
|
|
320
|
+
});
|
|
321
|
+
txBuilder.output({
|
|
322
|
+
address: 'addr1q8rm9z7w4yx5gz652kn2q238efvms6t0qelur9nlglun8eu4tr5knj4fu4adelzqhxg8adu5xca4jra0gtllfrpcawyq9psz23',
|
|
323
|
+
amount: '7328383',
|
|
324
|
+
});
|
|
325
|
+
txBuilder.changeAddress(testData.address.address2, '1000000000');
|
|
326
|
+
txBuilder.ttl(800000000);
|
|
327
|
+
txBuilder.sign({ key: testData.privateKeys.prvKey4 });
|
|
328
|
+
const builtTx = (await txBuilder.build());
|
|
329
|
+
builtTx.getFee.should.equal('168405');
|
|
330
|
+
});
|
|
331
|
+
it('should not calculate fee and use one passed in', async () => {
|
|
332
|
+
const txBuilder = factory.getTransferBuilder();
|
|
333
|
+
txBuilder.input({
|
|
334
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
335
|
+
transaction_index: 1,
|
|
336
|
+
});
|
|
337
|
+
txBuilder.output({
|
|
338
|
+
address: 'addr1q8rm9z7w4yx5gz652kn2q238efvms6t0qelur9nlglun8eu4tr5knj4fu4adelzqhxg8adu5xca4jra0gtllfrpcawyq9psz23',
|
|
339
|
+
amount: '7328383',
|
|
340
|
+
});
|
|
341
|
+
txBuilder.changeAddress(testData.address.address2, '1000000000');
|
|
342
|
+
txBuilder.ttl(800000000);
|
|
343
|
+
txBuilder.fee('170000');
|
|
344
|
+
txBuilder.sign({ key: testData.privateKeys.prvKey4 });
|
|
345
|
+
const builtTx = (await txBuilder.build());
|
|
346
|
+
builtTx.getFee.should.equal('170000');
|
|
347
|
+
});
|
|
348
|
+
it('build a send from unsigned rawTx', async () => {
|
|
349
|
+
const txBuilder = factory.from(testData.rawTx.unsignedTx2);
|
|
350
|
+
const builtTx = await txBuilder.build();
|
|
351
|
+
should_1.default.equal(builtTx.type, sdk_core_1.TransactionType.Send);
|
|
352
|
+
should_1.default.equal(builtTx.id, testData.rawTx.txHash2);
|
|
353
|
+
builtTx.outputs.length.should.equal(2);
|
|
354
|
+
builtTx.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
|
|
355
|
+
builtTx.outputs[1].address.should.equal(testData.rawTx.outputAddress2.address);
|
|
356
|
+
});
|
|
357
|
+
it('match signature', async () => {
|
|
358
|
+
const txRaw = '582070081eeb1f312ec75af1b4f94a7963db3b264f2451369e4ea244a54de5d0';
|
|
359
|
+
const keyPair = new src_1.KeyPair();
|
|
360
|
+
const pkey = CardanoWasm.PrivateKey.from_normal_bytes(Buffer.from(keyPair.getKeys().prv, 'hex'));
|
|
361
|
+
const vkeyw = CardanoWasm.make_vkey_witness(CardanoWasm.TransactionHash.from_bytes(Buffer.from(txRaw, 'hex')), pkey);
|
|
362
|
+
const sig1 = vkeyw.signature().to_hex();
|
|
363
|
+
const sig2 = Buffer.from(keyPair.signMessage(txRaw)).toString('hex');
|
|
364
|
+
should_1.default.equal(sig1, sig2);
|
|
365
|
+
});
|
|
366
|
+
describe('explicit outputs build (processExplicitOutputsBuild)', () => {
|
|
367
|
+
afterEach(() => {
|
|
368
|
+
sinon.restore();
|
|
369
|
+
});
|
|
370
|
+
it('builds a sponsored tx with explicit token output, inputs, fee change, and correct asset data', async () => {
|
|
371
|
+
const policyId = 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72';
|
|
372
|
+
const assetNameHex = '4d494e';
|
|
373
|
+
const tokenQty = '2000000';
|
|
374
|
+
const explicitAda = '2000000';
|
|
375
|
+
const feeAddress = testData.rawTx.outputAddress2.address;
|
|
376
|
+
const recipient = testData.rawTx.outputAddress1.address;
|
|
377
|
+
const txBuilder = factory.getTransferBuilder();
|
|
378
|
+
txBuilder.input({
|
|
379
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
380
|
+
transaction_index: 1,
|
|
381
|
+
});
|
|
382
|
+
txBuilder.sponsorshipInfo({
|
|
383
|
+
feeAddress,
|
|
384
|
+
feeAddressInputBalance: '10000000',
|
|
385
|
+
});
|
|
386
|
+
txBuilder.explicitOutput({
|
|
387
|
+
address: recipient,
|
|
388
|
+
amount: explicitAda,
|
|
389
|
+
assets: [
|
|
390
|
+
{
|
|
391
|
+
policy_id: policyId,
|
|
392
|
+
asset_name: assetNameHex,
|
|
393
|
+
quantity: tokenQty,
|
|
394
|
+
},
|
|
395
|
+
],
|
|
396
|
+
});
|
|
397
|
+
txBuilder.ttl(800000000);
|
|
398
|
+
const tx = (await txBuilder.build());
|
|
399
|
+
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
|
|
400
|
+
const txData = tx.toJson();
|
|
401
|
+
txData.inputs.length.should.equal(1);
|
|
402
|
+
txData.inputs[0].transaction_id.should.equal('3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21');
|
|
403
|
+
txData.inputs[0].transaction_index.should.equal(1);
|
|
404
|
+
txData.outputs.length.should.equal(2);
|
|
405
|
+
txData.outputs[0].address.should.equal(recipient);
|
|
406
|
+
txData.outputs[0].amount.should.equal(explicitAda);
|
|
407
|
+
txData.outputs[0].should.have.property('multiAssets');
|
|
408
|
+
const expectedPolicyId = CardanoWasm.ScriptHash.from_bytes(Buffer.from(policyId, 'hex'));
|
|
409
|
+
const expectedAssetName = CardanoWasm.AssetName.new(Buffer.from(assetNameHex, 'hex'));
|
|
410
|
+
txData.outputs[0].multiAssets
|
|
411
|
+
.get_asset(expectedPolicyId, expectedAssetName)
|
|
412
|
+
.to_str()
|
|
413
|
+
.should.equal(tokenQty);
|
|
414
|
+
txData.outputs[1].address.should.equal(feeAddress);
|
|
415
|
+
const fee = Number(tx.getFee);
|
|
416
|
+
(Number(txData.outputs[1].amount) + fee).should.equal(10000000);
|
|
417
|
+
(0, should_1.default)(fee).be.above(0);
|
|
418
|
+
});
|
|
419
|
+
it('does not call processExplicitOutputsBuild when _explicitOutputs is empty', async () => {
|
|
420
|
+
const spy = sinon.spy(src_1.TransactionBuilder.prototype, 'processExplicitOutputsBuild');
|
|
421
|
+
const txBuilder = factory.getTransferBuilder();
|
|
422
|
+
txBuilder.input({
|
|
423
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
424
|
+
transaction_index: 1,
|
|
425
|
+
});
|
|
426
|
+
txBuilder.output({
|
|
427
|
+
address: testData.rawTx.outputAddress1.address,
|
|
428
|
+
amount: '7823121',
|
|
429
|
+
});
|
|
430
|
+
txBuilder.changeAddress(testData.rawTx.outputAddress2.address, '21032023');
|
|
431
|
+
txBuilder.ttl(800000000);
|
|
432
|
+
await txBuilder.build();
|
|
433
|
+
spy.called.should.be.false();
|
|
434
|
+
});
|
|
435
|
+
it('throws when explicitOutput is set but sponsorshipInfo is missing', async () => {
|
|
436
|
+
const txBuilder = factory.getTransferBuilder();
|
|
437
|
+
txBuilder.input({
|
|
438
|
+
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
|
|
439
|
+
transaction_index: 1,
|
|
440
|
+
});
|
|
441
|
+
txBuilder.explicitOutput({
|
|
442
|
+
address: testData.rawTx.outputAddress1.address,
|
|
443
|
+
amount: '2000000',
|
|
444
|
+
assets: [
|
|
445
|
+
{
|
|
446
|
+
policy_id: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72',
|
|
447
|
+
asset_name: '4d494e',
|
|
448
|
+
quantity: '2000000',
|
|
449
|
+
},
|
|
450
|
+
],
|
|
451
|
+
});
|
|
452
|
+
txBuilder.ttl(800000000);
|
|
453
|
+
await txBuilder.build().should.rejectedWith('explicit outputs build requires sponsorshipInfo to be set');
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
// NOTE: The tests below have been commented out as they are for testing during development changes. We don't
|
|
457
|
+
// want full node tests as part of our sdk unit tests. If you are commenting these back in, add axios and
|
|
458
|
+
// AddressFormat imports.
|
|
459
|
+
// xit('should submit a transaction', async () => {
|
|
460
|
+
// const keyPair = new KeyPair({ prv: testData.privateKeys.prvKey4 });
|
|
461
|
+
// const senderAddress = keyPair.getAddress(AddressFormat.testnet);
|
|
462
|
+
//
|
|
463
|
+
// const axiosConfig = {
|
|
464
|
+
// headers: {
|
|
465
|
+
// 'Content-Type': 'application/cbor',
|
|
466
|
+
// },
|
|
467
|
+
// timeout: 10000,
|
|
468
|
+
// };
|
|
469
|
+
//
|
|
470
|
+
// const txBuilder = factory.getTransferBuilder();
|
|
471
|
+
// const utxoData = await axios.get('https://testnet.koios.rest/api/v0/address_info?_address=' + senderAddress);
|
|
472
|
+
// const senderBalance = utxoData.data[0].balance;
|
|
473
|
+
// txBuilder.changeAddress(senderAddress, senderBalance);
|
|
474
|
+
// const utxoSet = utxoData.data[0].utxo_set;
|
|
475
|
+
// for (const utxo of utxoSet) {
|
|
476
|
+
// txBuilder.input({ transaction_id: utxo.tx_hash, transaction_index: utxo.tx_index });
|
|
477
|
+
// }
|
|
478
|
+
//
|
|
479
|
+
// txBuilder.output({
|
|
480
|
+
// address:
|
|
481
|
+
// 'addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp',
|
|
482
|
+
// amount: '5000000',
|
|
483
|
+
// });
|
|
484
|
+
//
|
|
485
|
+
// txBuilder.ttl(800000000);
|
|
486
|
+
// txBuilder.sign({ key: keyPair.getKeys().prv });
|
|
487
|
+
//
|
|
488
|
+
// const tx = await txBuilder.build();
|
|
489
|
+
// const serializedTx = tx.toBroadcastFormat();
|
|
490
|
+
// const bytes = Uint8Array.from(Buffer.from(serializedTx, 'hex'));
|
|
491
|
+
//
|
|
492
|
+
// try {
|
|
493
|
+
// const res = await axios.post('https://testnet.koios.rest/api/v0/submittx', bytes, axiosConfig);
|
|
494
|
+
// console.log(res.data);
|
|
495
|
+
// } catch (err) {
|
|
496
|
+
// console.log(err);
|
|
497
|
+
// }
|
|
498
|
+
// });
|
|
499
|
+
//
|
|
500
|
+
// xit('should submit a transaction using signature interface', async () => {
|
|
501
|
+
// const keyPair = new KeyPair({ prv: testData.privateKeys.prvKey4 });
|
|
502
|
+
// const senderAddress = keyPair.getAddress(AddressFormat.testnet);
|
|
503
|
+
// const axiosConfig = {
|
|
504
|
+
// headers: {
|
|
505
|
+
// 'Content-Type': 'application/cbor',
|
|
506
|
+
// },
|
|
507
|
+
// timeout: 10000,
|
|
508
|
+
// };
|
|
509
|
+
// const txBuilder = factory.getTransferBuilder();
|
|
510
|
+
// const utxoData = await await axios.get('https://testnet.koios.rest/api/v0/address_info?_address=' + senderAddress);
|
|
511
|
+
// const senderBalance = utxoData.data[0].balance;
|
|
512
|
+
// txBuilder.changeAddress(senderAddress, senderBalance);
|
|
513
|
+
// const utxoSet = utxoData.data[0].utxo_set;
|
|
514
|
+
// for (const utxo of utxoSet) {
|
|
515
|
+
// txBuilder.input({ transaction_id: utxo.tx_hash, transaction_index: utxo.tx_index });
|
|
516
|
+
// }
|
|
517
|
+
// txBuilder.output({
|
|
518
|
+
// address:
|
|
519
|
+
// 'addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp',
|
|
520
|
+
// amount: '5000000',
|
|
521
|
+
// });
|
|
522
|
+
//
|
|
523
|
+
// txBuilder.ttl(800000000);
|
|
524
|
+
//
|
|
525
|
+
// const unsignedTx = await txBuilder.build();
|
|
526
|
+
// const serializedTx = unsignedTx.toBroadcastFormat();
|
|
527
|
+
//
|
|
528
|
+
// const txBuilder2 = factory.from(serializedTx);
|
|
529
|
+
// const tx = await txBuilder2.build();
|
|
530
|
+
// const signableHex = tx.signablePayload.toString('hex');
|
|
531
|
+
// const signature = keyPair.signMessage(signableHex);
|
|
532
|
+
// txBuilder2.addSignature({ pub: keyPair.getKeys().pub }, Buffer.from(signature));
|
|
533
|
+
// const signedTransaction = await txBuilder2.build();
|
|
534
|
+
// const serializedTransaction = signedTransaction.toBroadcastFormat();
|
|
535
|
+
// const bytes = Uint8Array.from(Buffer.from(serializedTransaction, 'hex'));
|
|
536
|
+
//
|
|
537
|
+
// try {
|
|
538
|
+
// const res = await axios.post('https://testnet.koios.rest/api/v0/submittx', bytes, axiosConfig);
|
|
539
|
+
// console.log(res.data);
|
|
540
|
+
// } catch (err) {
|
|
541
|
+
// console.log(err);
|
|
542
|
+
// }
|
|
543
|
+
// });
|
|
544
|
+
});
|
|
545
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L3RyYW5zYWN0aW9uQnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1Qiw2Q0FBK0I7QUFDL0IsbURBQXVEO0FBQ3ZELHVEQUF5QztBQUN6QyxtQ0FBbUY7QUFDbkYsaURBQTRDO0FBQzVDLHNGQUF3RTtBQUN4RSwyREFBd0Q7QUFFeEQsUUFBUSxDQUFDLHlCQUF5QixFQUFFLEtBQUssSUFBSSxFQUFFO0lBQzdDLE1BQU0sT0FBTyxHQUFHLElBQUksK0JBQXlCLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ2pFLEVBQUUsQ0FBQywyREFBMkQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN6RSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMvQyxTQUFTLENBQUMsS0FBSyxDQUFDO1lBQ2QsY0FBYyxFQUFFLGtFQUFrRTtZQUNsRixpQkFBaUIsRUFBRSxDQUFDO1NBQ3JCLENBQUMsQ0FBQztRQUNILE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQztRQUMvQixTQUFTLENBQUMsTUFBTSxDQUFDO1lBQ2YsT0FBTyxFQUFFLFFBQVEsQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLE9BQU87WUFDbkQsTUFBTSxFQUFFLFlBQVksQ0FBQyxRQUFRLEVBQUU7U0FDaEMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDO1FBQzdCLFNBQVMsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQzNGLFNBQVMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENB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Q0FBQyxDQUFDO1FBQzVDLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUMzQixNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDOUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM5RSxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxVQUFVLEdBQUcsWUFBWSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDNUYsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDM0IsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0MsTUFB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TTtJQUNOLEVBQUU7SUFDRiw2RUFBNkU7SUFDN0Usd0VBQXdFO0lBQ3hFLHFFQUFxRTtJQUNyRSwwQkFBMEI7SUFDMUIsaUJBQWlCO0lBQ2pCLDRDQUE0QztJQUM1QyxTQUFTO0lBQ1Qsc0JBQXNCO0lBQ3RCLE9BQU87SUFDUCxvREFBb0Q7SUFDcEQsd0hBQXdIO0lBQ3hILG9EQUFvRDtJQUNwRCwyREFBMkQ7SUFDM0QsK0NBQStDO0lBQy9DLGtDQUFrQztJQUNsQywyRkFBMkY7SUFDM0YsTUFBTTtJQUNOLHVCQUF1QjtJQUN2QixlQUFlO0lBQ2Ysd0hBQXdIO0lBQ3hILHlCQUF5QjtJQUN6QixRQUFRO0lBQ1IsRUFBRTtJQUNGLDhCQUE4QjtJQUM5QixFQUFFO0lBQ0YsZ0RBQWdEO0lBQ2hELHlEQUF5RDtJQUN6RCxFQUFFO0lBQ0YsbURBQW1EO0lBQ25ELHlDQUF5QztJQUN6Qyw0REFBNEQ7SUFDNUQsd0RBQXdEO0lBQ3hELHFGQUFxRjtJQUNyRix3REFBd0Q7SUFDeEQseUVBQXlFO0lBQ3pFLDhFQUE4RTtJQUM5RSxFQUFFO0lBQ0YsVUFBVTtJQUNWLHNHQUFzRztJQUN0Ryw2QkFBNkI7SUFDN0Isb0JBQW9CO0lBQ3BCLHdCQUF3QjtJQUN4QixNQUFNO0lBQ04sTUFBTTtBQUNSLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vcmVzb3VyY2VzJztcbmltcG9ydCB7IEtleVBhaXIsIFRyYW5zYWN0aW9uQnVpbGRlciwgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB9IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0ICogYXMgQ2FyZGFub1dhc20gZnJvbSAnQGVtdXJnby9jYXJkYW5vLXNlcmlhbGl6YXRpb24tbGliLW5vZGVqcyc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbiB9IGZyb20gJy4uLy4uL3NyYy9saWIvdHJhbnNhY3Rpb24nO1xuXG5kZXNjcmliZSgnQURBIFRyYW5zYWN0aW9uIEJ1aWxkZXInLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ3RhZGEnKSk7XG4gIGl0KCdzdGFydCBhbmQgYnVpbGQgYW4gdW5zaWduZWQgdHJhbnNmZXIgdHggZm9yIGJ5cm9uIGFkZHJlc3MnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICB0eEJ1aWxkZXIuaW5wdXQoe1xuICAgICAgdHJhbnNhY3Rpb25faWQ6ICcxYjUzMzMxZTA2OWE2ZTU4ZmU3NzkxOWQzMGMwY2YyOTlkMTNhMmY1YjNkOTk3MGNlNDczYzFhNjZkNzFiZjAzJyxcbiAgICAgIHRyYW5zYWN0aW9uX2luZGV4OiAxLFxuICAgIH0pO1xuICAgIGNvbnN0IG91dHB1dEFtb3VudCA9IDIwMDAwMDAwMDtcbiAgICB0eEJ1aWxkZXIub3V0cHV0KHtcbiAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnJhd1R4Qnlyb24ub3V0cHV0QWRkcmVzczEuYWRkcmVzcyxcbiAgICAgIGFtb3VudDogb3V0cHV0QW1vdW50LnRvU3RyaW5nKCksXG4gICAgfSk7XG4gICAgY29uc3QgdG90YWxJbnB1dCA9IDk5OTYwMDAwMDtcbiAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5yYXdUeEJ5cm9uLm91dHB1dEFkZHJlc3MyLmFkZHJlc3MsIHRvdGFsSW5wdXQudG9TdHJpbmcoKSk7XG4gICAgdHhCdWlsZGVyLnR0bCg4MDAwMDAwMDApO1xuICAgIC8vIHR4QnVpbGRlci5mZWUoJzIwMDAwMCcpO1xuICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBzaG91bGQuZXF1YWwodHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgIGNvbnN0IHR4RGF0YSA9IHR4LnRvSnNvbigpO1xuICAgIHR4RGF0YS53aXRuZXNzZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEuY2VydHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEud2l0aGRyYXdhbHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Qnlyb24ub3V0cHV0QWRkcmVzczEuYWRkcmVzcyk7XG4gICAgdHhEYXRhLm91dHB1dHNbMV0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHhCeXJvbi5vdXRwdXRBZGRyZXNzMi5hZGRyZXNzKTtcbiAgICBjb25zdCBmZWUgPSB0eC5nZXRGZWU7XG4gICAgdHhEYXRhLm91dHB1dHNbMV0uYW1vdW50LnNob3VsZC5lcXVhbCgodG90YWxJbnB1dCAtIG91dHB1dEFtb3VudCAtIE51bWJlcihmZWUpKS50b1N0cmluZygpKTtcbiAgICBmZWUuc2hvdWxkLmVxdWFsKCcxNjc0MzcnKTtcbiAgICB0eERhdGEuaWQuc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Qnlyb24udHhIYXNoMik7XG4gICAgY29uc3QgdHhCcm9hZGNhc3QgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIHNob3VsZC5lcXVhbCh0eEJyb2FkY2FzdCwgdGVzdERhdGEucmF3VHhCeXJvbi51bnNpZ25lZFR4Mik7XG4gIH0pO1xuXG4gIGl0KCdzdGFydCBhbmQgYnVpbGQgYW4gdW5zaWduZWQgdHJhbnNmZXIgdHggZm9yIHNoZWxsZXkgYWRkcmVzcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgdHJhbnNhY3Rpb25faW5kZXg6IDEsXG4gICAgfSk7XG4gICAgY29uc3Qgb3V0cHV0QW1vdW50ID0gNzgyMzEyMTtcbiAgICB0eEJ1aWxkZXIub3V0cHV0KHtcbiAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MsXG4gICAgICBhbW91bnQ6IG91dHB1dEFtb3VudC50b1N0cmluZygpLFxuICAgIH0pO1xuICAgIGNvbnN0IHRvdGFsSW5wdXQgPSAyMTAzMjAyMztcbiAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMi5hZGRyZXNzLCB0b3RhbElucHV0LnRvU3RyaW5nKCkpO1xuICAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgc2hvdWxkLmVxdWFsKHR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICBjb25zdCB0eERhdGEgPSB0eC50b0pzb24oKTtcbiAgICB0eERhdGEud2l0bmVzc2VzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLmNlcnRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLndpdGhkcmF3YWxzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICB0eERhdGEub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMS5hZGRyZXNzKTtcbiAgICB0eERhdGEub3V0cHV0c1sxXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMi5hZGRyZXNzKTtcbiAgICBjb25zdCBmZWUgPSB0eC5nZXRGZWU7XG4gICAgdHhEYXRhLm91dHB1dHNbMV0uYW1vdW50LnNob3VsZC5lcXVhbCgodG90YWxJbnB1dCAtIG91dHB1dEFtb3VudCAtIE51bWJlcihmZWUpKS50b1N0cmluZygpKTtcbiAgICBmZWUuc2hvdWxkLmVxdWFsKCcxNjcxNzMnKTtcbiAgICB0eERhdGEuaWQuc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4LnR4SGFzaDIpO1xuICAgIGNvbnN0IHR4QnJvYWRjYXN0ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICBzaG91bGQuZXF1YWwodHhCcm9hZGNhc3QsIHRlc3REYXRhLnJhd1R4LnVuc2lnbmVkVHgyKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBidWlsZCBhIGNvbnNvbGlkYXRlIHR4IHdpdGggbm8gYXNzZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICB0eEJ1aWxkZXIuaW5wdXQoe1xuICAgICAgdHJhbnNhY3Rpb25faWQ6ICczNjc3ZTc1YzdiYTY5OWJmZGM2Y2Q1N2Q0MmYyNDZmODZmNjNhZWZkNzYwMjUwMDZhYzc4MzEzZmFkMmJiYTIxJyxcbiAgICAgIHRyYW5zYWN0aW9uX2luZGV4OiAxLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgb3V0cHV0QW1vdW50ID0gMDtcbiAgICBjb25zdCB0b3RhbElucHV0ID0gMjAwMDAwMDA7XG4gICAgdHhCdWlsZGVyLmNoYW5nZUFkZHJlc3ModGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcywgdG90YWxJbnB1dC50b1N0cmluZygpKTtcbiAgICB0eEJ1aWxkZXIudHRsKDgwMDAwMDAwMCk7XG4gICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgIHNob3VsZC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgY29uc3QgdHhEYXRhID0gdHgudG9Kc29uKCk7XG4gICAgdHhEYXRhLndpdG5lc3Nlcy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIHR4RGF0YS5jZXJ0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIHR4RGF0YS53aXRoZHJhd2Fscy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIHR4RGF0YS5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgdHhEYXRhLm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcyk7XG4gICAgY29uc3QgZmVlID0gdHguZ2V0RmVlO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoKHRvdGFsSW5wdXQgLSBvdXRwdXRBbW91bnQgLSBOdW1iZXIoZmVlKSkudG9TdHJpbmcoKSk7XG4gICAgZmVlLnNob3VsZC5lcXVhbCgnMTY1NTQ1Jyk7XG4gICAgdHhEYXRhLmlkLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC50eEhhc2g1KTtcbiAgICBjb25zdCB0eEJyb2FkY2FzdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgc2hvdWxkLmVxdWFsKHR4QnJvYWRjYXN0LCB0ZXN0RGF0YS5yYXdUeC51bnNpZ25lZFR4NSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgaW5pdGlhbGl6ZSBhbmQgYnVpbGQgdHggd2l0aCBhc3NldCBkYXRhJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHBvbGljeUlkID0gJ2UxNmMyZGM4YWU5MzdlOGQzNzkwYzdmZDcxNjhkN2I5OTQ2MjFiYTE0Y2ExMTQxNWYzOWZlZDcyJztcbiAgICBjb25zdCBhc3NldE5hbWUgPSAnNGQ0OTRlJztcbiAgICBjb25zdCBxdWFudGl0eSA9ICcyMDAwMDAwJztcbiAgICBjb25zdCBwcmVCdWlsdFR4ID0gbmV3IFRyYW5zYWN0aW9uKGNvaW5zLmdldCgndGFkYScpKTtcbiAgICBwcmVCdWlsdFR4LmZyb21SYXdUcmFuc2FjdGlvbih0ZXN0RGF0YS5yYXdUeC51bnNpZ25lZFR4Myk7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICB0eEJ1aWxkZXIuaW5pdEJ1aWxkZXIocHJlQnVpbHRUeCk7XG5cbiAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgY29uc3QgdHhEYXRhID0gdHgudG9Kc29uKCk7XG4gICAgY29uc3QgZXhwZWN0ZWRBc3NldE5hbWUgPSBDYXJkYW5vV2FzbS5Bc3NldE5hbWUubmV3KEJ1ZmZlci5mcm9tKGFzc2V0TmFtZSwgJ2hleCcpKTtcbiAgICBjb25zdCBleHBlY3RlZFBvbGljeUlkID0gQ2FyZGFub1dhc20uU2NyaXB0SGFzaC5mcm9tX2J5dGVzKEJ1ZmZlci5mcm9tKHBvbGljeUlkLCAnaGV4JykpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtdWx0aUFzc2V0cycpO1xuICAgICh0eERhdGEub3V0cHV0c1swXS5tdWx0aUFzc2V0cyBhcyBDYXJkYW5vV2FzbS5NdWx0aUFzc2V0KVxuICAgICAgLmdldF9hc3NldChleHBlY3RlZFBvbGljeUlkLCBleHBlY3RlZEFzc2V0TmFtZSlcbiAgICAgIC50b19zdHIoKVxuICAgICAgLnNob3VsZC5lcXVhbChxdWFudGl0eSk7XG4gICAgdHhEYXRhLmlkLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC50eEhhc2gzKTtcbiAgICBjb25zdCB0eEJyb2FkY2FzdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgc2hvdWxkLmVxdWFsKHR4QnJvYWRjYXN0LCB0ZXN0RGF0YS5yYXdUeC51bnNpZ25lZFR4Myk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYnVpbGQgYSBjb25zb2xpZGF0ZSB0eCB3aXRoIHNpbmdsZSBhc3NldCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgdHJhbnNhY3Rpb25faW5kZXg6IDEsXG4gICAgfSk7XG5cbiAgICBjb25zdCBvdXRwdXRBbW91bnQgPSAwO1xuICAgIGNvbnN0IHBvbGljeUlkID0gJ2UxNmMyZGM4YWU5MzdlOGQzNzkwYzdmZDcxNjhkN2I5OTQ2MjFiYTE0Y2ExMTQxNWYzOWZlZDcyJztcbiAgICBjb25zdCBhc3NldE5hbWUgPSAnNGQ0OTRlJztcbiAgICBjb25zdCBxdWFudGl0eSA9ICcyMDAwMDAwJztcbiAgICB0eEJ1aWxkZXIuYXNzZXRzKHtcbiAgICAgIHBvbGljeV9pZDogcG9saWN5SWQsXG4gICAgICBhc3NldF9uYW1lOiBhc3NldE5hbWUsXG4gICAgICBxdWFudGl0eTogcXVhbnRpdHksXG4gICAgfSk7XG4gICAgY29uc3QgbWluQW1vdW50Rm9yU2luZ2xlQXNzZXQgPSAxNTAwMDAwO1xuICAgIGNvbnN0IHRvdGFsSW5wdXQgPSAyMDAwMDAwMDtcbiAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMS5hZGRyZXNzLCB0b3RhbElucHV0LnRvU3RyaW5nKCkpO1xuICAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgc2hvdWxkLmVxdWFsKHR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICBjb25zdCB0eERhdGEgPSB0eC50b0pzb24oKTtcbiAgICB0eERhdGEud2l0bmVzc2VzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLmNlcnRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLndpdGhkcmF3YWxzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICB0eERhdGEub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMS5hZGRyZXNzKTtcbiAgICB0eERhdGEub3V0cHV0c1sxXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMS5hZGRyZXNzKTtcblxuICAgIC8vIHRva2VuIGFzc2VydGlvblxuICAgIGNvbnN0IGV4cGVjdGVkQXNzZXROYW1lID0gQ2FyZGFub1dhc20uQXNzZXROYW1lLm5ldyhCdWZmZXIuZnJvbShhc3NldE5hbWUsICdoZXgnKSk7XG4gICAgY29uc3QgZXhwZWN0ZWRQb2xpY3lJZCA9IENhcmRhbm9XYXNtLlNjcmlwdEhhc2guZnJvbV9ieXRlcyhCdWZmZXIuZnJvbShwb2xpY3lJZCwgJ2hleCcpKTtcbiAgICB0eERhdGEub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKG1pbkFtb3VudEZvclNpbmdsZUFzc2V0LnRvU3RyaW5nKCkpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtdWx0aUFzc2V0cycpO1xuICAgICh0eERhdGEub3V0cHV0c1swXS5tdWx0aUFzc2V0cyBhcyBDYXJkYW5vV2FzbS5NdWx0aUFzc2V0KVxuICAgICAgLmdldF9hc3NldChleHBlY3RlZFBvbGljeUlkLCBleHBlY3RlZEFzc2V0TmFtZSlcbiAgICAgIC50b19zdHIoKVxuICAgICAgLnNob3VsZC5lcXVhbChxdWFudGl0eSk7XG5cbiAgICBjb25zdCBmZWUgPSB0eC5nZXRGZWU7XG4gICAgdHhEYXRhLm91dHB1dHNbMV0uYW1vdW50LnNob3VsZC5lcXVhbChcbiAgICAgICh0b3RhbElucHV0IC0gbWluQW1vdW50Rm9yU2luZ2xlQXNzZXQgLSBvdXRwdXRBbW91bnQgLSBOdW1iZXIoZmVlKSkudG9TdHJpbmcoKVxuICAgICk7XG4gICAgZmVlLnNob3VsZC5lcXVhbCgnMTcwMjUzJyk7XG4gICAgdHhEYXRhLmlkLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC50eEhhc2gzKTtcbiAgICBjb25zdCB0eEJyb2FkY2FzdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgc2hvdWxkLmVxdWFsKHR4QnJvYWRjYXN0LCB0ZXN0RGF0YS5yYXdUeC51bnNpZ25lZFR4Myk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYnVpbGQgYSBjb25zb2xpZGF0ZSB0eCB3aXRoIG11bHRpcGxlIGFzc2V0cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgdHJhbnNhY3Rpb25faW5kZXg6IDEsXG4gICAgfSk7XG5cbiAgICBjb25zdCBvdXRwdXRBbW91bnQgPSAwO1xuICAgIGNvbnN0IGFzc2V0MV9wb2xpY3lJZCA9ICcyNzljOTA5ZjM0OGU1MzNkYTU4MDg4OThmODdmOWExNGJiMmMzZGZiYmFjY2NkNjMxZDkyN2EzZic7XG4gICAgY29uc3QgYXNzZXQxX2Fzc2V0TmFtZSA9ICc1MzRlNDU0Yic7XG4gICAgY29uc3QgYXNzZXQxX3F1YW50aXR5ID0gJzYwMDAwMDAnO1xuICAgIGNvbnN0IGFzc2V0Ml9wb2xpY3lJZCA9ICcxZjdhNThhMWFhMWU2YjA0N2E0MjEwOWFkZTMzMWNlMjZjOWMyY2NlMDI3ZDA0M2ZmMjY0ZmIxZic7XG4gICAgY29uc3QgYXNzZXQyX2Fzc2V0TmFtZSA9ICc0MjUyNDk0MzRiNTMnO1xuICAgIGNvbnN0IGFzc2V0Ml9xdWFudGl0eSA9ICc1MDAwMDAwJztcblxuICAgIHR4QnVpbGRlci5hc3NldHMoe1xuICAgICAgcG9saWN5X2lkOiBhc3NldDFfcG9saWN5SWQsXG4gICAgICBhc3NldF9uYW1lOiBhc3NldDFfYXNzZXROYW1lLFxuICAgICAgcXVhbnRpdHk6IGFzc2V0MV9xdWFudGl0eSxcbiAgICB9KTtcbiAgICB0eEJ1aWxkZXIuYXNzZXRzKHtcbiAgICAgIHBvbGljeV9pZDogYXNzZXQyX3BvbGljeUlkLFxuICAgICAgYXNzZXRfbmFtZTogYXNzZXQyX2Fzc2V0TmFtZSxcbiAgICAgIHF1YW50aXR5OiBhc3NldDJfcXVhbnRpdHksXG4gICAgfSk7XG5cbiAgICBjb25zdCB0b3RhbElucHV0ID0gMjAwMDAwMDA7XG4gICAgY29uc3QgbWluQW1vdW50Rm9yU2luZ2xlQXNzZXQgPSAxNTAwMDAwO1xuICAgIHR4QnVpbGRlci5jaGFuZ2VBZGRyZXNzKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MsIHRvdGFsSW5wdXQudG9TdHJpbmcoKSk7XG4gICAgdHhCdWlsZGVyLnR0bCg4MDAwMDAwMDApO1xuICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBzaG91bGQuZXF1YWwodHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgIGNvbnN0IHR4RGF0YSA9IHR4LnRvSnNvbigpO1xuICAgIHR4RGF0YS53aXRuZXNzZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEuY2VydHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEud2l0aGRyYXdhbHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDMpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzFdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzJdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MpO1xuXG4gICAgLy8gdG9rZW4gYXNzZXJ0aW9uXG4gICAgY29uc3QgYXNzZXQxX2V4cGVjdGVkQXNzZXROYW1lID0gQ2FyZGFub1dhc20uQXNzZXROYW1lLm5ldyhCdWZmZXIuZnJvbShhc3NldDFfYXNzZXROYW1lLCAnaGV4JykpO1xuICAgIGNvbnN0IGFzc2V0MV9leHBlY3RlZFBvbGljeUlkID0gQ2FyZGFub1dhc20uU2NyaXB0SGFzaC5mcm9tX2J5dGVzKEJ1ZmZlci5mcm9tKGFzc2V0MV9wb2xpY3lJZCwgJ2hleCcpKTtcbiAgICB0eERhdGEub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKG1pbkFtb3VudEZvclNpbmdsZUFzc2V0LnRvU3RyaW5nKCkpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtdWx0aUFzc2V0cycpO1xuICAgICh0eERhdGEub3V0cHV0c1swXS5tdWx0aUFzc2V0cyBhcyBDYXJkYW5vV2FzbS5NdWx0aUFzc2V0KVxuICAgICAgLmdldF9hc3NldChhc3NldDFfZXhwZWN0ZWRQb2xpY3lJZCwgYXNzZXQxX2V4cGVjdGVkQXNzZXROYW1lKVxuICAgICAgLnRvX3N0cigpXG4gICAgICAuc2hvdWxkLmVxdWFsKGFzc2V0MV9xdWFudGl0eSk7XG4gICAgY29uc3QgYXNzZXQyX2V4cGVjdGVkQXNzZXROYW1lID0gQ2FyZGFub1dhc20uQXNzZXROYW1lLm5ldyhCdWZmZXIuZnJvbShhc3NldDJfYXNzZXROYW1lLCAnaGV4JykpO1xuICAgIGNvbnN0IGFzc2V0Ml9leHBlY3RlZFBvbGljeUlkID0gQ2FyZGFub1dhc20uU2NyaXB0SGFzaC5mcm9tX2J5dGVzKEJ1ZmZlci5mcm9tKGFzc2V0Ml9wb2xpY3lJZCwgJ2hleCcpKTtcbiAgICB0eERhdGEub3V0cHV0c1sxXS5hbW91bnQuc2hvdWxkLmVxdWFsKG1pbkFtb3VudEZvclNpbmdsZUFzc2V0LnRvU3RyaW5nKCkpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzFdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtdWx0aUFzc2V0cycpO1xuICAgICh0eERhdGEub3V0cHV0c1sxXS5tdWx0aUFzc2V0cyBhcyBDYXJkYW5vV2FzbS5NdWx0aUFzc2V0KVxuICAgICAgLmdldF9hc3NldChhc3NldDJfZXhwZWN0ZWRQb2xpY3lJZCwgYXNzZXQyX2V4cGVjdGVkQXNzZXROYW1lKVxuICAgICAgLnRvX3N0cigpXG4gICAgICAuc2hvdWxkLmVxdWFsKGFzc2V0Ml9xdWFudGl0eSk7XG5cbiAgICBjb25zdCBmZWUgPSB0eC5nZXRGZWU7XG4gICAgdHhEYXRhLm91dHB1dHNbMl0uYW1vdW50LnNob3VsZC5lcXVhbChcbiAgICAgICh0b3RhbElucHV0IC0gbWluQW1vdW50Rm9yU2luZ2xlQXNzZXQgKiAyIC0gb3V0cHV0QW1vdW50IC0gTnVtYmVyKGZlZSkpLnRvU3RyaW5nKClcbiAgICApO1xuICAgIGZlZS5zaG91bGQuZXF1YWwoJzE3NTEzNycpO1xuICAgIHR4RGF0YS5pZC5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHgudHhIYXNoNCk7XG4gICAgY29uc3QgdHhCcm9hZGNhc3QgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIHNob3VsZC5lcXVhbCh0eEJyb2FkY2FzdCwgdGVzdERhdGEucmF3VHgudW5zaWduZWRUeDQpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGZhaWwgdG8gYnVpbGQgYSBjb25zb2xpZGF0ZSB0eCB3aXRoIHNpbmdsZSBhc3NldCBhbmQgaW5zdWZmaWNpZW50IG1pbmltdW0gQURBJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLmlucHV0KHtcbiAgICAgIHRyYW5zYWN0aW9uX2lkOiAnMzY3N2U3NWM3YmE2OTliZmRjNmNkNTdkNDJmMjQ2Zjg2ZjYzYWVmZDc2MDI1MDA2YWM3ODMxM2ZhZDJiYmEyMScsXG4gICAgICB0cmFuc2FjdGlvbl9pbmRleDogMSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHBvbGljeUlkID0gJzI3OWM5MDlmMzQ4ZTUzM2RhNTgwODg5OGY4N2Y5YTE0YmIyYzNkZmJiYWNjY2Q2MzFkOTI3YTNmJztcbiAgICBjb25zdCBhc3NldE5hbWUgPSAnNTM0ZTQ1NGInO1xuICAgIGNvbnN0IHF1YW50aXR5ID0gJzYwMDAwMDAnO1xuICAgIHR4QnVpbGRlci5hc3NldHMoe1xuICAgICAgcG9saWN5X2lkOiBwb2xpY3lJZCxcbiAgICAgIGFzc2V0X25hbWU6IGFzc2V0TmFtZSxcbiAgICAgIHF1YW50aXR5OiBxdWFudGl0eSxcbiAgICB9KTtcblxuICAgIC8vIGNoYW5nZSA9IGlucHV0IGFtdCAtIGZlZSAtIG91dHB1dCBhbXQgPT4gY2hhbmdlIHdpbGwgYmUgbGVzcyB0aGFuIDEwMDAwMDBcbiAgICAvLyBldmVuIGlmIG9uZSBvdXRwdXQgaGFzIGxlc3MgdGhhbiAxIEFEQSwgdHggd2lsbCBmYWlsXG4gICAgY29uc3QgdG90YWxJbnB1dCA9IDEwMDAwMDA7XG4gICAgdHhCdWlsZGVyLmNoYW5nZUFkZHJlc3ModGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcywgdG90YWxJbnB1dC50b1N0cmluZygpKTtcbiAgICB0eEJ1aWxkZXIudHRsKDgwMDAwMDAwMCk7XG4gICAgYXdhaXQgdHhCdWlsZGVyXG4gICAgICAuYnVpbGQoKVxuICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ0luc3VmZmljaWVudCBmdW5kczogbmVlZCBhIG1pbmltdW0gb2YgMS41IEFEQSBwZXIgb3V0cHV0IHRvIGNvbnN0cnVjdCB0b2tlbiBjb25zb2xpZGF0aW9uJyk7XG4gIH0pO1xuXG4gIGl0KCdidWlsZCBhbmQgc2lnbiBhIHRyYW5zZmVyIHR4JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLmlucHV0KHtcbiAgICAgIHRyYW5zYWN0aW9uX2lkOiAnMzY3N2U3NWM3YmE2OTliZmRjNmNkNTdkNDJmMjQ2Zjg2ZjYzYWVmZDc2MDI1MDA2YWM3ODMxM2ZhZDJiYmEyMScsXG4gICAgICB0cmFuc2FjdGlvbl9pbmRleDogMSxcbiAgICB9KTtcbiAgICBjb25zdCBvdXRwdXRBbW91bnQgPSA3ODIzMTIxO1xuICAgIHR4QnVpbGRlci5vdXRwdXQoe1xuICAgICAgYWRkcmVzczogdGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcyxcbiAgICAgIGFtb3VudDogb3V0cHV0QW1vdW50LnRvU3RyaW5nKCksXG4gICAgfSk7XG4gICAgY29uc3QgdG90YWxJbnB1dCA9IDIxMDMyMDIzO1xuICAgIHR4QnVpbGRlci5jaGFuZ2VBZGRyZXNzKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MyLmFkZHJlc3MsIHRvdGFsSW5wdXQudG9TdHJpbmcoKSk7XG4gICAgdHhCdWlsZGVyLnR0bCg4MDAwMDAwMDApO1xuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5wcml2YXRlS2V5cy5wcnZLZXk0IH0pO1xuICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBzaG91bGQuZXF1YWwodHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgIGNvbnN0IHR4RGF0YSA9IHR4LnRvSnNvbigpO1xuICAgIHR4RGF0YS53aXRuZXNzZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICB0eERhdGEuY2VydHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEud2l0aGRyYXdhbHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzFdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MyLmFkZHJlc3MpO1xuICAgIGNvbnN0IGZlZSA9IHR4LmdldEZlZTtcbiAgICB0eERhdGEub3V0cHV0c1sxXS5hbW91bnQuc2hvdWxkLmVxdWFsKCh0b3RhbElucHV0IC0gb3V0cHV0QW1vdW50IC0gTnVtYmVyKGZlZSkpLnRvU3RyaW5nKCkpO1xuICAgIGZlZS5zaG91bGQuZXF1YWwoJzE2NzE3MycpO1xuICAgIHR4RGF0YS5pZC5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHgudHhIYXNoMik7XG4gICAgY29uc3QgdHhCcm9hZGNhc3QgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIHNob3VsZC5lcXVhbCh0eEJyb2FkY2FzdCwgdGVzdERhdGEucmF3VHguc2lnbmVkVHgyKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIGEgZmVlIHByb3Blcmx5LCBub3QgYXMgemVybycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgdHJhbnNhY3Rpb25faW5kZXg6IDEsXG4gICAgfSk7XG4gICAgdHhCdWlsZGVyLm91dHB1dCh7XG4gICAgICBhZGRyZXNzOlxuICAgICAgICAnYWRkcjFxOHJtOXo3dzR5eDVnejY1MmtuMnEyMzhlZnZtczZ0MHFlbHVyOW5sZ2x1bjhldTR0cjVrbmo0ZnU0YWRlbHpxaHhnOGFkdTV4Y2E0anJhMGd0bGxmcnBjYXd5cTlwc3oyMycsXG4gICAgICBhbW91bnQ6ICc3MzI4MzgzJyxcbiAgICB9KTtcbiAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5hZGRyZXNzLmFkZHJlc3MyLCAnMTAwMDAwMDAwMCcpO1xuICAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEucHJpdmF0ZUtleXMucHJ2S2V5NCB9KTtcbiAgICBjb25zdCBidWlsdFR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBidWlsdFR4LmdldEZlZS5zaG91bGQuZXF1YWwoJzE2ODQwNScpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIG5vdCBjYWxjdWxhdGUgZmVlIGFuZCB1c2Ugb25lIHBhc3NlZCBpbicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgdHJhbnNhY3Rpb25faW5kZXg6IDEsXG4gICAgfSk7XG4gICAgdHhCdWlsZGVyLm91dHB1dCh7XG4gICAgICBhZGRyZXNzOlxuICAgICAgICAnYWRkcjFxOHJtOXo3dzR5eDVnejY1MmtuMnEyMzhlZnZtczZ0MHFlbHVyOW5sZ2x1bjhldTR0cjVrbmo0ZnU0YWRlbHpxaHhnOGFkdTV4Y2E0anJhMGd0bGxmcnBjYXd5cTlwc3oyMycsXG4gICAgICBhbW91bnQ6ICc3MzI4MzgzJyxcbiAgICB9KTtcbiAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5hZGRyZXNzLmFkZHJlc3MyLCAnMTAwMDAwMDAwMCcpO1xuICAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgICB0eEJ1aWxkZXIuZmVlKCcxNzAwMDAnKTtcbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEucHJpdmF0ZUtleXMucHJ2S2V5NCB9KTtcbiAgICBjb25zdCBidWlsdFR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBidWlsdFR4LmdldEZlZS5zaG91bGQuZXF1YWwoJzE3MDAwMCcpO1xuICB9KTtcblxuICBpdCgnYnVpbGQgYSBzZW5kIGZyb20gdW5zaWduZWQgcmF3VHgnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHRlc3REYXRhLnJhd1R4LnVuc2lnbmVkVHgyKTtcbiAgICBjb25zdCBidWlsdFR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgc2hvdWxkLmVxdWFsKGJ1aWx0VHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgIHNob3VsZC5lcXVhbChidWlsdFR4LmlkLCB0ZXN0RGF0YS5yYXdUeC50eEhhc2gyKTtcbiAgICBidWlsdFR4Lm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICBidWlsdFR4Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcyk7XG4gICAgYnVpbHRUeC5vdXRwdXRzWzFdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MyLmFkZHJlc3MpO1xuICB9KTtcblxuICBpdCgnbWF0Y2ggc2lnbmF0dXJlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHR4UmF3ID0gJzU4MjA3MDA4MWVlYjFmMzEyZWM3NWFmMWI0Zjk0YTc5NjNkYjNiMjY0ZjI0NTEzNjllNGVhMjQ0YTU0ZGU1ZDAnO1xuICAgIGNvbnN0IGtleVBhaXIgPSBuZXcgS2V5UGFpcigpO1xuXG4gICAgY29uc3QgcGtleSA9IENhcmRhbm9XYXNtLlByaXZhdGVLZXkuZnJvbV9ub3JtYWxfYnl0ZXMoQnVmZmVyLmZyb20oa2V5UGFpci5nZXRLZXlzKCkucHJ2ISwgJ2hleCcpKTtcbiAgICBjb25zdCB2a2V5dyA9IENhcmRhbm9XYXNtLm1ha2VfdmtleV93aXRuZXNzKFxuICAgICAgQ2FyZGFub1dhc20uVHJhbnNhY3Rpb25IYXNoLmZyb21fYnl0ZXMoQnVmZmVyLmZyb20odHhSYXcsICdoZXgnKSksXG4gICAgICBwa2V5XG4gICAgKTtcbiAgICBjb25zdCBzaWcxID0gdmtleXcuc2lnbmF0dXJlKCkudG9faGV4KCk7XG5cbiAgICBjb25zdCBzaWcyID0gQnVmZmVyLmZyb20oa2V5UGFpci5zaWduTWVzc2FnZSh0eFJhdykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICBzaG91bGQuZXF1YWwoc2lnMSwgc2lnMik7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdleHBsaWNpdCBvdXRwdXRzIGJ1aWxkIChwcm9jZXNzRXhwbGljaXRPdXRwdXRzQnVpbGQpJywgKCkgPT4ge1xuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnYnVpbGRzIGEgc3BvbnNvcmVkIHR4IHdpdGggZXhwbGljaXQgdG9rZW4gb3V0cHV0LCBpbnB1dHMsIGZlZSBjaGFuZ2UsIGFuZCBjb3JyZWN0IGFzc2V0IGRhdGEnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lJZCA9ICdlMTZjMmRjOGFlOTM3ZThkMzc5MGM3ZmQ3MTY4ZDdiOTk0NjIxYmExNGNhMTE0MTVmMzlmZWQ3Mic7XG4gICAgICBjb25zdCBhc3NldE5hbWVIZXggPSAnNGQ0OTRlJztcbiAgICAgIGNvbnN0IHRva2VuUXR5ID0gJzIwMDAwMDAnO1xuICAgICAgY29uc3QgZXhwbGljaXRBZGEgPSAnMjAwMDAwMCc7XG4gICAgICBjb25zdCBmZWVBZGRyZXNzID0gdGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczIuYWRkcmVzcztcbiAgICAgIGNvbnN0IHJlY2lwaWVudCA9IHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3M7XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuaW5wdXQoe1xuICAgICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgICB0cmFuc2FjdGlvbl9pbmRleDogMSxcbiAgICAgIH0pO1xuICAgICAgdHhCdWlsZGVyLnNwb25zb3JzaGlwSW5mbyh7XG4gICAgICAgIGZlZUFkZHJlc3MsXG4gICAgICAgIGZlZUFkZHJlc3NJbnB1dEJhbGFuY2U6ICcxMDAwMDAwMCcsXG4gICAgICB9KTtcbiAgICAgIHR4QnVpbGRlci5leHBsaWNpdE91dHB1dCh7XG4gICAgICAgIGFkZHJlc3M6IHJlY2lwaWVudCxcbiAgICAgICAgYW1vdW50OiBleHBsaWNpdEFkYSxcbiAgICAgICAgYXNzZXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgcG9saWN5X2lkOiBwb2xpY3lJZCxcbiAgICAgICAgICAgIGFzc2V0X25hbWU6IGFzc2V0TmFtZUhleCxcbiAgICAgICAgICAgIHF1YW50aXR5OiB0b2tlblF0eSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG4gICAgICB0eEJ1aWxkZXIudHRsKDgwMDAwMDAwMCk7XG5cbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICBjb25zdCB0eERhdGEgPSB0eC50b0pzb24oKTtcblxuICAgICAgdHhEYXRhLmlucHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgdHhEYXRhLmlucHV0c1swXS50cmFuc2FjdGlvbl9pZC5zaG91bGQuZXF1YWwoJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnKTtcbiAgICAgIHR4RGF0YS5pbnB1dHNbMF0udHJhbnNhY3Rpb25faW5kZXguc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICB0eERhdGEub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgdHhEYXRhLm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwocmVjaXBpZW50KTtcbiAgICAgIHR4RGF0YS5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoZXhwbGljaXRBZGEpO1xuICAgICAgdHhEYXRhLm91dHB1dHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ211bHRpQXNzZXRzJyk7XG4gICAgICBjb25zdCBleHBlY3RlZFBvbGljeUlkID0gQ2FyZGFub1dhc20uU2NyaXB0SGFzaC5mcm9tX2J5dGVzKEJ1ZmZlci5mcm9tKHBvbGljeUlkLCAnaGV4JykpO1xuICAgICAgY29uc3QgZXhwZWN0ZWRBc3NldE5hbWUgPSBDYXJkYW5vV2FzbS5Bc3NldE5hbWUubmV3KEJ1ZmZlci5mcm9tKGFzc2V0TmFtZUhleCwgJ2hleCcpKTtcbiAgICAgICh0eERhdGEub3V0cHV0c1swXS5tdWx0aUFzc2V0cyBhcyBDYXJkYW5vV2FzbS5NdWx0aUFzc2V0KVxuICAgICAgICAuZ2V0X2Fzc2V0KGV4cGVjdGVkUG9saWN5SWQsIGV4cGVjdGVkQXNzZXROYW1lKVxuICAgICAgICAudG9fc3RyKClcbiAgICAgICAgLnNob3VsZC5lcXVhbCh0b2tlblF0eSk7XG5cbiAgICAgIHR4RGF0YS5vdXRwdXRzWzFdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKGZlZUFkZHJlc3MpO1xuICAgICAgY29uc3QgZmVlID0gTnVtYmVyKHR4LmdldEZlZSk7XG4gICAgICAoTnVtYmVyKHR4RGF0YS5vdXRwdXRzWzFdLmFtb3VudCkgKyBmZWUpLnNob3VsZC5lcXVhbCgxMDAwMDAwMCk7XG4gICAgICBzaG91bGQoZmVlKS5iZS5hYm92ZSgwKTtcbiAgICB9KTtcblxuICAgIGl0KCdkb2VzIG5vdCBjYWxsIHByb2Nlc3NFeHBsaWNpdE91dHB1dHNCdWlsZCB3aGVuIF9leHBsaWNpdE91dHB1dHMgaXMgZW1wdHknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzcHkgPSBzaW5vbi5zcHkoVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZSBhcyBhbnksICdwcm9jZXNzRXhwbGljaXRPdXRwdXRzQnVpbGQnKTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuaW5wdXQoe1xuICAgICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgICB0cmFuc2FjdGlvbl9pbmRleDogMSxcbiAgICAgIH0pO1xuICAgICAgdHhCdWlsZGVyLm91dHB1dCh7XG4gICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MsXG4gICAgICAgIGFtb3VudDogJzc4MjMxMjEnLFxuICAgICAgfSk7XG4gICAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMi5hZGRyZXNzLCAnMjEwMzIwMjMnKTtcbiAgICAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgICAgIGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgc3B5LmNhbGxlZC5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgd2hlbiBleHBsaWNpdE91dHB1dCBpcyBzZXQgYnV0IHNwb25zb3JzaGlwSW5mbyBpcyBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICAgIHRyYW5zYWN0aW9uX2lkOiAnMzY3N2U3NWM3YmE2OTliZmRjNmNkNTdkNDJmMjQ2Zjg2ZjYzYWVmZDc2MDI1MDA2YWM3ODMxM2ZhZDJiYmEyMScsXG4gICAgICAgIHRyYW5zYWN0aW9uX2luZGV4OiAxLFxuICAgICAgfSk7XG4gICAgICB0eEJ1aWxkZXIuZXhwbGljaXRPdXRwdXQoe1xuICAgICAgICBhZGRyZXNzOiB0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMS5hZGRyZXNzLFxuICAgICAgICBhbW91bnQ6ICcyMDAwMDAwJyxcbiAgICAgICAgYXNzZXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgcG9saWN5X2lkOiAnZTE2YzJkYzhhZTkzN2U4ZDM3OTBjN2ZkNzE2OGQ3Yjk5NDYyMWJhMTRjYTExNDE1ZjM5ZmVkNzInLFxuICAgICAgICAgICAgYXNzZXRfbmFtZTogJzRkNDk0ZScsXG4gICAgICAgICAgICBxdWFudGl0eTogJzIwMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgICAgIGF3YWl0IHR4QnVpbGRlci5idWlsZCgpLnNob3VsZC5yZWplY3RlZFdpdGgoJ2V4cGxpY2l0IG91dHB1dHMgYnVpbGQgcmVxdWlyZXMgc3BvbnNvcnNoaXBJbmZvIHRvIGJlIHNldCcpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBOT1RFOiBUaGUgdGVzdHMgYmVsb3cgaGF2ZSBiZWVuIGNvbW1lbnRlZCBvdXQgYXMgdGhleSBhcmUgZm9yIHRlc3RpbmcgZHVyaW5nIGRldmVsb3BtZW50IGNoYW5nZXMuIFdlIGRvbid0XG4gIC8vIHdhbnQgZnVsbCBub2RlIHRlc3RzIGFzIHBhcnQgb2Ygb3VyIHNkayB1bml0IHRlc3RzLiBJZiB5b3UgYXJlIGNvbW1lbnRpbmcgdGhlc2UgYmFjayBpbiwgYWRkIGF4aW9zIGFuZFxuICAvLyBBZGRyZXNzRm9ybWF0IGltcG9ydHMuXG5cbiAgLy8geGl0KCdzaG91bGQgc3VibWl0IGEgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gIC8vICAgY29uc3Qga2V5UGFpciA9IG5ldyBLZXlQYWlyKHsgcHJ2OiB0ZXN0RGF0YS5wcml2YXRlS2V5cy5wcnZLZXk0IH0pO1xuICAvLyAgIGNvbnN0IHNlbmRlckFkZHJlc3MgPSBrZXlQYWlyLmdldEFkZHJlc3MoQWRkcmVzc0Zvcm1hdC50ZXN0bmV0KTtcbiAgLy9cbiAgLy8gICBjb25zdCBheGlvc0NvbmZpZyA9IHtcbiAgLy8gICAgIGhlYWRlcnM6IHtcbiAgLy8gICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9jYm9yJyxcbiAgLy8gICAgIH0sXG4gIC8vICAgICB0aW1lb3V0OiAxMDAwMCxcbiAgLy8gICB9O1xuICAvL1xuICAvLyAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gIC8vICAgY29uc3QgdXR4b0RhdGEgPSBhd2FpdCBheGlvcy5nZXQoJ2h0dHBzOi8vdGVzdG5ldC5rb2lvcy5yZXN0L2FwaS92MC9hZGRyZXNzX2luZm8/X2FkZHJlc3M9JyArIHNlbmRlckFkZHJlc3MpO1xuICAvLyAgIGNvbnN0IHNlbmRlckJhbGFuY2UgPSB1dHhvRGF0YS5kYXRhWzBdLmJhbGFuY2U7XG4gIC8vICAgdHhCdWlsZGVyLmNoYW5nZUFkZHJlc3Moc2VuZGVyQWRkcmVzcywgc2VuZGVyQmFsYW5jZSk7XG4gIC8vICAgY29uc3QgdXR4b1NldCA9IHV0eG9EYXRhLmRhdGFbMF0udXR4b19zZXQ7XG4gIC8vICAgZm9yIChjb25zdCB1dHhvIG9mIHV0eG9TZXQpIHtcbiAgLy8gICAgIHR4QnVpbGRlci5pbnB1dCh7IHRyYW5zYWN0aW9uX2lkOiB1dHhvLnR4X2hhc2gsIHRyYW5zYWN0aW9uX2luZGV4OiB1dHhvLnR4X2luZGV4IH0pO1xuICAvLyAgIH1cbiAgLy9cbiAgLy8gICB0eEJ1aWxkZXIub3V0cHV0KHtcbiAgLy8gICAgIGFkZHJlc3M6XG4gIC8vICAgICAgICdhZGRyX3Rlc3QxcXoyZnh2MnVteWh0dGt4eXhwOHgwZGxwZHQzazZjd25nNXB4ajNqaHN5ZHplcjNqY3U1ZDhwczd6ZXgyazJ4dDN1cXhnanFubmo4M3dzOGxocm42NDhqanh0d3EyeXRqcXAnLFxuICAvLyAgICAgYW1vdW50OiAnNTAwMDAwMCcsXG4gIC8vICAgfSk7XG4gIC8vXG4gIC8vICAgdHhCdWlsZGVyLnR0bCg4MDAwMDAwMDApO1xuICAvLyAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBrZXlQYWlyLmdldEtleXMoKS5wcnYgfSk7XG4gIC8vXG4gIC8vICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgLy8gICBjb25zdCBzZXJpYWxpemVkVHggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAvLyAgIGNvbnN0IGJ5dGVzID0gVWludDhBcnJheS5mcm9tKEJ1ZmZlci5mcm9tKHNlcmlhbGl6ZWRUeCwgJ2hleCcpKTtcbiAgLy9cbiAgLy8gICB0cnkge1xuICAvLyAgICAgY29uc3QgcmVzID0gYXdhaXQgYXhpb3MucG9zdCgnaHR0cHM6Ly90ZXN0bmV0LmtvaW9zLnJlc3QvYXBpL3YwL3N1Ym1pdHR4JywgYnl0ZXMsIGF4aW9zQ29uZmlnKTtcbiAgLy8gICAgIGNvbnNvbGUubG9nKHJlcy5kYXRhKTtcbiAgLy8gICB9IGNhdGNoIChlcnIpIHtcbiAgLy8gICAgIGNvbnNvbGUubG9nKGVycik7XG4gIC8vICAgfVxuICAvLyB9KTtcbiAgLy9cbiAgLy8geGl0KCdzaG91bGQgc3VibWl0IGEgdHJhbnNhY3Rpb24gdXNpbmcgc2lnbmF0dXJlIGludGVyZmFjZScsIGFzeW5jICgpID0+IHtcbiAgLy8gICBjb25zdCBrZXlQYWlyID0gbmV3IEtleVBhaXIoeyBwcnY6IHRlc3REYXRhLnByaXZhdGVLZXlzLnBydktleTQgfSk7XG4gIC8vICAgY29uc3Qgc2VuZGVyQWRkcmVzcyA9IGtleVBhaXIuZ2V0QWRkcmVzcyhBZGRyZXNzRm9ybWF0LnRlc3RuZXQpO1xuICAvLyAgIGNvbnN0IGF4aW9zQ29uZmlnID0ge1xuICAvLyAgICAgaGVhZGVyczoge1xuICAvLyAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2Nib3InLFxuICAvLyAgICAgfSxcbiAgLy8gICAgIHRpbWVvdXQ6IDEwMDAwLFxuICAvLyAgIH07XG4gIC8vICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgLy8gICBjb25zdCB1dHhvRGF0YSA9IGF3YWl0IGF3YWl0IGF4aW9zLmdldCgnaHR0cHM6Ly90ZXN0bmV0LmtvaW9zLnJlc3QvYXBpL3YwL2FkZHJlc3NfaW5mbz9fYWRkcmVzcz0nICsgc2VuZGVyQWRkcmVzcyk7XG4gIC8vICAgY29uc3Qgc2VuZGVyQmFsYW5jZSA9IHV0eG9EYXRhLmRhdGFbMF0uYmFsYW5jZTtcbiAgLy8gICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyhzZW5kZXJBZGRyZXNzLCBzZW5kZXJCYWxhbmNlKTtcbiAgLy8gICBjb25zdCB1dHhvU2V0ID0gdXR4b0RhdGEuZGF0YVswXS51dHhvX3NldDtcbiAgLy8gICBmb3IgKGNvbnN0IHV0eG8gb2YgdXR4b1NldCkge1xuICAvLyAgICAgdHhCdWlsZGVyLmlucHV0KHsgdHJhbnNhY3Rpb25faWQ6IHV0eG8udHhfaGFzaCwgdHJhbnNhY3Rpb25faW5kZXg6IHV0eG8udHhfaW5kZXggfSk7XG4gIC8vICAgfVxuICAvLyAgIHR4QnVpbGRlci5vdXRwdXQoe1xuICAvLyAgICAgYWRkcmVzczpcbiAgLy8gICAgICAgJ2FkZHJfdGVzdDFxejJmeHYydW15aHR0a3h5eHA4eDBkbHBkdDNrNmN3bmc1cHhqM2poc3lkemVyM2pjdTVkOHBzN3pleDJrMnh0M3VxeGdqcW5uajgzd3M4bGhybjY0OGpqeHR3cTJ5dGpxcCcsXG4gIC8vICAgICBhbW91bnQ6ICc1MDAwMDAwJyxcbiAgLy8gICB9KTtcbiAgLy9cbiAgLy8gICB0eEJ1aWxkZXIudHRsKDgwMDAwMDAwMCk7XG4gIC8vXG4gIC8vICAgY29uc3QgdW5zaWduZWRUeCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAvLyAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IHVuc2lnbmVkVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgLy9cbiAgLy8gICBjb25zdCB0eEJ1aWxkZXIyID0gZmFjdG9yeS5mcm9tKHNlcmlhbGl6ZWRUeCk7XG4gIC8vICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIyLmJ1aWxkKCk7XG4gIC8vICAgY29uc3Qgc2lnbmFibGVIZXggPSB0eC5zaWduYWJsZVBheWxvYWQudG9TdHJpbmcoJ2hleCcpO1xuICAvLyAgIGNvbnN0IHNpZ25hdHVyZSA9IGtleVBhaXIuc2lnbk1lc3NhZ2Uoc2lnbmFibGVIZXgpO1xuICAvLyAgIHR4QnVpbGRlcjIuYWRkU2lnbmF0dXJlKHsgcHViOiBrZXlQYWlyLmdldEtleXMoKS5wdWIgfSwgQnVmZmVyLmZyb20oc2lnbmF0dXJlKSk7XG4gIC8vICAgY29uc3Qgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCB0eEJ1aWxkZXIyLmJ1aWxkKCk7XG4gIC8vICAgY29uc3Qgc2VyaWFsaXplZFRyYW5zYWN0aW9uID0gc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgLy8gICBjb25zdCBieXRlcyA9IFVpbnQ4QXJyYXkuZnJvbShCdWZmZXIuZnJvbShzZXJpYWxpemVkVHJhbnNhY3Rpb24sICdoZXgnKSk7XG4gIC8vXG4gIC8vICAgdHJ5IHtcbiAgLy8gICAgIGNvbnN0IHJlcyA9IGF3YWl0IGF4aW9zLnBvc3QoJ2h0dHBzOi8vdGVzdG5ldC5rb2lvcy5yZXN0L2FwaS92MC9zdWJtaXR0eCcsIGJ5dGVzLCBheGlvc0NvbmZpZyk7XG4gIC8vICAgICBjb25zb2xlLmxvZyhyZXMuZGF0YSk7XG4gIC8vICAgfSBjYXRjaCAoZXJyKSB7XG4gIC8vICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAvLyAgIH1cbiAgLy8gfSk7XG59KTtcbiJdfQ==
|