@bitgo/utxo-bin 2.3.3 → 2.4.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/parse.js DELETED
@@ -1,270 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Parser = void 0;
4
- const utxolib = require("@bitgo/utxo-lib");
5
- function formatSat(v) {
6
- return (v / 1e8).toFixed(8);
7
- }
8
- function formatConsensusBranchId(branchId) {
9
- var _a;
10
- const map = {
11
- OVERWINTER_BRANCH_ID: 0x5ba81b19,
12
- CANOPY_BRANCH_ID: 0xe9ff75a6,
13
- NU5_BRANCH_ID: 0xc2d6d0b4,
14
- };
15
- return (_a = Object.keys(map).find((k) => map[k] === branchId)) !== null && _a !== void 0 ? _a : 'unknown';
16
- }
17
- function toBufferUInt32BE(n) {
18
- const buf = Buffer.alloc(4);
19
- buf.writeUInt32LE(n, 0);
20
- return buf;
21
- }
22
- function isPrintable(s) {
23
- // https://stackoverflow.com/a/66447494
24
- return !s.match(/[\p{Cc}\p{Cn}\p{Cs}]+/gu);
25
- }
26
- class Parser {
27
- constructor(params) {
28
- this.params = params;
29
- }
30
- node(label, value, nodes = []) {
31
- return {
32
- type: 'node',
33
- label: String(label),
34
- value,
35
- nodes,
36
- };
37
- }
38
- parseScriptAsm(type, part, i, n) {
39
- if ((type === 'taproot' && i === n - 2) ||
40
- ((type === 'scripthash' || type === 'witnessscripthash') && i === n - 1)) {
41
- let parsed;
42
- try {
43
- parsed = utxolib.script.toASM(part);
44
- }
45
- catch (e) {
46
- return 'error';
47
- }
48
- if (parsed) {
49
- return ['', ...parsed.split(' ')].join('\n');
50
- }
51
- }
52
- }
53
- parseScriptParts(type, parts) {
54
- return parts.map((v, i) => {
55
- let asmNode;
56
- if (this.params.parseScriptAsm && Buffer.isBuffer(v)) {
57
- const parsed = this.parseScriptAsm(type, v, i, parts.length);
58
- asmNode = parsed ? this.node('asm', parsed) : undefined;
59
- }
60
- return this.node(i, this.params.parseScriptData ? v : undefined, asmNode ? [asmNode] : undefined);
61
- });
62
- }
63
- parseInputScript(buffer) {
64
- var _a;
65
- let value;
66
- let nodes;
67
- if (buffer.length && this.params.parseSignatureData) {
68
- const type = (_a = utxolib.classify.input(buffer, true)) !== null && _a !== void 0 ? _a : 'unknown';
69
- const decompiled = utxolib.script.decompile(buffer);
70
- if (decompiled) {
71
- nodes = this.parseScriptParts(type, decompiled);
72
- }
73
- value = type;
74
- }
75
- else {
76
- value = buffer;
77
- }
78
- return this.node('scriptSig', value, nodes);
79
- }
80
- parseWitness(script) {
81
- var _a;
82
- if (script.length === 0) {
83
- return this.node('witness', '[]');
84
- }
85
- const type = (_a = utxolib.classify.witness(script, true)) !== null && _a !== void 0 ? _a : 'unknown';
86
- return this.node('witness', type, this.params.parseScriptData ? this.parseScriptParts(type, script) : undefined);
87
- }
88
- parsePubkeys(parsed) {
89
- return this.node('pubkeys', parsed.publicKeys.length, parsed.publicKeys.map((k, i) => this.node(i, k)));
90
- }
91
- parseSignatures(parsed, tx, inputIndex, prevOutputs) {
92
- const nodes = [];
93
- if (prevOutputs) {
94
- const signedBy = utxolib.bitgo.verifySignatureWithPublicKeys(tx, inputIndex, prevOutputs, parsed.publicKeys);
95
- nodes.push(this.node('signed by', `[${signedBy.flatMap((v, i) => (v ? [i] : [])).join(', ')}]`));
96
- }
97
- return this.node('signatures', parsed.signatures
98
- .map((s) => utxolib.bitgo.isPlaceholderSignature(s) ? '[]' : Buffer.isBuffer(s) ? `[${s.length}byte]` : `[${s}]`)
99
- .join(' '), nodes);
100
- }
101
- parseSigScript(tx, inputIndex, prevOutputs) {
102
- var _a;
103
- try {
104
- const parsed = utxolib.bitgo.parseSignatureScript(tx.ins[inputIndex]);
105
- return this.node('sigScript', (_a = parsed.scriptType) !== null && _a !== void 0 ? _a : 'unknown', parsed.scriptType && utxolib.bitgo.outputScripts.isScriptType2Of3(parsed.scriptType)
106
- ? [
107
- this.parsePubkeys(parsed),
108
- this.parseSignatures(parsed, tx, inputIndex, prevOutputs),
109
- ]
110
- : []);
111
- }
112
- catch (e) {
113
- return this.node('error', String(e));
114
- }
115
- }
116
- parsePrevOut(input, i, network, prevOutputs) {
117
- if (!prevOutputs || !prevOutputs[i]) {
118
- return [];
119
- }
120
- const { script, value } = prevOutputs[i];
121
- let address;
122
- try {
123
- address = utxolib.address.fromOutputScript(script, network);
124
- }
125
- catch (e) {
126
- address = '(error)';
127
- }
128
- return [
129
- this.node('value', value / 1e8),
130
- this.node('pubScript', script, address ? [this.node('address', address)] : undefined),
131
- ];
132
- }
133
- parseSpend(txid, index, spends, params) {
134
- if (!spends || !spends[index]) {
135
- // no spend data available
136
- return [];
137
- }
138
- const spend = spends[index];
139
- if (spend.txid === undefined) {
140
- return [this.node('spent', false)];
141
- }
142
- if (spend.txid === txid) {
143
- // if input is spent by this transaction we don't display it
144
- return [];
145
- }
146
- return [this.node('spent', `${spend.txid}:${spend.vin}`, params.conflict ? [this.node('conflict', true)] : [])];
147
- }
148
- parseIns(ins, tx, outputInfo) {
149
- const txid = tx.getId();
150
- return ins.map((input, i) => {
151
- return this.node(i, utxolib.bitgo.formatOutputId(utxolib.bitgo.getOutputIdForInput(input)), [
152
- this.node('sequence', toBufferUInt32BE(input.sequence)),
153
- this.parseInputScript(input.script),
154
- this.parseWitness(input.witness),
155
- this.parseSigScript(tx, i, outputInfo.prevOutputs),
156
- ...this.parsePrevOut(input, i, tx.network, outputInfo.prevOutputs),
157
- ...this.parseSpend(txid, i, outputInfo.prevOutputSpends, { conflict: true }),
158
- ]);
159
- });
160
- }
161
- tryParseOpReturn(script) {
162
- let data;
163
- try {
164
- ({ data } = utxolib.payments.embed({ output: script }));
165
- }
166
- catch (e) {
167
- // ignore
168
- }
169
- if (!data) {
170
- return [];
171
- }
172
- return data.map((buf, i) => {
173
- let utf8;
174
- try {
175
- utf8 = buf.toString('utf8');
176
- }
177
- catch (e) {
178
- // ignore
179
- }
180
- return this.node(`OP_RETURN ${i}`, `${buf.length} bytes`, [
181
- this.node('hex', buf),
182
- ...(utf8 && isPrintable(utf8) ? [this.node('utf8', utf8)] : []),
183
- ]);
184
- });
185
- }
186
- parseOutputScript(buffer) {
187
- return [
188
- this.node('scriptPubKey', `${buffer.length} bytes`, [
189
- this.node('hex', buffer.toString('hex')),
190
- this.node('asm', utxolib.script.toASM(buffer), this.tryParseOpReturn(buffer)),
191
- ]),
192
- ];
193
- }
194
- parseOutput(txid, o, i, network, params) {
195
- const type = utxolib.classify.output(o.script);
196
- let address;
197
- try {
198
- address = utxolib.address.fromOutputScript(o.script, network);
199
- }
200
- catch (e) { }
201
- return this.node(i, address !== null && address !== void 0 ? address : '(no address)', [
202
- this.node(`value`, formatSat(o.value)),
203
- this.node(`type`, type),
204
- ...(this.params.parseOutputScript || address === undefined ? this.parseOutputScript(o.script) : []),
205
- ...this.parseSpend(txid, i, params.outputSpends, { conflict: false }),
206
- ]);
207
- }
208
- parseOuts(outs, tx, params) {
209
- var _a;
210
- if (outs.length > ((_a = this.params.maxOutputs) !== null && _a !== void 0 ? _a : 200)) {
211
- return [this.node('(omitted)', undefined)];
212
- }
213
- const txid = tx.getId();
214
- return outs.map((o, i) => this.parseOutput(txid, o, i, tx.network, params));
215
- }
216
- parseStatus(tx, status) {
217
- if (!status) {
218
- return [this.node('status', 'unknown')];
219
- }
220
- return [
221
- this.node('status', status.found ? 'found' : 'not found', status.found
222
- ? status.confirmed
223
- ? [
224
- this.node('confirmed', `block ${status.blockHeight}` + (status.date ? ` date=${status.date.toISOString()}` : '')),
225
- ]
226
- : [this.node('confirmed', false)]
227
- : []),
228
- ];
229
- }
230
- parseVersion(tx) {
231
- return this.node('version', tx.version, tx instanceof utxolib.bitgo.ZcashTransaction
232
- ? [
233
- this.node('consensusBranchId (inferred)', tx.consensusBranchId.toString(16), [
234
- this.node('name', formatConsensusBranchId(tx.consensusBranchId)),
235
- ]),
236
- ]
237
- : []);
238
- }
239
- parse(tx, chainInfo = {}) {
240
- var _a;
241
- const weight = tx.weight();
242
- const vsize = tx.virtualSize();
243
- const outputSum = tx.outs.reduce((sum, o) => sum + o.value, 0);
244
- const inputSum = (_a = chainInfo.prevOutputs) === null || _a === void 0 ? void 0 : _a.reduce((sum, o) => sum + o.value, 0);
245
- const fee = inputSum ? inputSum - outputSum : undefined;
246
- const feeRate = fee ? fee / vsize : undefined;
247
- return this.node('transaction', tx.getId(), [
248
- this.node('parsedAs', `${utxolib.getNetworkName(utxolib.getMainnet(tx.network))} ` +
249
- `${utxolib.isMainnet(tx.network) ? 'mainnet' : 'testnet'}`),
250
- this.parseVersion(tx),
251
- this.node('locktime', tx.locktime),
252
- this.node('hasWitnesses', tx.hasWitnesses()),
253
- ...this.parseStatus(tx, chainInfo.status),
254
- this.node('vsize', `${vsize}vbytes (${weight}wu)`),
255
- ...(fee && feeRate
256
- ? [this.node('fee [btc]', formatSat(fee)), this.node('feeRate [sat/vbyte]', feeRate.toFixed(2))]
257
- : []),
258
- this.node(`inputs`, [String(tx.ins.length)].concat(inputSum ? ['sum=' + formatSat(inputSum)] : []).join(' '), this.parseIns(tx.ins, tx, chainInfo)),
259
- this.node(`outputs`, [String(tx.outs.length), 'sum=' + formatSat(outputSum)].join(' '), this.parseOuts(tx.outs, tx, chainInfo)),
260
- ]);
261
- }
262
- }
263
- exports.Parser = Parser;
264
- Parser.PARSE_ALL = {
265
- parseScriptData: true,
266
- parseScriptAsm: true,
267
- parseSignatureData: true,
268
- parseOutputScript: true,
269
- };
270
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFyc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQTJDO0FBTzNDLFNBQVMsU0FBUyxDQUFDLENBQVM7SUFDMUIsT0FBTyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUIsQ0FBQztBQUVELFNBQVMsdUJBQXVCLENBQUMsUUFBZ0I7O0lBQy9DLE1BQU0sR0FBRyxHQUEyQjtRQUNsQyxvQkFBb0IsRUFBRSxVQUFVO1FBQ2hDLGdCQUFnQixFQUFFLFVBQVU7UUFDNUIsYUFBYSxFQUFFLFVBQVU7S0FDMUIsQ0FBQztJQUNGLE9BQU8sTUFBQSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxtQ0FBSSxTQUFTLENBQUM7QUFDeEUsQ0FBQztBQXlCRCxTQUFTLGdCQUFnQixDQUFDLENBQVM7SUFDakMsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM1QixHQUFHLENBQUMsYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN4QixPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxDQUFTO0lBQzVCLHVDQUF1QztJQUN2QyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0FBQzdDLENBQUM7QUFFRCxNQUFhLE1BQU07SUFRakIsWUFBb0IsTUFBa0I7UUFBbEIsV0FBTSxHQUFOLE1BQU0sQ0FBWTtJQUFHLENBQUM7SUFFMUMsSUFBSSxDQUFDLEtBQXNCLEVBQUUsS0FBa0IsRUFBRSxRQUFrQixFQUFFO1FBQ25FLE9BQU87WUFDTCxJ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IjpbImltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCB7IE91dHB1dFNwZW5kLCBUcmFuc2FjdGlvblN0YXR1cyB9IGZyb20gJ0BiaXRnby9ibG9ja2FwaXMnO1xuXG5leHBvcnQgdHlwZSBJbnB1dEZvcm1hdCA9ICdhc20nIHwgJ3BhcnNlU2lnbmF0dXJlJztcblxuZXhwb3J0IHR5cGUgVHhOb2RlVmFsdWUgPSBudW1iZXIgfCBzdHJpbmcgfCBCdWZmZXIgfCBib29sZWFuIHwgdW5kZWZpbmVkIHwgbnVsbDtcblxuZnVuY3Rpb24gZm9ybWF0U2F0KHY6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiAodiAvIDFlOCkudG9GaXhlZCg4KTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0Q29uc2Vuc3VzQnJhbmNoSWQoYnJhbmNoSWQ6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IG1hcDogUmVjb3JkPHN0cmluZywgbnVtYmVyPiA9IHtcbiAgICBPVkVSV0lOVEVSX0JSQU5DSF9JRDogMHg1YmE4MWIxOSxcbiAgICBDQU5PUFlfQlJBTkNIX0lEOiAweGU5ZmY3NWE2LFxuICAgIE5VNV9CUkFOQ0hfSUQ6IDB4YzJkNmQwYjQsXG4gIH07XG4gIHJldHVybiBPYmplY3Qua2V5cyhtYXApLmZpbmQoKGspID0+IG1hcFtrXSA9PT0gYnJhbmNoSWQpID8/ICd1bmtub3duJztcbn1cblxuZXhwb3J0IHR5cGUgVHhOb2RlID0ge1xuICB0eXBlOiAnbm9kZSc7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHZhbHVlOiBUeE5vZGVWYWx1ZSB8IHVuZGVmaW5lZDtcbiAgbm9kZXM6IFR4Tm9kZVtdIHwgdW5kZWZpbmVkO1xufTtcblxuZXhwb3J0IHR5cGUgUGFyc2VyQXJncyA9IHtcbiAgcGFyc2VTY3JpcHREYXRhOiBib29sZWFuO1xuICBwYXJzZVNjcmlwdEFzbTogYm9vbGVhbjtcbiAgcGFyc2VPdXRwdXRTY3JpcHQ6IGJvb2xlYW47XG4gIHBhcnNlU2lnbmF0dXJlRGF0YTogYm9vbGVhbjtcbiAgaGlkZT86IHN0cmluZ1tdO1xuICBtYXhPdXRwdXRzPzogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgQ2hhaW5JbmZvID0ge1xuICBzdGF0dXM/OiBUcmFuc2FjdGlvblN0YXR1cztcbiAgb3V0cHV0U3BlbmRzPzogT3V0cHV0U3BlbmRbXTtcbiAgcHJldk91dHB1dHM/OiB1dHhvbGliLlR4T3V0cHV0W107XG4gIHByZXZPdXRwdXRTcGVuZHM/OiBPdXRwdXRTcGVuZFtdO1xufTtcblxuZnVuY3Rpb24gdG9CdWZmZXJVSW50MzJCRShuOiBudW1iZXIpOiBCdWZmZXIge1xuICBjb25zdCBidWYgPSBCdWZmZXIuYWxsb2MoNCk7XG4gIGJ1Zi53cml0ZVVJbnQzMkxFKG4sIDApO1xuICByZXR1cm4gYnVmO1xufVxuXG5mdW5jdGlvbiBpc1ByaW50YWJsZShzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzY2NDQ3NDk0XG4gIHJldHVybiAhcy5tYXRjaCgvW1xccHtDY31cXHB7Q259XFxwe0NzfV0rL2d1KTtcbn1cblxuZXhwb3J0IGNsYXNzIFBhcnNlciB7XG4gIHN0YXRpYyBQQVJTRV9BTEw6IFBhcnNlckFyZ3MgPSB7XG4gICAgcGFyc2VTY3JpcHREYXRhOiB0cnVlLFxuICAgIHBhcnNlU2NyaXB0QXNtOiB0cnVlLFxuICAgIHBhcnNlU2lnbmF0dXJlRGF0YTogdHJ1ZSxcbiAgICBwYXJzZU91dHB1dFNjcmlwdDogdHJ1ZSxcbiAgfTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHBhcmFtczogUGFyc2VyQXJncykge31cblxuICBub2RlKGxhYmVsOiBzdHJpbmcgfCBudW1iZXIsIHZhbHVlOiBUeE5vZGVWYWx1ZSwgbm9kZXM6IFR4Tm9kZVtdID0gW10pOiBUeE5vZGUge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnbm9kZScsXG4gICAgICBsYWJlbDogU3RyaW5nKGxhYmVsKSxcbiAgICAgIHZhbHVlLFxuICAgICAgbm9kZXMsXG4gICAgfTtcbiAgfVxuXG4gIHBhcnNlU2NyaXB0QXNtKHR5cGU6IHN0cmluZywgcGFydDogQnVmZmVyLCBpOiBudW1iZXIsIG46IG51bWJlcik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKFxuICAgICAgKHR5cGUgPT09ICd0YXByb290JyAmJiBpID09PSBuIC0gMikgfHxcbiAgICAgICgodHlwZSA9PT0gJ3NjcmlwdGhhc2gnIHx8IHR5cGUgPT09ICd3aXRuZXNzc2NyaXB0aGFzaCcpICYmIGkgPT09IG4gLSAxKVxuICAgICkge1xuICAgICAgbGV0IHBhcnNlZDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcGFyc2VkID0gdXR4b2xpYi5zY3JpcHQudG9BU00ocGFydCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiAnZXJyb3InO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFyc2VkKSB7XG4gICAgICAgIHJldHVybiBbJycsIC4uLnBhcnNlZC5zcGxpdCgnICcpXS5qb2luKCdcXG4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwYXJzZVNjcmlwdFBhcnRzKHR5cGU6IHN0cmluZywgcGFydHM6IEFycmF5PEJ1ZmZlciB8IG51bWJlcj4pOiBUeE5vZGVbXSB7XG4gICAgcmV0dXJuIHBhcnRzLm1hcCgodiwgaSkgPT4ge1xuICAgICAgbGV0IGFzbU5vZGU6IFR4Tm9kZSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmICh0aGlzLnBhcmFtcy5wYXJzZVNjcmlwdEFzbSAmJiBCdWZmZXIuaXNCdWZmZXIodikpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5wYXJzZVNjcmlwdEFzbSh0eXBlLCB2LCBpLCBwYXJ0cy5sZW5ndGgpO1xuICAgICAgICBhc21Ob2RlID0gcGFyc2VkID8gdGhpcy5ub2RlKCdhc20nLCBwYXJzZWQpIDogdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5ub2RlKGksIHRoaXMucGFyYW1zLnBhcnNlU2NyaXB0RGF0YSA/IHYgOiB1bmRlZmluZWQsIGFzbU5vZGUgPyBbYXNtTm9kZV0gOiB1bmRlZmluZWQpO1xuICAgIH0pO1xuICB9XG5cbiAgcGFyc2VJbnB1dFNjcmlwdChidWZmZXI6IEJ1ZmZlcik6IFR4Tm9kZSB7XG4gICAgbGV0IHZhbHVlO1xuICAgIGxldCBub2RlcztcbiAgICBpZiAoYnVmZmVyLmxlbmd0aCAmJiB0aGlzLnBhcmFtcy5wYXJzZVNpZ25hdHVyZURhdGEpIHtcbiAgICAgIGNvbnN0IHR5cGUgPSB1dHhvbGliLmNsYXNzaWZ5LmlucHV0KGJ1ZmZlciwgdHJ1ZSkgPz8gJ3Vua25vd24nO1xuICAgICAgY29uc3QgZGVjb21waWxlZCA9IHV0eG9saWIuc2NyaXB0LmRlY29tcGlsZShidWZmZXIpO1xuICAgICAgaWYgKGRlY29tcGlsZWQpIHtcbiAgICAgICAgbm9kZXMgPSB0aGlzLnBhcnNlU2NyaXB0UGFydHModHlwZSwgZGVjb21waWxlZCk7XG4gICAgICB9XG4gICAgICB2YWx1ZSA9IHR5cGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlID0gYnVmZmVyO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm5vZGUoJ3NjcmlwdFNpZycsIHZhbHVlLCBub2Rlcyk7XG4gIH1cblxuICBwYXJzZVdpdG5lc3Moc2NyaXB0OiBCdWZmZXJbXSk6IFR4Tm9kZSB7XG4gICAgaWYgKHNjcmlwdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0aGlzLm5vZGUoJ3dpdG5lc3MnLCAnW10nKTtcbiAgICB9XG4gICAgY29uc3QgdHlwZSA9IHV0eG9saWIuY2xhc3NpZnkud2l0bmVzcyhzY3JpcHQsIHRydWUpID8/ICd1bmtub3duJztcbiAgICByZXR1cm4gdGhpcy5ub2RlKCd3aXRuZXNzJywgdHlwZSwgdGhpcy5wYXJhbXMucGFyc2VTY3JpcHREYXRhID8gdGhpcy5wYXJzZVNjcmlwdFBhcnRzKHR5cGUsIHNjcmlwdCkgOiB1bmRlZmluZWQpO1xuICB9XG5cbiAgcGFyc2VQdWJrZXlzKHBhcnNlZDogdXR4b2xpYi5iaXRnby5QYXJzZWRTaWduYXR1cmVTY3JpcHQyT2YzKTogVHhOb2RlIHtcbiAgICByZXR1cm4gdGhpcy5ub2RlKFxuICAgICAgJ3B1YmtleXMnLFxuICAgICAgcGFyc2VkLnB1YmxpY0tleXMubGVuZ3RoLFxuICAgICAgcGFyc2VkLnB1YmxpY0tleXMubWFwKChrLCBpKSA9PiB0aGlzLm5vZGUoaSwgaykpXG4gICAgKTtcbiAgfVxuXG4gIHBhcnNlU2lnbmF0dXJlcyhcbiAgICBwYXJzZWQ6IHV0eG9saWIuYml0Z28uUGFyc2VkU2lnbmF0dXJlU2NyaXB0Mk9mMyxcbiAgICB0eDogdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb24sXG4gICAgaW5wdXRJbmRleDogbnVtYmVyLFxuICAgIHByZXZPdXRwdXRzPzogdXR4b2xpYi5UeE91dHB1dFtdXG4gICk6IFR4Tm9kZSB7XG4gICAgY29uc3Qgbm9kZXMgPSBbXTtcbiAgICBpZiAocHJldk91dHB1dHMpIHtcbiAgICAgIGNvbnN0IHNpZ25lZEJ5ID0gdXR4b2xpYi5iaXRnby52ZXJpZnlTaWduYXR1cmVXaXRoUHVibGljS2V5cyh0eCwgaW5wdXRJbmRleCwgcHJldk91dHB1dHMsIHBhcnNlZC5wdWJsaWNLZXlzKTtcbiAgICAgIG5vZGVzLnB1c2godGhpcy5ub2RlKCdzaWduZWQgYnknLCBgWyR7c2lnbmVkQnkuZmxhdE1hcCgodiwgaSkgPT4gKHYgPyBbaV0gOiBbXSkpLmpvaW4oJywgJyl9XWApKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubm9kZShcbiAgICAgICdzaWduYXR1cmVzJyxcbiAgICAgIHBhcnNlZC5zaWduYXR1cmVzXG4gICAgICAgIC5tYXAoKHM6IEJ1ZmZlciB8IDApID0+XG4gICAgICAgICAgdXR4b2xpYi5iaXRnby5pc1BsYWNlaG9sZGVyU2lnbmF0dXJlKHMpID8gJ1tdJyA6IEJ1ZmZlci5pc0J1ZmZlcihzKSA/IGBbJHtzLmxlbmd0aH1ieXRlXWAgOiBgWyR7c31dYFxuICAgICAgICApXG4gICAgICAgIC5qb2luKCcgJyksXG4gICAgICBub2Rlc1xuICAgICk7XG4gIH1cblxuICBwYXJzZVNpZ1NjcmlwdCh0eDogdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb24sIGlucHV0SW5kZXg6IG51bWJlciwgcHJldk91dHB1dHM/OiB1dHhvbGliLlR4T3V0cHV0W10pOiBUeE5vZGUge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYXJzZWQgPSB1dHhvbGliLmJpdGdvLnBhcnNlU2lnbmF0dXJlU2NyaXB0KHR4Lmluc1tpbnB1dEluZGV4XSk7XG4gICAgICByZXR1cm4gdGhpcy5ub2RlKFxuICAgICAgICAnc2lnU2NyaXB0JyxcbiAgICAgICAgcGFyc2VkLnNjcmlwdFR5cGUgPz8gJ3Vua25vd24nLFxuICAgICAgICBwYXJzZWQuc2NyaXB0VHlwZSAmJiB1dHhvbGliLmJpdGdvLm91dHB1dFNjcmlwdHMuaXNTY3JpcHRUeXBlMk9mMyhwYXJzZWQuc2NyaXB0VHlwZSlcbiAgICAgICAgICA/IFtcbiAgICAgICAgICAgICAgdGhpcy5wYXJzZVB1YmtleXMocGFyc2VkIGFzIHV0eG9saWIuYml0Z28uUGFyc2VkU2lnbmF0dXJlU2NyaXB0Mk9mMyksXG4gICAgICAgICAgICAgIHRoaXMucGFyc2VTaWduYXR1cmVzKHBhcnNlZCBhcyB1dHhvbGliLmJpdGdvLlBhcnNlZFNpZ25hdHVyZVNjcmlwdDJPZjMsIHR4LCBpbnB1dEluZGV4LCBwcmV2T3V0cHV0cyksXG4gICAgICAgICAgICBdXG4gICAgICAgICAgOiBbXVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gdGhpcy5ub2RlKCdlcnJvcicsIFN0cmluZyhlKSk7XG4gICAgfVxuICB9XG5cbiAgcGFyc2VQcmV2T3V0KFxuICAgIGlucHV0OiB1dHhvbGliLlR4SW5wdXQsXG4gICAgaTogbnVtYmVyLFxuICAgIG5ldHdvcms6IHV0eG9saWIuTmV0d29yayxcbiAgICBwcmV2T3V0cHV0cz86IHV0eG9saWIuVHhPdXRwdXRbXVxuICApOiBUeE5vZGVbXSB7XG4gICAgaWYgKCFwcmV2T3V0cHV0cyB8fCAhcHJldk91dHB1dHNbaV0pIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgY29uc3QgeyBzY3JpcHQsIHZhbHVlIH0gPSBwcmV2T3V0cHV0c1tpXTtcbiAgICBsZXQgYWRkcmVzcztcbiAgICB0cnkge1xuICAgICAgYWRkcmVzcyA9IHV0eG9saWIuYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KHNjcmlwdCwgbmV0d29yayk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgYWRkcmVzcyA9ICcoZXJyb3IpJztcbiAgICB9XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMubm9kZSgndmFsdWUnLCB2YWx1ZSAvIDFlOCksXG4gICAgICB0aGlzLm5vZGUoJ3B1YlNjcmlwdCcsIHNjcmlwdCwgYWRkcmVzcyA/IFt0aGlzLm5vZGUoJ2FkZHJlc3MnLCBhZGRyZXNzKV0gOiB1bmRlZmluZWQpLFxuICAgIF07XG4gIH1cblxuICBwYXJzZVNwZW5kKHR4aWQ6IHN0cmluZywgaW5kZXg6IG51bWJlciwgc3BlbmRzOiBPdXRwdXRTcGVuZFtdIHwgdW5kZWZpbmVkLCBwYXJhbXM6IHsgY29uZmxpY3Q6IGJvb2xlYW4gfSk6IFR4Tm9kZVtdIHtcbiAgICBpZiAoIXNwZW5kcyB8fCAhc3BlbmRzW2luZGV4XSkge1xuICAgICAgLy8gbm8gc3BlbmQgZGF0YSBhdmFpbGFibGVcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgY29uc3Qgc3BlbmQgPSBzcGVuZHNbaW5kZXhdO1xuICAgIGlmIChzcGVuZC50eGlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBbdGhpcy5ub2RlKCdzcGVudCcsIGZhbHNlKV07XG4gICAgfVxuICAgIGlmIChzcGVuZC50eGlkID09PSB0eGlkKSB7XG4gICAgICAvLyBpZiBpbnB1dCBpcyBzcGVudCBieSB0aGlzIHRyYW5zYWN0aW9uIHdlIGRvbid0IGRpc3BsYXkgaXRcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgcmV0dXJuIFt0aGlzLm5vZGUoJ3NwZW50JywgYCR7c3BlbmQudHhpZH06JHtzcGVuZC52aW59YCwgcGFyYW1zLmNvbmZsaWN0ID8gW3RoaXMubm9kZSgnY29uZmxpY3QnLCB0cnVlKV0gOiBbXSldO1xuICB9XG5cbiAgcGFyc2VJbnMoaW5zOiB1dHhvbGliLlR4SW5wdXRbXSwgdHg6IHV0eG9saWIuYml0Z28uVXR4b1RyYW5zYWN0aW9uLCBvdXRwdXRJbmZvOiBDaGFpbkluZm8pOiBUeE5vZGVbXSB7XG4gICAgY29uc3QgdHhpZCA9IHR4LmdldElkKCk7XG4gICAgcmV0dXJuIGlucy5tYXAoKGlucHV0LCBpKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ub2RlKGksIHV0eG9saWIuYml0Z28uZm9ybWF0T3V0cHV0SWQodXR4b2xpYi5iaXRnby5nZXRPdXRwdXRJZEZvcklucHV0KGlucHV0KSksIFtcbiAgICAgICAgdGhpcy5ub2RlKCdzZXF1ZW5jZScsIHRvQnVmZmVyVUludDMyQkUoaW5wdXQuc2VxdWVuY2UpKSxcbiAgICAgICAgdGhpcy5wYXJzZUlucHV0U2NyaXB0KGlucHV0LnNjcmlwdCksXG4gICAgICAgIHRoaXMucGFyc2VXaXRuZXNzKGlucHV0LndpdG5lc3MpLFxuICAgICAgICB0aGlzLnBhcnNlU2lnU2NyaXB0KHR4LCBpLCBvdXRwdXRJbmZvLnByZXZPdXRwdXRzKSxcbiAgICAgICAgLi4udGhpcy5wYXJzZVByZXZPdXQoaW5wdXQsIGksIHR4Lm5ldHdvcmssIG91dHB1dEluZm8ucHJldk91dHB1dHMpLFxuICAgICAgICAuLi50aGlzLnBhcnNlU3BlbmQodHhpZCwgaSwgb3V0cHV0SW5mby5wcmV2T3V0cHV0U3BlbmRzLCB7IGNvbmZsaWN0OiB0cnVlIH0pLFxuICAgICAgXSk7XG4gICAgfSk7XG4gIH1cblxuICB0cnlQYXJzZU9wUmV0dXJuKHNjcmlwdDogQnVmZmVyKTogVHhOb2RlW10ge1xuICAgIGxldCBkYXRhOiBCdWZmZXJbXSB8IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgKHsgZGF0YSB9ID0gdXR4b2xpYi5wYXltZW50cy5lbWJlZCh7IG91dHB1dDogc2NyaXB0IH0pKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBpZ25vcmVcbiAgICB9XG4gICAgaWYgKCFkYXRhKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHJldHVybiBkYXRhLm1hcCgoYnVmLCBpKSA9PiB7XG4gICAgICBsZXQgdXRmODtcbiAgICAgIHRyeSB7XG4gICAgICAgIHV0ZjggPSBidWYudG9TdHJpbmcoJ3V0ZjgnKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gaWdub3JlXG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5ub2RlKGBPUF9SRVRVUk4gJHtpfWAsIGAke2J1Zi5sZW5ndGh9IGJ5dGVzYCwgW1xuICAgICAgICB0aGlzLm5vZGUoJ2hleCcsIGJ1ZiksXG4gICAgICAgIC4uLih1dGY4ICYmIGlzUHJpbnRhYmxlKHV0ZjgpID8gW3RoaXMubm9kZSgndXRmOCcsIHV0ZjgpXSA6IFtdKSxcbiAgICAgIF0pO1xuICAgIH0pO1xuICB9XG5cbiAgcGFyc2VPdXRwdXRTY3JpcHQoYnVmZmVyOiBCdWZmZXIpOiBUeE5vZGVbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMubm9kZSgnc2NyaXB0UHViS2V5JywgYCR7YnVmZmVyLmxlbmd0aH0gYnl0ZXNgLCBbXG4gICAgICAgIHRoaXMubm9kZSgnaGV4JywgYnVmZmVyLnRvU3RyaW5nKCdoZXgnKSksXG4gICAgICAgIHRoaXMubm9kZSgnYXNtJywgdXR4b2xpYi5zY3JpcHQudG9BU00oYnVmZmVyKSwgdGhpcy50cnlQYXJzZU9wUmV0dXJuKGJ1ZmZlcikpLFxuICAgICAgXSksXG4gICAgXTtcbiAgfVxuXG4gIHBhcnNlT3V0cHV0KHR4aWQ6IHN0cmluZywgbzogdXR4b2xpYi5UeE91dHB1dCwgaTogbnVtYmVyLCBuZXR3b3JrOiB1dHhvbGliLk5ldHdvcmssIHBhcmFtczogQ2hhaW5JbmZvKTogVHhOb2RlIHtcbiAgICBjb25zdCB0eXBlID0gdXR4b2xpYi5jbGFzc2lmeS5vdXRwdXQoby5zY3JpcHQpO1xuXG4gICAgbGV0IGFkZHJlc3M7XG4gICAgdHJ5IHtcbiAgICAgIGFkZHJlc3MgPSB1dHhvbGliLmFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChvLnNjcmlwdCwgbmV0d29yayk7XG4gICAgfSBjYXRjaCAoZSkge31cblxuICAgIHJldHVybiB0aGlzLm5vZGUoaSwgYWRkcmVzcyA/PyAnKG5vIGFkZHJlc3MpJywgW1xuICAgICAgdGhpcy5ub2RlKGB2YWx1ZWAsIGZvcm1hdFNhdChvLnZhbHVlKSksXG4gICAgICB0aGlzLm5vZGUoYHR5cGVgLCB0eXBlKSxcbiAgICAgIC4uLih0aGlzLnBhcmFtcy5wYXJzZU91dHB1dFNjcmlwdCB8fCBhZGRyZXNzID09PSB1bmRlZmluZWQgPyB0aGlzLnBhcnNlT3V0cHV0U2NyaXB0KG8uc2NyaXB0KSA6IFtdKSxcbiAgICAgIC4uLnRoaXMucGFyc2VTcGVuZCh0eGlkLCBpLCBwYXJhbXMub3V0cHV0U3BlbmRzLCB7IGNvbmZsaWN0OiBmYWxzZSB9KSxcbiAgICBdKTtcbiAgfVxuXG4gIHBhcnNlT3V0cyhvdXRzOiB1dHhvbGliLlR4T3V0cHV0W10sIHR4OiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbiwgcGFyYW1zOiBDaGFpbkluZm8pOiBUeE5vZGVbXSB7XG4gICAgaWYgKG91dHMubGVuZ3RoID4gKHRoaXMucGFyYW1zLm1heE91dHB1dHMgPz8gMjAwKSkge1xuICAgICAgcmV0dXJuIFt0aGlzLm5vZGUoJyhvbWl0dGVkKScsIHVuZGVmaW5lZCldO1xuICAgIH1cblxuICAgIGNvbnN0IHR4aWQgPSB0eC5nZXRJZCgpO1xuICAgIHJldHVybiBvdXRzLm1hcCgobywgaSkgPT4gdGhpcy5wYXJzZU91dHB1dCh0eGlkLCBvLCBpLCB0eC5uZXR3b3JrLCBwYXJhbXMpKTtcbiAgfVxuXG4gIHBhcnNlU3RhdHVzKHR4OiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbiwgc3RhdHVzPzogVHJhbnNhY3Rpb25TdGF0dXMpOiBUeE5vZGVbXSB7XG4gICAgaWYgKCFzdGF0dXMpIHtcbiAgICAgIHJldHVybiBbdGhpcy5ub2RlKCdzdGF0dXMnLCAndW5rbm93bicpXTtcbiAgICB9XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMubm9kZShcbiAgICAgICAgJ3N0YXR1cycsXG4gICAgICAgIHN0YXR1cy5mb3VuZCA/ICdmb3VuZCcgOiAnbm90IGZvdW5kJyxcbiAgICAgICAgc3RhdHVzLmZvdW5kXG4gICAgICAgICAgPyBzdGF0dXMuY29uZmlybWVkXG4gICAgICAgICAgICA/IFtcbiAgICAgICAgICAgICAgICB0aGlzLm5vZGUoXG4gICAgICAgICAgICAgICAgICAnY29uZmlybWVkJyxcbiAgICAgICAgICAgICAgICAgIGBibG9jayAke3N0YXR1cy5ibG9ja0hlaWdodH1gICsgKHN0YXR1cy5kYXRlID8gYCBkYXRlPSR7c3RhdHVzLmRhdGUudG9JU09TdHJpbmcoKX1gIDogJycpXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgOiBbdGhpcy5ub2RlKCdjb25maXJtZWQnLCBmYWxzZSldXG4gICAgICAgICAgOiBbXVxuICAgICAgKSxcbiAgICBdO1xuICB9XG5cbiAgcGFyc2VWZXJzaW9uKHR4OiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbik6IFR4Tm9kZSB7XG4gICAgcmV0dXJuIHRoaXMubm9kZShcbiAgICAgICd2ZXJzaW9uJyxcbiAgICAgIHR4LnZlcnNpb24sXG4gICAgICB0eCBpbnN0YW5jZW9mIHV0eG9saWIuYml0Z28uWmNhc2hUcmFuc2FjdGlvblxuICAgICAgICA/IFtcbiAgICAgICAgICAgIHRoaXMubm9kZSgnY29uc2Vuc3VzQnJhbmNoSWQgKGluZmVycmVkKScsIHR4LmNvbnNlbnN1c0JyYW5jaElkLnRvU3RyaW5nKDE2KSwgW1xuICAgICAgICAgICAgICB0aGlzLm5vZGUoJ25hbWUnLCBmb3JtYXRDb25zZW5zdXNCcmFuY2hJZCh0eC5jb25zZW5zdXNCcmFuY2hJZCkpLFxuICAgICAgICAgICAgXSksXG4gICAgICAgICAgXVxuICAgICAgICA6IFtdXG4gICAgKTtcbiAgfVxuXG4gIHBhcnNlKHR4OiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbiwgY2hhaW5JbmZvOiBDaGFpbkluZm8gPSB7fSk6IFR4Tm9kZSB7XG4gICAgY29uc3Qgd2VpZ2h0ID0gdHgud2VpZ2h0KCk7XG4gICAgY29uc3QgdnNpemUgPSB0eC52aXJ0dWFsU2l6ZSgpO1xuICAgIGNvbnN0IG91dHB1dFN1bSA9IHR4Lm91dHMucmVkdWNlKChzdW0sIG8pID0+IHN1bSArIG8udmFsdWUsIDApO1xuICAgIGNvbnN0IGlucHV0U3VtID0gY2hhaW5JbmZvLnByZXZPdXRwdXRzPy5yZWR1Y2UoKHN1bSwgbykgPT4gc3VtICsgby52YWx1ZSwgMCk7XG4gICAgY29uc3QgZmVlID0gaW5wdXRTdW0gPyBpbnB1dFN1bSAtIG91dHB1dFN1bSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBmZWVSYXRlID0gZmVlID8gZmVlIC8gdnNpemUgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHRoaXMubm9kZSgndHJhbnNhY3Rpb24nLCB0eC5nZXRJZCgpLCBbXG4gICAgICB0aGlzLm5vZGUoXG4gICAgICAgICdwYXJzZWRBcycsXG4gICAgICAgIGAke3V0eG9saWIuZ2V0TmV0d29ya05hbWUodXR4b2xpYi5nZXRNYWlubmV0KHR4Lm5ldHdvcmspKX0gYCArXG4gICAgICAgICAgYCR7dXR4b2xpYi5pc01haW5uZXQodHgubmV0d29yaykgPyAnbWFpbm5ldCcgOiAndGVzdG5ldCd9YFxuICAgICAgKSxcbiAgICAgIHRoaXMucGFyc2VWZXJzaW9uKHR4KSxcbiAgICAgIHRoaXMubm9kZSgnbG9ja3RpbWUnLCB0eC5sb2NrdGltZSksXG4gICAgICB0aGlzLm5vZGUoJ2hhc1dpdG5lc3NlcycsIHR4Lmhhc1dpdG5lc3NlcygpKSxcbiAgICAgIC4uLnRoaXMucGFyc2VTdGF0dXModHgsIGNoYWluSW5mby5zdGF0dXMpLFxuICAgICAgdGhpcy5ub2RlKCd2c2l6ZScsIGAke3ZzaXplfXZieXRlcyAoJHt3ZWlnaHR9d3UpYCksXG4gICAgICAuLi4oZmVlICYmIGZlZVJhdGVcbiAgICAgICAgPyBbdGhpcy5ub2RlKCdmZWUgW2J0Y10nLCBmb3JtYXRTYXQoZmVlKSksIHRoaXMubm9kZSgnZmVlUmF0ZSBbc2F0L3ZieXRlXScsIGZlZVJhdGUudG9GaXhlZCgyKSldXG4gICAgICAgIDogW10pLFxuICAgICAgdGhpcy5ub2RlKFxuICAgICAgICBgaW5wdXRzYCxcbiAgICAgICAgW1N0cmluZyh0eC5pbnMubGVuZ3RoKV0uY29uY2F0KGlucHV0U3VtID8gWydzdW09JyArIGZvcm1hdFNhdChpbnB1dFN1bSldIDogW10pLmpvaW4oJyAnKSxcbiAgICAgICAgdGhpcy5wYXJzZUlucyh0eC5pbnMsIHR4LCBjaGFpbkluZm8pXG4gICAgICApLFxuICAgICAgdGhpcy5ub2RlKFxuICAgICAgICBgb3V0cHV0c2AsXG4gICAgICAgIFtTdHJpbmcodHgub3V0cy5sZW5ndGgpLCAnc3VtPScgKyBmb3JtYXRTYXQob3V0cHV0U3VtKV0uam9pbignICcpLFxuICAgICAgICB0aGlzLnBhcnNlT3V0cyh0eC5vdXRzLCB0eCwgY2hhaW5JbmZvKVxuICAgICAgKSxcbiAgICBdKTtcbiAgfVxufVxuIl19