@bitgo/utxo-bin 2.13.0 → 2.14.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.
@@ -1,196 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InputOutputParser = void 0;
4
- const utxolib = require("@bitgo/utxo-lib");
5
- const bitcoinjs_lib_1 = require("bitcoinjs-lib");
6
- const Parser_1 = require("./Parser");
7
- const AddressParser_1 = require("./AddressParser");
8
- const format_1 = require("./format");
9
- const hollowSegwitSpend_1 = require("./hollowSegwitSpend");
10
- const ecdsa_1 = require("./ecdsa");
11
- function toBufferUInt32BE(n) {
12
- const buf = Buffer.alloc(4);
13
- buf.writeUInt32LE(n, 0);
14
- return buf;
15
- }
16
- function parseSignatureScript(input, network) {
17
- return hollowSegwitSpend_1.parseHollowSegwitSpend(input, network) || utxolib.bitgo.parseSignatureScript(input);
18
- }
19
- class InputOutputParser extends Parser_1.Parser {
20
- constructor(params) {
21
- super();
22
- this.params = params;
23
- }
24
- parseScriptAsm(type, part, i, n) {
25
- if ((type === 'taproot' && i === n - 2) ||
26
- ((type === 'scripthash' || type === 'witnessscripthash') && i === n - 1)) {
27
- let parsed;
28
- try {
29
- parsed = utxolib.script.toASM(part);
30
- }
31
- catch (e) {
32
- return 'error';
33
- }
34
- if (parsed) {
35
- return ['', ...parsed.split(' ')].join('\n');
36
- }
37
- }
38
- }
39
- parseScriptParts(type, parts) {
40
- return parts.map((v, i) => {
41
- let asmNode;
42
- if (this.params.parseScriptAsm && Buffer.isBuffer(v)) {
43
- const parsed = this.parseScriptAsm(type, v, i, parts.length);
44
- asmNode = parsed ? this.node('asm', parsed) : undefined;
45
- }
46
- return this.node(i, this.params.parseScriptData ? v : undefined, asmNode ? [asmNode] : undefined);
47
- });
48
- }
49
- parseInputScript(buffer) {
50
- var _a;
51
- let value;
52
- let nodes;
53
- if (buffer.length && this.params.parseSignatureData.script) {
54
- const type = (_a = utxolib.classify.input(buffer, true)) !== null && _a !== void 0 ? _a : 'unknown';
55
- const decompiled = utxolib.script.decompile(buffer);
56
- if (decompiled) {
57
- nodes = this.parseScriptParts(type, decompiled);
58
- }
59
- value = type;
60
- }
61
- else {
62
- value = buffer;
63
- }
64
- return this.node('scriptSig', value, nodes);
65
- }
66
- parseWitness(script) {
67
- var _a;
68
- if (script.length === 0) {
69
- return this.node('witness', '[]');
70
- }
71
- const type = (_a = utxolib.classify.witness(script, true)) !== null && _a !== void 0 ? _a : 'unknown';
72
- return this.node('witness', type, this.params.parseScriptData ? this.parseScriptParts(type, script) : undefined);
73
- }
74
- parsePubkeys(parsed) {
75
- return this.node('pubkeys', parsed.publicKeys.length, parsed.publicKeys.map((k, i) => this.node(i, k)));
76
- }
77
- parseSignatureBuffer(type, buf, signerIndex) {
78
- if (buf === 0) {
79
- return [this.node('type', 'placeholder (0)')];
80
- }
81
- const nodes = [this.node('bytes', buf), this.node('valid', 0 <= signerIndex)];
82
- if (0 <= signerIndex) {
83
- nodes.push(this.node('signedBy', ['user', 'backup', 'bitgo'][signerIndex]));
84
- }
85
- if (type === 'taprootScriptPathSpend') {
86
- // TODO
87
- }
88
- else {
89
- const { signature, hashType } = bitcoinjs_lib_1.ScriptSignature.decode(buf);
90
- const r = signature.subarray(0, 32);
91
- const s = signature.subarray(32);
92
- if (r.length !== 32 || s.length !== 32) {
93
- throw new Error(`invalid scalar length`);
94
- }
95
- nodes.push(this.node('isCanonical', bitcoinjs_lib_1.script.isCanonicalScriptSignature(buf)), this.node('hashType', hashType), this.node('r', r), this.node('s', s), this.node('highS', ecdsa_1.isHighS(s)));
96
- }
97
- return nodes;
98
- }
99
- parseSignatures(parsed, tx, inputIndex, prevOutputs) {
100
- const nodes = [];
101
- if (prevOutputs) {
102
- const signedBy = utxolib.bitgo.getSignaturesWithPublicKeys(tx, inputIndex, prevOutputs, parsed.publicKeys);
103
- nodes.push(this.node('signed by', `[${signedBy.flatMap((v, i) => (v ? [i] : [])).join(', ')}]`));
104
- if (this.params.parseSignatureData.ecdsa || this.params.parseSignatureData.schnorr) {
105
- nodes.push(...parsed.signatures.map((s, i) => this.node(i, undefined, this.parseSignatureBuffer(parsed.scriptType, s, s === 0 ? -1 : signedBy.indexOf(s)))));
106
- }
107
- }
108
- return this.node('signatures', parsed.signatures
109
- .map((s) => utxolib.bitgo.isPlaceholderSignature(s) ? '[]' : Buffer.isBuffer(s) ? `[${s.length}byte]` : `[${s}]`)
110
- .join(' '), nodes);
111
- }
112
- parseSigScriptWithType(tx, inputIndex, parsed, prevOutputs) {
113
- var _a;
114
- if (parsed.scriptType &&
115
- (utxolib.bitgo.outputScripts.isScriptType2Of3(parsed.scriptType) ||
116
- parsed.scriptType === 'taprootScriptPathSpend' ||
117
- parsed.scriptType === 'taprootKeyPathSpend')) {
118
- const parsed2Of3 = parsed.scriptType === 'taprootScriptPathSpend' ? { ...parsed, scriptType: 'p2tr' } : parsed;
119
- return this.node('sigScript', parsed2Of3.scriptType, [
120
- this.parsePubkeys(parsed),
121
- this.parseSignatures(parsed, tx, inputIndex, prevOutputs),
122
- ]);
123
- }
124
- if (parsed.scriptType === 'p2shP2wshHollow' || parsed.scriptType === 'p2shP2wpkhHollow') {
125
- return this.node('sigScript', parsed.scriptType, [this.node('info', hollowSegwitSpend_1.getHollowSpendMessage())]);
126
- }
127
- return this.node('sigScript', (_a = parsed.scriptType) !== null && _a !== void 0 ? _a : 'unknown');
128
- }
129
- parseSigScript(tx, inputIndex, prevOutputs) {
130
- try {
131
- return this.parseSigScriptWithType(tx, inputIndex, parseSignatureScript(tx.ins[inputIndex], tx.network), prevOutputs);
132
- }
133
- catch (e) {
134
- return this.node('error', String(e));
135
- }
136
- }
137
- parsePrevOut(input, i, network, prevOutputs) {
138
- if (!prevOutputs || !prevOutputs[i]) {
139
- return [];
140
- }
141
- const { script, value } = prevOutputs[i];
142
- let address;
143
- try {
144
- address = utxolib.address.fromOutputScript(script, network);
145
- }
146
- catch (e) {
147
- address = '(error)';
148
- }
149
- return [
150
- this.node('value', value / 1e8),
151
- this.node('pubScript', script, address ? [this.node('address', address)] : undefined),
152
- ];
153
- }
154
- parseInput(txid, tx, i, input, outputInfo) {
155
- return this.node(i, utxolib.bitgo.formatOutputId(utxolib.bitgo.getOutputIdForInput(input)), [
156
- this.node('sequence', toBufferUInt32BE(input.sequence)),
157
- this.parseInputScript(input.script),
158
- this.parseWitness(input.witness),
159
- this.parseSigScript(tx, i, outputInfo.prevOutputs),
160
- ...this.parsePrevOut(input, i, tx.network, outputInfo.prevOutputs),
161
- ...this.parseSpend(txid, i, outputInfo.prevOutputSpends, { conflict: true }),
162
- ]);
163
- }
164
- parseSpend(txid, index, spends, params) {
165
- if (!spends || !spends[index]) {
166
- // no spend data available
167
- return [];
168
- }
169
- const spend = spends[index];
170
- if (spend.txid === undefined) {
171
- return [this.node('spent', false)];
172
- }
173
- if (spend.txid === txid) {
174
- // if input is spent by this transaction we don't display it
175
- return [];
176
- }
177
- return [this.node('spent', `${spend.txid}:${spend.vin}`, params.conflict ? [this.node('conflict', true)] : [])];
178
- }
179
- parseOutput(txid, o, i, network, params) {
180
- let address;
181
- try {
182
- address = utxolib.address.fromOutputScript(o.script, network);
183
- }
184
- catch (e) {
185
- // ignore
186
- }
187
- const addressParser = new AddressParser_1.AddressParser({ network, all: false, convert: false });
188
- return this.node(i, address !== null && address !== void 0 ? address : '(no address)', [
189
- this.node(`value`, format_1.formatSat(o.value)),
190
- ...(this.params.parseOutputScript || address === undefined ? addressParser.parseOutputScript(o.script) : []),
191
- ...this.parseSpend(txid, i, params.outputSpends, { conflict: false }),
192
- ]);
193
- }
194
- }
195
- exports.InputOutputParser = InputOutputParser;
196
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5wdXRPdXRwdXRQYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvSW5wdXRPdXRwdXRQYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQTJDO0FBRTNDLGlEQUF3RDtBQUV4RCxxQ0FBOEM7QUFDOUMsbURBQWdEO0FBQ2hELHFDQUFxQztBQUVyQywyREFBdUc7QUFDdkcsbUNBQWtDO0FBRWxDLFNBQVMsZ0JBQWdCLENBQUMsQ0FBUztJQUNqQyxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVCLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVELFNBQVMsb0JBQW9CLENBQzNCLEtBQXNCLEVBQ3RCLE9BQXdCO0lBRXhCLE9BQU8sMENBQXNCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDN0YsQ0FBQztBQUVELE1BQWEsaUJBQWtCLFNBQVEsZUFBTTtJQUMzQyxZQUNVLE1BU1A7UUFFRCxLQUFLLEVBQUUsQ0FBQztRQVhBLFdBQU0sR0FBTixNQUFNLENBU2I7SUFHSCxDQUFDO0lBRUQsY0FBYyxDQUFDLElBQVksRUFBRSxJQUFZLEVBQUUsQ0FBUyxFQUFFLENBQVM7UUFDN0QsSUFDRSxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbkMsQ0FBQyxDQUFDLElBQUksS0FBSyxZQUFZLElBQUksSUFBSSxLQUFLLG1CQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsRUFDeEU7WUFDQSxJQUFJLE1BQU0sQ0FBQztZQUVYLElBQUk7Z0JBQ0YsTUFBTSxHQUFHLE9BQU8sQ0FB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aWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCB7IE91dHB1dFNwZW5kIH0gZnJvbSAnQGJpdGdvL2Jsb2NrYXBpcyc7XG5pbXBvcnQgeyBzY3JpcHQsIFNjcmlwdFNpZ25hdHVyZSB9IGZyb20gJ2JpdGNvaW5qcy1saWInO1xuXG5pbXBvcnQgeyBQYXJzZXIsIFBhcnNlck5vZGUgfSBmcm9tICcuL1BhcnNlcic7XG5pbXBvcnQgeyBBZGRyZXNzUGFyc2VyIH0gZnJvbSAnLi9BZGRyZXNzUGFyc2VyJztcbmltcG9ydCB7IGZvcm1hdFNhdCB9IGZyb20gJy4vZm9ybWF0JztcbmltcG9ydCB7IENoYWluSW5mbyB9IGZyb20gJy4vVHhQYXJzZXInO1xuaW1wb3J0IHsgcGFyc2VIb2xsb3dTZWd3aXRTcGVuZCwgSG9sbG93U2Vnd2l0U3BlbmQsIGdldEhvbGxvd1NwZW5kTWVzc2FnZSB9IGZyb20gJy4vaG9sbG93U2Vnd2l0U3BlbmQnO1xuaW1wb3J0IHsgaXNIaWdoUyB9IGZyb20gJy4vZWNkc2EnO1xuXG5mdW5jdGlvbiB0b0J1ZmZlclVJbnQzMkJFKG46IG51bWJlcik6IEJ1ZmZlciB7XG4gIGNvbnN0IGJ1ZiA9IEJ1ZmZlci5hbGxvYyg0KTtcbiAgYnVmLndyaXRlVUludDMyTEUobiwgMCk7XG4gIHJldHVybiBidWY7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU2lnbmF0dXJlU2NyaXB0KFxuICBpbnB1dDogdXR4b2xpYi5UeElucHV0LFxuICBuZXR3b3JrOiB1dHhvbGliLk5ldHdvcmtcbik6IHV0eG9saWIuYml0Z28uUGFyc2VkU2lnbmF0dXJlU2NyaXB0IHwgSG9sbG93U2Vnd2l0U3BlbmQge1xuICByZXR1cm4gcGFyc2VIb2xsb3dTZWd3aXRTcGVuZChpbnB1dCwgbmV0d29yaykgfHwgdXR4b2xpYi5iaXRnby5wYXJzZVNpZ25hdHVyZVNjcmlwdChpbnB1dCk7XG59XG5cbmV4cG9ydCBjbGFzcyBJbnB1dE91dHB1dFBhcnNlciBleHRlbmRzIFBhcnNlciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcGFyYW1zOiB7XG4gICAgICBwYXJzZU91dHB1dFNjcmlwdDogYm9vbGVhbjtcbiAgICAgIHBhcnNlU2NyaXB0QXNtOiBib29sZWFuO1xuICAgICAgcGFyc2VTY3JpcHREYXRhOiBib29sZWFuO1xuICAgICAgcGFyc2VTaWduYXR1cmVEYXRhOiB7XG4gICAgICAgIHNjcmlwdDogYm9vbGVhbjtcbiAgICAgICAgZWNkc2E6IGJvb2xlYW47XG4gICAgICAgIHNjaG5vcnI6IGJvb2xlYW47XG4gICAgICB9O1xuICAgIH1cbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIHBhcnNlU2NyaXB0QXNtKHR5cGU6IHN0cmluZywgcGFydDogQnVmZmVyLCBpOiBudW1iZXIsIG46IG51bWJlcik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKFxuICAgICAgKHR5cGUgPT09ICd0YXByb290JyAmJiBpID09PSBuIC0gMikgfHxcbiAgICAgICgodHlwZSA9PT0gJ3NjcmlwdGhhc2gnIHx8IHR5cGUgPT09ICd3aXRuZXNzc2NyaXB0aGFzaCcpICYmIGkgPT09IG4gLSAxKVxuICAgICkge1xuICAgICAgbGV0IHBhcnNlZDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcGFyc2VkID0gdXR4b2xpYi5zY3JpcHQudG9BU00ocGFydCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiAnZXJyb3InO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFyc2VkKSB7XG4gICAgICAgIHJldHVybiBbJycsIC4uLnBhcnNlZC5zcGxpdCgnICcpXS5qb2luKCdcXG4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwYXJzZVNjcmlwdFBhcnRzKHR5cGU6IHN0cmluZywgcGFydHM6IEFycmF5PEJ1ZmZlciB8IG51bWJlcj4pOiBQYXJzZXJOb2RlW10ge1xuICAgIHJldHVybiBwYXJ0cy5tYXAoKHYsIGkpID0+IHtcbiAgICAgIGxldCBhc21Ob2RlOiBQYXJzZXJOb2RlIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKHRoaXMucGFyYW1zLnBhcnNlU2NyaXB0QXNtICYmIEJ1ZmZlci5pc0J1ZmZlcih2KSkge1xuICAgICAgICBjb25zdCBwYXJzZWQgPSB0aGlzLnBhcnNlU2NyaXB0QXNtKHR5cGUsIHYsIGksIHBhcnRzLmxlbmd0aCk7XG4gICAgICAgIGFzbU5vZGUgPSBwYXJzZWQgPyB0aGlzLm5vZGUoJ2FzbScsIHBhcnNlZCkgOiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLm5vZGUoaSwgdGhpcy5wYXJhbXMucGFyc2VTY3JpcHREYXRhID8gdiA6IHVuZGVmaW5lZCwgYXNtTm9kZSA/IFthc21Ob2RlXSA6IHVuZGVmaW5lZCk7XG4gICAgfSk7XG4gIH1cblxuICBwYXJzZUlucHV0U2NyaXB0KGJ1ZmZlcjogQnVmZmVyKTogUGFyc2VyTm9kZSB7XG4gICAgbGV0IHZhbHVlO1xuICAgIGxldCBub2RlcztcbiAgICBpZiAoYnVmZmVyLmxlbmd0aCAmJiB0aGlzLnBhcmFtcy5wYXJzZVNpZ25hdHVyZURhdGEuc2NyaXB0KSB7XG4gICAgICBjb25zdCB0eXBlID0gdXR4b2xpYi5jbGFzc2lmeS5pbnB1dChidWZmZXIsIHRydWUpID8/ICd1bmtub3duJztcbiAgICAgIGNvbnN0IGRlY29tcGlsZWQgPSB1dHhvbGliLnNjcmlwdC5kZWNvbXBpbGUoYnVmZmVyKTtcbiAgICAgIGlmIChkZWNvbXBpbGVkKSB7XG4gICAgICAgIG5vZGVzID0gdGhpcy5wYXJzZVNjcmlwdFBhcnRzKHR5cGUsIGRlY29tcGlsZWQpO1xuICAgICAgfVxuICAgICAgdmFsdWUgPSB0eXBlO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSA9IGJ1ZmZlcjtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5ub2RlKCdzY3JpcHRTaWcnLCB2YWx1ZSwgbm9kZXMpO1xuICB9XG5cbiAgcGFyc2VXaXRuZXNzKHNjcmlwdDogQnVmZmVyW10pOiBQYXJzZXJOb2RlIHtcbiAgICBpZiAoc2NyaXB0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMubm9kZSgnd2l0bmVzcycsICdbXScpO1xuICAgIH1cbiAgICBjb25zdCB0eXBlID0gdXR4b2xpYi5jbGFzc2lmeS53aXRuZXNzKHNjcmlwdCwgdHJ1ZSkgPz8gJ3Vua25vd24nO1xuICAgIHJldHVybiB0aGlzLm5vZGUoJ3dpdG5lc3MnLCB0eXBlLCB0aGlzLnBhcmFtcy5wYXJzZVNjcmlwdERhdGEgPyB0aGlzLnBhcnNlU2NyaXB0UGFydHModHlwZSwgc2NyaXB0KSA6IHVuZGVmaW5lZCk7XG4gIH1cblxuICBwYXJzZVB1YmtleXMocGFyc2VkOiB1dHhvbGliLmJpdGdvLlBhcnNlZFNpZ25hdHVyZVNjcmlwdFAybXMpOiBQYXJzZXJOb2RlIHtcbiAgICByZXR1cm4gdGhpcy5ub2RlKFxuICAgICAgJ3B1YmtleXMnLFxuICAgICAgcGFyc2VkLnB1YmxpY0tleXMubGVuZ3RoLFxuICAgICAgcGFyc2VkLnB1YmxpY0tleXMubWFwKChrLCBpKSA9PiB0aGlzLm5vZGUoaSwgaykpXG4gICAgKTtcbiAgfVxuXG4gIHBhcnNlU2lnbmF0dXJlQnVmZmVyKFxuICAgIHR5cGU6IHV0eG9saWIuYml0Z28ub3V0cHV0U2NyaXB0cy5TY3JpcHRUeXBlMk9mMyB8IHV0eG9saWIuYml0Z28uUGFyc2VkU2NyaXB0VHlwZTJPZjMsXG4gICAgYnVmOiBCdWZmZXIgfCAwLFxuICAgIHNpZ25lckluZGV4OiBudW1iZXJcbiAgKTogUGFyc2VyTm9kZVtdIHtcbiAgICBpZiAoYnVmID09PSAwKSB7XG4gICAgICByZXR1cm4gW3RoaXMubm9kZSgndHlwZScsICdwbGFjZWhvbGRlciAoMCknKV07XG4gICAgfVxuXG4gICAgY29uc3Qgbm9kZXMgPSBbdGhpcy5ub2RlKCdieXRlcycsIGJ1ZiksIHRoaXMubm9kZSgndmFsaWQnLCAwIDw9IHNpZ25lckluZGV4KV07XG4gICAgaWYgKDAgPD0gc2lnbmVySW5kZXgpIHtcbiAgICAgIG5vZGVzLnB1c2godGhpcy5ub2RlKCdzaWduZWRCeScsIFsndXNlcicsICdiYWNrdXAnLCAnYml0Z28nXVtzaWduZXJJbmRleF0pKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZSA9PT0gJ3RhcHJvb3RTY3JpcHRQYXRoU3BlbmQnKSB7XG4gICAgICAvLyBUT0RPXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHsgc2lnbmF0dXJlLCBoYXNoVHlwZSB9ID0gU2NyaXB0U2lnbmF0dXJlLmRlY29kZShidWYpO1xuICAgICAgY29uc3QgciA9IHNpZ25hdHVyZS5zdWJhcnJheSgwLCAzMik7XG4gICAgICBjb25zdCBzID0gc2lnbmF0dXJlLnN1YmFycmF5KDMyKTtcblxuICAgICAgaWYgKHIubGVuZ3RoICE9PSAzMiB8fCBzLmxlbmd0aCAhPT0gMzIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIHNjYWxhciBsZW5ndGhgKTtcbiAgICAgIH1cblxuICAgICAgbm9kZXMucHVzaChcbiAgICAgICAgdGhpcy5ub2RlKCdpc0Nhbm9uaWNhbCcsIHNjcmlwdC5pc0Nhbm9uaWNhbFNjcmlwdFNpZ25hdHVyZShidWYpKSxcbiAgICAgICAgdGhpcy5ub2RlKCdoYXNoVHlwZScsIGhhc2hUeXBlKSxcbiAgICAgICAgdGhpcy5ub2RlKCdyJywgciksXG4gICAgICAgIHRoaXMubm9kZSgncycsIHMpLFxuICAgICAgICB0aGlzLm5vZGUoJ2hpZ2hTJywgaXNIaWdoUyhzKSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGVzO1xuICB9XG5cbiAgcGFyc2VTaWduYXR1cmVzKFxuICAgIHBhcnNlZDogdXR4b2xpYi5iaXRnby5QYXJzZWRTaWduYXR1cmVTY3JpcHRQMm1zLFxuICAgIHR4OiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbixcbiAgICBpbnB1dEluZGV4OiBudW1iZXIsXG4gICAgcHJldk91dHB1dHM/OiB1dHhvbGliLlR4T3V0cHV0W11cbiAgKTogUGFyc2VyTm9kZSB7XG4gICAgY29uc3Qgbm9kZXM6IFBhcnNlck5vZGVbXSA9IFtdO1xuICAgIGlmIChwcmV2T3V0cHV0cykge1xuICAgICAgY29uc3Qgc2lnbmVkQnkgPSB1dHhvbGliLmJpdGdvLmdldFNpZ25hdHVyZXNXaXRoUHVibGljS2V5cyh0eCwgaW5wdXRJbmRleCwgcHJldk91dHB1dHMsIHBhcnNlZC5wdWJsaWNLZXlzKTtcbiAgICAgIG5vZGVzLnB1c2godGhpcy5ub2RlKCdzaWduZWQgYnknLCBgWyR7c2lnbmVkQnkuZmxhdE1hcCgodiwgaSkgPT4gKHYgPyBbaV0gOiBbXSkpLmpvaW4oJywgJyl9XWApKTtcbiAgICAgIGlmICh0aGlzLnBhcmFtcy5wYXJzZVNpZ25hdHVyZURhdGEuZWNkc2EgfHwgdGhpcy5wYXJhbXMucGFyc2VTaWduYXR1cmVEYXRhLnNjaG5vcnIpIHtcbiAgICAgICAgbm9kZXMucHVzaChcbiAgICAgICAgICAuLi5wYXJzZWQuc2lnbmF0dXJlcy5tYXAoKHM6IEJ1ZmZlciB8IDAsIGk6IG51bWJlcikgPT5cbiAgICAgICAgICAgIHRoaXMubm9kZShpLCB1bmRlZmluZWQsIHRoaXMucGFyc2VTaWduYXR1cmVCdWZmZXIocGFyc2VkLnNjcmlwdFR5cGUsIHMsIHMgPT09IDAgPyAtMSA6IHNpZ25lZEJ5LmluZGV4T2YocykpKVxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubm9kZShcbiAgICAgICdzaWduYXR1cmVzJyxcbiAgICAgIHBhcnNlZC5zaWduYXR1cmVzXG4gICAgICAgIC5tYXAoKHM6IEJ1ZmZlciB8IDApID0+XG4gICAgICAgICAgdXR4b2xpYi5iaXRnby5pc1BsYWNlaG9sZGVyU2lnbmF0dXJlKHMpID8gJ1tdJyA6IEJ1ZmZlci5pc0J1ZmZlcihzKSA/IGBbJHtzLmxlbmd0aH1ieXRlXWAgOiBgWyR7c31dYFxuICAgICAgICApXG4gICAgICAgIC5qb2luKCcgJyksXG4gICAgICBub2Rlc1xuICAgICk7XG4gIH1cblxuICBwYXJzZVNpZ1NjcmlwdFdpdGhUeXBlKFxuICAgIHR4OiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbixcbiAgICBpbnB1dEluZGV4OiBudW1iZXIsXG4gICAgcGFyc2VkOiB1dHhvbGliLmJpdGdvLlBhcnNlZFNpZ25hdHVyZVNjcmlwdCB8IEhvbGxvd1NlZ3dpdFNwZW5kLFxuICAgIHByZXZPdXRwdXRzPzogdXR4b2xpYi5UeE91dHB1dFtdXG4gICk6IFBhcnNlck5vZGUge1xuICAgIGlmIChcbiAgICAgIHBhcnNlZC5zY3JpcHRUeXBlICYmXG4gICAgICAodXR4b2xpYi5iaXRnby5vdXRwdXRTY3JpcHRzLmlzU2NyaXB0VHlwZTJPZjMocGFyc2VkLnNjcmlwdFR5cGUpIHx8XG4gICAgICAgIHBhcnNlZC5zY3JpcHRUeXBlID09PSAndGFwcm9vdFNjcmlwdFBhdGhTcGVuZCcgfHxcbiAgICAgICAgcGFyc2VkLnNjcmlwdFR5cGUgPT09ICd0YXByb290S2V5UGF0aFNwZW5kJylcbiAgICApIHtcbiAgICAgIGNvbnN0IHBhcnNlZDJPZjMgPSBwYXJzZWQuc2NyaXB0VHlwZSA9PT0gJ3RhcHJvb3RTY3JpcHRQYXRoU3BlbmQnID8geyAuLi5wYXJzZWQsIHNjcmlwdFR5cGU6ICdwMnRyJyB9IDogcGFyc2VkO1xuICAgICAgcmV0dXJuIHRoaXMubm9kZSgnc2lnU2NyaXB0JywgcGFyc2VkMk9mMy5zY3JpcHRUeXBlLCBbXG4gICAgICAgIHRoaXMucGFyc2VQdWJrZXlzKHBhcnNlZCBhcyB1dHhvbGliLmJpdGdvLlBhcnNlZFNpZ25hdHVyZVNjcmlwdFAybXMpLFxuICAgICAgICB0aGlzLnBhcnNlU2lnbmF0dXJlcyhwYXJzZWQgYXMgdXR4b2xpYi5iaXRnby5QYXJzZWRTaWduYXR1cmVTY3JpcHRQMm1zLCB0eCwgaW5wdXRJbmRleCwgcHJldk91dHB1dHMpLFxuICAgICAgXSk7XG4gICAgfVxuXG4gICAgaWYgKHBhcnNlZC5zY3JpcHRUeXBlID09PSAncDJzaFAyd3NoSG9sbG93JyB8fCBwYXJzZWQuc2NyaXB0VHlwZSA9PT0gJ3Ayc2hQMndwa2hIb2xsb3cnKSB7XG4gICAgICByZXR1cm4gdGhpcy5ub2RlKCdzaWdTY3JpcHQnLCBwYXJzZWQuc2NyaXB0VHlwZSwgW3RoaXMubm9kZSgnaW5mbycsIGdldEhvbGxvd1NwZW5kTWVzc2FnZSgpKV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm5vZGUoJ3NpZ1NjcmlwdCcsIHBhcnNlZC5zY3JpcHRUeXBlID8/ICd1bmtub3duJyk7XG4gIH1cblxuICBwYXJzZVNpZ1NjcmlwdCh0eDogdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb24sIGlucHV0SW5kZXg6IG51bWJlciwgcHJldk91dHB1dHM/OiB1dHhvbGliLlR4T3V0cHV0W10pOiBQYXJzZXJOb2RlIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VTaWdTY3JpcHRXaXRoVHlwZShcbiAgICAgICAgdHgsXG4gICAgICAgIGlucHV0SW5kZXgsXG4gICAgICAgIHBhcnNlU2lnbmF0dXJlU2NyaXB0KHR4Lmluc1tpbnB1dEluZGV4XSwgdHgubmV0d29yayksXG4gICAgICAgIHByZXZPdXRwdXRzXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB0aGlzLm5vZGUoJ2Vycm9yJywgU3RyaW5nKGUpKTtcbiAgICB9XG4gIH1cblxuICBwYXJzZVByZXZPdXQoXG4gICAgaW5wdXQ6IHV0eG9saWIuVHhJbnB1dCxcbiAgICBpOiBudW1iZXIsXG4gICAgbmV0d29yazogdXR4b2xpYi5OZXR3b3JrLFxuICAgIHByZXZPdXRwdXRzPzogdXR4b2xpYi5UeE91dHB1dFtdXG4gICk6IFBhcnNlck5vZGVbXSB7XG4gICAgaWYgKCFwcmV2T3V0cHV0cyB8fCAhcHJldk91dHB1dHNbaV0pIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgY29uc3QgeyBzY3JpcHQsIHZhbHVlIH0gPSBwcmV2T3V0cHV0c1tpXTtcbiAgICBsZXQgYWRkcmVzcztcbiAgICB0cnkge1xuICAgICAgYWRkcmVzcyA9IHV0eG9saWIuYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KHNjcmlwdCwgbmV0d29yayk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgYWRkcmVzcyA9ICcoZXJyb3IpJztcbiAgICB9XG4gICAgcmV0dXJuIFtcbiAgICAgIHRoaXMubm9kZSgndmFsdWUnLCB2YWx1ZSAvIDFlOCksXG4gICAgICB0aGlzLm5vZGUoJ3B1YlNjcmlwdCcsIHNjcmlwdCwgYWRkcmVzcyA/IFt0aGlzLm5vZGUoJ2FkZHJlc3MnLCBhZGRyZXNzKV0gOiB1bmRlZmluZWQpLFxuICAgIF07XG4gIH1cblxuICBwYXJzZUlucHV0KFxuICAgIHR4aWQ6IHN0cmluZyxcbiAgICB0eDogdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb24sXG4gICAgaTogbnVtYmVyLFxuICAgIGlucHV0OiB1dHhvbGliLlR4SW5wdXQsXG4gICAgb3V0cHV0SW5mbzogQ2hhaW5JbmZvXG4gICk6IFBhcnNlck5vZGUge1xuICAgIHJldHVybiB0aGlzLm5vZGUoaSwgdXR4b2xpYi5iaXRnby5mb3JtYXRPdXRwdXRJZCh1dHhvbGliLmJpdGdvLmdldE91dHB1dElkRm9ySW5wdXQoaW5wdXQpKSwgW1xuICAgICAgdGhpcy5ub2RlKCdzZXF1ZW5jZScsIHRvQnVmZmVyVUludDMyQkUoaW5wdXQuc2VxdWVuY2UpKSxcbiAgICAgIHRoaXMucGFyc2VJbnB1dFNjcmlwdChpbnB1dC5zY3JpcHQpLFxuICAgICAgdGhpcy5wYXJzZVdpdG5lc3MoaW5wdXQud2l0bmVzcyksXG4gICAgICB0aGlzLnBhcnNlU2lnU2NyaXB0KHR4LCBpLCBvdXRwdXRJbmZvLnByZXZPdXRwdXRzKSxcbiAgICAgIC4uLnRoaXMucGFyc2VQcmV2T3V0KGlucHV0LCBpLCB0eC5uZXR3b3JrLCBvdXRwdXRJbmZvLnByZXZPdXRwdXRzKSxcbiAgICAgIC4uLnRoaXMucGFyc2VTcGVuZCh0eGlkLCBpLCBvdXRwdXRJbmZvLnByZXZPdXRwdXRTcGVuZHMsIHsgY29uZmxpY3Q6IHRydWUgfSksXG4gICAgXSk7XG4gIH1cblxuICBwYXJzZVNwZW5kKFxuICAgIHR4aWQ6IHN0cmluZyxcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIHNwZW5kczogT3V0cHV0U3BlbmRbXSB8IHVuZGVmaW5lZCxcbiAgICBwYXJhbXM6IHsgY29uZmxpY3Q6IGJvb2xlYW4gfVxuICApOiBQYXJzZXJOb2RlW10ge1xuICAgIGlmICghc3BlbmRzIHx8ICFzcGVuZHNbaW5kZXhdKSB7XG4gICAgICAvLyBubyBzcGVuZCBkYXRhIGF2YWlsYWJsZVxuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBjb25zdCBzcGVuZCA9IHNwZW5kc1tpbmRleF07XG4gICAgaWYgKHNwZW5kLnR4aWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIFt0aGlzLm5vZGUoJ3NwZW50JywgZmFsc2UpXTtcbiAgICB9XG4gICAgaWYgKHNwZW5kLnR4aWQgPT09IHR4aWQpIHtcbiAgICAgIC8vIGlmIGlucHV0IGlzIHNwZW50IGJ5IHRoaXMgdHJhbnNhY3Rpb24gd2UgZG9uJ3QgZGlzcGxheSBpdFxuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICByZXR1cm4gW3RoaXMubm9kZSgnc3BlbnQnLCBgJHtzcGVuZC50eGlkfToke3NwZW5kLnZpbn1gLCBwYXJhbXMuY29uZmxpY3QgPyBbdGhpcy5ub2RlKCdjb25mbGljdCcsIHRydWUpXSA6IFtdKV07XG4gIH1cblxuICBwYXJzZU91dHB1dCh0eGlkOiBzdHJpbmcsIG86IHV0eG9saWIuVHhPdXRwdXQsIGk6IG51bWJlciwgbmV0d29yazogdXR4b2xpYi5OZXR3b3JrLCBwYXJhbXM6IENoYWluSW5mbyk6IFBhcnNlck5vZGUge1xuICAgIGxldCBhZGRyZXNzO1xuICAgIHRyeSB7XG4gICAgICBhZGRyZXNzID0gdXR4b2xpYi5hZGRyZXNzLmZyb21PdXRwdXRTY3JpcHQoby5zY3JpcHQsIG5ldHdvcmspO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGlnbm9yZVxuICAgIH1cblxuICAgIGNvbnN0IGFkZHJlc3NQYXJzZXIgPSBuZXcgQWRkcmVzc1BhcnNlcih7IG5ldHdvcmssIGFsbDogZmFsc2UsIGNvbnZlcnQ6IGZhbHNlIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMubm9kZShpLCBhZGRyZXNzID8/ICcobm8gYWRkcmVzcyknLCBbXG4gICAgICB0aGlzLm5vZGUoYHZhbHVlYCwgZm9ybWF0U2F0KG8udmFsdWUpKSxcbiAgICAgIC4uLih0aGlzLnBhcmFtcy5wYXJzZU91dHB1dFNjcmlwdCB8fCBhZGRyZXNzID09PSB1bmRlZmluZWQgPyBhZGRyZXNzUGFyc2VyLnBhcnNlT3V0cHV0U2NyaXB0KG8uc2NyaXB0KSA6IFtdKSxcbiAgICAgIC4uLnRoaXMucGFyc2VTcGVuZCh0eGlkLCBpLCBwYXJhbXMub3V0cHV0U3BlbmRzLCB7IGNvbmZsaWN0OiBmYWxzZSB9KSxcbiAgICBdKTtcbiAgfVxufVxuIl19