@bitgo-beta/sdk-coin-kaspa 0.0.1-beta.21 → 0.0.1-beta.210

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +224 -33
  2. package/dist/src/kaspa.d.ts +86 -18
  3. package/dist/src/kaspa.d.ts.map +1 -1
  4. package/dist/src/kaspa.js +119 -31
  5. package/dist/src/lib/constants.d.ts +38 -0
  6. package/dist/src/lib/constants.d.ts.map +1 -1
  7. package/dist/src/lib/constants.js +56 -5
  8. package/dist/src/lib/iface.d.ts +28 -17
  9. package/dist/src/lib/iface.d.ts.map +1 -1
  10. package/dist/src/lib/iface.js +1 -1
  11. package/dist/src/lib/index.d.ts +2 -0
  12. package/dist/src/lib/index.d.ts.map +1 -1
  13. package/dist/src/lib/index.js +4 -2
  14. package/dist/src/lib/keyPair.d.ts +6 -2
  15. package/dist/src/lib/keyPair.d.ts.map +1 -1
  16. package/dist/src/lib/keyPair.js +7 -4
  17. package/dist/src/lib/pskt.d.ts +257 -0
  18. package/dist/src/lib/pskt.d.ts.map +1 -0
  19. package/dist/src/lib/pskt.js +439 -0
  20. package/dist/src/lib/sighash.d.ts +34 -13
  21. package/dist/src/lib/sighash.d.ts.map +1 -1
  22. package/dist/src/lib/sighash.js +115 -56
  23. package/dist/src/lib/transaction.d.ts +94 -6
  24. package/dist/src/lib/transaction.d.ts.map +1 -1
  25. package/dist/src/lib/transaction.js +199 -21
  26. package/dist/src/lib/transactionBuilder.d.ts +22 -0
  27. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  28. package/dist/src/lib/transactionBuilder.js +53 -5
  29. package/dist/src/lib/transactionBuilderFactory.d.ts +8 -3
  30. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  31. package/dist/src/lib/transactionBuilderFactory.js +14 -4
  32. package/dist/src/lib/utils.d.ts +17 -3
  33. package/dist/src/lib/utils.d.ts.map +1 -1
  34. package/dist/src/lib/utils.js +45 -11
  35. package/dist/src/register.js +2 -2
  36. package/dist/test/fixtures/kaspa.fixtures.d.ts +12 -0
  37. package/dist/test/fixtures/kaspa.fixtures.d.ts.map +1 -1
  38. package/dist/test/fixtures/kaspa.fixtures.js +76 -11
  39. package/dist/test/unit/coin.test.js +129 -9
  40. package/dist/test/unit/keyPair.test.js +35 -1
  41. package/dist/test/unit/pskt.test.d.ts +15 -0
  42. package/dist/test/unit/pskt.test.d.ts.map +1 -0
  43. package/dist/test/unit/pskt.test.js +383 -0
  44. package/dist/test/unit/transaction.test.js +291 -11
  45. package/dist/test/unit/transactionBuilder.test.js +16 -3
  46. package/dist/test/unit/transactionFlow.test.js +67 -2
  47. package/dist/test/unit/utils.test.js +63 -4
  48. package/dist/tsconfig.tsbuildinfo +1 -1
  49. package/package.json +6 -5
@@ -0,0 +1,383 @@
1
+ "use strict";
2
+ /**
3
+ * PSKT (Partially Signed Kaspa Transaction) — Unit Tests
4
+ *
5
+ * Covers:
6
+ * - Full role flow: CREATOR → UPDATER → SIGNER → FINALIZER → EXTRACTOR
7
+ * - HSM / external signing path via addSignature()
8
+ * - Multi-party COMBINER role
9
+ * - serialize() / deserialize() round-trip
10
+ * - Extractor output matches Transaction.toBroadcastFormat()
11
+ * - Transaction.toPskt() and Transaction.fromPskt() bridge methods
12
+ * - TransactionBuilder.toPskt() unsigned PSKT construction
13
+ * - Role guard errors
14
+ */
15
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ const assert_1 = __importDefault(require("assert"));
20
+ const statics_1 = require("@bitgo-beta/statics");
21
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
22
+ const pskt_1 = require("../../src/lib/pskt");
23
+ const transaction_1 = require("../../src/lib/transaction");
24
+ const transactionBuilder_1 = require("../../src/lib/transactionBuilder");
25
+ const sighash_1 = require("../../src/lib/sighash");
26
+ const constants_1 = require("../../src/lib/constants");
27
+ const kaspa_fixtures_1 = require("../fixtures/kaspa.fixtures");
28
+ const PRV_KEY_BUF = Buffer.from(kaspa_fixtures_1.KEYS.prv, 'hex');
29
+ const PUB_KEY_BUF = Buffer.from(kaspa_fixtures_1.KEYS.pub, 'hex');
30
+ const X_ONLY_PUB = PUB_KEY_BUF.slice(1); // 32-byte x-only key for Schnorr verify
31
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
32
+ function makePsktInput(utxo) {
33
+ return {
34
+ previousOutpoint: { transactionId: utxo.transactionId, index: utxo.transactionIndex },
35
+ utxoEntry: { amount: utxo.amount, scriptPublicKey: utxo.scriptPublicKey },
36
+ sequence: utxo.sequence,
37
+ sigOpCount: utxo.sigOpCount ?? 1,
38
+ partialSigs: {},
39
+ sighashType: constants_1.SIGHASH_ALL,
40
+ bip32Derivations: {},
41
+ proprietaries: {},
42
+ };
43
+ }
44
+ function makePsktOutput() {
45
+ return {
46
+ amount: '99998000',
47
+ scriptPublicKey: { version: 0, scriptPublicKey: kaspa_fixtures_1.SCRIPT_PUBLIC_KEY },
48
+ bip32Derivations: {},
49
+ proprietaries: {},
50
+ };
51
+ }
52
+ // ─── Tests ────────────────────────────────────────────────────────────────────
53
+ describe('PSKT — role state machine', function () {
54
+ it('enforces role transitions: CREATOR → UPDATER → SIGNER → FINALIZER → EXTRACTOR', function () {
55
+ const pskt = pskt_1.Pskt.creator();
56
+ assert_1.default.equal(pskt.role, 'CREATOR');
57
+ const updater = pskt.toUpdater();
58
+ assert_1.default.equal(updater.role, 'UPDATER');
59
+ const signer = updater.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
60
+ assert_1.default.equal(signer.role, 'SIGNER');
61
+ const finalizer = signer.sign(PRV_KEY_BUF).toFinalizer();
62
+ assert_1.default.equal(finalizer.role, 'FINALIZER');
63
+ const extractor = finalizer.finalize().toExtractor();
64
+ assert_1.default.equal(extractor.role, 'EXTRACTOR');
65
+ });
66
+ it('enforces role transitions: SIGNER → COMBINER → FINALIZER → EXTRACTOR', function () {
67
+ const signer = pskt_1.Pskt.creator()
68
+ .toUpdater()
69
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
70
+ .output(makePsktOutput())
71
+ .toSigner()
72
+ .sign(PRV_KEY_BUF);
73
+ const combiner = signer.toCombiner();
74
+ assert_1.default.equal(combiner.role, 'COMBINER');
75
+ const finalizer = combiner.toFinalizer();
76
+ assert_1.default.equal(finalizer.role, 'FINALIZER');
77
+ const extractor = finalizer.finalize().toExtractor();
78
+ assert_1.default.equal(extractor.role, 'EXTRACTOR');
79
+ });
80
+ it('throws when calling toUpdater() from SIGNER role', function () {
81
+ const signer = pskt_1.Pskt.creator().toUpdater().input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
82
+ assert_1.default.throws(() => signer.toUpdater(), /role/i);
83
+ });
84
+ it('throws when calling sign() from FINALIZER role', function () {
85
+ const finalizer = pskt_1.Pskt.creator()
86
+ .toUpdater()
87
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
88
+ .output(makePsktOutput())
89
+ .toSigner()
90
+ .sign(PRV_KEY_BUF)
91
+ .toFinalizer();
92
+ assert_1.default.throws(() => finalizer.sign(PRV_KEY_BUF), /role/i);
93
+ });
94
+ it('throws toExtractor() when inputs are not finalized', function () {
95
+ const finalizer = pskt_1.Pskt.creator()
96
+ .toUpdater()
97
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
98
+ .output(makePsktOutput())
99
+ .toSigner()
100
+ .toFinalizer(); // skip signing
101
+ assert_1.default.throws(() => finalizer.toExtractor(), /finalised|finalScriptSig/i);
102
+ });
103
+ it('throws finalize() when input has no partial signatures', function () {
104
+ const finalizer = pskt_1.Pskt.creator()
105
+ .toUpdater()
106
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
107
+ .output(makePsktOutput())
108
+ .toSigner()
109
+ .toFinalizer();
110
+ assert_1.default.throws(() => finalizer.finalize(), /no partial signatures/i);
111
+ });
112
+ });
113
+ describe('PSKT — sign() produces valid Schnorr signatures', function () {
114
+ it('sign() writes partialSigs for each input', function () {
115
+ const signer = pskt_1.Pskt.creator()
116
+ .toUpdater()
117
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
118
+ .output(makePsktOutput())
119
+ .toSigner()
120
+ .sign(PRV_KEY_BUF);
121
+ assert_1.default.equal(signer.inputs.length, 1);
122
+ const sigs = Object.entries(signer.inputs[0].partialSigs);
123
+ assert_1.default.equal(sigs.length, 1, 'should have exactly one partial sig');
124
+ const [pubKeyHex, sigHex] = sigs[0];
125
+ assert_1.default.equal(pubKeyHex, kaspa_fixtures_1.KEYS.pub, 'pubKey key should match');
126
+ assert_1.default.equal(Buffer.from(sigHex, 'hex').length, 64, 'sig should be 64 bytes');
127
+ });
128
+ it('sign() Schnorr signatures verify against the correct per-input sighash', function () {
129
+ const pskt = pskt_1.Pskt.creator()
130
+ .toUpdater()
131
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
132
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.second))
133
+ .output({
134
+ amount: '299998000',
135
+ scriptPublicKey: { version: 0, scriptPublicKey: kaspa_fixtures_1.SCRIPT_PUBLIC_KEY },
136
+ bip32Derivations: {},
137
+ proprietaries: {},
138
+ })
139
+ .toSigner()
140
+ .sign(PRV_KEY_BUF);
141
+ // Build matching KaspaTransactionData for sighash reference
142
+ const txData = kaspa_fixtures_1.TRANSACTIONS.multiInput;
143
+ for (let i = 0; i < pskt.inputs.length; i++) {
144
+ const sigs = Object.values(pskt.inputs[i].partialSigs);
145
+ assert_1.default.equal(sigs.length, 1);
146
+ const sig = Buffer.from(sigs[0], 'hex');
147
+ const expectedHash = (0, sighash_1.computeKaspaSigningHash)(txData, i, constants_1.SIGHASH_ALL);
148
+ assert_1.default.ok(secp256k1_1.ecc.verifySchnorr(expectedHash, X_ONLY_PUB, sig), `Input[${i}] Schnorr sig should verify`);
149
+ }
150
+ });
151
+ });
152
+ describe('PSKT — addSignature() (HSM / external signing path)', function () {
153
+ it('addSignature() writes the provided sig into partialSigs', function () {
154
+ const signer = pskt_1.Pskt.creator().toUpdater().input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
155
+ // Produce sig externally
156
+ const txData = kaspa_fixtures_1.TRANSACTIONS.simple;
157
+ const sigHash = (0, sighash_1.computeKaspaSigningHash)(txData, 0, constants_1.SIGHASH_ALL);
158
+ const sig = Buffer.from(secp256k1_1.ecc.signSchnorr(sigHash, PRV_KEY_BUF));
159
+ signer.addSignature(0, kaspa_fixtures_1.KEYS.pub, sig.toString('hex'));
160
+ const sigs = Object.entries(signer.inputs[0].partialSigs);
161
+ assert_1.default.equal(sigs.length, 1);
162
+ assert_1.default.equal(sigs[0][0], kaspa_fixtures_1.KEYS.pub);
163
+ assert_1.default.equal(sigs[0][1], sig.toString('hex'));
164
+ });
165
+ it('addSignature() → finalize() produces a valid finalScriptSig', function () {
166
+ const txData = kaspa_fixtures_1.TRANSACTIONS.simple;
167
+ const sigHash = (0, sighash_1.computeKaspaSigningHash)(txData, 0, constants_1.SIGHASH_ALL);
168
+ const sig = Buffer.from(secp256k1_1.ecc.signSchnorr(sigHash, PRV_KEY_BUF));
169
+ const pskt = pskt_1.Pskt.creator()
170
+ .toUpdater()
171
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
172
+ .output(makePsktOutput())
173
+ .toSigner()
174
+ .addSignature(0, kaspa_fixtures_1.KEYS.pub, sig.toString('hex'))
175
+ .toFinalizer()
176
+ .finalize();
177
+ const finalSig = pskt.inputs[0].finalScriptSig;
178
+ assert_1.default.ok(finalSig, 'finalScriptSig should be set');
179
+ const finalBuf = Buffer.from(finalSig, 'hex');
180
+ assert_1.default.equal(finalBuf.length, 66, 'finalScriptSig should be 66 bytes (0x41 + 64-byte sig + 1-byte sighash)');
181
+ assert_1.default.equal(finalBuf[0], 0x41, 'first byte should be OP_DATA_65');
182
+ assert_1.default.equal(finalBuf[65], constants_1.SIGHASH_ALL, 'last byte should be sighash type');
183
+ });
184
+ it('throws on addSignature() with wrong-sized signature', function () {
185
+ const signer = pskt_1.Pskt.creator().toUpdater().input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
186
+ assert_1.default.throws(() => signer.addSignature(0, kaspa_fixtures_1.KEYS.pub, 'deadbeef'), /64-byte/i);
187
+ });
188
+ it('throws on addSignature() with out-of-range input index', function () {
189
+ const signer = pskt_1.Pskt.creator().toUpdater().input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
190
+ assert_1.default.throws(() => signer.addSignature(99, kaspa_fixtures_1.KEYS.pub, 'aa'.repeat(64)), /out of range/i);
191
+ });
192
+ });
193
+ describe('PSKT — combine() merges partialSigs', function () {
194
+ it('combine() merges partial signatures from two signers', function () {
195
+ const buildSigned = () => pskt_1.Pskt.creator()
196
+ .toUpdater()
197
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
198
+ .output(makePsktOutput())
199
+ .toSigner()
200
+ .sign(PRV_KEY_BUF);
201
+ const pskt1 = buildSigned();
202
+ const pskt2 = buildSigned();
203
+ // Both have the same sig; combining should succeed (idempotent)
204
+ const combined = pskt1.toCombiner().combine(pskt2);
205
+ const sigs = Object.entries(combined.inputs[0].partialSigs);
206
+ assert_1.default.equal(sigs.length, 1);
207
+ });
208
+ it('combine() throws on conflicting signatures for the same pubKey', function () {
209
+ // Simulate two different signers by manually injecting different sigs
210
+ const signer1 = pskt_1.Pskt.creator()
211
+ .toUpdater()
212
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
213
+ .output(makePsktOutput())
214
+ .toSigner()
215
+ .addSignature(0, kaspa_fixtures_1.KEYS.pub, 'aa'.repeat(64));
216
+ const signer2 = pskt_1.Pskt.creator()
217
+ .toUpdater()
218
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
219
+ .output(makePsktOutput())
220
+ .toSigner()
221
+ .addSignature(0, kaspa_fixtures_1.KEYS.pub, 'bb'.repeat(64));
222
+ assert_1.default.throws(() => signer1.toCombiner().combine(signer2), /conflicting signature/i);
223
+ });
224
+ it('combine() throws on input count mismatch', function () {
225
+ const a = pskt_1.Pskt.creator()
226
+ .toUpdater()
227
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
228
+ .output(makePsktOutput())
229
+ .toSigner()
230
+ .toCombiner();
231
+ const b = pskt_1.Pskt.creator()
232
+ .toUpdater()
233
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
234
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.second))
235
+ .output(makePsktOutput())
236
+ .toSigner()
237
+ .toCombiner();
238
+ assert_1.default.throws(() => a.combine(b), /input count mismatch/i);
239
+ });
240
+ });
241
+ describe('PSKT — serialize() / deserialize() round-trip', function () {
242
+ it('round-trips a PSKT in SIGNER role before signing', function () {
243
+ const original = pskt_1.Pskt.creator().toUpdater().input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
244
+ const json = original.serialize();
245
+ assert_1.default.doesNotThrow(() => JSON.parse(json), 'serialized form should be valid JSON');
246
+ const restored = pskt_1.Pskt.deserialize(json);
247
+ assert_1.default.equal(restored.role, 'SIGNER');
248
+ assert_1.default.equal(restored.inputs.length, 1);
249
+ assert_1.default.equal(restored.outputs.length, 1);
250
+ assert_1.default.equal(restored.inputs[0].previousOutpoint.transactionId, kaspa_fixtures_1.UTXOS.simple.transactionId);
251
+ assert_1.default.equal(restored.outputs[0].amount, '99998000');
252
+ });
253
+ it('round-trips a signed PSKT preserving partialSigs', function () {
254
+ const signed = pskt_1.Pskt.creator()
255
+ .toUpdater()
256
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
257
+ .output(makePsktOutput())
258
+ .toSigner()
259
+ .sign(PRV_KEY_BUF);
260
+ const restored = pskt_1.Pskt.deserialize(signed.serialize());
261
+ assert_1.default.equal(restored.role, 'SIGNER');
262
+ const sigs = Object.entries(restored.inputs[0].partialSigs);
263
+ assert_1.default.equal(sigs.length, 1, 'partialSigs should survive round-trip');
264
+ assert_1.default.equal(sigs[0][0], kaspa_fixtures_1.KEYS.pub);
265
+ });
266
+ it('throws on invalid PSKT JSON', function () {
267
+ assert_1.default.throws(() => pskt_1.Pskt.deserialize('not json'), /JSON/i);
268
+ assert_1.default.throws(() => pskt_1.Pskt.deserialize('{}'), /missing required fields/i);
269
+ });
270
+ });
271
+ describe('PSKT — extract() matches Transaction.toBroadcastFormat()', function () {
272
+ it('single-input: extract() === toBroadcastFormat()', function () {
273
+ const tx = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.simple);
274
+ tx.sign(PRV_KEY_BUF);
275
+ // PSKT path
276
+ const broadcastViaPskt = tx
277
+ .toPskt() // SIGNER role, finalScriptSig already set from tx.sign()
278
+ .toFinalizer()
279
+ .finalize()
280
+ .toExtractor()
281
+ .extract();
282
+ // Direct path
283
+ const broadcastDirect = tx.toBroadcastFormat();
284
+ assert_1.default.deepStrictEqual(JSON.parse(broadcastViaPskt), JSON.parse(broadcastDirect));
285
+ });
286
+ it('multi-input: extract() === toBroadcastFormat()', function () {
287
+ const tx = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.multiInput);
288
+ tx.sign(PRV_KEY_BUF);
289
+ const broadcastViaPskt = tx.toPskt().toFinalizer().finalize().toExtractor().extract();
290
+ const broadcastDirect = tx.toBroadcastFormat();
291
+ assert_1.default.deepStrictEqual(JSON.parse(broadcastViaPskt), JSON.parse(broadcastDirect));
292
+ });
293
+ it('PSKT-signed extract() === direct sign + toBroadcastFormat()', function () {
294
+ // Build via PSKT from scratch
295
+ const broadcastViaPskt = pskt_1.Pskt.creator()
296
+ .toUpdater()
297
+ .input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
298
+ .output(makePsktOutput())
299
+ .toSigner()
300
+ .sign(PRV_KEY_BUF)
301
+ .toFinalizer()
302
+ .finalize()
303
+ .toExtractor()
304
+ .extract();
305
+ // Build via Transaction directly
306
+ const tx = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.simple);
307
+ tx.sign(PRV_KEY_BUF);
308
+ const broadcastDirect = tx.toBroadcastFormat();
309
+ assert_1.default.deepStrictEqual(JSON.parse(broadcastViaPskt), JSON.parse(broadcastDirect));
310
+ });
311
+ });
312
+ describe('PSKT — Transaction.toPskt() and Transaction.fromPskt()', function () {
313
+ it('toPskt() returns a SIGNER-role PSKT with UTXO data populated', function () {
314
+ const tx = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.simple);
315
+ const pskt = tx.toPskt();
316
+ assert_1.default.equal(pskt.role, 'SIGNER');
317
+ assert_1.default.equal(pskt.inputs.length, 1);
318
+ assert_1.default.equal(pskt.inputs[0].utxoEntry?.amount, kaspa_fixtures_1.UTXOS.simple.amount);
319
+ assert_1.default.equal(pskt.inputs[0].utxoEntry?.scriptPublicKey, kaspa_fixtures_1.UTXOS.simple.scriptPublicKey);
320
+ });
321
+ it('fromPskt() reconstructs a Transaction from a finalised PSKT', function () {
322
+ const original = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.simple);
323
+ original.sign(PRV_KEY_BUF);
324
+ const pskt = original.toPskt().toFinalizer().finalize();
325
+ const restored = transaction_1.Transaction.fromPskt('kaspa', pskt);
326
+ assert_1.default.deepStrictEqual(JSON.parse(restored.toBroadcastFormat()), JSON.parse(original.toBroadcastFormat()));
327
+ });
328
+ it('fromPskt() → verifySignature() succeeds', function () {
329
+ const original = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.simple);
330
+ original.sign(PRV_KEY_BUF);
331
+ const pskt = original.toPskt().toFinalizer().finalize();
332
+ const restored = transaction_1.Transaction.fromPskt('kaspa', pskt);
333
+ assert_1.default.ok(restored.verifySignature(PUB_KEY_BUF, 0), 'signature should verify after fromPskt()');
334
+ });
335
+ });
336
+ describe('PSKT — TransactionBuilder.toPskt()', function () {
337
+ it('returns an UPDATER-role PSKT with all inputs and outputs', async function () {
338
+ const coinConfig = statics_1.coins.get('kaspa');
339
+ const builder = new transactionBuilder_1.TransactionBuilder(coinConfig);
340
+ builder.addInput(kaspa_fixtures_1.UTXOS.simple).to(kaspa_fixtures_1.ADDRESSES.recipient, '99998000').fee('2000');
341
+ const pskt = await builder.toPskt();
342
+ assert_1.default.equal(pskt.role, 'UPDATER');
343
+ assert_1.default.equal(pskt.inputs.length, 1);
344
+ assert_1.default.equal(pskt.outputs.length, 1);
345
+ assert_1.default.equal(pskt.inputs[0].previousOutpoint.transactionId, kaspa_fixtures_1.UTXOS.simple.transactionId);
346
+ assert_1.default.equal(pskt.outputs[0].amount, '99998000');
347
+ });
348
+ it('UPDATER PSKT can be signed and extracted to produce a valid broadcast payload', async function () {
349
+ const coinConfig = statics_1.coins.get('kaspa');
350
+ const builder = new transactionBuilder_1.TransactionBuilder(coinConfig);
351
+ builder.addInput(kaspa_fixtures_1.UTXOS.simple).to(kaspa_fixtures_1.ADDRESSES.recipient, '99998000').fee('2000');
352
+ const broadcast = (await builder.toPskt())
353
+ .toSigner()
354
+ .sign(PRV_KEY_BUF)
355
+ .toFinalizer()
356
+ .finalize()
357
+ .toExtractor()
358
+ .extract();
359
+ assert_1.default.doesNotThrow(() => JSON.parse(broadcast), 'extract() should produce valid JSON');
360
+ const parsed = JSON.parse(broadcast);
361
+ assert_1.default.ok(parsed.inputs[0].signatureScript, 'signatureScript should be set');
362
+ assert_1.default.equal(Buffer.from(parsed.inputs[0].signatureScript, 'hex').length, 66);
363
+ });
364
+ it('PSKT from builder matches broadcast from Transaction.sign()', async function () {
365
+ const coinConfig = statics_1.coins.get('kaspa');
366
+ const builder = new transactionBuilder_1.TransactionBuilder(coinConfig);
367
+ builder.addInput(kaspa_fixtures_1.UTXOS.simple).to(kaspa_fixtures_1.ADDRESSES.recipient, '99998000').fee('2000');
368
+ const broadcastViaPskt = (await builder.toPskt())
369
+ .toSigner()
370
+ .sign(PRV_KEY_BUF)
371
+ .toFinalizer()
372
+ .finalize()
373
+ .toExtractor()
374
+ .extract();
375
+ // Rebuild via standard path
376
+ const builder2 = new transactionBuilder_1.TransactionBuilder(coinConfig);
377
+ builder2.addInput(kaspa_fixtures_1.UTXOS.simple).to(kaspa_fixtures_1.ADDRESSES.recipient, '99998000').fee('2000');
378
+ const tx = (await builder2.build());
379
+ tx.sign(PRV_KEY_BUF);
380
+ assert_1.default.deepStrictEqual(JSON.parse(broadcastViaPskt), JSON.parse(tx.toBroadcastFormat()));
381
+ });
382
+ });
383
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHNrdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L3Bza3QudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7OztHQVlHOzs7OztBQUVILG9EQUE0QjtBQUM1QixpREFBNEM7QUFDNUMscURBQTRDO0FBQzVDLDZDQUFpRTtBQUNqRSwyREFBd0Q7QUFDeEQseUVBQXNFO0FBQ3RFLG1EQUFnRTtBQUNoRSx1REFBc0Q7QUFDdEQsK0RBQXFHO0FBRXJHLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMscUJBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDakQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxxQkFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNqRCxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0FBRWpGLGlGQUFpRjtBQUVqRixTQUFTLGFBQWEsQ0FBQyxJQUE4QjtJQUNuRCxPQUFPO1FBQ0wsZ0JBQWdCLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1FBQ3JGLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLGVBQWUsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFFO1FBQ3pFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtRQUN2QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDO1FBQ2hDLFdBQVcsRUFBRSxFQUFFO1FBQ2YsV0FBVyxFQUFFLHVCQUFXO1FBQ3hCLGdCQUFnQixFQUFFLEVBQUU7UUFDcEIsYUFBYSxFQUFFLEVBQUU7S0FDbEIsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLGNBQWM7SUFDckIs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Q0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsMEJBQVMsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRS9FLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQzthQUM5QyxRQUFRLEVBQUU7YUFDVixJQUFJLENBQUMsV0FBVyxDQUFDO2FBQ2pCLFdBQVcsRUFBRTthQUNiLFFBQVEsRUFBRTthQUNWLFdBQVcsRUFBRTthQUNiLE9BQU8sRUFBRSxDQUFDO1FBRWIsNEJBQTRCO1FBQzVCLE1BQU0sUUFBUSxHQUFHLElBQUksdUNBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDcEQsUUFBUSxDQUFDLFFBQVEsQ0FBQyxzQkFBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQywwQkFBUyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEYsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBZ0IsQ0FBQztRQUNuRCxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXJCLGdCQUFNLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMzRixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQU0tUIChQYXJ0aWFsbHkgU2lnbmVkIEthc3BhIFRyYW5zYWN0aW9uKSDigJQgVW5pdCBUZXN0c1xuICpcbiAqIENvdmVyczpcbiAqICAgLSBGdWxsIHJvbGUgZmxvdzogQ1JFQVRPUiDihpIgVVBEQVRFUiDihpIgU0lHTkVSIOKGkiBGSU5BTElaRVIg4oaSIEVYVFJBQ1RPUlxuICogICAtIEhTTSAvIGV4dGVybmFsIHNpZ25pbmcgcGF0aCB2aWEgYWRkU2lnbmF0dXJlKClcbiAqICAgLSBNdWx0aS1wYXJ0eSBDT01CSU5FUiByb2xlXG4gKiAgIC0gc2VyaWFsaXplKCkgLyBkZXNlcmlhbGl6ZSgpIHJvdW5kLXRyaXBcbiAqICAgLSBFeHRyYWN0b3Igb3V0cHV0IG1hdGNoZXMgVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKVxuICogICAtIFRyYW5zYWN0aW9uLnRvUHNrdCgpIGFuZCBUcmFuc2FjdGlvbi5mcm9tUHNrdCgpIGJyaWRnZSBtZXRob2RzXG4gKiAgIC0gVHJhbnNhY3Rpb25CdWlsZGVyLnRvUHNrdCgpIHVuc2lnbmVkIFBTS1QgY29uc3RydWN0aW9uXG4gKiAgIC0gUm9sZSBndWFyZCBlcnJvcnNcbiAqL1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgZWNjIH0gZnJvbSAnQGJpdGdvLWJldGEvc2VjcDI1NmsxJztcbmltcG9ydCB7IFBza3QsIFBza3RJbnB1dCwgUHNrdE91dHB1dCB9IGZyb20gJy4uLy4uL3NyYy9saWIvcHNrdCc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbiB9IGZyb20gJy4uLy4uL3NyYy9saWIvdHJhbnNhY3Rpb24nO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25CdWlsZGVyIH0gZnJvbSAnLi4vLi4vc3JjL2xpYi90cmFuc2FjdGlvbkJ1aWxkZXInO1xuaW1wb3J0IHsgY29tcHV0ZUthc3BhU2lnbmluZ0hhc2ggfSBmcm9tICcuLi8uLi9zcmMvbGliL3NpZ2hhc2gnO1xuaW1wb3J0IHsgU0lHSEFTSF9BTEwgfSBmcm9tICcuLi8uLi9zcmMvbGliL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBLRVlTLCBBRERSRVNTRVMsIFVUWE9TLCBUUkFOU0FDVElPTlMsIFNDUklQVF9QVUJMSUNfS0VZIH0gZnJvbSAnLi4vZml4dHVyZXMva2FzcGEuZml4dHVyZXMnO1xuXG5jb25zdCBQUlZfS0VZX0JVRiA9IEJ1ZmZlci5mcm9tKEtFWVMucHJ2LCAnaGV4Jyk7XG5jb25zdCBQVUJfS0VZX0JVRiA9IEJ1ZmZlci5mcm9tKEtFWVMucHViLCAnaGV4Jyk7XG5jb25zdCBYX09OTFlfUFVCID0gUFVCX0tFWV9CVUYuc2xpY2UoMSk7IC8vIDMyLWJ5dGUgeC1vbmx5IGtleSBmb3IgU2Nobm9yciB2ZXJpZnlcblxuLy8g4pSA4pSA4pSAIEhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmZ1bmN0aW9uIG1ha2VQc2t0SW5wdXQodXR4bzogKHR5cGVvZiBVVFhPUylbJ3NpbXBsZSddKTogUHNrdElucHV0IHtcbiAgcmV0dXJuIHtcbiAgICBwcmV2aW91c091dHBvaW50OiB7IHRyYW5zYWN0aW9uSWQ6IHV0eG8udHJhbnNhY3Rpb25JZCwgaW5kZXg6IHV0eG8udHJhbnNhY3Rpb25JbmRleCB9LFxuICAgIHV0eG9FbnRyeTogeyBhbW91bnQ6IHV0eG8uYW1vdW50LCBzY3JpcHRQdWJsaWNLZXk6IHV0eG8uc2NyaXB0UHVibGljS2V5IH0sXG4gICAgc2VxdWVuY2U6IHV0eG8uc2VxdWVuY2UsXG4gICAgc2lnT3BDb3VudDogdXR4by5zaWdPcENvdW50ID8/IDEsXG4gICAgcGFydGlhbFNpZ3M6IHt9LFxuICAgIHNpZ2hhc2hUeXBlOiBTSUdIQVNIX0FMTCxcbiAgICBiaXAzMkRlcml2YXRpb25zOiB7fSxcbiAgICBwcm9wcmlldGFyaWVzOiB7fSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbWFrZVBza3RPdXRwdXQoKTogUHNrdE91dHB1dCB7XG4gIHJldHVybiB7XG4gICAgYW1vdW50OiAnOTk5OTgwMDAnLFxuICAgIHNjcmlwdFB1YmxpY0tleTogeyB2ZXJzaW9uOiAwLCBzY3JpcHRQdWJsaWNLZXk6IFNDUklQVF9QVUJMSUNfS0VZIH0sXG4gICAgYmlwMzJEZXJpdmF0aW9uczoge30sXG4gICAgcHJvcHJpZXRhcmllczoge30sXG4gIH07XG59XG5cbi8vIOKUgOKUgOKUgCBUZXN0cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZGVzY3JpYmUoJ1BTS1Qg4oCUIHJvbGUgc3RhdGUgbWFjaGluZScsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ2VuZm9yY2VzIHJvbGUgdHJhbnNpdGlvbnM6IENSRUFUT1Ig4oaSIFVQREFURVIg4oaSIFNJR05FUiDihpIgRklOQUxJWkVSIOKGkiBFWFRSQUNUT1InLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgcHNrdCA9IFBza3QuY3JlYXRvcigpO1xuICAgIGFzc2VydC5lcXVhbChwc2t0LnJvbGUsICdDUkVBVE9SJyk7XG5cbiAgICBjb25zdCB1cGRhdGVyID0gcHNrdC50b1VwZGF0ZXIoKTtcbiAgICBhc3NlcnQuZXF1YWwodXBkYXRlci5yb2xlLCAnVVBEQVRFUicpO1xuXG4gICAgY29uc3Qgc2lnbmVyID0gdXBkYXRlci5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKS50b1NpZ25lcigpO1xuICAgIGFzc2VydC5lcXVhbChzaWduZXIucm9sZSwgJ1NJR05FUicpO1xuXG4gICAgY29uc3QgZmluYWxpemVyID0gc2lnbmVyLnNpZ24oUFJWX0tFWV9CVUYpLnRvRmluYWxpemVyKCk7XG4gICAgYXNzZXJ0LmVxdWFsKGZpbmFsaXplci5yb2xlLCAnRklOQUxJWkVSJyk7XG5cbiAgICBjb25zdCBleHRyYWN0b3IgPSBmaW5hbGl6ZXIuZmluYWxpemUoKS50b0V4dHJhY3RvcigpO1xuICAgIGFzc2VydC5lcXVhbChleHRyYWN0b3Iucm9sZSwgJ0VYVFJBQ1RPUicpO1xuICB9KTtcblxuICBpdCgnZW5mb3JjZXMgcm9sZSB0cmFuc2l0aW9uczogU0lHTkVSIOKGkiBDT01CSU5FUiDihpIgRklOQUxJWkVSIOKGkiBFWFRSQUNUT1InLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2lnbmVyID0gUHNrdC5jcmVhdG9yKClcbiAgICAgIC50b1VwZGF0ZXIoKVxuICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSlcbiAgICAgIC5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSlcbiAgICAgIC50b1NpZ25lcigpXG4gICAgICAuc2lnbihQUlZfS0VZX0JVRik7XG5cbiAgICBjb25zdCBjb21iaW5lciA9IHNpZ25lci50b0NvbWJpbmVyKCk7XG4gICAgYXNzZXJ0LmVxdWFsKGNvbWJpbmVyLnJvbGUsICdDT01CSU5FUicpO1xuXG4gICAgY29uc3QgZmluYWxpemVyID0gY29tYmluZXIudG9GaW5hbGl6ZXIoKTtcbiAgICBhc3NlcnQuZXF1YWwoZmluYWxpemVyLnJvbGUsICdGSU5BTElaRVInKTtcblxuICAgIGNvbnN0IGV4dHJhY3RvciA9IGZpbmFsaXplci5maW5hbGl6ZSgpLnRvRXh0cmFjdG9yKCk7XG4gICAgYXNzZXJ0LmVxdWFsKGV4dHJhY3Rvci5yb2xlLCAnRVhUUkFDVE9SJyk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgd2hlbiBjYWxsaW5nIHRvVXBkYXRlcigpIGZyb20gU0lHTkVSIHJvbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2lnbmVyID0gUHNrdC5jcmVhdG9yKCkudG9VcGRhdGVyKCkuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKS5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSkudG9TaWduZXIoKTtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHNpZ25lci50b1VwZGF0ZXIoKSwgL3JvbGUvaSk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgd2hlbiBjYWxsaW5nIHNpZ24oKSBmcm9tIEZJTkFMSVpFUiByb2xlJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGZpbmFsaXplciA9IFBza3QuY3JlYXRvcigpXG4gICAgICAudG9VcGRhdGVyKClcbiAgICAgIC5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpXG4gICAgICAub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpXG4gICAgICAudG9TaWduZXIoKVxuICAgICAgLnNpZ24oUFJWX0tFWV9CVUYpXG4gICAgICAudG9GaW5hbGl6ZXIoKTtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IGZpbmFsaXplci5zaWduKFBSVl9LRVlfQlVGKSwgL3JvbGUvaSk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3MgdG9FeHRyYWN0b3IoKSB3aGVuIGlucHV0cyBhcmUgbm90IGZpbmFsaXplZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBmaW5hbGl6ZXIgPSBQc2t0LmNyZWF0b3IoKVxuICAgICAgLnRvVXBkYXRlcigpXG4gICAgICAuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKVxuICAgICAgLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC50b0ZpbmFsaXplcigpOyAvLyBza2lwIHNpZ25pbmdcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IGZpbmFsaXplci50b0V4dHJhY3RvcigpLCAvZmluYWxpc2VkfGZpbmFsU2NyaXB0U2lnL2kpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGZpbmFsaXplKCkgd2hlbiBpbnB1dCBoYXMgbm8gcGFydGlhbCBzaWduYXR1cmVzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGZpbmFsaXplciA9IFBza3QuY3JlYXRvcigpXG4gICAgICAudG9VcGRhdGVyKClcbiAgICAgIC5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpXG4gICAgICAub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpXG4gICAgICAudG9TaWduZXIoKVxuICAgICAgLnRvRmluYWxpemVyKCk7XG4gICAgYXNzZXJ0LnRocm93cygoKSA9PiBmaW5hbGl6ZXIuZmluYWxpemUoKSwgL25vIHBhcnRpYWwgc2lnbmF0dXJlcy9pKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ1BTS1Qg4oCUIHNpZ24oKSBwcm9kdWNlcyB2YWxpZCBTY2hub3JyIHNpZ25hdHVyZXMnLCBmdW5jdGlvbiAoKSB7XG4gIGl0KCdzaWduKCkgd3JpdGVzIHBhcnRpYWxTaWdzIGZvciBlYWNoIGlucHV0JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNpZ25lciA9IFBza3QuY3JlYXRvcigpXG4gICAgICAudG9VcGRhdGVyKClcbiAgICAgIC5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpXG4gICAgICAub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpXG4gICAgICAudG9TaWduZXIoKVxuICAgICAgLnNpZ24oUFJWX0tFWV9CVUYpO1xuXG4gICAgYXNzZXJ0LmVxdWFsKHNpZ25lci5pbnB1dHMubGVuZ3RoLCAxKTtcbiAgICBjb25zdCBzaWdzID0gT2JqZWN0LmVudHJpZXMoc2lnbmVyLmlucHV0c1swXS5wYXJ0aWFsU2lncyk7XG4gICAgYXNzZXJ0LmVxdWFsKHNpZ3MubGVuZ3RoLCAxLCAnc2hvdWxkIGhhdmUgZXhhY3RseSBvbmUgcGFydGlhbCBzaWcnKTtcbiAgICBjb25zdCBbcHViS2V5SGV4LCBzaWdIZXhdID0gc2lnc1swXTtcbiAgICBhc3NlcnQuZXF1YWwocHViS2V5SGV4LCBLRVlTLnB1YiwgJ3B1YktleSBrZXkgc2hvdWxkIG1hdGNoJyk7XG4gICAgYXNzZXJ0LmVxdWFsKEJ1ZmZlci5mcm9tKHNpZ0hleCwgJ2hleCcpLmxlbmd0aCwgNjQsICdzaWcgc2hvdWxkIGJlIDY0IGJ5dGVzJyk7XG4gIH0pO1xuXG4gIGl0KCdzaWduKCkgU2Nobm9yciBzaWduYXR1cmVzIHZlcmlmeSBhZ2FpbnN0IHRoZSBjb3JyZWN0IHBlci1pbnB1dCBzaWdoYXNoJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHBza3QgPSBQc2t0LmNyZWF0b3IoKVxuICAgICAgLnRvVXBkYXRlcigpXG4gICAgICAuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKVxuICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2Vjb25kKSlcbiAgICAgIC5vdXRwdXQoe1xuICAgICAgICBhbW91bnQ6ICcyOTk5OTgwMDAnLFxuICAgICAgICBzY3JpcHRQdWJsaWNLZXk6IHsgdmVyc2lvbjogMCwgc2NyaXB0UHVibGljS2V5OiBTQ1JJUFRfUFVCTElDX0tFWSB9LFxuICAgICAgICBiaXAzMkRlcml2YXRpb25zOiB7fSxcbiAgICAgICAgcHJvcHJpZXRhcmllczoge30sXG4gICAgICB9KVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC5zaWduKFBSVl9LRVlfQlVGKTtcblxuICAgIC8vIEJ1aWxkIG1hdGNoaW5nIEthc3BhVHJhbnNhY3Rpb25EYXRhIGZvciBzaWdoYXNoIHJlZmVyZW5jZVxuICAgIGNvbnN0IHR4RGF0YSA9IFRSQU5TQUNUSU9OUy5tdWx0aUlucHV0O1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwc2t0LmlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgc2lncyA9IE9iamVjdC52YWx1ZXMocHNrdC5pbnB1dHNbaV0ucGFydGlhbFNpZ3MpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHNpZ3MubGVuZ3RoLCAxKTtcbiAgICAgIGNvbnN0IHNpZyA9IEJ1ZmZlci5mcm9tKHNpZ3NbMF0sICdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkSGFzaCA9IGNvbXB1dGVLYXNwYVNpZ25pbmdIYXNoKHR4RGF0YSwgaSwgU0lHSEFTSF9BTEwpO1xuICAgICAgYXNzZXJ0Lm9rKGVjYy52ZXJpZnlTY2hub3JyKGV4cGVjdGVkSGFzaCwgWF9PTkxZX1BVQiwgc2lnKSwgYElucHV0WyR7aX1dIFNjaG5vcnIgc2lnIHNob3VsZCB2ZXJpZnlgKTtcbiAgICB9XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBhZGRTaWduYXR1cmUoKSAoSFNNIC8gZXh0ZXJuYWwgc2lnbmluZyBwYXRoKScsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ2FkZFNpZ25hdHVyZSgpIHdyaXRlcyB0aGUgcHJvdmlkZWQgc2lnIGludG8gcGFydGlhbFNpZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2lnbmVyID0gUHNrdC5jcmVhdG9yKCkudG9VcGRhdGVyKCkuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKS5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSkudG9TaWduZXIoKTtcblxuICAgIC8vIFByb2R1Y2Ugc2lnIGV4dGVybmFsbHlcbiAgICBjb25zdCB0eERhdGEgPSBUUkFOU0FDVElPTlMuc2ltcGxlO1xuICAgIGNvbnN0IHNpZ0hhc2ggPSBjb21wdXRlS2FzcGFTaWduaW5nSGFzaCh0eERhdGEsIDAsIFNJR0hBU0hfQUxMKTtcbiAgICBjb25zdCBzaWcgPSBCdWZmZXIuZnJvbShlY2Muc2lnblNjaG5vcnIoc2lnSGFzaCwgUFJWX0tFWV9CVUYpKTtcbiAgICBzaWduZXIuYWRkU2lnbmF0dXJlKDAsIEtFWVMucHViLCBzaWcudG9TdHJpbmcoJ2hleCcpKTtcblxuICAgIGNvbnN0IHNpZ3MgPSBPYmplY3QuZW50cmllcyhzaWduZXIuaW5wdXRzWzBdLnBhcnRpYWxTaWdzKTtcbiAgICBhc3NlcnQuZXF1YWwoc2lncy5sZW5ndGgsIDEpO1xuICAgIGFzc2VydC5lcXVhbChzaWdzWzBdWzBdLCBLRVlTLnB1Yik7XG4gICAgYXNzZXJ0LmVxdWFsKHNpZ3NbMF1bMV0sIHNpZy50b1N0cmluZygnaGV4JykpO1xuICB9KTtcblxuICBpdCgnYWRkU2lnbmF0dXJlKCkg4oaSIGZpbmFsaXplKCkgcHJvZHVjZXMgYSB2YWxpZCBmaW5hbFNjcmlwdFNpZycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB0eERhdGEgPSBUUkFOU0FDVElPTlMuc2ltcGxlO1xuICAgIGNvbnN0IHNpZ0hhc2ggPSBjb21wdXRlS2FzcGFTaWduaW5nSGFzaCh0eERhdGEsIDAsIFNJR0hBU0hfQUxMKTtcbiAgICBjb25zdCBzaWcgPSBCdWZmZXIuZnJvbShlY2Muc2lnblNjaG5vcnIoc2lnSGFzaCwgUFJWX0tFWV9CVUYpKTtcblxuICAgIGNvbnN0IHBza3QgPSBQc2t0LmNyZWF0b3IoKVxuICAgICAgLnRvVXBkYXRlcigpXG4gICAgICAuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKVxuICAgICAgLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC5hZGRTaWduYXR1cmUoMCwgS0VZUy5wdWIsIHNpZy50b1N0cmluZygnaGV4JykpXG4gICAgICAudG9GaW5hbGl6ZXIoKVxuICAgICAgLmZpbmFsaXplKCk7XG5cbiAgICBjb25zdCBmaW5hbFNpZyA9IHBza3QuaW5wdXRzWzBdLmZpbmFsU2NyaXB0U2lnO1xuICAgIGFzc2VydC5vayhmaW5hbFNpZywgJ2ZpbmFsU2NyaXB0U2lnIHNob3VsZCBiZSBzZXQnKTtcbiAgICBjb25zdCBmaW5hbEJ1ZiA9IEJ1ZmZlci5mcm9tKGZpbmFsU2lnLCAnaGV4Jyk7XG4gICAgYXNzZXJ0LmVxdWFsKGZpbmFsQnVmLmxlbmd0aCwgNjYsICdmaW5hbFNjcmlwdFNpZyBzaG91bGQgYmUgNjYgYnl0ZXMgKDB4NDEgKyA2NC1ieXRlIHNpZyArIDEtYnl0ZSBzaWdoYXNoKScpO1xuICAgIGFzc2VydC5lcXVhbChmaW5hbEJ1ZlswXSwgMHg0MSwgJ2ZpcnN0IGJ5dGUgc2hvdWxkIGJlIE9QX0RBVEFfNjUnKTtcbiAgICBhc3NlcnQuZXF1YWwoZmluYWxCdWZbNjVdLCBTSUdIQVNIX0FMTCwgJ2xhc3QgYnl0ZSBzaG91bGQgYmUgc2lnaGFzaCB0eXBlJyk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgb24gYWRkU2lnbmF0dXJlKCkgd2l0aCB3cm9uZy1zaXplZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2lnbmVyID0gUHNrdC5jcmVhdG9yKCkudG9VcGRhdGVyKCkuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKS5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSkudG9TaWduZXIoKTtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHNpZ25lci5hZGRTaWduYXR1cmUoMCwgS0VZUy5wdWIsICdkZWFkYmVlZicpLCAvNjQtYnl0ZS9pKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyBvbiBhZGRTaWduYXR1cmUoKSB3aXRoIG91dC1vZi1yYW5nZSBpbnB1dCBpbmRleCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBzaWduZXIgPSBQc2t0LmNyZWF0b3IoKS50b1VwZGF0ZXIoKS5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKS50b1NpZ25lcigpO1xuICAgIGFzc2VydC50aHJvd3MoKCkgPT4gc2lnbmVyLmFkZFNpZ25hdHVyZSg5OSwgS0VZUy5wdWIsICdhYScucmVwZWF0KDY0KSksIC9vdXQgb2YgcmFuZ2UvaSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBjb21iaW5lKCkgbWVyZ2VzIHBhcnRpYWxTaWdzJywgZnVuY3Rpb24gKCkge1xuICBpdCgnY29tYmluZSgpIG1lcmdlcyBwYXJ0aWFsIHNpZ25hdHVyZXMgZnJvbSB0d28gc2lnbmVycycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBidWlsZFNpZ25lZCA9ICgpID0+XG4gICAgICBQc2t0LmNyZWF0b3IoKVxuICAgICAgICAudG9VcGRhdGVyKClcbiAgICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSlcbiAgICAgICAgLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKVxuICAgICAgICAudG9TaWduZXIoKVxuICAgICAgICAuc2lnbihQUlZfS0VZX0JVRik7XG5cbiAgICBjb25zdCBwc2t0MSA9IGJ1aWxkU2lnbmVkKCk7XG4gICAgY29uc3QgcHNrdDIgPSBidWlsZFNpZ25lZCgpO1xuXG4gICAgLy8gQm90aCBoYXZlIHRoZSBzYW1lIHNpZzsgY29tYmluaW5nIHNob3VsZCBzdWNjZWVkIChpZGVtcG90ZW50KVxuICAgIGNvbnN0IGNvbWJpbmVkID0gcHNrdDEudG9Db21iaW5lcigpLmNvbWJpbmUocHNrdDIpO1xuICAgIGNvbnN0IHNpZ3MgPSBPYmplY3QuZW50cmllcyhjb21iaW5lZC5pbnB1dHNbMF0ucGFydGlhbFNpZ3MpO1xuICAgIGFzc2VydC5lcXVhbChzaWdzLmxlbmd0aCwgMSk7XG4gIH0pO1xuXG4gIGl0KCdjb21iaW5lKCkgdGhyb3dzIG9uIGNvbmZsaWN0aW5nIHNpZ25hdHVyZXMgZm9yIHRoZSBzYW1lIHB1YktleScsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBTaW11bGF0ZSB0d28gZGlmZmVyZW50IHNpZ25lcnMgYnkgbWFudWFsbHkgaW5qZWN0aW5nIGRpZmZlcmVudCBzaWdzXG4gICAgY29uc3Qgc2lnbmVyMSA9IFBza3QuY3JlYXRvcigpXG4gICAgICAudG9VcGRhdGVyKClcbiAgICAgIC5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpXG4gICAgICAub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpXG4gICAgICAudG9TaWduZXIoKVxuICAgICAgLmFkZFNpZ25hdHVyZSgwLCBLRVlTLnB1YiwgJ2FhJy5yZXBlYXQoNjQpKTtcblxuICAgIGNvbnN0IHNpZ25lcjIgPSBQc2t0LmNyZWF0b3IoKVxuICAgICAgLnRvVXBkYXRlcigpXG4gICAgICAuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKVxuICAgICAgLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC5hZGRTaWduYXR1cmUoMCwgS0VZUy5wdWIsICdiYicucmVwZWF0KDY0KSk7XG5cbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHNpZ25lcjEudG9Db21iaW5lcigpLmNvbWJpbmUoc2lnbmVyMiksIC9jb25mbGljdGluZyBzaWduYXR1cmUvaSk7XG4gIH0pO1xuXG4gIGl0KCdjb21iaW5lKCkgdGhyb3dzIG9uIGlucHV0IGNvdW50IG1pc21hdGNoJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGEgPSBQc2t0LmNyZWF0b3IoKVxuICAgICAgLnRvVXBkYXRlcigpXG4gICAgICAuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKVxuICAgICAgLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC50b0NvbWJpbmVyKCk7XG5cbiAgICBjb25zdCBiID0gUHNrdC5jcmVhdG9yKClcbiAgICAgIC50b1VwZGF0ZXIoKVxuICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSlcbiAgICAgIC5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNlY29uZCkpXG4gICAgICAub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpXG4gICAgICAudG9TaWduZXIoKVxuICAgICAgLnRvQ29tYmluZXIoKTtcblxuICAgIGFzc2VydC50aHJvd3MoKCkgPT4gYS5jb21iaW5lKGIpLCAvaW5wdXQgY291bnQgbWlzbWF0Y2gvaSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBzZXJpYWxpemUoKSAvIGRlc2VyaWFsaXplKCkgcm91bmQtdHJpcCcsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ3JvdW5kLXRyaXBzIGEgUFNLVCBpbiBTSUdORVIgcm9sZSBiZWZvcmUgc2lnbmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBvcmlnaW5hbCA9IFBza3QuY3JlYXRvcigpLnRvVXBkYXRlcigpLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSkub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpLnRvU2lnbmVyKCk7XG5cbiAgICBjb25zdCBqc29uID0gb3JpZ2luYWwuc2VyaWFsaXplKCk7XG4gICAgYXNzZXJ0LmRvZXNOb3RUaHJvdygoKSA9PiBKU09OLnBhcnNlKGpzb24pLCAnc2VyaWFsaXplZCBmb3JtIHNob3VsZCBiZSB2YWxpZCBKU09OJyk7XG5cbiAgICBjb25zdCByZXN0b3JlZCA9IFBza3QuZGVzZXJpYWxpemUoanNvbik7XG4gICAgYXNzZXJ0LmVxdWFsKHJlc3RvcmVkLnJvbGUsICdTSUdORVInKTtcbiAgICBhc3NlcnQuZXF1YWwocmVzdG9yZWQuaW5wdXRzLmxlbmd0aCwgMSk7XG4gICAgYXNzZXJ0LmVxdWFsKHJlc3RvcmVkLm91dHB1dHMubGVuZ3RoLCAxKTtcbiAgICBhc3NlcnQuZXF1YWwocmVzdG9yZWQuaW5wdXRzWzBdLnByZXZpb3VzT3V0cG9pbnQudHJhbnNhY3Rpb25JZCwgVVRYT1Muc2ltcGxlLnRyYW5zYWN0aW9uSWQpO1xuICAgIGFzc2VydC5lcXVhbChyZXN0b3JlZC5vdXRwdXRzWzBdLmFtb3VudCwgJzk5OTk4MDAwJyk7XG4gIH0pO1xuXG4gIGl0KCdyb3VuZC10cmlwcyBhIHNpZ25lZCBQU0tUIHByZXNlcnZpbmcgcGFydGlhbFNpZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2lnbmVkID0gUHNrdC5jcmVhdG9yKClcbiAgICAgIC50b1VwZGF0ZXIoKVxuICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSlcbiAgICAgIC5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSlcbiAgICAgIC50b1NpZ25lcigpXG4gICAgICAuc2lnbihQUlZfS0VZX0JVRik7XG5cbiAgICBjb25zdCByZXN0b3JlZCA9IFBza3QuZGVzZXJpYWxpemUoc2lnbmVkLnNlcmlhbGl6ZSgpKTtcbiAgICBhc3NlcnQuZXF1YWwocmVzdG9yZWQucm9sZSwgJ1NJR05FUicpO1xuICAgIGNvbnN0IHNpZ3MgPSBPYmplY3QuZW50cmllcyhyZXN0b3JlZC5pbnB1dHNbMF0ucGFydGlhbFNpZ3MpO1xuICAgIGFzc2VydC5lcXVhbChzaWdzLmxlbmd0aCwgMSwgJ3BhcnRpYWxTaWdzIHNob3VsZCBzdXJ2aXZlIHJvdW5kLXRyaXAnKTtcbiAgICBhc3NlcnQuZXF1YWwoc2lnc1swXVswXSwgS0VZUy5wdWIpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIG9uIGludmFsaWQgUFNLVCBKU09OJywgZnVuY3Rpb24gKCkge1xuICAgIGFzc2VydC50aHJvd3MoKCkgPT4gUHNrdC5kZXNlcmlhbGl6ZSgnbm90IGpzb24nKSwgL0pTT04vaSk7XG4gICAgYXNzZXJ0LnRocm93cygoKSA9PiBQc2t0LmRlc2VyaWFsaXplKCd7fScpLCAvbWlzc2luZyByZXF1aXJlZCBmaWVsZHMvaSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBleHRyYWN0KCkgbWF0Y2hlcyBUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpJywgZnVuY3Rpb24gKCkge1xuICBpdCgnc2luZ2xlLWlucHV0OiBleHRyYWN0KCkgPT09IHRvQnJvYWRjYXN0Rm9ybWF0KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgdHggPSBUcmFuc2FjdGlvbi5mcm9tSnNvbigna2FzcGEnLCBUUkFOU0FDVElPTlMuc2ltcGxlKTtcbiAgICB0eC5zaWduKFBSVl9LRVlfQlVGKTtcblxuICAgIC8vIFBTS1QgcGF0aFxuICAgIGNvbnN0IGJyb2FkY2FzdFZpYVBza3QgPSB0eFxuICAgICAgLnRvUHNrdCgpIC8vIFNJR05FUiByb2xlLCBmaW5hbFNjcmlwdFNpZyBhbHJlYWR5IHNldCBmcm9tIHR4LnNpZ24oKVxuICAgICAgLnRvRmluYWxpemVyKClcbiAgICAgIC5maW5hbGl6ZSgpXG4gICAgICAudG9FeHRyYWN0b3IoKVxuICAgICAgLmV4dHJhY3QoKTtcblxuICAgIC8vIERpcmVjdCBwYXRoXG4gICAgY29uc3QgYnJvYWRjYXN0RGlyZWN0ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoSlNPTi5wYXJzZShicm9hZGNhc3RWaWFQc2t0KSwgSlNPTi5wYXJzZShicm9hZGNhc3REaXJlY3QpKTtcbiAgfSk7XG5cbiAgaXQoJ211bHRpLWlucHV0OiBleHRyYWN0KCkgPT09IHRvQnJvYWRjYXN0Rm9ybWF0KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgdHggPSBUcmFuc2FjdGlvbi5mcm9tSnNvbigna2FzcGEnLCBUUkFOU0FDVElPTlMubXVsdGlJbnB1dCk7XG4gICAgdHguc2lnbihQUlZfS0VZX0JVRik7XG5cbiAgICBjb25zdCBicm9hZGNhc3RWaWFQc2t0ID0gdHgudG9Qc2t0KCkudG9GaW5hbGl6ZXIoKS5maW5hbGl6ZSgpLnRvRXh0cmFjdG9yKCkuZXh0cmFjdCgpO1xuICAgIGNvbnN0IGJyb2FkY2FzdERpcmVjdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKEpTT04ucGFyc2UoYnJvYWRjYXN0VmlhUHNrdCksIEpTT04ucGFyc2UoYnJvYWRjYXN0RGlyZWN0KSk7XG4gIH0pO1xuXG4gIGl0KCdQU0tULXNpZ25lZCBleHRyYWN0KCkgPT09IGRpcmVjdCBzaWduICsgdG9Ccm9hZGNhc3RGb3JtYXQoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBCdWlsZCB2aWEgUFNLVCBmcm9tIHNjcmF0Y2hcbiAgICBjb25zdCBicm9hZGNhc3RWaWFQc2t0ID0gUHNrdC5jcmVhdG9yKClcbiAgICAgIC50b1VwZGF0ZXIoKVxuICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSlcbiAgICAgIC5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSlcbiAgICAgIC50b1NpZ25lcigpXG4gICAgICAuc2lnbihQUlZfS0VZX0JVRilcbiAgICAgIC50b0ZpbmFsaXplcigpXG4gICAgICAuZmluYWxpemUoKVxuICAgICAgLnRvRXh0cmFjdG9yKClcbiAgICAgIC5leHRyYWN0KCk7XG5cbiAgICAvLyBCdWlsZCB2aWEgVHJhbnNhY3Rpb24gZGlyZWN0bHlcbiAgICBjb25zdCB0eCA9IFRyYW5zYWN0aW9uLmZyb21Kc29uKCdrYXNwYScsIFRSQU5TQUNUSU9OUy5zaW1wbGUpO1xuICAgIHR4LnNpZ24oUFJWX0tFWV9CVUYpO1xuICAgIGNvbnN0IGJyb2FkY2FzdERpcmVjdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKEpTT04ucGFyc2UoYnJvYWRjYXN0VmlhUHNrdCksIEpTT04ucGFyc2UoYnJvYWRjYXN0RGlyZWN0KSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBUcmFuc2FjdGlvbi50b1Bza3QoKSBhbmQgVHJhbnNhY3Rpb24uZnJvbVBza3QoKScsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ3RvUHNrdCgpIHJldHVybnMgYSBTSUdORVItcm9sZSBQU0tUIHdpdGggVVRYTyBkYXRhIHBvcHVsYXRlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB0eCA9IFRyYW5zYWN0aW9uLmZyb21Kc29uKCdrYXNwYScsIFRSQU5TQUNUSU9OUy5zaW1wbGUpO1xuICAgIGNvbnN0IHBza3QgPSB0eC50b1Bza3QoKTtcbiAgICBhc3NlcnQuZXF1YWwocHNrdC5yb2xlLCAnU0lHTkVSJyk7XG4gICAgYXNzZXJ0LmVxdWFsKHBza3QuaW5wdXRzLmxlbmd0aCwgMSk7XG4gICAgYXNzZXJ0LmVxdWFsKHBza3QuaW5wdXRzWzBdLnV0eG9FbnRyeT8uYW1vdW50LCBVVFhPUy5zaW1wbGUuYW1vdW50KTtcbiAgICBhc3NlcnQuZXF1YWwocHNrdC5pbnB1dHNbMF0udXR4b0VudHJ5Py5zY3JpcHRQdWJsaWNLZXksIFVUWE9TLnNpbXBsZS5zY3JpcHRQdWJsaWNLZXkpO1xuICB9KTtcblxuICBpdCgnZnJvbVBza3QoKSByZWNvbnN0cnVjdHMgYSBUcmFuc2FjdGlvbiBmcm9tIGEgZmluYWxpc2VkIFBTS1QnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgb3JpZ2luYWwgPSBUcmFuc2FjdGlvbi5mcm9tSnNvbigna2FzcGEnLCBUUkFOU0FDVElPTlMuc2ltcGxlKTtcbiAgICBvcmlnaW5hbC5zaWduKFBSVl9LRVlfQlVGKTtcblxuICAgIGNvbnN0IHBza3QgPSBvcmlnaW5hbC50b1Bza3QoKS50b0ZpbmFsaXplcigpLmZpbmFsaXplKCk7XG4gICAgY29uc3QgcmVzdG9yZWQgPSBUcmFuc2FjdGlvbi5mcm9tUHNrdCgna2FzcGEnLCBwc2t0KTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoSlNPTi5wYXJzZShyZXN0b3JlZC50b0Jyb2FkY2FzdEZvcm1hdCgpKSwgSlNPTi5wYXJzZShvcmlnaW5hbC50b0Jyb2FkY2FzdEZvcm1hdCgpKSk7XG4gIH0pO1xuXG4gIGl0KCdmcm9tUHNrdCgpIOKGkiB2ZXJpZnlTaWduYXR1cmUoKSBzdWNjZWVkcycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBvcmlnaW5hbCA9IFRyYW5zYWN0aW9uLmZyb21Kc29uKCdrYXNwYScsIFRSQU5TQUNUSU9OUy5zaW1wbGUpO1xuICAgIG9yaWdpbmFsLnNpZ24oUFJWX0tFWV9CVUYpO1xuXG4gICAgY29uc3QgcHNrdCA9IG9yaWdpbmFsLnRvUHNrdCgpLnRvRmluYWxpemVyKCkuZmluYWxpemUoKTtcbiAgICBjb25zdCByZXN0b3JlZCA9IFRyYW5zYWN0aW9uLmZyb21Qc2t0KCdrYXNwYScsIHBza3QpO1xuXG4gICAgYXNzZXJ0Lm9rKHJlc3RvcmVkLnZlcmlmeVNpZ25hdHVyZShQVUJfS0VZX0JVRiwgMCksICdzaWduYXR1cmUgc2hvdWxkIHZlcmlmeSBhZnRlciBmcm9tUHNrdCgpJyk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBUcmFuc2FjdGlvbkJ1aWxkZXIudG9Qc2t0KCknLCBmdW5jdGlvbiAoKSB7XG4gIGl0KCdyZXR1cm5zIGFuIFVQREFURVItcm9sZSBQU0tUIHdpdGggYWxsIGlucHV0cyBhbmQgb3V0cHV0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjb2luQ29uZmlnID0gY29pbnMuZ2V0KCdrYXNwYScpO1xuICAgIGNvbnN0IGJ1aWxkZXIgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyKGNvaW5Db25maWcpO1xuICAgIGJ1aWxkZXIuYWRkSW5wdXQoVVRYT1Muc2ltcGxlKS50byhBRERSRVNTRVMucmVjaXBpZW50LCAnOTk5OTgwMDAnKS5mZWUoJzIwMDAnKTtcblxuICAgIGNvbnN0IHBza3QgPSBhd2FpdCBidWlsZGVyLnRvUHNrdCgpO1xuICAgIGFzc2VydC5lcXVhbChwc2t0LnJvbGUsICdVUERBVEVSJyk7XG4gICAgYXNzZXJ0LmVxdWFsKHBza3QuaW5wdXRzLmxlbmd0aCwgMSk7XG4gICAgYXNzZXJ0LmVxdWFsKHBza3Qub3V0cHV0cy5sZW5ndGgsIDEpO1xuICAgIGFzc2VydC5lcXVhbChwc2t0LmlucHV0c1swXS5wcmV2aW91c091dHBvaW50LnRyYW5zYWN0aW9uSWQsIFVUWE9TLnNpbXBsZS50cmFuc2FjdGlvbklkKTtcbiAgICBhc3NlcnQuZXF1YWwocHNrdC5vdXRwdXRzWzBdLmFtb3VudCwgJzk5OTk4MDAwJyk7XG4gIH0pO1xuXG4gIGl0KCdVUERBVEVSIFBTS1QgY2FuIGJlIHNpZ25lZCBhbmQgZXh0cmFjdGVkIHRvIHByb2R1Y2UgYSB2YWxpZCBicm9hZGNhc3QgcGF5bG9hZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjb2luQ29uZmlnID0gY29pbnMuZ2V0KCdrYXNwYScpO1xuICAgIGNvbnN0IGJ1aWxkZXIgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyKGNvaW5Db25maWcpO1xuICAgIGJ1aWxkZXIuYWRkSW5wdXQoVVRYT1Muc2ltcGxlKS50byhBRERSRVNTRVMucmVjaXBpZW50LCAnOTk5OTgwMDAnKS5mZWUoJzIwMDAnKTtcblxuICAgIGNvbnN0IGJyb2FkY2FzdCA9IChhd2FpdCBidWlsZGVyLnRvUHNrdCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC5zaWduKFBSVl9LRVlfQlVGKVxuICAgICAgLnRvRmluYWxpemVyKClcbiAgICAgIC5maW5hbGl6ZSgpXG4gICAgICAudG9FeHRyYWN0b3IoKVxuICAgICAgLmV4dHJhY3QoKTtcblxuICAgIGFzc2VydC5kb2VzTm90VGhyb3coKCkgPT4gSlNPTi5wYXJzZShicm9hZGNhc3QpLCAnZXh0cmFjdCgpIHNob3VsZCBwcm9kdWNlIHZhbGlkIEpTT04nKTtcbiAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGJyb2FkY2FzdCk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5pbnB1dHNbMF0uc2lnbmF0dXJlU2NyaXB0LCAnc2lnbmF0dXJlU2NyaXB0IHNob3VsZCBiZSBzZXQnKTtcbiAgICBhc3NlcnQuZXF1YWwoQnVmZmVyLmZyb20ocGFyc2VkLmlucHV0c1swXS5zaWduYXR1cmVTY3JpcHQsICdoZXgnKS5sZW5ndGgsIDY2KTtcbiAgfSk7XG5cbiAgaXQoJ1BTS1QgZnJvbSBidWlsZGVyIG1hdGNoZXMgYnJvYWRjYXN0IGZyb20gVHJhbnNhY3Rpb24uc2lnbigpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGNvaW5Db25maWcgPSBjb2lucy5nZXQoJ2thc3BhJyk7XG4gICAgY29uc3QgYnVpbGRlciA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXIoY29pbkNvbmZpZyk7XG4gICAgYnVpbGRlci5hZGRJbnB1dChVVFhPUy5zaW1wbGUpLnRvKEFERFJFU1NFUy5yZWNpcGllbnQsICc5OTk5ODAwMCcpLmZlZSgnMjAwMCcpO1xuXG4gICAgY29uc3QgYnJvYWRjYXN0VmlhUHNrdCA9IChhd2FpdCBidWlsZGVyLnRvUHNrdCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC5zaWduKFBSVl9LRVlfQlVGKVxuICAgICAgLnRvRmluYWxpemVyKClcbiAgICAgIC5maW5hbGl6ZSgpXG4gICAgICAudG9FeHRyYWN0b3IoKVxuICAgICAgLmV4dHJhY3QoKTtcblxuICAgIC8vIFJlYnVpbGQgdmlhIHN0YW5kYXJkIHBhdGhcbiAgICBjb25zdCBidWlsZGVyMiA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXIoY29pbkNvbmZpZyk7XG4gICAgYnVpbGRlcjIuYWRkSW5wdXQoVVRYT1Muc2ltcGxlKS50byhBRERSRVNTRVMucmVjaXBpZW50LCAnOTk5OTgwMDAnKS5mZWUoJzIwMDAnKTtcbiAgICBjb25zdCB0eCA9IChhd2FpdCBidWlsZGVyMi5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICB0eC5zaWduKFBSVl9LRVlfQlVGKTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoSlNPTi5wYXJzZShicm9hZGNhc3RWaWFQc2t0KSwgSlNPTi5wYXJzZSh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpKSk7XG4gIH0pO1xufSk7XG4iXX0=