@zcomb/programs-sdk 1.11.0 → 1.11.2

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,767 +1 @@
1
- "use strict";
2
- /*
3
- * High-level client for the Futarchy program.
4
- * Handles account derivation, instruction building, and transaction composition.
5
- */
6
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
- if (k2 === undefined) k2 = k;
8
- var desc = Object.getOwnPropertyDescriptor(m, k);
9
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
- desc = { enumerable: true, get: function() { return m[k]; } };
11
- }
12
- Object.defineProperty(o, k2, desc);
13
- }) : (function(o, m, k, k2) {
14
- if (k2 === undefined) k2 = k;
15
- o[k2] = m[k];
16
- }));
17
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
- Object.defineProperty(o, "default", { enumerable: true, value: v });
19
- }) : function(o, v) {
20
- o["default"] = v;
21
- });
22
- var __importStar = (this && this.__importStar) || (function () {
23
- var ownKeys = function(o) {
24
- ownKeys = Object.getOwnPropertyNames || function (o) {
25
- var ar = [];
26
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
- return ar;
28
- };
29
- return ownKeys(o);
30
- };
31
- return function (mod) {
32
- if (mod && mod.__esModule) return mod;
33
- var result = {};
34
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
- __setModuleDefault(result, mod);
36
- return result;
37
- };
38
- })();
39
- Object.defineProperty(exports, "__esModule", { value: true });
40
- exports.FutarchyClient = void 0;
41
- const anchor_1 = require("@coral-xyz/anchor");
42
- const web3_js_1 = require("@solana/web3.js");
43
- const spl_token_1 = require("@solana/spl-token");
44
- const constants_1 = require("./constants");
45
- const utils_1 = require("./utils");
46
- const instructions_1 = require("./instructions");
47
- const vault_1 = require("../vault");
48
- const amm_1 = require("../amm");
49
- const idls_1 = require("../generated/idls");
50
- const multisig = __importStar(require("@sqds/multisig"));
51
- const DEFAULT_COMPUTE_UNITS = 500000;
52
- class FutarchyClient {
53
- constructor(provider, programId, computeUnits) {
54
- this.programId = programId ?? constants_1.PROGRAM_ID;
55
- this.program = new anchor_1.Program(idls_1.FutarchyIDL, provider);
56
- this.vault = new vault_1.VaultClient(provider);
57
- this.amm = new amm_1.AMMClient(provider);
58
- this.defaultComputeUnits = computeUnits ?? DEFAULT_COMPUTE_UNITS;
59
- }
60
- /* PDA Helpers */
61
- deriveDAOPDA(name) {
62
- return (0, utils_1.deriveDAOPDA)(name, this.programId);
63
- }
64
- deriveModeratorPDA(name) {
65
- return (0, utils_1.deriveModeratorPDA)(name, this.programId);
66
- }
67
- deriveProposalPDA(moderator, proposalId) {
68
- return (0, utils_1.deriveProposalPDA)(moderator, proposalId, this.programId);
69
- }
70
- /* Fetchers */
71
- async fetchDAO(daoPda) {
72
- return (0, utils_1.fetchDAOAccount)(this.program, daoPda);
73
- }
74
- async fetchModerator(moderatorPda) {
75
- return (0, utils_1.fetchModeratorAccount)(this.program, moderatorPda);
76
- }
77
- async fetchProposal(proposalPda) {
78
- return (0, utils_1.fetchProposalAccount)(this.program, proposalPda);
79
- }
80
- /* Proposal Helpers */
81
- isProposalExpired(proposal) {
82
- return (0, utils_1.isProposalExpired)(proposal);
83
- }
84
- getTimeRemaining(proposal) {
85
- return (0, utils_1.getTimeRemaining)(proposal);
86
- }
87
- getComputeUnits(options) {
88
- return options?.computeUnits ?? this.defaultComputeUnits;
89
- }
90
- maybeAddComputeBudget(options) {
91
- if (options?.includeCuBudget === false) {
92
- return [];
93
- }
94
- const instructions = [web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: this.getComputeUnits(options) })];
95
- if (options?.priorityFeeMicroLamports !== undefined && options.priorityFeeMicroLamports > 0) {
96
- instructions.push(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: options.priorityFeeMicroLamports }));
97
- }
98
- return instructions;
99
- }
100
- /* Instruction Builders */
101
- async initializeModerator(admin, baseMint, quoteMint, name, options) {
102
- const [moderatorPda] = this.deriveModeratorPDA(name);
103
- const builder = (0, instructions_1.initializeModerator)(this.program, admin, baseMint, quoteMint, moderatorPda, name).preInstructions(this.maybeAddComputeBudget(options));
104
- return { builder, moderatorPda, name };
105
- }
106
- async addHistoricalProposal(admin, moderatorPda, numOptions, winningIdx, length, createdAt, metadata, options) {
107
- const moderator = await this.fetchModerator(moderatorPda);
108
- const proposalId = moderator.proposalIdCounter;
109
- const [proposalPda] = this.deriveProposalPDA(moderatorPda, proposalId);
110
- const builder = (0, instructions_1.addHistoricalProposal)(this.program, admin, moderatorPda, proposalPda, numOptions, winningIdx, length, createdAt, metadata).preInstructions(this.maybeAddComputeBudget(options));
111
- return { builder, proposalPda, proposalId };
112
- }
113
- async initializeProposal(creator, moderatorPda, proposalParams, metadata, options) {
114
- const moderator = await this.fetchModerator(moderatorPda);
115
- const proposalId = moderator.proposalIdCounter;
116
- const [proposalPda] = this.deriveProposalPDA(moderatorPda, proposalId);
117
- // Derive vault PDA (proposal is the owner, nonce=proposalId)
118
- const [vaultPda] = (0, vault_1.deriveVaultPDA)(proposalPda, proposalId, this.vault.programId);
119
- // Derive conditional mints for initial 2 options
120
- const [condBaseMint0] = (0, vault_1.deriveConditionalMint)(vaultPda, vault_1.VaultType.Base, 0, this.vault.programId);
121
- const [condBaseMint1] = (0, vault_1.deriveConditionalMint)(vaultPda, vault_1.VaultType.Base, 1, this.vault.programId);
122
- const [condQuoteMint0] = (0, vault_1.deriveConditionalMint)(vaultPda, vault_1.VaultType.Quote, 0, this.vault.programId);
123
- const [condQuoteMint1] = (0, vault_1.deriveConditionalMint)(vaultPda, vault_1.VaultType.Quote, 1, this.vault.programId);
124
- // Derive pool PDAs for initial 2 options (proposal is admin, mintA=condQuote, mintB=condBase)
125
- const [pool0] = (0, amm_1.derivePoolPDA)(proposalPda, condQuoteMint0, condBaseMint0, this.amm.programId);
126
- const [pool1] = (0, amm_1.derivePoolPDA)(proposalPda, condQuoteMint1, condBaseMint1, this.amm.programId);
127
- // Derive reserves and fee vaults
128
- const [reserveA0] = (0, amm_1.deriveReservePDA)(pool0, condQuoteMint0, this.amm.programId);
129
- const [reserveB0] = (0, amm_1.deriveReservePDA)(pool0, condBaseMint0, this.amm.programId);
130
- const [feeVault0] = (0, amm_1.deriveFeeVaultPDA)(pool0, this.amm.programId);
131
- const [reserveA1] = (0, amm_1.deriveReservePDA)(pool1, condQuoteMint1, this.amm.programId);
132
- const [reserveB1] = (0, amm_1.deriveReservePDA)(pool1, condBaseMint1, this.amm.programId);
133
- const [feeVault1] = (0, amm_1.deriveFeeVaultPDA)(pool1, this.amm.programId);
134
- // Vault token accounts
135
- const baseTokenAcc = (0, spl_token_1.getAssociatedTokenAddressSync)(moderator.baseMint, vaultPda, true);
136
- const quoteTokenAcc = (0, spl_token_1.getAssociatedTokenAddressSync)(moderator.quoteMint, vaultPda, true);
137
- // Build remaining accounts in expected order (see initialize_proposal.rs)
138
- const remainingAccounts = [
139
- { pubkey: moderator.baseMint, isSigner: false, isWritable: false }, // 0: base_mint
140
- { pubkey: moderator.quoteMint, isSigner: false, isWritable: false }, // 1: quote_mint
141
- { pubkey: vaultPda, isSigner: false, isWritable: true }, // 2: vault
142
- { pubkey: baseTokenAcc, isSigner: false, isWritable: true }, // 3: base_token_acc
143
- { pubkey: quoteTokenAcc, isSigner: false, isWritable: true }, // 4: quote_token_acc
144
- { pubkey: condBaseMint0, isSigner: false, isWritable: true }, // 5: cond_base_mint_0
145
- { pubkey: condBaseMint1, isSigner: false, isWritable: true }, // 6: cond_base_mint_1
146
- { pubkey: condQuoteMint0, isSigner: false, isWritable: true }, // 7: cond_quote_mint_0
147
- { pubkey: condQuoteMint1, isSigner: false, isWritable: true }, // 8: cond_quote_mint_1
148
- { pubkey: pool0, isSigner: false, isWritable: true }, // 9: pool_0
149
- { pubkey: reserveA0, isSigner: false, isWritable: true }, // 10: reserve_a_0
150
- { pubkey: reserveB0, isSigner: false, isWritable: true }, // 11: reserve_b_0
151
- { pubkey: amm_1.FEE_AUTHORITY, isSigner: false, isWritable: false }, // 12: fee_authority
152
- { pubkey: feeVault0, isSigner: false, isWritable: true }, // 13: fee_vault_0
153
- { pubkey: pool1, isSigner: false, isWritable: true }, // 14: pool_1
154
- { pubkey: reserveA1, isSigner: false, isWritable: true }, // 15: reserve_a_1
155
- { pubkey: reserveB1, isSigner: false, isWritable: true }, // 16: reserve_b_1
156
- { pubkey: feeVault1, isSigner: false, isWritable: true }, // 17: fee_vault_1
157
- ];
158
- const builder = (0, instructions_1.initializeProposal)(this.program, creator, moderatorPda, proposalPda, proposalParams, metadata ?? null, remainingAccounts).preInstructions(this.maybeAddComputeBudget(options));
159
- return {
160
- builder,
161
- proposalPda,
162
- proposalId,
163
- vaultPda,
164
- pools: [pool0, pool1],
165
- condBaseMints: [condBaseMint0, condBaseMint1],
166
- condQuoteMints: [condQuoteMint0, condQuoteMint1],
167
- };
168
- }
169
- async addOption(creator, proposalPda, options) {
170
- const proposal = await this.fetchProposal(proposalPda);
171
- const optionIndex = proposal.numOptions;
172
- // Derive new conditional mints
173
- const [condBaseMint] = (0, vault_1.deriveConditionalMint)(proposal.vault, vault_1.VaultType.Base, optionIndex, this.vault.programId);
174
- const [condQuoteMint] = (0, vault_1.deriveConditionalMint)(proposal.vault, vault_1.VaultType.Quote, optionIndex, this.vault.programId);
175
- // Derive pool PDA
176
- const [pool] = (0, amm_1.derivePoolPDA)(proposalPda, condQuoteMint, condBaseMint, this.amm.programId);
177
- const [reserveA] = (0, amm_1.deriveReservePDA)(pool, condQuoteMint, this.amm.programId);
178
- const [reserveB] = (0, amm_1.deriveReservePDA)(pool, condBaseMint, this.amm.programId);
179
- const [feeVault] = (0, amm_1.deriveFeeVaultPDA)(pool, this.amm.programId);
180
- // Build remaining accounts (see add_option.rs)
181
- const remainingAccounts = [
182
- { pubkey: proposal.vault, isSigner: false, isWritable: true }, // 0: vault
183
- { pubkey: condBaseMint, isSigner: false, isWritable: true }, // 1: cond_base_mint
184
- { pubkey: condQuoteMint, isSigner: false, isWritable: true }, // 2: cond_quote_mint
185
- { pubkey: pool, isSigner: false, isWritable: true }, // 3: pool
186
- { pubkey: reserveA, isSigner: false, isWritable: true }, // 4: reserve_a
187
- { pubkey: reserveB, isSigner: false, isWritable: true }, // 5: reserve_b
188
- { pubkey: amm_1.FEE_AUTHORITY, isSigner: false, isWritable: false }, // 6: fee_authority
189
- { pubkey: feeVault, isSigner: false, isWritable: true }, // 7: fee_vault
190
- ];
191
- const builder = (0, instructions_1.addOption)(this.program, creator, proposalPda, remainingAccounts)
192
- .preInstructions(this.maybeAddComputeBudget(options));
193
- return { builder, optionIndex, pool, condBaseMint, condQuoteMint };
194
- }
195
- async launchProposal(creator, proposalPda, baseAmount, quoteAmount, options) {
196
- const proposal = await this.fetchProposal(proposalPda);
197
- const vault = await this.vault.fetchVault(proposal.vault);
198
- const numOptions = proposal.numOptions;
199
- // Slice arrays to numOptions (fixed-size arrays from Rust include empty slots)
200
- const condBaseMints = vault.condBaseMints.slice(0, numOptions);
201
- const condQuoteMints = vault.condQuoteMints.slice(0, numOptions);
202
- // Pre-create conditional ATAs for 3+ options to avoid exceeding the
203
- // 64 instruction trace limit. Each ATA creation via vault deposit adds
204
- // 5 inner instructions; with 4 options that's 40 extra instructions.
205
- const shouldEnsureATAs = options?.ensureATAs ?? (numOptions >= 3);
206
- if (shouldEnsureATAs) {
207
- await this._createConditionalATAs(creator, condBaseMints, condQuoteMints);
208
- }
209
- const pools = proposal.pools.slice(0, numOptions);
210
- // Derive all user conditional token ATAs
211
- const userCondBaseATAs = condBaseMints.map((m) => (0, spl_token_1.getAssociatedTokenAddressSync)(m, creator));
212
- const userCondQuoteATAs = condQuoteMints.map((m) => (0, spl_token_1.getAssociatedTokenAddressSync)(m, creator));
213
- // Derive reserve accounts for each pool
214
- const reservesA = [];
215
- const reservesB = [];
216
- for (let i = 0; i < numOptions; i++) {
217
- const [resA] = (0, amm_1.deriveReservePDA)(pools[i], condQuoteMints[i], this.amm.programId);
218
- const [resB] = (0, amm_1.deriveReservePDA)(pools[i], condBaseMints[i], this.amm.programId);
219
- reservesA.push(resA);
220
- reservesB.push(resB);
221
- }
222
- // Build remaining accounts (see launch_proposal.rs)
223
- // Layout: 6 fixed + 7*N variable
224
- const remainingAccounts = [
225
- { pubkey: vault.baseMint.address, isSigner: false, isWritable: false }, // 0: base_mint
226
- { pubkey: vault.quoteMint.address, isSigner: false, isWritable: false }, // 1: quote_mint
227
- { pubkey: (0, spl_token_1.getAssociatedTokenAddressSync)(vault.baseMint.address, proposal.vault, true), isSigner: false, isWritable: true }, // 2: vault_base_ata
228
- { pubkey: (0, spl_token_1.getAssociatedTokenAddressSync)(vault.quoteMint.address, proposal.vault, true), isSigner: false, isWritable: true }, // 3: vault_quote_ata
229
- { pubkey: (0, spl_token_1.getAssociatedTokenAddressSync)(vault.baseMint.address, creator), isSigner: false, isWritable: true }, // 4: user_base_ata
230
- { pubkey: (0, spl_token_1.getAssociatedTokenAddressSync)(vault.quoteMint.address, creator), isSigner: false, isWritable: true }, // 5: user_quote_ata
231
- ];
232
- // 6..6+N: cond_base_mints
233
- for (const mint of condBaseMints) {
234
- remainingAccounts.push({ pubkey: mint, isSigner: false, isWritable: true });
235
- }
236
- // 6+N..6+2N: cond_quote_mints
237
- for (const mint of condQuoteMints) {
238
- remainingAccounts.push({ pubkey: mint, isSigner: false, isWritable: true });
239
- }
240
- // 6+2N..6+3N: user_cond_base_atas
241
- for (const ata of userCondBaseATAs) {
242
- remainingAccounts.push({ pubkey: ata, isSigner: false, isWritable: true });
243
- }
244
- // 6+3N..6+4N: user_cond_quote_atas
245
- for (const ata of userCondQuoteATAs) {
246
- remainingAccounts.push({ pubkey: ata, isSigner: false, isWritable: true });
247
- }
248
- // 6+4N..6+5N: pools
249
- for (const pool of pools) {
250
- remainingAccounts.push({ pubkey: pool, isSigner: false, isWritable: true });
251
- }
252
- // 6+5N..6+6N: reserves_a
253
- for (const res of reservesA) {
254
- remainingAccounts.push({ pubkey: res, isSigner: false, isWritable: true });
255
- }
256
- // 6+6N..6+7N: reserves_b
257
- for (const res of reservesB) {
258
- remainingAccounts.push({ pubkey: res, isSigner: false, isWritable: true });
259
- }
260
- const builder = (0, instructions_1.launchProposal)(this.program, creator, proposalPda, proposal.vault, baseAmount, quoteAmount, remainingAccounts).preInstructions(this.maybeAddComputeBudget(options));
261
- return { builder };
262
- }
263
- /**
264
- * Pre-creates all conditional token ATAs for a user before launching a proposal.
265
- *
266
- * This is REQUIRED for proposals with 3+ options to avoid exceeding Solana's
267
- * max instruction trace length limit (64 instructions). The vault's deposit CPI
268
- * creates ATAs on-the-fly, each requiring 5 inner instructions. For 4 options:
269
- * 8 ATAs × 5 = 40 extra instructions, pushing the total over 64.
270
- *
271
- * Pre-creating ATAs eliminates this overhead, reducing the trace to ~32 instructions.
272
- *
273
- * @param creator - The user who will receive conditional tokens
274
- * @param proposalPda - The proposal PDA (must be initialized but not launched)
275
- * @returns Transaction signature
276
- */
277
- async ensureConditionalATAs(creator, proposalPda) {
278
- const proposal = await this.fetchProposal(proposalPda);
279
- const vault = await this.vault.fetchVault(proposal.vault);
280
- const condBaseMints = vault.condBaseMints.slice(0, proposal.numOptions);
281
- const condQuoteMints = vault.condQuoteMints.slice(0, proposal.numOptions);
282
- return this._createConditionalATAs(creator, condBaseMints, condQuoteMints);
283
- }
284
- /**
285
- * Internal helper to create conditional ATAs given mint arrays.
286
- * Used by both ensureConditionalATAs and launchProposal to avoid redundant fetches.
287
- */
288
- async _createConditionalATAs(creator, condBaseMints, condQuoteMints) {
289
- const provider = this.program.provider;
290
- // Build ATA creation instructions (idempotent - won't fail if exists)
291
- const instructions = [];
292
- for (let i = 0; i < condBaseMints.length; i++) {
293
- const userCondBaseAta = (0, spl_token_1.getAssociatedTokenAddressSync)(condBaseMints[i], creator);
294
- const userCondQuoteAta = (0, spl_token_1.getAssociatedTokenAddressSync)(condQuoteMints[i], creator);
295
- instructions.push((0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(creator, userCondBaseAta, creator, condBaseMints[i]), (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(creator, userCondQuoteAta, creator, condQuoteMints[i]));
296
- }
297
- // Send transaction
298
- const tx = new web3_js_1.Transaction().add(...instructions);
299
- return provider.sendAndConfirm(tx);
300
- }
301
- async finalizeProposal(signer, proposalPda, options) {
302
- const proposal = await this.fetchProposal(proposalPda);
303
- const vault = await this.vault.fetchVault(proposal.vault);
304
- const numOptions = proposal.numOptions;
305
- // Build remaining accounts (3 per pool: pool, reserve_a, reserve_b)
306
- const remainingAccounts = [];
307
- for (let i = 0; i < numOptions; i++) {
308
- const pool = proposal.pools[i];
309
- const [reserveA] = (0, amm_1.deriveReservePDA)(pool, vault.condQuoteMints[i], this.amm.programId);
310
- const [reserveB] = (0, amm_1.deriveReservePDA)(pool, vault.condBaseMints[i], this.amm.programId);
311
- remainingAccounts.push({ pubkey: pool, isSigner: false, isWritable: true });
312
- remainingAccounts.push({ pubkey: reserveA, isSigner: false, isWritable: false });
313
- remainingAccounts.push({ pubkey: reserveB, isSigner: false, isWritable: false });
314
- }
315
- const builder = (0, instructions_1.finalizeProposal)(this.program, signer, proposalPda, proposal.vault, remainingAccounts).preInstructions(this.maybeAddComputeBudget(options));
316
- return { builder };
317
- }
318
- async redeemLiquidity(creator, proposalPda, options) {
319
- const proposal = await this.fetchProposal(proposalPda);
320
- const vault = await this.vault.fetchVault(proposal.vault);
321
- const numOptions = proposal.numOptions;
322
- const { winningIdx } = (0, utils_1.parseProposalState)(proposal.state);
323
- if (winningIdx === null) {
324
- throw new Error("Proposal not finalized");
325
- }
326
- const winningPool = proposal.pools[winningIdx];
327
- // Derive winning pool reserves
328
- const [reserveA] = (0, amm_1.deriveReservePDA)(winningPool, vault.condQuoteMints[winningIdx], this.amm.programId);
329
- const [reserveB] = (0, amm_1.deriveReservePDA)(winningPool, vault.condBaseMints[winningIdx], this.amm.programId);
330
- // User's winning conditional token ATAs
331
- const creatorCondQuoteAta = (0, spl_token_1.getAssociatedTokenAddressSync)(vault.condQuoteMints[winningIdx], creator);
332
- const creatorCondBaseAta = (0, spl_token_1.getAssociatedTokenAddressSync)(vault.condBaseMints[winningIdx], creator);
333
- // Build remaining accounts (see redeem_liquidity.rs)
334
- const remainingAccounts = [
335
- // remove_liquidity accounts (0-3)
336
- { pubkey: reserveA, isSigner: false, isWritable: true },
337
- { pubkey: reserveB, isSigner: false, isWritable: true },
338
- { pubkey: creatorCondQuoteAta, isSigner: false, isWritable: true },
339
- { pubkey: creatorCondBaseAta, isSigner: false, isWritable: true },
340
- // redeem_winnings base fixed accounts (4-6)
341
- { pubkey: vault.baseMint.address, isSigner: false, isWritable: false },
342
- { pubkey: (0, spl_token_1.getAssociatedTokenAddressSync)(vault.baseMint.address, proposal.vault, true), isSigner: false, isWritable: true },
343
- { pubkey: (0, spl_token_1.getAssociatedTokenAddressSync)(vault.baseMint.address, creator), isSigner: false, isWritable: true },
344
- ];
345
- // redeem_winnings base remaining (7..7+2N): [cond_base_mint_i, user_cond_base_ata_i]
346
- for (let i = 0; i < numOptions; i++) {
347
- remainingAccounts.push({ pubkey: vault.condBaseMints[i], isSigner: false, isWritable: true });
348
- remainingAccounts.push({ pubkey: (0, spl_token_1.getAssociatedTokenAddressSync)(vault.condBaseMints[i], creator), isSigner: false, isWritable: true });
349
- }
350
- // redeem_winnings quote fixed accounts
351
- remainingAccounts.push({ pubkey: vault.quoteMint.address, isSigner: false, isWritable: false });
352
- remainingAccounts.push({ pubkey: (0, spl_token_1.getAssociatedTokenAddressSync)(vault.quoteMint.address, proposal.vault, true), isSigner: false, isWritable: true });
353
- remainingAccounts.push({ pubkey: (0, spl_token_1.getAssociatedTokenAddressSync)(vault.quoteMint.address, creator), isSigner: false, isWritable: true });
354
- // redeem_winnings quote remaining: [cond_quote_mint_i, user_cond_quote_ata_i]
355
- for (let i = 0; i < numOptions; i++) {
356
- remainingAccounts.push({ pubkey: vault.condQuoteMints[i], isSigner: false, isWritable: true });
357
- remainingAccounts.push({ pubkey: (0, spl_token_1.getAssociatedTokenAddressSync)(vault.condQuoteMints[i], creator), isSigner: false, isWritable: true });
358
- }
359
- const builder = (0, instructions_1.redeemLiquidity)(this.program, creator, proposalPda, proposal.vault, winningPool, remainingAccounts).preInstructions(this.maybeAddComputeBudget(options));
360
- return { builder, numOptions };
361
- }
362
- /**
363
- * Creates an Address Lookup Table for redemption operations.
364
- * Required for proposals with 3+ options to avoid exceeding transaction size limits.
365
- *
366
- * @param creator - The user redeeming (creator of proposal or liquidity provider)
367
- * @param proposalPda - The proposal PDA
368
- * @returns ALT address
369
- */
370
- async createRedemptionALT(creator, proposalPda) {
371
- const provider = this.program.provider;
372
- const proposal = await this.fetchProposal(proposalPda);
373
- const vault = await this.vault.fetchVault(proposal.vault);
374
- const numOptions = proposal.numOptions;
375
- const { winningIdx } = (0, utils_1.parseProposalState)(proposal.state);
376
- if (winningIdx === null) {
377
- throw new Error("Proposal not finalized");
378
- }
379
- const addresses = [
380
- // Programs
381
- this.programId,
382
- this.vault.programId,
383
- this.amm.programId,
384
- web3_js_1.SystemProgram.programId,
385
- spl_token_1.TOKEN_PROGRAM_ID,
386
- spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
387
- // Core accounts
388
- proposalPda,
389
- proposal.vault,
390
- proposal.moderator,
391
- vault.baseMint.address,
392
- vault.quoteMint.address,
393
- // Winning pool and reserves
394
- proposal.pools[winningIdx],
395
- // Vault token accounts
396
- (0, spl_token_1.getAssociatedTokenAddressSync)(vault.baseMint.address, proposal.vault, true),
397
- (0, spl_token_1.getAssociatedTokenAddressSync)(vault.quoteMint.address, proposal.vault, true),
398
- // Creator's base/quote ATAs
399
- (0, spl_token_1.getAssociatedTokenAddressSync)(vault.baseMint.address, creator),
400
- (0, spl_token_1.getAssociatedTokenAddressSync)(vault.quoteMint.address, creator),
401
- ];
402
- // Winning pool reserves
403
- const [reserveA] = (0, amm_1.deriveReservePDA)(proposal.pools[winningIdx], vault.condQuoteMints[winningIdx], this.amm.programId);
404
- const [reserveB] = (0, amm_1.deriveReservePDA)(proposal.pools[winningIdx], vault.condBaseMints[winningIdx], this.amm.programId);
405
- addresses.push(reserveA, reserveB);
406
- // Per-option accounts (conditional mints and user ATAs)
407
- for (let i = 0; i < numOptions; i++) {
408
- addresses.push(vault.condBaseMints[i], vault.condQuoteMints[i], (0, spl_token_1.getAssociatedTokenAddressSync)(vault.condBaseMints[i], creator), (0, spl_token_1.getAssociatedTokenAddressSync)(vault.condQuoteMints[i], creator));
409
- }
410
- // Get recent slot for ALT creation
411
- const slot = await provider.connection.getSlot("finalized");
412
- const [createIx, altAddress] = web3_js_1.AddressLookupTableProgram.createLookupTable({
413
- authority: creator,
414
- payer: creator,
415
- recentSlot: slot,
416
- });
417
- // Create ALT
418
- const createTx = new web3_js_1.Transaction().add(createIx);
419
- const { blockhash: createBlockhash, lastValidBlockHeight: createLastValidBlockHeight } = await provider.connection.getLatestBlockhash('confirmed');
420
- createTx.recentBlockhash = createBlockhash;
421
- createTx.feePayer = creator;
422
- const signedTx = await provider.wallet.signTransaction(createTx);
423
- const sig = await provider.connection.sendRawTransaction(signedTx.serialize(), {
424
- skipPreflight: true,
425
- });
426
- await provider.connection.confirmTransaction({
427
- signature: sig,
428
- blockhash: createBlockhash,
429
- lastValidBlockHeight: createLastValidBlockHeight,
430
- }, "confirmed");
431
- // Extend ALT with addresses
432
- // Use skipPreflight to avoid race condition where simulation sees stale state
433
- // before previous extend has propagated (same pattern as CREATE above)
434
- const CHUNK_SIZE = 20;
435
- for (let i = 0; i < addresses.length; i += CHUNK_SIZE) {
436
- const chunk = addresses.slice(i, i + CHUNK_SIZE);
437
- const extendIx = web3_js_1.AddressLookupTableProgram.extendLookupTable({
438
- payer: creator,
439
- authority: creator,
440
- lookupTable: altAddress,
441
- addresses: chunk,
442
- });
443
- const extendTx = new web3_js_1.Transaction().add(extendIx);
444
- const { blockhash: extendBlockhash, lastValidBlockHeight: extendLastValidBlockHeight } = await provider.connection.getLatestBlockhash('confirmed');
445
- extendTx.recentBlockhash = extendBlockhash;
446
- extendTx.feePayer = creator;
447
- const signedExtendTx = await provider.wallet.signTransaction(extendTx);
448
- const extendSig = await provider.connection.sendRawTransaction(signedExtendTx.serialize(), {
449
- skipPreflight: true,
450
- });
451
- await provider.connection.confirmTransaction({
452
- signature: extendSig,
453
- blockhash: extendBlockhash,
454
- lastValidBlockHeight: extendLastValidBlockHeight,
455
- }, "confirmed");
456
- }
457
- return { altAddress };
458
- }
459
- /**
460
- * Builds a versioned transaction for redeeming liquidity with ALT.
461
- * Required for proposals with 3+ options to avoid exceeding transaction size limits.
462
- *
463
- * @param creator - The user redeeming
464
- * @param proposalPda - The proposal PDA
465
- * @param altAddress - Optional ALT address (will be created if not provided for 3+ options)
466
- * @param options - Optional transaction options (priority fee, compute units)
467
- * @returns Unsigned versioned transaction, ALT address, number of options, and blockhash info for confirmation
468
- */
469
- async redeemLiquidityVersioned(creator, proposalPda, altAddress, options) {
470
- const provider = this.program.provider;
471
- const { builder, numOptions } = await this.redeemLiquidity(creator, proposalPda);
472
- // Create ALT if not provided and needed
473
- let altPubkey = altAddress;
474
- let verifiedALT = null;
475
- if (!altPubkey && numOptions >= 3) {
476
- console.log(` Creating redemption ALT for ${numOptions} options...`);
477
- const result = await this.createRedemptionALT(creator, proposalPda);
478
- altPubkey = result.altAddress;
479
- console.log(` ✓ Redemption ALT created: ${altPubkey.toBase58()}`);
480
- // Wait for ALT to be fully available with all addresses
481
- // Use longer delays after extending to ensure propagation
482
- console.log(` Waiting for ALT propagation...`);
483
- const expectedAddresses = 18 + (numOptions * 4); // Base accounts + per-option accounts
484
- let attempts = 0;
485
- // Initial delay after extension
486
- await new Promise(resolve => setTimeout(resolve, 2000));
487
- while (attempts < 30) {
488
- const altAccount = await provider.connection.getAddressLookupTable(altPubkey, {
489
- commitment: 'confirmed',
490
- });
491
- if (altAccount.value) {
492
- const addressCount = altAccount.value.state.addresses.length;
493
- console.log(` Attempt ${attempts + 1}: ALT has ${addressCount}/${expectedAddresses} addresses`);
494
- if (addressCount >= expectedAddresses) {
495
- verifiedALT = altAccount.value;
496
- console.log(` ✓ ALT verified with ${addressCount} addresses`);
497
- break;
498
- }
499
- }
500
- await new Promise(resolve => setTimeout(resolve, 1000));
501
- attempts++;
502
- }
503
- if (!verifiedALT) {
504
- throw new Error(`ALT failed to populate with expected ${expectedAddresses} addresses after ${attempts} attempts`);
505
- }
506
- }
507
- if (!altPubkey) {
508
- throw new Error("ALT address required for multi-option redemption");
509
- }
510
- // Fetch ALT if we don't have it verified already
511
- if (!verifiedALT) {
512
- verifiedALT = await this.fetchALT(altPubkey);
513
- }
514
- // Build instruction
515
- const instruction = await builder.instruction();
516
- const computeBudgetIx = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: 500000 });
517
- // Build pre-instructions array with optional priority fee
518
- const preInstructions = [computeBudgetIx];
519
- if (options?.priorityFeeMicroLamports !== undefined && options.priorityFeeMicroLamports > 0) {
520
- preInstructions.push(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: options.priorityFeeMicroLamports }));
521
- }
522
- // Get fresh blockhash with lastValidBlockHeight for confirmation tracking
523
- const { blockhash, lastValidBlockHeight } = await provider.connection.getLatestBlockhash('confirmed');
524
- // Build versioned transaction using the verified ALT (no re-fetch)
525
- const versionedTx = this.buildVersionedTxWithALT(creator, [...preInstructions, instruction], verifiedALT, blockhash);
526
- // Return the versioned transaction along with blockhash info for proper confirmation
527
- // This allows the caller to use their own signing mechanism (e.g., keypair.sign)
528
- return { versionedTx, altAddress: altPubkey, numOptions, blockhash, lastValidBlockHeight };
529
- }
530
- /**
531
- * Helper to send a signed versioned transaction with robust confirmation handling.
532
- * Uses blockhash-based confirmation to properly detect transaction expiration
533
- * instead of relying on a fixed timeout.
534
- *
535
- * @param signedTx - The signed versioned transaction to send
536
- * @param confirmationInfo - Optional blockhash info from when the transaction was built.
537
- * If not provided, a fresh blockhash will be fetched (less accurate).
538
- */
539
- async sendVersionedTransaction(signedTx, confirmationInfo) {
540
- const provider = this.program.provider;
541
- // Use provided blockhash info or fetch fresh one
542
- // Using the original blockhash is more accurate for detecting expiration
543
- let blockhash;
544
- let lastValidBlockHeight;
545
- if (confirmationInfo) {
546
- blockhash = confirmationInfo.blockhash;
547
- lastValidBlockHeight = confirmationInfo.lastValidBlockHeight;
548
- }
549
- else {
550
- // Fallback: get fresh blockhash (may wait longer than necessary if tx already expired)
551
- const latestBlockhash = await provider.connection.getLatestBlockhash('confirmed');
552
- blockhash = latestBlockhash.blockhash;
553
- lastValidBlockHeight = latestBlockhash.lastValidBlockHeight;
554
- }
555
- const signature = await provider.connection.sendTransaction(signedTx, {
556
- skipPreflight: false,
557
- preflightCommitment: 'confirmed',
558
- });
559
- // Use blockhash-based confirmation which waits until either:
560
- // 1. Transaction is confirmed
561
- // 2. Blockhash expires (lastValidBlockHeight passed)
562
- // This is more robust than a fixed timeout on congested networks
563
- await provider.connection.confirmTransaction({
564
- signature,
565
- blockhash,
566
- lastValidBlockHeight,
567
- }, 'confirmed');
568
- return signature;
569
- }
570
- /* Address Lookup Table */
571
- async createProposalALT(creator, moderatorPda, numOptions = 2) {
572
- const provider = this.program.provider;
573
- const moderator = await this.fetchModerator(moderatorPda);
574
- const proposalId = moderator.proposalIdCounter;
575
- const [proposalPda] = this.deriveProposalPDA(moderatorPda, proposalId);
576
- const [vaultPda] = (0, vault_1.deriveVaultPDA)(proposalPda, proposalId, this.vault.programId);
577
- const addresses = [
578
- // Programs
579
- this.programId,
580
- this.vault.programId,
581
- this.amm.programId,
582
- web3_js_1.SystemProgram.programId,
583
- spl_token_1.TOKEN_PROGRAM_ID,
584
- spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
585
- // Core accounts
586
- moderatorPda,
587
- proposalPda,
588
- vaultPda,
589
- moderator.baseMint,
590
- moderator.quoteMint,
591
- amm_1.FEE_AUTHORITY,
592
- // Vault token accounts
593
- (0, spl_token_1.getAssociatedTokenAddressSync)(moderator.baseMint, vaultPda, true),
594
- (0, spl_token_1.getAssociatedTokenAddressSync)(moderator.quoteMint, vaultPda, true),
595
- // Creator's base/quote ATAs
596
- (0, spl_token_1.getAssociatedTokenAddressSync)(moderator.baseMint, creator),
597
- (0, spl_token_1.getAssociatedTokenAddressSync)(moderator.quoteMint, creator),
598
- ];
599
- // Per-option accounts
600
- for (let i = 0; i < numOptions; i++) {
601
- const [condBaseMint] = (0, vault_1.deriveConditionalMint)(vaultPda, vault_1.VaultType.Base, i, this.vault.programId);
602
- const [condQuoteMint] = (0, vault_1.deriveConditionalMint)(vaultPda, vault_1.VaultType.Quote, i, this.vault.programId);
603
- const [pool] = (0, amm_1.derivePoolPDA)(proposalPda, condQuoteMint, condBaseMint, this.amm.programId);
604
- const [reserveA] = (0, amm_1.deriveReservePDA)(pool, condQuoteMint, this.amm.programId);
605
- const [reserveB] = (0, amm_1.deriveReservePDA)(pool, condBaseMint, this.amm.programId);
606
- const [feeVault] = (0, amm_1.deriveFeeVaultPDA)(pool, this.amm.programId);
607
- addresses.push(condBaseMint, condQuoteMint, pool, reserveA, reserveB, feeVault,
608
- // Creator's conditional token ATAs
609
- (0, spl_token_1.getAssociatedTokenAddressSync)(condBaseMint, creator), (0, spl_token_1.getAssociatedTokenAddressSync)(condQuoteMint, creator));
610
- }
611
- // Get the most recent slot using "finalized" commitment for stability
612
- const slot = await provider.connection.getSlot("finalized");
613
- const [createIx, altAddress] = web3_js_1.AddressLookupTableProgram.createLookupTable({
614
- authority: creator,
615
- payer: creator,
616
- recentSlot: slot,
617
- });
618
- // Send create transaction immediately, skip preflight to avoid slot timing issues
619
- const createTx = new web3_js_1.Transaction().add(createIx);
620
- const { blockhash: createBlockhash, lastValidBlockHeight: createLastValidBlockHeight } = await provider.connection.getLatestBlockhash('confirmed');
621
- createTx.recentBlockhash = createBlockhash;
622
- createTx.feePayer = creator;
623
- const signedTx = await provider.wallet.signTransaction(createTx);
624
- const sig = await provider.connection.sendRawTransaction(signedTx.serialize(), {
625
- skipPreflight: true,
626
- });
627
- await provider.connection.confirmTransaction({
628
- signature: sig,
629
- blockhash: createBlockhash,
630
- lastValidBlockHeight: createLastValidBlockHeight,
631
- }, "confirmed");
632
- // Split addresses into chunks to avoid transaction size limits
633
- // Each address is 32 bytes, ~20 addresses per extend instruction is safe
634
- // Use skipPreflight to avoid race condition where simulation sees stale state
635
- // before previous extend has propagated (same pattern as CREATE above)
636
- const CHUNK_SIZE = 20;
637
- for (let i = 0; i < addresses.length; i += CHUNK_SIZE) {
638
- const chunk = addresses.slice(i, i + CHUNK_SIZE);
639
- const extendIx = web3_js_1.AddressLookupTableProgram.extendLookupTable({
640
- payer: creator,
641
- authority: creator,
642
- lookupTable: altAddress,
643
- addresses: chunk,
644
- });
645
- const extendTx = new web3_js_1.Transaction().add(extendIx);
646
- const { blockhash: extendBlockhash, lastValidBlockHeight: extendLastValidBlockHeight } = await provider.connection.getLatestBlockhash('confirmed');
647
- extendTx.recentBlockhash = extendBlockhash;
648
- extendTx.feePayer = creator;
649
- const signedExtendTx = await provider.wallet.signTransaction(extendTx);
650
- const extendSig = await provider.connection.sendRawTransaction(signedExtendTx.serialize(), {
651
- skipPreflight: true,
652
- });
653
- await provider.connection.confirmTransaction({
654
- signature: extendSig,
655
- blockhash: extendBlockhash,
656
- lastValidBlockHeight: extendLastValidBlockHeight,
657
- }, "confirmed");
658
- }
659
- return { altAddress };
660
- }
661
- async fetchALT(altAddress) {
662
- const alt = await this.program.provider.connection.getAddressLookupTable(altAddress);
663
- if (!alt.value) {
664
- throw new Error("ALT not found");
665
- }
666
- return alt.value;
667
- }
668
- async buildVersionedTx(payer, instructions, altAddress) {
669
- const provider = this.program.provider;
670
- const alt = await this.fetchALT(altAddress);
671
- const { blockhash, lastValidBlockHeight } = await provider.connection.getLatestBlockhash('confirmed');
672
- const versionedTx = this.buildVersionedTxWithALT(payer, instructions, alt, blockhash);
673
- return { versionedTx, blockhash, lastValidBlockHeight };
674
- }
675
- buildVersionedTxWithALT(payer, instructions, alt, blockhash) {
676
- const message = new web3_js_1.TransactionMessage({
677
- payerKey: payer,
678
- recentBlockhash: blockhash,
679
- instructions,
680
- }).compileToV0Message([alt]);
681
- return new web3_js_1.VersionedTransaction(message);
682
- }
683
- /* DAO Methods */
684
- deriveMintCreateKeyPDA(daoPda, name) {
685
- return (0, utils_1.deriveMintCreateKeyPDA)(daoPda, name, this.programId);
686
- }
687
- async fetchSquadsProgramConfig() {
688
- const [programConfigPda] = multisig.getProgramConfigPda({
689
- programId: constants_1.SQUADS_PROGRAM_ID,
690
- });
691
- const programConfig = await multisig.accounts.ProgramConfig.fromAccountAddress(this.program.provider.connection, programConfigPda);
692
- return {
693
- programConfig: programConfigPda,
694
- programConfigTreasury: programConfig.treasury,
695
- };
696
- }
697
- deriveMultisigPda(createKey) {
698
- const [multisigPda] = multisig.getMultisigPda({
699
- createKey,
700
- programId: constants_1.SQUADS_PROGRAM_ID,
701
- });
702
- return multisigPda;
703
- }
704
- async initializeParentDAO(admin, parentAdmin, name, baseMint, quoteMint, treasuryCosigner, pool, poolType, options) {
705
- const [daoPda] = this.deriveDAOPDA(name);
706
- const [moderatorPda] = this.deriveModeratorPDA(name);
707
- const [mintCreateKeyPda] = this.deriveMintCreateKeyPDA(daoPda, name);
708
- // Derive Squads accounts (single RPC call)
709
- const squadsConfig = await this.fetchSquadsProgramConfig();
710
- const treasuryMultisigPda = this.deriveMultisigPda(daoPda);
711
- const mintMultisigPda = this.deriveMultisigPda(mintCreateKeyPda);
712
- const builder = (0, instructions_1.initializeParentDAO)(this.program, admin, parentAdmin, daoPda, moderatorPda, baseMint, quoteMint, squadsConfig.programConfig, squadsConfig.programConfigTreasury, treasuryMultisigPda, mintMultisigPda, mintCreateKeyPda, constants_1.SQUADS_PROGRAM_ID, name, treasuryCosigner, pool, poolType).preInstructions(this.maybeAddComputeBudget(options));
713
- return {
714
- builder,
715
- daoPda,
716
- moderatorPda,
717
- treasuryMultisig: treasuryMultisigPda,
718
- mintMultisig: mintMultisigPda,
719
- };
720
- }
721
- async initializeChildDAO(admin, parentAdmin, parentDaoName, name, tokenMint, treasuryCosigner, options) {
722
- const [daoPda] = this.deriveDAOPDA(name);
723
- const [parentDaoPda] = this.deriveDAOPDA(parentDaoName);
724
- const [mintCreateKeyPda] = this.deriveMintCreateKeyPDA(daoPda, name);
725
- // Derive Squads accounts (single RPC call)
726
- const squadsConfig = await this.fetchSquadsProgramConfig();
727
- const treasuryMultisigPda = this.deriveMultisigPda(daoPda);
728
- const mintMultisigPda = this.deriveMultisigPda(mintCreateKeyPda);
729
- const builder = (0, instructions_1.initializeChildDAO)(this.program, admin, parentAdmin, daoPda, parentDaoPda, tokenMint, squadsConfig.programConfig, squadsConfig.programConfigTreasury, treasuryMultisigPda, mintMultisigPda, mintCreateKeyPda, constants_1.SQUADS_PROGRAM_ID, name, treasuryCosigner).preInstructions(this.maybeAddComputeBudget(options));
730
- return {
731
- builder,
732
- daoPda,
733
- parentDaoPda,
734
- treasuryMultisig: treasuryMultisigPda,
735
- mintMultisig: mintMultisigPda,
736
- };
737
- }
738
- async upgradeDAO(admin, parentAdmin, daoName, parentDaoName, baseMint, quoteMint, pool, poolType, options) {
739
- const [daoPda] = this.deriveDAOPDA(daoName);
740
- const [parentDaoPda] = this.deriveDAOPDA(parentDaoName);
741
- const [moderatorPda] = this.deriveModeratorPDA(daoName);
742
- const builder = (0, instructions_1.upgradeDAO)(this.program, admin, parentAdmin, daoPda, parentDaoPda, moderatorPda, baseMint, quoteMint, pool, poolType).preInstructions(this.maybeAddComputeBudget(options));
743
- return { builder, daoPda, moderatorPda };
744
- }
745
- async addHistoricalParentDAO(admin, name, baseMint, quoteMint, treasuryMultisig, mintAuthMultisig, cosigner, pool, poolType, proposalIdCounter, adminPubkey, options) {
746
- const [daoPda] = this.deriveDAOPDA(name);
747
- const [moderatorPda] = this.deriveModeratorPDA(name);
748
- const builder = (0, instructions_1.addHistoricalParentDAO)(this.program, admin, daoPda, moderatorPda, treasuryMultisig, mintAuthMultisig, baseMint, quoteMint, name, cosigner, pool, poolType, proposalIdCounter, adminPubkey).preInstructions(this.maybeAddComputeBudget(options));
749
- return {
750
- builder,
751
- daoPda,
752
- moderatorPda,
753
- };
754
- }
755
- async transferAdmin(admin, name, newAdmin, options) {
756
- const [daoPda] = this.deriveDAOPDA(name);
757
- const [moderatorPda] = this.deriveModeratorPDA(name);
758
- const builder = (0, instructions_1.transferAdmin)(this.program, admin, daoPda, moderatorPda, newAdmin).preInstructions(this.maybeAddComputeBudget(options));
759
- return {
760
- builder,
761
- daoPda,
762
- moderatorPda,
763
- };
764
- }
765
- }
766
- exports.FutarchyClient = FutarchyClient;
767
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Z1dGFyY2h5L2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztHQUdHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFSCw4Q0FBZ0U7QUFDaEUsNkNBVXlCO0FBQ3pCLGlEQUsyQjtBQUMzQiwyQ0FBNEQ7QUFTNUQsbUNBV2lCO0FBQ2pCLGlEQWF3QjtBQUd4QixvQ0FBeUY7QUFDekYsZ0NBQXNHO0FBRXRHLDRDQUFnRDtBQUNoRCx5REFBMkM7QUFFM0MsTUFBTSxxQkFBcUIsR0FBRyxNQUFPLENBQUM7QUFFdEMsTUFBYSxjQUFjO0lBT3pCLFlBQVksUUFBd0IsRUFBRSxTQUFxQixFQUFFLFlBQXFCO1FBQ2hGLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxJQUFJLHNCQUFVLENBQUM7UUFDekMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLGdCQUFPLENBQUMsa0JBQXVCLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLG1CQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLGVBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsWUFBWSxJQUFJLHFCQUFxQixDQUFDO0lBQ25FLENBQUM7SUFFRCxpQkFBaUI7SUFFakIsWUFBWSxDQUFDLElBQVk7UUFDdkIsT0FBTyxJQUFBLG9CQUFZLEVBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsa0JBQWtCLENBQUMsSUFBWTtRQUM3QixPQUFPLElBQUEsMEJBQWtCLEVBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQsaUJBQWlCLENBQUMsU0FBb0IsRUFBRSxV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QyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekMsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVyRCxNQUFNLE9BQU8sR0FBRyxJQUFBLDRCQUFhLEVBQzNCLElBQUksQ0FBQyxPQUFPLEVBQ1osS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBQ1osUUFBUSxDQUNULENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBRXZELE9BQU87WUFDTCxPQUFPO1lBQ1AsTUFBTTtZQUNOLFlBQVk7U0FDYixDQUFDO0lBQ0osQ0FBQztDQUNGO0FBeGxDRCx3Q0F3bENDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIEhpZ2gtbGV2ZWwgY2xpZW50IGZvciB0aGUgRnV0YXJjaHkgcHJvZ3JhbS5cbiAqIEhhbmRsZXMgYWNjb3VudCBkZXJpdmF0aW9uLCBpbnN0cnVjdGlvbiBidWlsZGluZywgYW5kIHRyYW5zYWN0aW9uIGNvbXBvc2l0aW9uLlxuICovXG5cbmltcG9ydCB7IFByb2dyYW0sIEFuY2hvclByb3ZpZGVyLCBCTiB9IGZyb20gXCJAY29yYWwteHl6L2FuY2hvclwiO1xuaW1wb3J0IHtcbiAgUHVibGljS2V5LFxuICBDb21wdXRlQnVkZ2V0UHJvZ3JhbSxcbiAgQWRkcmVzc0xvb2t1cFRhYmxlUHJvZ3JhbSxcbiAgQWRkcmVzc0xvb2t1cFRhYmxlQWNjb3VudCxcbiAgU3lzdGVtUHJvZ3JhbSxcbiAgVHJhbnNhY3Rpb24sXG4gIFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb24sXG4gIFRyYW5zYWN0aW9uTWVzc2FnZSxcbiAgVmVyc2lvbmVkVHJhbnNhY3Rpb24sXG59IGZyb20gXCJAc29sYW5hL3dlYjMuanNcIjtcbmltcG9ydCB7XG4gIGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jLFxuICBUT0tFTl9QUk9HUkFNX0lELFxuICBBU1NPQ0lBVEVEX1RPS0VOX1BST0dSQU1fSUQsXG4gIGNyZWF0ZUFzc29jaWF0ZWRUb2tlbkFjY291bnRJZGVtcG90ZW50SW5zdHJ1Y3Rpb24sXG59IGZyb20gXCJAc29sYW5hL3NwbC10b2tlblwiO1xuaW1wb3J0IHsgUFJPR1JBTV9JRCwgU1FVQURTX1BST0dSQU1fSUQgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIEZ1dGFyY2h5LFxuICBEQU9BY2NvdW50LFxuICBNb2RlcmF0b3JBY2NvdW50LFxuICBQcm9wb3NhbEFjY291bnQsXG4gIFByb3Bvc2FsUGFyYW1zLFxuICBQb29sVHlwZSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIGRlcml2ZURBT1BEQSxcbiAgZGVyaXZlTW9kZXJhdG9yUERBLFxuICBkZXJpdmVQcm9wb3NhbFBEQSxcbiAgZGVyaXZlTWludENyZWF0ZUtleVBEQSxcbiAgZmV0Y2hEQU9BY2NvdW50LFxuICBmZXRjaE1vZGVyYXRvckFjY291bnQsXG4gIGZldGNoUHJvcG9zYWxBY2NvdW50LFxuICBwYXJzZVByb3Bvc2FsU3RhdGUsXG4gIGlzUHJvcG9zYWxFeHBpcmVkLFxuICBnZXRUaW1lUmVtYWluaW5nLFxufSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHtcbiAgaW5pdGlhbGl6ZU1vZGVyYXRvcixcbiAgaW5pdGlhbGl6ZVByb3Bvc2FsLFxuICBhZGRPcHRpb24sXG4gIGxhdW5jaFByb3Bvc2FsLFxuICBmaW5hbGl6ZVByb3Bvc2FsLFxuICByZWRlZW1MaXF1aWRpdHksXG4gIGFkZEhpc3RvcmljYWxQcm9wb3NhbCxcbiAgaW5pdGlhbGl6ZVBhcmVudERBTyxcbiAgaW5pdGlhbGl6ZUNoaWxkREFPLFxuICB1cGdyYWRlREFPLFxuICBhZGRIaXN0b3JpY2FsUGFyZW50REFPLFxuICB0cmFuc2ZlckFkbWluLFxufSBmcm9tIFwiLi9pbnN0cnVjdGlvbnNcIjtcbmltcG9ydCB7IFR4T3B0aW9ucyB9IGZyb20gXCIuLi91dGlsc1wiO1xuXG5pbXBvcnQgeyBWYXVsdENsaWVudCwgZGVyaXZlVmF1bHRQREEsIGRlcml2ZUNvbmRpdGlvbmFsTWludCwgVmF1bHRUeXBlIH0gZnJvbSBcIi4uL3ZhdWx0XCI7XG5pbXBvcnQgeyBBTU1DbGllbnQsIGRlcml2ZVBvb2xQREEsIGRlcml2ZVJlc2VydmVQREEsIGRlcml2ZUZlZVZhdWx0UERBLCBGRUVfQVVUSE9SSVRZIH0gZnJvbSBcIi4uL2FtbVwiO1xuXG5pbXBvcnQgeyBGdXRhcmNoeUlETCB9IGZyb20gXCIuLi9nZW5lcmF0ZWQvaWRsc1wiO1xuaW1wb3J0ICogYXMgbXVsdGlzaWcgZnJvbSBcIkBzcWRzL211bHRpc2lnXCI7XG5cbmNvbnN0IERFRkFVTFRfQ09NUFVURV9VTklUUyA9IDUwMF8wMDA7XG5cbmV4cG9ydCBjbGFzcyBGdXRhcmNoeUNsaWVudCB7XG4gIHB1YmxpYyBwcm9ncmFtOiBQcm9ncmFtPEZ1dGFyY2h5PjtcbiAgcHVibGljIHByb2dyYW1JZDogUHVibGljS2V5O1xuICBwdWJsaWMgdmF1bHQ6IFZhdWx0Q2xpZW50O1xuICBwdWJsaWMgYW1tOiBBTU1DbGllbnQ7XG4gIHByaXZhdGUgZGVmYXVsdENvbXB1dGVVbml0czogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHByb3ZpZGVyOiBBbmNob3JQcm92aWRlciwgcHJvZ3JhbUlkPzogUHVibGljS2V5LCBjb21wdXRlVW5pdHM/OiBudW1iZXIpIHtcbiAgICB0aGlzLnByb2dyYW1JZCA9IHByb2dyYW1JZCA/PyBQUk9HUkFNX0lEO1xuICAgIHRoaXMucHJvZ3JhbSA9IG5ldyBQcm9ncmFtKEZ1dGFyY2h5SURMIGFzIEZ1dGFyY2h5LCBwcm92aWRlcik7XG4gICAgdGhpcy52YXVsdCA9IG5ldyBWYXVsdENsaWVudChwcm92aWRlcik7XG4gICAgdGhpcy5hbW0gPSBuZXcgQU1NQ2xpZW50KHByb3ZpZGVyKTtcbiAgICB0aGlzLmRlZmF1bHRDb21wdXRlVW5pdHMgPSBjb21wdXRlVW5pdHMgPz8gREVGQVVMVF9DT01QVVRFX1VOSVRTO1xuICB9XG5cbiAgLyogUERBIEhlbHBlcnMgKi9cblxuICBkZXJpdmVEQU9QREEobmFtZTogc3RyaW5nKTogW1B1YmxpY0tleSwgbnVtYmVyXSB7XG4gICAgcmV0dXJuIGRlcml2ZURBT1BEQShuYW1lLCB0aGlzLnByb2dyYW1JZCk7XG4gIH1cblxuICBkZXJpdmVNb2RlcmF0b3JQREEobmFtZTogc3RyaW5nKTogW1B1YmxpY0tleSwgbnVtYmVyXSB7XG4gICAgcmV0dXJuIGRlcml2ZU1vZGVyYXRvclBEQShuYW1lLCB0aGlzLnByb2dyYW1JZCk7XG4gIH1cblxuICBkZXJpdmVQcm9wb3NhbFBEQShtb2RlcmF0b3I6IFB1YmxpY0tleSwgcHJvcG9zYWxJZDogbnVtYmVyKTogW1B1YmxpY0tleSwgbnVtYmVyXSB7XG4gICAgcmV0dXJuIGRlcml2ZVByb3Bvc2FsUERBKG1vZGVyYXRvciwgcHJvcG9zYWxJZCwgdGhpcy5wcm9ncmFtSWQpO1xuICB9XG5cbiAgLyogRmV0Y2hlcnMgKi9cblxuICBhc3luYyBmZXRjaERBTyhkYW9QZGE6IFB1YmxpY0tleSk6IFByb21pc2U8REFPQWNjb3VudD4ge1xuICAgIHJldHVybiBmZXRjaERBT0FjY291bnQodGhpcy5wcm9ncmFtLCBkYW9QZGEpO1xuICB9XG5cbiAgYXN5bmMgZmV0Y2hNb2RlcmF0b3IobW9kZXJhdG9yUGRhOiBQdWJsaWNLZXkpOiBQcm9taXNlPE1vZGVyYXRvckFjY291bnQ+IHtcbiAgICByZXR1cm4gZmV0Y2hNb2RlcmF0b3JBY2NvdW50KHRoaXMucHJvZ3JhbSwgbW9kZXJhdG9yUGRhKTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoUHJvcG9zYWwocHJvcG9zYWxQZGE6IFB1YmxpY0tleSk6IFByb21pc2U8UHJvcG9zYWxBY2NvdW50PiB7XG4gICAgcmV0dXJuIGZldGNoUHJvcG9zYWxBY2NvdW50KHRoaXMucHJvZ3JhbSwgcHJvcG9zYWxQZGEpO1xuICB9XG5cbiAgLyogUHJvcG9zYWwgSGVscGVycyAqL1xuXG4gIGlzUHJvcG9zYWxFeHBpcmVkKHByb3Bvc2FsOiBQcm9wb3NhbEFjY291bnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNQcm9wb3NhbEV4cGlyZWQocHJvcG9zYWwpO1xuICB9XG5cbiAgZ2V0VGltZVJlbWFpbmluZyhwcm9wb3NhbDogUHJvcG9zYWxBY2NvdW50KTogbnVtYmVyIHtcbiAgICByZXR1cm4gZ2V0VGltZVJlbWFpbmluZyhwcm9wb3NhbCk7XG4gIH1cblxuICBwcml2YXRlIGdldENvbXB1dGVVbml0cyhvcHRpb25zPzogVHhPcHRpb25zKTogbnVtYmVyIHtcbiAgICByZXR1cm4gb3B0aW9ucz8uY29tcHV0ZVVuaXRzID8/IHRoaXMuZGVmYXVsdENvbXB1dGVVbml0cztcbiAgfVxuXG4gIHByaXZhdGUgbWF5YmVBZGRDb21wdXRlQnVkZ2V0KG9wdGlvbnM/OiBUeE9wdGlvbnMpOiBUcmFuc2FjdGlvbkluc3RydWN0aW9uW10ge1xuICAgIGlmIChvcHRpb25zPy5pbmNsdWRlQ3VCdWRnZXQgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IFtDb21wdXRlQnVkZ2V0UHJvZ3JhbS5zZXRDb21wdXRlVW5pdExpbWl0KHsgdW5pdHM6IHRoaXMuZ2V0Q29tcHV0ZVVuaXRzKG9wdGlvbnMpIH0pXTtcbiAgICBpZiAob3B0aW9ucz8ucHJpb3JpdHlGZWVNaWNyb0xhbXBvcnRzICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5wcmlvcml0eUZlZU1pY3JvTGFtcG9ydHMgPiAwKSB7XG4gICAgICBpbnN0cnVjdGlvbnMucHVzaChDb21wdXRlQnVkZ2V0UHJvZ3JhbS5zZXRDb21wdXRlVW5pdFByaWNlKHsgbWljcm9MYW1wb3J0czogb3B0aW9ucy5wcmlvcml0eUZlZU1pY3JvTGFtcG9ydHMgfSkpO1xuICAgIH1cbiAgICByZXR1cm4gaW5zdHJ1Y3Rpb25zO1xuICB9XG5cbiAgLyogSW5zdHJ1Y3Rpb24gQnVpbGRlcnMgKi9cblxuICBhc3luYyBpbml0aWFsaXplTW9kZXJhdG9yKFxuICAgIGFkbWluOiBQdWJsaWNLZXksXG4gICAgYmFzZU1pbnQ6IFB1YmxpY0tleSxcbiAgICBxdW90ZU1pbnQ6IFB1YmxpY0tleSxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IFR4T3B0aW9uc1xuICApIHtcbiAgICBjb25zdCBbbW9kZXJhdG9yUGRhXSA9IHRoaXMuZGVyaXZlTW9kZXJhdG9yUERBKG5hbWUpO1xuXG4gICAgY29uc3QgYnVpbGRlciA9IGluaXRpYWxpemVNb2RlcmF0b3IoXG4gICAgICB0aGlzLnByb2dyYW0sXG4gICAgICBhZG1pbixcbiAgICAgIGJhc2VNaW50LFxuICAgICAgcXVvdGVNaW50LFxuICAgICAgbW9kZXJhdG9yUGRhLFxuICAgICAgbmFtZVxuICAgICkucHJlSW5zdHJ1Y3Rpb25zKHRoaXMubWF5YmVBZGRDb21wdXRlQnVkZ2V0KG9wdGlvbnMpKTtcblxuICAgIHJldHVybiB7IGJ1aWxkZXIsIG1vZGVyYXRvclBkYSwgbmFtZSB9O1xuICB9XG5cbiAgYXN5bmMgYWRkSGlzdG9yaWNhbFByb3Bvc2FsKFxuICAgIGFkbWluOiBQdWJsaWNLZXksXG4gICAgbW9kZXJhdG9yUGRhOiBQdWJsaWNLZXksXG4gICAgbnVtT3B0aW9uczogbnVtYmVyLFxuICAgIHdpbm5pbmdJZHg6IG51bWJlcixcbiAgICBsZW5ndGg6IG51bWJlcixcbiAgICBjcmVhdGVkQXQ6IEJOIHwgbnVtYmVyLFxuICAgIG1ldGFkYXRhOiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IFR4T3B0aW9uc1xuICApIHtcbiAgICBjb25zdCBtb2RlcmF0b3IgPSBhd2FpdCB0aGlzLmZldGNoTW9kZXJhdG9yKG1vZGVyYXRvclBkYSk7XG4gICAgY29uc3QgcHJvcG9zYWxJZCA9IG1vZGVyYXRvci5wcm9wb3NhbElkQ291bnRlcjtcbiAgICBjb25zdCBbcHJvcG9zYWxQZGFdID0gdGhpcy5kZXJpdmVQcm9wb3NhbFBEQShtb2RlcmF0b3JQZGEsIHByb3Bvc2FsSWQpO1xuXG4gICAgY29uc3QgYnVpbGRlciA9IGFkZEhpc3RvcmljYWxQcm9wb3NhbChcbiAgICAgIHRoaXMucHJvZ3JhbSxcbiAgICAgIGFkbWluLFxuICAgICAgbW9kZXJhdG9yUGRhLFxuICAgICAgcHJvcG9zYWxQZGEsXG4gICAgICBudW1PcHRpb25zLFxuICAgICAgd2lubmluZ0lkeCxcbiAgICAgIGxlbmd0aCxcbiAgICAgIGNyZWF0ZWRBdCxcbiAgICAgIG1ldGFkYXRhXG4gICAgKS5wcmVJbnN0cnVjdGlvbnModGhpcy5tYXliZUFkZENvbXB1dGVCdWRnZXQob3B0aW9ucykpO1xuXG4gICAgcmV0dXJuIHsgYnVpbGRlciwgcHJvcG9zYWxQZGEsIHByb3Bvc2FsSWQgfTtcbiAgfVxuXG4gIGFzeW5jIGluaXRpYWxpemVQcm9wb3NhbChcbiAgICBjcmVhdG9yOiBQdWJsaWNLZXksXG4gICAgbW9kZXJhdG9yUGRhOiBQdWJsaWNLZXksXG4gICAgcHJvcG9zYWxQYXJhbXM6IFByb3Bvc2FsUGFyYW1zLFxuICAgIG1ldGFkYXRhPzogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBUeE9wdGlvbnNcbiAgKSB7XG4gICAgY29uc3QgbW9kZXJhdG9yID0gYXdhaXQgdGhpcy5mZXRjaE1vZGVyYXRvcihtb2RlcmF0b3JQZGEpO1xuICAgIGNvbnN0IHByb3Bvc2FsSWQgPSBtb2RlcmF0b3IucHJvcG9zYWxJZENvdW50ZXI7XG4gICAgY29uc3QgW3Byb3Bvc2FsUGRhXSA9IHRoaXMuZGVyaXZlUHJvcG9zYWxQREEobW9kZXJhdG9yUGRhLCBwcm9wb3NhbElkKTtcblxuICAgIC8vIERlcml2ZSB2YXVsdCBQREEgKHByb3Bvc2FsIGlzIHRoZSBvd25lciwgbm9uY2U9cHJvcG9zYWxJZClcbiAgICBjb25zdCBbdmF1bHRQZGFdID0gZGVyaXZlVmF1bHRQREEocHJvcG9zYWxQZGEsIHByb3Bvc2FsSWQsIHRoaXMudmF1bHQucHJvZ3JhbUlkKTtcblxuICAgIC8vIERlcml2ZSBjb25kaXRpb25hbCBtaW50cyBmb3IgaW5pdGlhbCAyIG9wdGlvbnNcbiAgICBjb25zdCBbY29uZEJhc2VNaW50MF0gPSBkZXJpdmVDb25kaXRpb25hbE1pbnQodmF1bHRQZGEsIFZhdWx0VHlwZS5CYXNlLCAwLCB0aGlzLnZhdWx0LnByb2dyYW1JZCk7XG4gICAgY29uc3QgW2NvbmRCYXNlTWludDFdID0gZGVyaXZlQ29uZGl0aW9uYWxNaW50KHZhdWx0UGRhLCBWYXVsdFR5cGUuQmFzZSwgMSwgdGhpcy52YXVsdC5wcm9ncmFtSWQpO1xuICAgIGNvbnN0IFtjb25kUXVvdGVNaW50MF0gPSBkZXJpdmVDb25kaXRpb25hbE1pbnQodmF1bHRQZGEsIFZhdWx0VHlwZS5RdW90ZSwgMCwgdGhpcy52YXVsdC5wcm9ncmFtSWQpO1xuICAgIGNvbnN0IFtjb25kUXVvdGVNaW50MV0gPSBkZXJpdmVDb25kaXRpb25hbE1pbnQodmF1bHRQZGEsIFZhdWx0VHlwZS5RdW90ZSwgMSwgdGhpcy52YXVsdC5wcm9ncmFtSWQpO1xuXG4gICAgLy8gRGVyaXZlIHBvb2wgUERBcyBmb3IgaW5pdGlhbCAyIG9wdGlvbnMgKHByb3Bvc2FsIGlzIGFkbWluLCBtaW50QT1jb25kUXVvdGUsIG1pbnRCPWNvbmRCYXNlKVxuICAgIGNvbnN0IFtwb29sMF0gPSBkZXJpdmVQb29sUERBKHByb3Bvc2FsUGRhLCBjb25kUXVvdGVNaW50MCwgY29uZEJhc2VNaW50MCwgdGhpcy5hbW0ucHJvZ3JhbUlkKTtcbiAgICBjb25zdCBbcG9vbDFdID0gZGVyaXZlUG9vbFBEQShwcm9wb3NhbFBkYSwgY29uZFF1b3RlTWludDEsIGNvbmRCYXNlTWludDEsIHRoaXMuYW1tLnByb2dyYW1JZCk7XG5cbiAgICAvLyBEZXJpdmUgcmVzZXJ2ZXMgYW5kIGZlZSB2YXVsdHNcbiAgICBjb25zdCBbcmVzZXJ2ZUEwXSA9IGRlcml2ZVJlc2VydmVQREEocG9vbDAsIGNvbmRRdW90ZU1pbnQwLCB0aGlzLmFtbS5wcm9ncmFtSWQpO1xuICAgIGNvbnN0IFtyZXNlcnZlQjBdID0gZGVyaXZlUmVzZXJ2ZVBEQShwb29sMCwgY29uZEJhc2VNaW50MCwgdGhpcy5hbW0ucHJvZ3JhbUlkKTtcbiAgICBjb25zdCBbZmVlVmF1bHQwXSA9IGRlcml2ZUZlZVZhdWx0UERBKHBvb2wwLCB0aGlzLmFtbS5wcm9ncmFtSWQpO1xuICAgIGNvbnN0IFtyZXNlcnZlQTFdID0gZGVyaXZlUmVzZXJ2ZVBEQShwb29sMSwgY29uZFF1b3RlTWludDEsIHRoaXMuYW1tLnByb2dyYW1JZCk7XG4gICAgY29uc3QgW3Jlc2VydmVCMV0gPSBkZXJpdmVSZXNlcnZlUERBKHBvb2wxLCBjb25kQmFzZU1pbnQxLCB0aGlzLmFtbS5wcm9ncmFtSWQpO1xuICAgIGNvbnN0IFtmZWVWYXVsdDFdID0gZGVyaXZlRmVlVmF1bHRQREEocG9vbDEsIHRoaXMuYW1tLnByb2dyYW1JZCk7XG5cbiAgICAvLyBWYXVsdCB0b2tlbiBhY2NvdW50c1xuICAgIGNvbnN0IGJhc2VUb2tlbkFjYyA9IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKG1vZGVyYXRvci5iYXNlTWludCwgdmF1bHRQZGEsIHRydWUpO1xuICAgIGNvbnN0IHF1b3RlVG9rZW5BY2MgPSBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyhtb2RlcmF0b3IucXVvdGVNaW50LCB2YXVsdFBkYSwgdHJ1ZSk7XG5cbiAgICAvLyBCdWlsZCByZW1haW5pbmcgYWNjb3VudHMgaW4gZXhwZWN0ZWQgb3JkZXIgKHNlZSBpbml0aWFsaXplX3Byb3Bvc2FsLnJzKVxuICAgIGNvbnN0IHJlbWFpbmluZ0FjY291bnRzID0gW1xuICAgICAgeyBwdWJrZXk6IG1vZGVyYXRvci5iYXNlTWludCwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiBmYWxzZSB9LCAgICAgIC8vIDA6IGJhc2VfbWludFxuICAgICAgeyBwdWJrZXk6IG1vZGVyYXRvci5xdW90ZU1pbnQsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogZmFsc2UgfSwgICAgIC8vIDE6IHF1b3RlX21pbnRcbiAgICAgIHsgcHVia2V5OiB2YXVsdFBkYSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sICAgICAgICAgICAgICAgICAvLyAyOiB2YXVsdFxuICAgICAgeyBwdWJrZXk6IGJhc2VUb2tlbkFjYywgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sICAgICAgICAgICAgIC8vIDM6IGJhc2VfdG9rZW5fYWNjXG4gICAgICB7IHB1YmtleTogcXVvdGVUb2tlbkFjYywgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sICAgICAgICAgICAgLy8gNDogcXVvdGVfdG9rZW5fYWNjXG4gICAgICB7IHB1YmtleTogY29uZEJhc2VNaW50MCwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sICAgICAgICAgICAgLy8gNTogY29uZF9iYXNlX21pbnRfMFxuICAgICAgeyBwdWJrZXk6IGNvbmRCYXNlTWludDEsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LCAgICAgICAgICAgIC8vIDY6IGNvbmRfYmFzZV9taW50XzFcbiAgICAgIHsgcHVia2V5OiBjb25kUXVvdGVNaW50MCwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sICAgICAgICAgICAvLyA3OiBjb25kX3F1b3RlX21pbnRfMFxuICAgICAgeyBwdWJrZXk6IGNvbmRRdW90ZU1pbnQxLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSwgICAgICAgICAgIC8vIDg6IGNvbmRfcXVvdGVfbWludF8xXG4gICAgICB7IHB1YmtleTogcG9vbDAsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LCAgICAgICAgICAgICAgICAgICAgLy8gOTogcG9vbF8wXG4gICAgICB7IHB1YmtleTogcmVzZXJ2ZUEwLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSwgICAgICAgICAgICAgICAgLy8gMTA6IHJlc2VydmVfYV8wXG4gICAgICB7IHB1YmtleTogcmVzZXJ2ZUIwLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSwgICAgICAgICAgICAgICAgLy8gMTE6IHJlc2VydmVfYl8wXG4gICAgICB7IHB1YmtleTogRkVFX0FVVEhPUklUWSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiBmYWxzZSB9LCAgICAgICAgICAgLy8gMTI6IGZlZV9hdXRob3JpdHlcbiAgICAgIHsgcHVia2V5OiBmZWVWYXVsdDAsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LCAgICAgICAgICAgICAgICAvLyAxMzogZmVlX3ZhdWx0XzBcbiAgICAgIHsgcHVia2V5OiBwb29sMSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sICAgICAgICAgICAgICAgICAgICAvLyAxNDogcG9vbF8xXG4gICAgICB7IHB1YmtleTogcmVzZXJ2ZUExLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSwgICAgICAgICAgICAgICAgLy8gMTU6IHJlc2VydmVfYV8xXG4gICAgICB7IHB1YmtleTogcmVzZXJ2ZUIxLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSwgICAgICAgICAgICAgICAgLy8gMTY6IHJlc2VydmVfYl8xXG4gICAgICB7IHB1YmtleTogZmVlVmF1bHQxLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSwgICAgICAgICAgICAgICAgLy8gMTc6IGZlZV92YXVsdF8xXG4gICAgXTtcblxuICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0aWFsaXplUHJvcG9zYWwoXG4gICAgICB0aGlzLnByb2dyYW0sXG4gICAgICBjcmVhdG9yLFxuICAgICAgbW9kZXJhdG9yUGRhLFxuICAgICAgcHJvcG9zYWxQZGEsXG4gICAgICBwcm9wb3NhbFBhcmFtcyxcbiAgICAgIG1ldGFkYXRhID8/IG51bGwsXG4gICAgICByZW1haW5pbmdBY2NvdW50c1xuICAgICkucHJlSW5zdHJ1Y3Rpb25zKHRoaXMubWF5YmVBZGRDb21wdXRlQnVkZ2V0KG9wdGlvbnMpKTtcblxuICAgIHJldHVybiB7XG4gICAgICBidWlsZGVyLFxuICAgICAgcHJvcG9zYWxQZGEsXG4gICAgICBwcm9wb3NhbElkLFxuICAgICAgdmF1bHRQZGEsXG4gICAgICBwb29sczogW3Bvb2wwLCBwb29sMV0sXG4gICAgICBjb25kQmFzZU1pbnRzOiBbY29uZEJhc2VNaW50MCwgY29uZEJhc2VNaW50MV0sXG4gICAgICBjb25kUXVvdGVNaW50czogW2NvbmRRdW90ZU1pbnQwLCBjb25kUXVvdGVNaW50MV0sXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGFkZE9wdGlvbihjcmVhdG9yOiBQdWJsaWNLZXksIHByb3Bvc2FsUGRhOiBQdWJsaWNLZXksIG9wdGlvbnM/OiBUeE9wdGlvbnMpIHtcbiAgICBjb25zdCBwcm9wb3NhbCA9IGF3YWl0IHRoaXMuZmV0Y2hQcm9wb3NhbChwcm9wb3NhbFBkYSk7XG4gICAgY29uc3Qgb3B0aW9uSW5kZXggPSBwcm9wb3NhbC5udW1PcHRpb25zO1xuXG4gICAgLy8gRGVyaXZlIG5ldyBjb25kaXRpb25hbCBtaW50c1xuICAgIGNvbnN0IFtjb25kQmFzZU1pbnRdID0gZGVyaXZlQ29uZGl0aW9uYWxNaW50KHByb3Bvc2FsLnZhdWx0LCBWYXVsdFR5cGUuQmFzZSwgb3B0aW9uSW5kZXgsIHRoaXMudmF1bHQucHJvZ3JhbUlkKTtcbiAgICBjb25zdCBbY29uZFF1b3RlTWludF0gPSBkZXJpdmVDb25kaXRpb25hbE1pbnQocHJvcG9zYWwudmF1bHQsIFZhdWx0VHlwZS5RdW90ZSwgb3B0aW9uSW5kZXgsIHRoaXMudmF1bHQucHJvZ3JhbUlkKTtcblxuICAgIC8vIERlcml2ZSBwb29sIFBEQVxuICAgIGNvbnN0IFtwb29sXSA9IGRlcml2ZVBvb2xQREEocHJvcG9zYWxQZGEsIGNvbmRRdW90ZU1pbnQsIGNvbmRCYXNlTWludCwgdGhpcy5hbW0ucHJvZ3JhbUlkKTtcbiAgICBjb25zdCBbcmVzZXJ2ZUFdID0gZGVyaXZlUmVzZXJ2ZVBEQShwb29sLCBjb25kUXVvdGVNaW50LCB0aGlzLmFtbS5wcm9ncmFtSWQpO1xuICAgIGNvbnN0IFtyZXNlcnZlQl0gPSBkZXJpdmVSZXNlcnZlUERBKHBvb2wsIGNvbmRCYXNlTWludCwgdGhpcy5hbW0ucHJvZ3JhbUlkKTtcbiAgICBjb25zdCBbZmVlVmF1bHRdID0gZGVyaXZlRmVlVmF1bHRQREEocG9vbCwgdGhpcy5hbW0ucHJvZ3JhbUlkKTtcblxuICAgIC8vIEJ1aWxkIHJlbWFpbmluZyBhY2NvdW50cyAoc2VlIGFkZF9vcHRpb24ucnMpXG4gICAgY29uc3QgcmVtYWluaW5nQWNjb3VudHMgPSBbXG4gICAgICB7IHB1YmtleTogcHJvcG9zYWwudmF1bHQsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LCAgICAgICAgICAgLy8gMDogdmF1bHRcbiAgICAgIHsgcHVia2V5OiBjb25kQmFzZU1pbnQsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LCAgICAgICAgICAgICAvLyAxOiBjb25kX2Jhc2VfbWludFxuICAgICAgeyBwdWJrZXk6IGNvbmRRdW90ZU1pbnQsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LCAgICAgICAgICAgIC8vIDI6IGNvbmRfcXVvdGVfbWludFxuICAgICAgeyBwdWJrZXk6IHBvb2wsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LCAgICAgICAgICAgICAgICAgICAgIC8vIDM6IHBvb2xcbiAgICAgIHsgcHVia2V5OiByZXNlcnZlQSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sICAgICAgICAgICAgICAgICAvLyA0OiByZXNlcnZlX2FcbiAgICAgIHsgcHVia2V5OiByZXNlcnZlQiwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sICAgICAgICAgICAgICAgICAvLyA1OiByZXNlcnZlX2JcbiAgICAgIHsgcHVia2V5OiBGRUVfQVVUSE9SSVRZLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IGZhbHNlIH0sICAgICAgICAgICAvLyA2OiBmZWVfYXV0aG9yaXR5XG4gICAgICB7IHB1YmtleTogZmVlVmF1bHQsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LCAgICAgICAgICAgICAgICAgLy8gNzogZmVlX3ZhdWx0XG4gICAgXTtcblxuICAgIGNvbnN0IGJ1aWxkZXIgPSBhZGRPcHRpb24odGhpcy5wcm9ncmFtLCBjcmVhdG9yLCBwcm9wb3NhbFBkYSwgcmVtYWluaW5nQWNjb3VudHMpXG4gICAgICAucHJlSW5zdHJ1Y3Rpb25zKHRoaXMubWF5YmVBZGRDb21wdXRlQnVkZ2V0KG9wdGlvbnMpKTtcblxuICAgIHJldHVybiB7IGJ1aWxkZXIsIG9wdGlvbkluZGV4LCBwb29sLCBjb25kQmFzZU1pbnQsIGNvbmRRdW90ZU1pbnQgfTtcbiAgfVxuXG4gIGFzeW5jIGxhdW5jaFByb3Bvc2FsKFxuICAgIGNyZWF0b3I6IFB1YmxpY0tleSxcbiAgICBwcm9wb3NhbFBkYTogUHVibGljS2V5LFxuICAgIGJhc2VBbW91bnQ6IEJOIHwgbnVtYmVyLFxuICAgIHF1b3RlQW1vdW50OiBCTiB8IG51bWJlcixcbiAgICBvcHRpb25zPzogVHhPcHRpb25zXG4gICkge1xuICAgIGNvbnN0IHByb3Bvc2FsID0gYXdhaXQgdGhpcy5mZXRjaFByb3Bvc2FsKHByb3Bvc2FsUGRhKTtcbiAgICBjb25zdCB2YXVsdCA9IGF3YWl0IHRoaXMudmF1bHQuZmV0Y2hWYXVsdChwcm9wb3NhbC52YXVsdCk7XG4gICAgY29uc3QgbnVtT3B0aW9ucyA9IHByb3Bvc2FsLm51bU9wdGlvbnM7XG5cbiAgICAvLyBTbGljZSBhcnJheXMgdG8gbnVtT3B0aW9ucyAoZml4ZWQtc2l6ZSBhcnJheXMgZnJvbSBSdXN0IGluY2x1ZGUgZW1wdHkgc2xvdHMpXG4gICAgY29uc3QgY29uZEJhc2VNaW50cyA9IHZhdWx0LmNvbmRCYXNlTWludHMuc2xpY2UoMCwgbnVtT3B0aW9ucyk7XG4gICAgY29uc3QgY29uZFF1b3RlTWludHMgPSB2YXVsdC5jb25kUXVvdGVNaW50cy5zbGljZSgwLCBudW1PcHRpb25zKTtcblxuICAgIC8vIFByZS1jcmVhdGUgY29uZGl0aW9uYWwgQVRBcyBmb3IgMysgb3B0aW9ucyB0byBhdm9pZCBleGNlZWRpbmcgdGhlXG4gICAgLy8gNjQgaW5zdHJ1Y3Rpb24gdHJhY2UgbGltaXQuIEVhY2ggQVRBIGNyZWF0aW9uIHZpYSB2YXVsdCBkZXBvc2l0IGFkZHNcbiAgICAvLyA1IGlubmVyIGluc3RydWN0aW9uczsgd2l0aCA0IG9wdGlvbnMgdGhhdCdzIDQwIGV4dHJhIGluc3RydWN0aW9ucy5cbiAgICBjb25zdCBzaG91bGRFbnN1cmVBVEFzID0gb3B0aW9ucz8uZW5zdXJlQVRBcyA/PyAobnVtT3B0aW9ucyA+PSAzKTtcbiAgICBpZiAoc2hvdWxkRW5zdXJlQVRBcykge1xuICAgICAgYXdhaXQgdGhpcy5fY3JlYXRlQ29uZGl0aW9uYWxBVEFzKGNyZWF0b3IsIGNvbmRCYXNlTWludHMsIGNvbmRRdW90ZU1pbnRzKTtcbiAgICB9XG4gICAgY29uc3QgcG9vbHMgPSBwcm9wb3NhbC5wb29scy5zbGljZSgwLCBudW1PcHRpb25zKTtcblxuICAgIC8vIERlcml2ZSBhbGwgdXNlciBjb25kaXRpb25hbCB0b2tlbiBBVEFzXG4gICAgY29uc3QgdXNlckNvbmRCYXNlQVRBcyA9IGNvbmRCYXNlTWludHMubWFwKChtKSA9PiBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyhtLCBjcmVhdG9yKSk7XG4gICAgY29uc3QgdXNlckNvbmRRdW90ZUFUQXMgPSBjb25kUXVvdGVNaW50cy5tYXAoKG0pID0+IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKG0sIGNyZWF0b3IpKTtcblxuICAgIC8vIERlcml2ZSByZXNlcnZlIGFjY291bnRzIGZvciBlYWNoIHBvb2xcbiAgICBjb25zdCByZXNlcnZlc0E6IFB1YmxpY0tleVtdID0gW107XG4gICAgY29uc3QgcmVzZXJ2ZXNCOiBQdWJsaWNLZXlbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtT3B0aW9uczsgaSsrKSB7XG4gICAgICBjb25zdCBbcmVzQV0gPSBkZXJpdmVSZXNlcnZlUERBKHBvb2xzW2ldLCBjb25kUXVvdGVNaW50c1tpXSwgdGhpcy5hbW0ucHJvZ3JhbUlkKTtcbiAgICAgIGNvbnN0IFtyZXNCXSA9IGRlcml2ZVJlc2VydmVQREEocG9vbHNbaV0sIGNvbmRCYXNlTWludHNbaV0sIHRoaXMuYW1tLnByb2dyYW1JZCk7XG4gICAgICByZXNlcnZlc0EucHVzaChyZXNBKTtcbiAgICAgIHJlc2VydmVzQi5wdXNoKHJlc0IpO1xuICAgIH1cblxuICAgIC8vIEJ1aWxkIHJlbWFpbmluZyBhY2NvdW50cyAoc2VlIGxhdW5jaF9wcm9wb3NhbC5ycylcbiAgICAvLyBMYXlvdXQ6IDYgZml4ZWQgKyA3Kk4gdmFyaWFibGVcbiAgICBjb25zdCByZW1haW5pbmdBY2NvdW50czogeyBwdWJrZXk6IFB1YmxpY0tleTsgaXNTaWduZXI6IGJvb2xlYW47IGlzV3JpdGFibGU6IGJvb2xlYW4gfVtdID0gW1xuICAgICAgeyBwdWJrZXk6IHZhdWx0LmJhc2VNaW50LmFkZHJlc3MsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogZmFsc2UgfSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAwOiBiYXNlX21pbnRcbiAgICAgIHsgcHVia2V5OiB2YXVsdC5xdW90ZU1pbnQuYWRkcmVzcywgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiBmYWxzZSB9LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMTogcXVvdGVfbWludFxuICAgICAgeyBwdWJrZXk6IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHZhdWx0LmJhc2VNaW50LmFkZHJlc3MsIHByb3Bvc2FsLnZhdWx0LCB0cnVlKSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sICAgLy8gMjogdmF1bHRfYmFzZV9hdGFcbiAgICAgIHsgcHVia2V5OiBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyh2YXVsdC5xdW90ZU1pbnQuYWRkcmVzcywgcHJvcG9zYWwudmF1bHQsIHRydWUpLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSwgIC8vIDM6IHZhdWx0X3F1b3RlX2F0YVxuICAgICAgeyBwdWJrZXk6IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHZhdWx0LmJhc2VNaW50LmFkZHJlc3MsIGNyZWF0b3IpLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSwgIC8vIDQ6IHVzZXJfYmFzZV9hdGFcbiAgICAgIHsgcHVia2V5OiBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyh2YXVsdC5xdW90ZU1pbnQuYWRkcmVzcywgY3JlYXRvciksIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LCAvLyA1OiB1c2VyX3F1b3RlX2F0YVxuICAgIF07XG5cbiAgICAvLyA2Li42K046IGNvbmRfYmFzZV9taW50c1xuICAgIGZvciAoY29uc3QgbWludCBvZiBjb25kQmFzZU1pbnRzKSB7XG4gICAgICByZW1haW5pbmdBY2NvdW50cy5wdXNoKHsgcHVia2V5OiBtaW50LCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSk7XG4gICAgfVxuICAgIC8vIDYrTi4uNisyTjogY29uZF9xdW90ZV9taW50c1xuICAgIGZvciAoY29uc3QgbWludCBvZiBjb25kUXVvdGVNaW50cykge1xuICAgICAgcmVtYWluaW5nQWNjb3VudHMucHVzaCh7IHB1YmtleTogbWludCwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0pO1xuICAgIH1cbiAgICAvLyA2KzJOLi42KzNOOiB1c2VyX2NvbmRfYmFzZV9hdGFzXG4gICAgZm9yIChjb25zdCBhdGEgb2YgdXNlckNvbmRCYXNlQVRBcykge1xuICAgICAgcmVtYWluaW5nQWNjb3VudHMucHVzaCh7IHB1YmtleTogYXRhLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSk7XG4gICAgfVxuICAgIC8vIDYrM04uLjYrNE46IHVzZXJfY29uZF9xdW90ZV9hdGFzXG4gICAgZm9yIChjb25zdCBhdGEgb2YgdXNlckNvbmRRdW90ZUFUQXMpIHtcbiAgICAgIHJlbWFpbmluZ0FjY291bnRzLnB1c2goeyBwdWJrZXk6IGF0YSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0pO1xuICAgIH1cbiAgICAvLyA2KzROLi42KzVOOiBwb29sc1xuICAgIGZvciAoY29uc3QgcG9vbCBvZiBwb29scykge1xuICAgICAgcmVtYWluaW5nQWNjb3VudHMucHVzaCh7IHB1YmtleTogcG9vbCwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0pO1xuICAgIH1cbiAgICAvLyA2KzVOLi42KzZOOiByZXNlcnZlc19hXG4gICAgZm9yIChjb25zdCByZXMgb2YgcmVzZXJ2ZXNBKSB7XG4gICAgICByZW1haW5pbmdBY2NvdW50cy5wdXNoKHsgcHVia2V5OiByZXMsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9KTtcbiAgICB9XG4gICAgLy8gNis2Ti4uNis3TjogcmVzZXJ2ZXNfYlxuICAgIGZvciAoY29uc3QgcmVzIG9mIHJlc2VydmVzQikge1xuICAgICAgcmVtYWluaW5nQWNjb3VudHMucHVzaCh7IHB1YmtleTogcmVzLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgYnVpbGRlciA9IGxhdW5jaFByb3Bvc2FsKFxuICAgICAgdGhpcy5wcm9ncmFtLFxuICAgICAgY3JlYXRvcixcbiAgICAgIHByb3Bvc2FsUGRhLFxuICAgICAgcHJvcG9zYWwudmF1bHQsXG4gICAgICBiYXNlQW1vdW50LFxuICAgICAgcXVvdGVBbW91bnQsXG4gICAgICByZW1haW5pbmdBY2NvdW50c1xuICAgICkucHJlSW5zdHJ1Y3Rpb25zKHRoaXMubWF5YmVBZGRDb21wdXRlQnVkZ2V0KG9wdGlvbnMpKTtcblxuICAgIHJldHVybiB7IGJ1aWxkZXIgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcmUtY3JlYXRlcyBhbGwgY29uZGl0aW9uYWwgdG9rZW4gQVRBcyBmb3IgYSB1c2VyIGJlZm9yZSBsYXVuY2hpbmcgYSBwcm9wb3NhbC5cbiAgICpcbiAgICogVGhpcyBpcyBSRVFVSVJFRCBmb3IgcHJvcG9zYWxzIHdpdGggMysgb3B0aW9ucyB0byBhdm9pZCBleGNlZWRpbmcgU29sYW5hJ3NcbiAgICogbWF4IGluc3RydWN0aW9uIHRyYWNlIGxlbmd0aCBsaW1pdCAoNjQgaW5zdHJ1Y3Rpb25zKS4gVGhlIHZhdWx0J3MgZGVwb3NpdCBDUElcbiAgICogY3JlYXRlcyBBVEFzIG9uLXRoZS1mbHksIGVhY2ggcmVxdWlyaW5nIDUgaW5uZXIgaW5zdHJ1Y3Rpb25zLiBGb3IgNCBvcHRpb25zOlxuICAgKiA4IEFUQXMgw5cgNSA9IDQwIGV4dHJhIGluc3RydWN0aW9ucywgcHVzaGluZyB0aGUgdG90YWwgb3ZlciA2NC5cbiAgICpcbiAgICogUHJlLWNyZWF0aW5nIEFUQXMgZWxpbWluYXRlcyB0aGlzIG92ZXJoZWFkLCByZWR1Y2luZyB0aGUgdHJhY2UgdG8gfjMyIGluc3RydWN0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIGNyZWF0b3IgLSBUaGUgdXNlciB3aG8gd2lsbCByZWNlaXZlIGNvbmRpdGlvbmFsIHRva2Vuc1xuICAgKiBAcGFyYW0gcHJvcG9zYWxQZGEgLSBUaGUgcHJvcG9zYWwgUERBIChtdXN0IGJlIGluaXRpYWxpemVkIGJ1dCBub3QgbGF1bmNoZWQpXG4gICAqIEByZXR1cm5zIFRyYW5zYWN0aW9uIHNpZ25hdHVyZVxuICAgKi9cbiAgYXN5bmMgZW5zdXJlQ29uZGl0aW9uYWxBVEFzKFxuICAgIGNyZWF0b3I6IFB1YmxpY0tleSxcbiAgICBwcm9wb3NhbFBkYTogUHVibGljS2V5LFxuICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHByb3Bvc2FsID0gYXdhaXQgdGhpcy5mZXRjaFByb3Bvc2FsKHByb3Bvc2FsUGRhKTtcbiAgICBjb25zdCB2YXVsdCA9IGF3YWl0IHRoaXMudmF1bHQuZmV0Y2hWYXVsdChwcm9wb3NhbC52YXVsdCk7XG4gICAgY29uc3QgY29uZEJhc2VNaW50cyA9IHZhdWx0LmNvbmRCYXNlTWludHMuc2xpY2UoMCwgcHJvcG9zYWwubnVtT3B0aW9ucyk7XG4gICAgY29uc3QgY29uZFF1b3RlTWludHMgPSB2YXVsdC5jb25kUXVvdGVNaW50cy5zbGljZSgwLCBwcm9wb3NhbC5udW1PcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlQ29uZGl0aW9uYWxBVEFzKGNyZWF0b3IsIGNvbmRCYXNlTWludHMsIGNvbmRRdW90ZU1pbnRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnRlcm5hbCBoZWxwZXIgdG8gY3JlYXRlIGNvbmRpdGlvbmFsIEFUQXMgZ2l2ZW4gbWludCBhcnJheXMuXG4gICAqIFVzZWQgYnkgYm90aCBlbnN1cmVDb25kaXRpb25hbEFUQXMgYW5kIGxhdW5jaFByb3Bvc2FsIHRvIGF2b2lkIHJlZHVuZGFudCBmZXRjaGVzLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBfY3JlYXRlQ29uZGl0aW9uYWxBVEFzKFxuICAgIGNyZWF0b3I6IFB1YmxpY0tleSxcbiAgICBjb25kQmFzZU1pbnRzOiBQdWJsaWNLZXlbXSxcbiAgICBjb25kUXVvdGVNaW50czogUHVibGljS2V5W10sXG4gICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLnByb2dyYW0ucHJvdmlkZXIgYXMgQW5jaG9yUHJvdmlkZXI7XG5cbiAgICAvLyBCdWlsZCBBVEEgY3JlYXRpb24gaW5zdHJ1Y3Rpb25zIChpZGVtcG90ZW50IC0gd29uJ3QgZmFpbCBpZiBleGlzdHMpXG4gICAgY29uc3QgaW5zdHJ1Y3Rpb25zOiBUcmFuc2FjdGlvbkluc3RydWN0aW9uW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbmRCYXNlTWludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHVzZXJDb25kQmFzZUF0YSA9IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKGNvbmRCYXNlTWludHNbaV0sIGNyZWF0b3IpO1xuICAgICAgY29uc3QgdXNlckNvbmRRdW90ZUF0YSA9IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKGNvbmRRdW90ZU1pbnRzW2ldLCBjcmVhdG9yKTtcblxuICAgICAgaW5zdHJ1Y3Rpb25zLnB1c2goXG4gICAgICAgIGNyZWF0ZUFzc29jaWF0ZWRUb2tlbkFjY291bnRJZGVtcG90ZW50SW5zdHJ1Y3Rpb24oXG4gICAgICAgICAgY3JlYXRvcixcbiAgICAgICAgICB1c2VyQ29uZEJhc2VBdGEsXG4gICAgICAgICAgY3JlYXRvcixcbiAgICAgICAgICBjb25kQmFzZU1pbnRzW2ldXG4gICAgICAgICksXG4gICAgICAgIGNyZWF0ZUFzc29jaWF0ZWRUb2tlbkFjY291bnRJZGVtcG90ZW50SW5zdHJ1Y3Rpb24oXG4gICAgICAgICAgY3JlYXRvcixcbiAgICAgICAgICB1c2VyQ29uZFF1b3RlQXRhLFxuICAgICAgICAgIGNyZWF0b3IsXG4gICAgICAgICAgY29uZFF1b3RlTWludHNbaV1cbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBTZW5kIHRyYW5zYWN0aW9uXG4gICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oKS5hZGQoLi4uaW5zdHJ1Y3Rpb25zKTtcbiAgICByZXR1cm4gcHJvdmlkZXIuc2VuZEFuZENvbmZpcm0odHgpO1xuICB9XG5cbiAgYXN5bmMgZmluYWxpemVQcm9wb3NhbChzaWduZXI6IFB1YmxpY0tleSwgcHJvcG9zYWxQZGE6IFB1YmxpY0tleSwgb3B0aW9ucz86IFR4T3B0aW9ucykge1xuICAgIGNvbnN0IHByb3Bvc2FsID0gYXdhaXQgdGhpcy5mZXRjaFByb3Bvc2FsKHByb3Bvc2FsUGRhKTtcbiAgICBjb25zdCB2YXVsdCA9IGF3YWl0IHRoaXMudmF1bHQuZmV0Y2hWYXVsdChwcm9wb3NhbC52YXVsdCk7XG4gICAgY29uc3QgbnVtT3B0aW9ucyA9IHByb3Bvc2FsLm51bU9wdGlvbnM7XG5cbiAgICAvLyBCdWlsZCByZW1haW5pbmcgYWNjb3VudHMgKDMgcGVyIHBvb2w6IHBvb2wsIHJlc2VydmVfYSwgcmVzZXJ2ZV9iKVxuICAgIGNvbnN0IHJlbWFpbmluZ0FjY291bnRzOiB7IHB1YmtleTogUHVibGljS2V5OyBpc1NpZ25lcjogYm9vbGVhbjsgaXNXcml0YWJsZTogYm9vbGVhbiB9W10gPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtT3B0aW9uczsgaSsrKSB7XG4gICAgICBjb25zdCBwb29sID0gcHJvcG9zYWwucG9vbHNbaV07XG4gICAgICBjb25zdCBbcmVzZXJ2ZUFdID0gZGVyaXZlUmVzZXJ2ZVBEQShwb29sLCB2YXVsdC5jb25kUXVvdGVNaW50c1tpXSwgdGhpcy5hbW0ucHJvZ3JhbUlkKTtcbiAgICAgIGNvbnN0IFtyZXNlcnZlQl0gPSBkZXJpdmVSZXNlcnZlUERBKHBvb2wsIHZhdWx0LmNvbmRCYXNlTWludHNbaV0sIHRoaXMuYW1tLnByb2dyYW1JZCk7XG5cbiAgICAgIHJlbWFpbmluZ0FjY291bnRzLnB1c2goeyBwdWJrZXk6IHBvb2wsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9KTtcbiAgICAgIHJlbWFpbmluZ0FjY291bnRzLnB1c2goeyBwdWJrZXk6IHJlc2VydmVBLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IGZhbHNlIH0pO1xuICAgICAgcmVtYWluaW5nQWNjb3VudHMucHVzaCh7IHB1YmtleTogcmVzZXJ2ZUIsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogZmFsc2UgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgYnVpbGRlciA9IGZpbmFsaXplUHJvcG9zYWwoXG4gICAgICB0aGlzLnByb2dyYW0sXG4gICAgICBzaWduZXIsXG4gICAgICBwcm9wb3NhbFBkYSxcbiAgICAgIHByb3Bvc2FsLnZhdWx0LFxuICAgICAgcmVtYWluaW5nQWNjb3VudHNcbiAgICApLnByZUluc3RydWN0aW9ucyh0aGlzLm1heWJlQWRkQ29tcHV0ZUJ1ZGdldChvcHRpb25zKSk7XG5cbiAgICByZXR1cm4geyBidWlsZGVyIH07XG4gIH1cblxuICBhc3luYyByZWRlZW1MaXF1aWRpdHkoY3JlYXRvcjogUHVibGljS2V5LCBwcm9wb3NhbFBkYTogUHVibGljS2V5LCBvcHRpb25zPzogVHhPcHRpb25zKSB7XG4gICAgY29uc3QgcHJvcG9zYWwgPSBhd2FpdCB0aGlzLmZldGNoUHJvcG9zYWwocHJvcG9zYWxQZGEpO1xuICAgIGNvbnN0IHZhdWx0ID0gYXdhaXQgdGhpcy52YXVsdC5mZXRjaFZhdWx0KHByb3Bvc2FsLnZhdWx0KTtcbiAgICBjb25zdCBudW1PcHRpb25zID0gcHJvcG9zYWwubnVtT3B0aW9ucztcblxuICAgIGNvbnN0IHsgd2lubmluZ0lkeCB9ID0gcGFyc2VQcm9wb3NhbFN0YXRlKHByb3Bvc2FsLnN0YXRlKTtcbiAgICBpZiAod2lubmluZ0lkeCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUHJvcG9zYWwgbm90IGZpbmFsaXplZFwiKTtcbiAgICB9XG4gICAgY29uc3Qgd2lubmluZ1Bvb2wgPSBwcm9wb3NhbC5wb29sc1t3aW5uaW5nSWR4XTtcblxuICAgIC8vIERlcml2ZSB3aW5uaW5nIHBvb2wgcmVzZXJ2ZXNcbiAgICBjb25zdCBbcmVzZXJ2ZUFdID0gZGVyaXZlUmVzZXJ2ZVBEQSh3aW5uaW5nUG9vbCwgdmF1bHQuY29uZFF1b3RlTWludHNbd2lubmluZ0lkeF0sIHRoaXMuYW1tLnByb2dyYW1JZCk7XG4gICAgY29uc3QgW3Jlc2VydmVCXSA9IGRlcml2ZVJlc2VydmVQREEod2lubmluZ1Bvb2wsIHZhdWx0LmNvbmRCYXNlTWludHNbd2lubmluZ0lkeF0sIHRoaXMuYW1tLnByb2dyYW1JZCk7XG5cbiAgICAvLyBVc2VyJ3Mgd2lubmluZyBjb25kaXRpb25hbCB0b2tlbiBBVEFzXG4gICAgY29uc3QgY3JlYXRvckNvbmRRdW90ZUF0YSA9IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHZhdWx0LmNvbmRRdW90ZU1pbnRzW3dpbm5pbmdJZHhdLCBjcmVhdG9yKTtcbiAgICBjb25zdCBjcmVhdG9yQ29uZEJhc2VBdGEgPSBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyh2YXVsdC5jb25kQmFzZU1pbnRzW3dpbm5pbmdJZHhdLCBjcmVhdG9yKTtcblxuICAgIC8vIEJ1aWxkIHJlbWFpbmluZyBhY2NvdW50cyAoc2VlIHJlZGVlbV9saXF1aWRpdHkucnMpXG4gICAgY29uc3QgcmVtYWluaW5nQWNjb3VudHM6IHsgcHVia2V5OiBQdWJsaWNLZXk7IGlzU2lnbmVyOiBib29sZWFuOyBpc1dyaXRhYmxlOiBib29sZWFuIH1bXSA9IFtcbiAgICAgIC8vIHJlbW92ZV9saXF1aWRpdHkgYWNjb3VudHMgKDAtMylcbiAgICAgIHsgcHVia2V5OiByZXNlcnZlQSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sXG4gICAgICB7IHB1YmtleTogcmVzZXJ2ZUIsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LFxuICAgICAgeyBwdWJrZXk6IGNyZWF0b3JDb25kUXVvdGVBdGEsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LFxuICAgICAgeyBwdWJrZXk6IGNyZWF0b3JDb25kQmFzZUF0YSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sXG5cbiAgICAgIC8vIHJlZGVlbV93aW5uaW5ncyBiYXNlIGZpeGVkIGFjY291bnRzICg0LTYpXG4gICAgICB7IHB1YmtleTogdmF1bHQuYmFzZU1pbnQuYWRkcmVzcywgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiBmYWxzZSB9LFxuICAgICAgeyBwdWJrZXk6IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHZhdWx0LmJhc2VNaW50LmFkZHJlc3MsIHByb3Bvc2FsLnZhdWx0LCB0cnVlKSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0sXG4gICAgICB7IHB1YmtleTogZ2V0QXNzb2NpYXRlZFRva2VuQWRkcmVzc1N5bmModmF1bHQuYmFzZU1pbnQuYWRkcmVzcywgY3JlYXRvciksIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9LFxuICAgIF07XG5cbiAgICAvLyByZWRlZW1fd2lubmluZ3MgYmFzZSByZW1haW5pbmcgKDcuLjcrMk4pOiBbY29uZF9iYXNlX21pbnRfaSwgdXNlcl9jb25kX2Jhc2VfYXRhX2ldXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1PcHRpb25zOyBpKyspIHtcbiAgICAgIHJlbWFpbmluZ0FjY291bnRzLnB1c2goeyBwdWJrZXk6IHZhdWx0LmNvbmRCYXNlTWludHNbaV0sIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9KTtcbiAgICAgIHJlbWFpbmluZ0FjY291bnRzLnB1c2goeyBwdWJrZXk6IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHZhdWx0LmNvbmRCYXNlTWludHNbaV0sIGNyZWF0b3IpLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSk7XG4gICAgfVxuXG4gICAgLy8gcmVkZWVtX3dpbm5pbmdzIHF1b3RlIGZpeGVkIGFjY291bnRzXG4gICAgcmVtYWluaW5nQWNjb3VudHMucHVzaCh7IHB1YmtleTogdmF1bHQucXVvdGVNaW50LmFkZHJlc3MsIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogZmFsc2UgfSk7XG4gICAgcmVtYWluaW5nQWNjb3VudHMucHVzaCh7IHB1YmtleTogZ2V0QXNzb2NpYXRlZFRva2VuQWRkcmVzc1N5bmModmF1bHQucXVvdGVNaW50LmFkZHJlc3MsIHByb3Bvc2FsLnZhdWx0LCB0cnVlKSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0pO1xuICAgIHJlbWFpbmluZ0FjY291bnRzLnB1c2goeyBwdWJrZXk6IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHZhdWx0LnF1b3RlTWludC5hZGRyZXNzLCBjcmVhdG9yKSwgaXNTaWduZXI6IGZhbHNlLCBpc1dyaXRhYmxlOiB0cnVlIH0pO1xuXG4gICAgLy8gcmVkZWVtX3dpbm5pbmdzIHF1b3RlIHJlbWFpbmluZzogW2NvbmRfcXVvdGVfbWludF9pLCB1c2VyX2NvbmRfcXVvdGVfYXRhX2ldXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1PcHRpb25zOyBpKyspIHtcbiAgICAgIHJlbWFpbmluZ0FjY291bnRzLnB1c2goeyBwdWJrZXk6IHZhdWx0LmNvbmRRdW90ZU1pbnRzW2ldLCBpc1NpZ25lcjogZmFsc2UsIGlzV3JpdGFibGU6IHRydWUgfSk7XG4gICAgICByZW1haW5pbmdBY2NvdW50cy5wdXNoKHsgcHVia2V5OiBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyh2YXVsdC5jb25kUXVvdGVNaW50c1tpXSwgY3JlYXRvciksIGlzU2lnbmVyOiBmYWxzZSwgaXNXcml0YWJsZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBidWlsZGVyID0gcmVkZWVtTGlxdWlkaXR5KFxuICAgICAgdGhpcy5wcm9ncmFtLFxuICAgICAgY3JlYXRvcixcbiAgICAgIHByb3Bvc2FsUGRhLFxuICAgICAgcHJvcG9zYWwudmF1bHQsXG4gICAgICB3aW5uaW5nUG9vbCxcbiAgICAgIHJlbWFpbmluZ0FjY291bnRzXG4gICAgKS5wcmVJbnN0cnVjdGlvbnModGhpcy5tYXliZUFkZENvbXB1dGVCdWRnZXQob3B0aW9ucykpO1xuXG4gICAgcmV0dXJuIHsgYnVpbGRlciwgbnVtT3B0aW9ucyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gQWRkcmVzcyBMb29rdXAgVGFibGUgZm9yIHJlZGVtcHRpb24gb3BlcmF0aW9ucy5cbiAgICogUmVxdWlyZWQgZm9yIHByb3Bvc2FscyB3aXRoIDMrIG9wdGlvbnMgdG8gYXZvaWQgZXhjZWVkaW5nIHRyYW5zYWN0aW9uIHNpemUgbGltaXRzLlxuICAgKlxuICAgKiBAcGFyYW0gY3JlYXRvciAtIFRoZSB1c2VyIHJlZGVlbWluZyAoY3JlYXRvciBvZiBwcm9wb3NhbCBvciBsaXF1aWRpdHkgcHJvdmlkZXIpXG4gICAqIEBwYXJhbSBwcm9wb3NhbFBkYSAtIFRoZSBwcm9wb3NhbCBQREFcbiAgICogQHJldHVybnMgQUxUIGFkZHJlc3NcbiAgICovXG4gIGFzeW5jIGNyZWF0ZVJlZGVtcHRpb25BTFQoXG4gICAgY3JlYXRvcjogUHVibGljS2V5LFxuICAgIHByb3Bvc2FsUGRhOiBQdWJsaWNLZXksXG4gICk6IFByb21pc2U8eyBhbHRBZGRyZXNzOiBQdWJsaWNLZXkgfT4ge1xuICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5wcm9ncmFtLnByb3ZpZGVyIGFzIEFuY2hvclByb3ZpZGVyO1xuICAgIGNvbnN0IHByb3Bvc2FsID0gYXdhaXQgdGhpcy5mZXRjaFByb3Bvc2FsKHByb3Bvc2FsUGRhKTtcbiAgICBjb25zdCB2YXVsdCA9IGF3YWl0IHRoaXMudmF1bHQuZmV0Y2hWYXVsdChwcm9wb3NhbC52YXVsdCk7XG4gICAgY29uc3QgbnVtT3B0aW9ucyA9IHByb3Bvc2FsLm51bU9wdGlvbnM7XG5cbiAgICBjb25zdCB7IHdpbm5pbmdJZHggfSA9IHBhcnNlUHJvcG9zYWxTdGF0ZShwcm9wb3NhbC5zdGF0ZSk7XG4gICAgaWYgKHdpbm5pbmdJZHggPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlByb3Bvc2FsIG5vdCBmaW5hbGl6ZWRcIik7XG4gICAgfVxuXG4gICAgY29uc3QgYWRkcmVzc2VzOiBQdWJsaWNLZXlbXSA9IFtcbiAgICAgIC8vIFByb2dyYW1zXG4gICAgICB0aGlzLnByb2dyYW1JZCxcbiAgICAgIHRoaXMudmF1bHQucHJvZ3JhbUlkLFxuICAgICAgdGhpcy5hbW0ucHJvZ3JhbUlkLFxuICAgICAgU3lzdGVtUHJvZ3JhbS5wcm9ncmFtSWQsXG4gICAgICBUT0tFTl9QUk9HUkFNX0lELFxuICAgICAgQVNTT0NJQVRFRF9UT0tFTl9QUk9HUkFNX0lELFxuICAgICAgLy8gQ29yZSBhY2NvdW50c1xuICAgICAgcHJvcG9zYWxQZGEsXG4gICAgICBwcm9wb3NhbC52YXVsdCxcbiAgICAgIHByb3Bvc2FsLm1vZGVyYXRvcixcbiAgICAgIHZhdWx0LmJhc2VNaW50LmFkZHJlc3MsXG4gICAgICB2YXVsdC5xdW90ZU1pbnQuYWRkcmVzcyxcbiAgICAgIC8vIFdpbm5pbmcgcG9vbCBhbmQgcmVzZXJ2ZXNcbiAgICAgIHByb3Bvc2FsLnBvb2xzW3dpbm5pbmdJZHhdLFxuICAgICAgLy8gVmF1bHQgdG9rZW4gYWNjb3VudHNcbiAgICAgIGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHZhdWx0LmJhc2VNaW50LmFkZHJlc3MsIHByb3Bvc2FsLnZhdWx0LCB0cnVlKSxcbiAgICAgIGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHZhdWx0LnF1b3RlTWludC5hZGRyZXNzLCBwcm9wb3NhbC52YXVsdCwgdHJ1ZSksXG4gICAgICAvLyBDcmVhdG9yJ3MgYmFzZS9xdW90ZSBBVEFzXG4gICAgICBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyh2YXVsdC5iYXNlTWludC5hZGRyZXNzLCBjcmVhdG9yKSxcbiAgICAgIGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHZhdWx0LnF1b3RlTWludC5hZGRyZXNzLCBjcmVhdG9yKSxcbiAgICBdO1xuXG4gICAgLy8gV2lubmluZyBwb29sIHJlc2VydmVzXG4gICAgY29uc3QgW3Jlc2VydmVBXSA9IGRlcml2ZVJlc2VydmVQREEocHJvcG9zYWwucG9vbHNbd2lubmluZ0lkeF0sIHZhdWx0LmNvbmRRdW90ZU1pbnRzW3dpbm5pbmdJZHhdLCB0aGlzLmFtbS5wcm9ncmFtSWQpO1xuICAgIGNvbnN0IFtyZXNlcnZlQl0gPSBkZXJpdmVSZXNlcnZlUERBKHByb3Bvc2FsLnBvb2xzW3dpbm5pbmdJZHhdLCB2YXVsdC5jb25kQmFzZU1pbnRzW3dpbm5pbmdJZHhdLCB0aGlzLmFtbS5wcm9ncmFtSWQpO1xuICAgIGFkZHJlc3Nlcy5wdXNoKHJlc2VydmVBLCByZXNlcnZlQik7XG5cbiAgICAvLyBQZXItb3B0aW9uIGFjY291bnRzIChjb25kaXRpb25hbCBtaW50cyBhbmQgdXNlciBBVEFzKVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtT3B0aW9uczsgaSsrKSB7XG4gICAgICBhZGRyZXNzZXMucHVzaChcbiAgICAgICAgdmF1bHQuY29uZEJhc2VNaW50c1tpXSxcbiAgICAgICAgdmF1bHQuY29uZFF1b3RlTWludHNbaV0sXG4gICAgICAgIGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHZhdWx0LmNvbmRCYXNlTWludHNbaV0sIGNyZWF0b3IpLFxuICAgICAgICBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyh2YXVsdC5jb25kUXVvdGVNaW50c1tpXSwgY3JlYXRvciksXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEdldCByZWNlbnQgc2xvdCBmb3IgQUxUIGNyZWF0aW9uXG4gICAgY29uc3Qgc2xvdCA9IGF3YWl0IHByb3ZpZGVyLmNvbm5lY3Rpb24uZ2V0U2xvdChcImZpbmFsaXplZFwiKTtcblxuICAgIGNvbnN0IFtjcmVhdGVJeCwgYWx0QWRkcmVzc10gPSBBZGRyZXNzTG9va3VwVGFibGVQcm9ncmFtLmNyZWF0ZUxvb2t1cFRhYmxlKHtcbiAgICAgIGF1dGhvcml0eTogY3JlYXRvcixcbiAgICAgIHBheWVyOiBjcmVhdG9yLFxuICAgICAgcmVjZW50U2xvdDogc2xvdCxcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBBTFRcbiAgICBjb25zdCBjcmVhdGVUeCA9IG5ldyBUcmFuc2FjdGlvbigpLmFkZChjcmVhdGVJeCk7XG4gICAgY29uc3QgeyBibG9ja2hhc2g6IGNyZWF0ZUJsb2NraGFzaCwgbGFzdFZhbGlkQmxvY2tIZWlnaHQ6IGNyZWF0ZUxhc3RWYWxpZEJsb2NrSGVpZ2h0IH0gPVxuICAgICAgYXdhaXQgcHJvdmlkZXIuY29ubmVjdGlvbi5nZXRMYXRlc3RCbG9ja2hhc2goJ2NvbmZpcm1lZCcpO1xuICAgIGNyZWF0ZVR4LnJlY2VudEJsb2NraGFzaCA9IGNyZWF0ZUJsb2NraGFzaDtcbiAgICBjcmVhdGVUeC5mZWVQYXllciA9IGNyZWF0b3I7XG4gICAgY29uc3Qgc2lnbmVkVHggPSBhd2FpdCBwcm92aWRlci53YWxsZXQuc2lnblRyYW5zYWN0aW9uKGNyZWF0ZVR4KTtcbiAgICBjb25zdCBzaWcgPSBhd2FpdCBwcm92aWRlci5jb25uZWN0aW9uLnNlbmRSYXdUcmFuc2FjdGlvbihzaWduZWRUeC5zZXJpYWxpemUoKSwge1xuICAgICAgc2tpcFByZWZsaWdodDogdHJ1ZSxcbiAgICB9KTtcbiAgICBhd2FpdCBwcm92aWRlci5jb25uZWN0aW9uLmNvbmZpcm1UcmFuc2FjdGlvbih7XG4gICAgICBzaWduYXR1cmU6IHNpZyxcbiAgICAgIGJsb2NraGFzaDogY3JlYXRlQmxvY2toYXNoLFxuICAgICAgbGFzdFZhbGlkQmxvY2tIZWlnaHQ6IGNyZWF0ZUxhc3RWYWxpZEJsb2NrSGVpZ2h0LFxuICAgIH0sIFwiY29uZmlybWVkXCIpO1xuXG4gICAgLy8gRXh0ZW5kIEFMVCB3aXRoIGFkZHJlc3Nlc1xuICAgIC8vIFVzZSBza2lwUHJlZmxpZ2h0IHRvIGF2b2lkIHJhY2UgY29uZGl0aW9uIHdoZXJlIHNpbXVsYXRpb24gc2VlcyBzdGFsZSBzdGF0ZVxuICAgIC8vIGJlZm9yZSBwcmV2aW91cyBleHRlbmQgaGFzIHByb3BhZ2F0ZWQgKHNhbWUgcGF0dGVybiBhcyBDUkVBVEUgYWJvdmUpXG4gICAgY29uc3QgQ0hVTktfU0laRSA9IDIwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWRkcmVzc2VzLmxlbmd0aDsgaSArPSBDSFVOS19TSVpFKSB7XG4gICAgICBjb25zdCBjaHVuayA9IGFkZHJlc3Nlcy5zbGljZShpLCBpICsgQ0hVTktfU0laRSk7XG4gICAgICBjb25zdCBleHRlbmRJeCA9IEFkZHJlc3NMb29rdXBUYWJsZVByb2dyYW0uZXh0ZW5kTG9va3VwVGFibGUoe1xuICAgICAgICBwYXllcjogY3JlYXRvcixcbiAgICAgICAgYXV0aG9yaXR5OiBjcmVhdG9yLFxuICAgICAgICBsb29rdXBUYWJsZTogYWx0QWRkcmVzcyxcbiAgICAgICAgYWRkcmVzc2VzOiBjaHVuayxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZXh0ZW5kVHggPSBuZXcgVHJhbnNhY3Rpb24oKS5hZGQoZXh0ZW5kSXgpO1xuICAgICAgY29uc3QgeyBibG9ja2hhc2g6IGV4dGVuZEJsb2NraGFzaCwgbGFzdFZhbGlkQmxvY2tIZWlnaHQ6IGV4dGVuZExhc3RWYWxpZEJsb2NrSGVpZ2h0IH0gPVxuICAgICAgICBhd2FpdCBwcm92aWRlci5jb25uZWN0aW9uLmdldExhdGVzdEJsb2NraGFzaCgnY29uZmlybWVkJyk7XG4gICAgICBleHRlbmRUeC5yZWNlbnRCbG9ja2hhc2ggPSBleHRlbmRCbG9ja2hhc2g7XG4gICAgICBleHRlbmRUeC5mZWVQYXllciA9IGNyZWF0b3I7XG4gICAgICBjb25zdCBzaWduZWRFeHRlbmRUeCA9IGF3YWl0IHByb3ZpZGVyLndhbGxldC5zaWduVHJhbnNhY3Rpb24oZXh0ZW5kVHgpO1xuICAgICAgY29uc3QgZXh0ZW5kU2lnID0gYXdhaXQgcHJvdmlkZXIuY29ubmVjdGlvbi5zZW5kUmF3VHJhbnNhY3Rpb24oc2lnbmVkRXh0ZW5kVHguc2VyaWFsaXplKCksIHtcbiAgICAgICAgc2tpcFByZWZsaWdodDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgcHJvdmlkZXIuY29ubmVjdGlvbi5jb25maXJtVHJhbnNhY3Rpb24oe1xuICAgICAgICBzaWduYXR1cmU6IGV4dGVuZFNpZyxcbiAgICAgICAgYmxvY2toYXNoOiBleHRlbmRCbG9ja2hhc2gsXG4gICAgICAgIGxhc3RWYWxpZEJsb2NrSGVpZ2h0OiBleHRlbmRMYXN0VmFsaWRCbG9ja0hlaWdodCxcbiAgICAgIH0sIFwiY29uZmlybWVkXCIpO1xuICAgIH1cblxuICAgIHJldHVybiB7IGFsdEFkZHJlc3MgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSB2ZXJzaW9uZWQgdHJhbnNhY3Rpb24gZm9yIHJlZGVlbWluZyBsaXF1aWRpdHkgd2l0aCBBTFQuXG4gICAqIFJlcXVpcmVkIGZvciBwcm9wb3NhbHMgd2l0aCAzKyBvcHRpb25zIHRvIGF2b2lkIGV4Y2VlZGluZyB0cmFuc2FjdGlvbiBzaXplIGxpbWl0cy5cbiAgICpcbiAgICogQHBhcmFtIGNyZWF0b3IgLSBUaGUgdXNlciByZWRlZW1pbmdcbiAgICogQHBhcmFtIHByb3Bvc2FsUGRhIC0gVGhlIHByb3Bvc2FsIFBEQVxuICAgKiBAcGFyYW0gYWx0QWRkcmVzcyAtIE9wdGlvbmFsIEFMVCBhZGRyZXNzICh3aWxsIGJlIGNyZWF0ZWQgaWYgbm90IHByb3ZpZGVkIGZvciAzKyBvcHRpb25zKVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIHRyYW5zYWN0aW9uIG9wdGlvbnMgKHByaW9yaXR5IGZlZSwgY29tcHV0ZSB1bml0cylcbiAgICogQHJldHVybnMgVW5zaWduZWQgdmVyc2lvbmVkIHRyYW5zYWN0aW9uLCBBTFQgYWRkcmVzcywgbnVtYmVyIG9mIG9wdGlvbnMsIGFuZCBibG9ja2hhc2ggaW5mbyBmb3IgY29uZmlybWF0aW9uXG4gICAqL1xuICBhc3luYyByZWRlZW1MaXF1aWRpdHlWZXJzaW9uZWQoXG4gICAgY3JlYXRvcjogUHVibGljS2V5LFxuICAgIHByb3Bvc2FsUGRhOiBQdWJsaWNLZXksXG4gICAgYWx0QWRkcmVzcz86IFB1YmxpY0tleSxcbiAgICBvcHRpb25zPzogVHhPcHRpb25zLFxuICApOiBQcm9taXNlPHtcbiAgICB2ZXJzaW9uZWRUeDogVmVyc2lvbmVkVHJhbnNhY3Rpb247XG4gICAgYWx0QWRkcmVzczogUHVibGljS2V5O1xuICAgIG51bU9wdGlvbnM6IG51bWJlcjtcbiAgICBibG9ja2hhc2g6IHN0cmluZztcbiAgICBsYXN0VmFsaWRCbG9ja0hlaWdodDogbnVtYmVyO1xuICB9PiB7XG4gICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLnByb2dyYW0ucHJvdmlkZXIgYXMgQW5jaG9yUHJvdmlkZXI7XG4gICAgY29uc3QgeyBidWlsZGVyLCBudW1PcHRpb25zIH0gPSBhd2FpdCB0aGlzLnJlZGVlbUxpcXVpZGl0eShjcmVhdG9yLCBwcm9wb3NhbFBkYSk7XG5cbiAgICAvLyBDcmVhdGUgQUxUIGlmIG5vdCBwcm92aWRlZCBhbmQgbmVlZGVkXG4gICAgbGV0IGFsdFB1YmtleSA9IGFsdEFkZHJlc3M7XG4gICAgbGV0IHZlcmlmaWVkQUxUOiBBZGRyZXNzTG9va3VwVGFibGVBY2NvdW50IHwgbnVsbCA9IG51bGw7XG5cbiAgICBpZiAoIWFsdFB1YmtleSAmJiBudW1PcHRpb25zID49IDMpIHtcbiAgICAgIGNvbnNvbGUubG9nKGAgIENyZWF0aW5nIHJlZGVtcHRpb24gQUxUIGZvciAke251bU9wdGlvbnN9IG9wdGlvbnMuLi5gKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuY3JlYXRlUmVkZW1wdGlvbkFMVChjcmVhdG9yLCBwcm9wb3NhbFBkYSk7XG4gICAgICBhbHRQdWJrZXkgPSByZXN1bHQuYWx0QWRkcmVzcztcbiAgICAgIGNvbnNvbGUubG9nKGAgIOKckyBSZWRlbXB0aW9uIEFMVCBjcmVhdGVkOiAke2FsdFB1YmtleS50b0Jhc2U1OCgpfWApO1xuXG4gICAgICAvLyBXYWl0IGZvciBBTFQgdG8gYmUgZnVsbHkgYXZhaWxhYmxlIHdpdGggYWxsIGFkZHJlc3Nlc1xuICAgICAgLy8gVXNlIGxvbmdlciBkZWxheXMgYWZ0ZXIgZXh0ZW5kaW5nIHRvIGVuc3VyZSBwcm9wYWdhdGlvblxuICAgICAgY29uc29sZS5sb2coYCAgV2FpdGluZyBmb3IgQUxUIHByb3BhZ2F0aW9uLi4uYCk7XG4gICAgICBjb25zdCBleHBlY3RlZEFkZHJlc3NlcyA9IDE4ICsgKG51bU9wdGlvbnMgKiA0KTsgLy8gQmFzZSBhY2NvdW50cyArIHBlci1vcHRpb24gYWNjb3VudHNcbiAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG5cbiAgICAgIC8vIEluaXRpYWwgZGVsYXkgYWZ0ZXIgZXh0ZW5zaW9uXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMjAwMCkpO1xuXG4gICAgICB3aGlsZSAoYXR0ZW1wdHMgPCAzMCkge1xuICAgICAgICBjb25zdCBhbHRBY2NvdW50ID0gYXdhaXQgcHJvdmlkZXIuY29ubmVjdGlvbi5nZXRBZGRyZXNzTG9va3VwVGFibGUoYWx0UHVia2V5LCB7XG4gICAgICAgICAgY29tbWl0bWVudDogJ2NvbmZpcm1lZCcsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoYWx0QWNjb3VudC52YWx1ZSkge1xuICAgICAgICAgIGNvbnN0IGFkZHJlc3NDb3VudCA9IGFsdEFjY291bnQudmFsdWUuc3RhdGUuYWRkcmVzc2VzLmxlbmd0aDtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgICBBdHRlbXB0ICR7YXR0ZW1wdHMgKyAxfTogQUxUIGhhcyAke2FkZHJlc3NDb3VudH0vJHtleHBlY3RlZEFkZHJlc3Nlc30gYWRkcmVzc2VzYCk7XG4gICAgICAgICAgaWYgKGFkZHJlc3NDb3VudCA+PSBleHBlY3RlZEFkZHJlc3Nlcykge1xuICAgICAgICAgICAgdmVyaWZpZWRBTFQgPSBhbHRBY2NvdW50LnZhbHVlO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYCAg4pyTIEFMVCB2ZXJpZmllZCB3aXRoICR7YWRkcmVzc0NvdW50fSBhZGRyZXNzZXNgKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMTAwMCkpO1xuICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXZlcmlmaWVkQUxUKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQUxUIGZhaWxlZCB0byBwb3B1bGF0ZSB3aXRoIGV4cGVjdGVkICR7ZXhwZWN0ZWRBZGRyZXNzZXN9IGFkZHJlc3NlcyBhZnRlciAke2F0dGVtcHRzfSBhdHRlbXB0c2ApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghYWx0UHVia2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBTFQgYWRkcmVzcyByZXF1aXJlZCBmb3IgbXVsdGktb3B0aW9uIHJlZGVtcHRpb25cIik7XG4gICAgfVxuXG4gICAgLy8gRmV0Y2ggQUxUIGlmIHdlIGRvbid0IGhhdmUgaXQgdmVyaWZpZWQgYWxyZWFkeVxuICAgIGlmICghdmVyaWZpZWRBTFQpIHtcbiAgICAgIHZlcmlmaWVkQUxUID0gYXdhaXQgdGhpcy5mZXRjaEFMVChhbHRQdWJrZXkpO1xuICAgIH1cblxuICAgIC8vIEJ1aWxkIGluc3RydWN0aW9uXG4gICAgY29uc3QgaW5zdHJ1Y3Rpb24gPSBhd2FpdCBidWlsZGVyLmluc3RydWN0aW9uKCk7XG4gICAgY29uc3QgY29tcHV0ZUJ1ZGdldEl4ID0gQ29tcHV0ZUJ1ZGdldFByb2dyYW0uc2V0Q29tcHV0ZVVuaXRMaW1pdCh7IHVuaXRzOiA1MDBfMDAwIH0pO1xuXG4gICAgLy8gQnVpbGQgcHJlLWluc3RydWN0aW9ucyBhcnJheSB3aXRoIG9wdGlvbmFsIHByaW9yaXR5IGZlZVxuICAgIGNvbnN0IHByZUluc3RydWN0aW9ucyA9IFtjb21wdXRlQnVkZ2V0SXhdO1xuICAgIGlmIChvcHRpb25zPy5wcmlvcml0eUZlZU1pY3JvTGFtcG9ydHMgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnByaW9yaXR5RmVlTWljcm9MYW1wb3J0cyA+IDApIHtcbiAgICAgIHByZUluc3RydWN0aW9ucy5wdXNoKENvbXB1dGVCdWRnZXRQcm9ncmFtLnNldENvbXB1dGVVbml0UHJpY2UoeyBtaWNyb0xhbXBvcnRzOiBvcHRpb25zLnByaW9yaXR5RmVlTWljcm9MYW1wb3J0cyB9KSk7XG4gICAgfVxuXG4gICAgLy8gR2V0IGZyZXNoIGJsb2NraGFzaCB3aXRoIGxhc3RWYWxpZEJsb2NrSGVpZ2h0IGZvciBjb25maXJtYXRpb24gdHJhY2tpbmdcbiAgICBjb25zdCB7IGJsb2NraGFzaCwgbGFzdFZhbGlkQmxvY2tIZWlnaHQgfSA9IGF3YWl0IHByb3ZpZGVyLmNvbm5lY3Rpb24uZ2V0TGF0ZXN0QmxvY2toYXNoKCdjb25maXJtZWQnKTtcblxuICAgIC8vIEJ1aWxkIHZlcnNpb25lZCB0cmFuc2FjdGlvbiB1c2luZyB0aGUgdmVyaWZpZWQgQUxUIChubyByZS1mZXRjaClcbiAgICBjb25zdCB2ZXJzaW9uZWRUeCA9IHRoaXMuYnVpbGRWZXJzaW9uZWRUeFdpdGhBTFQoXG4gICAgICBjcmVhdG9yLFxuICAgICAgWy4uLnByZUluc3RydWN0aW9ucywgaW5zdHJ1Y3Rpb25dLFxuICAgICAgdmVyaWZpZWRBTFQsXG4gICAgICBibG9ja2hhc2gsXG4gICAgKTtcblxuICAgIC8vIFJldHVybiB0aGUgdmVyc2lvbmVkIHRyYW5zYWN0aW9uIGFsb25nIHdpdGggYmxvY2toYXNoIGluZm8gZm9yIHByb3BlciBjb25maXJtYXRpb25cbiAgICAvLyBUaGlzIGFsbG93cyB0aGUgY2FsbGVyIHRvIHVzZSB0aGVpciBvd24gc2lnbmluZyBtZWNoYW5pc20gKGUuZy4sIGtleXBhaXIuc2lnbilcbiAgICByZXR1cm4geyB2ZXJzaW9uZWRUeCwgYWx0QWRkcmVzczogYWx0UHVia2V5LCBudW1PcHRpb25zLCBibG9ja2hhc2gsIGxhc3RWYWxpZEJsb2NrSGVpZ2h0IH07XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIHRvIHNlbmQgYSBzaWduZWQgdmVyc2lvbmVkIHRyYW5zYWN0aW9uIHdpdGggcm9idXN0IGNvbmZpcm1hdGlvbiBoYW5kbGluZy5cbiAgICogVXNlcyBibG9ja2hhc2gtYmFzZWQgY29uZmlybWF0aW9uIHRvIHByb3Blcmx5IGRldGVjdCB0cmFuc2FjdGlvbiBleHBpcmF0aW9uXG4gICAqIGluc3RlYWQgb2YgcmVseWluZyBvbiBhIGZpeGVkIHRpbWVvdXQuXG4gICAqXG4gICAqIEBwYXJhbSBzaWduZWRUeCAtIFRoZSBzaWduZWQgdmVyc2lvbmVkIHRyYW5zYWN0aW9uIHRvIHNlbmRcbiAgICogQHBhcmFtIGNvbmZpcm1hdGlvbkluZm8gLSBPcHRpb25hbCBibG9ja2hhc2ggaW5mbyBmcm9tIHdoZW4gdGhlIHRyYW5zYWN0aW9uIHdhcyBidWlsdC5cbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgIElmIG5vdCBwcm92aWRlZCwgYSBmcmVzaCBibG9ja2hhc2ggd2lsbCBiZSBmZXRjaGVkIChsZXNzIGFjY3VyYXRlKS5cbiAgICovXG4gIGFzeW5jIHNlbmRWZXJzaW9uZWRUcmFuc2FjdGlvbihcbiAgICBzaWduZWRUeDogVmVyc2lvbmVkVHJhbnNhY3Rpb24sXG4gICAgY29uZmlybWF0aW9uSW5mbz86IHsgYmxvY2toYXNoOiBzdHJpbmc7IGxhc3RWYWxpZEJsb2NrSGVpZ2h0OiBudW1iZXIgfSxcbiAgKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBwcm92aWRlciA9IHRoaXMucHJvZ3JhbS5wcm92aWRlciBhcyBBbmNob3JQcm92aWRlcjtcblxuICAgIC8vIFVzZSBwcm92aWRlZCBibG9ja2hhc2ggaW5mbyBvciBmZXRjaCBmcmVzaCBvbmVcbiAgICAvLyBVc2luZyB0aGUgb3JpZ2luYWwgYmxvY2toYXNoIGlzIG1vcmUgYWNjdXJhdGUgZm9yIGRldGVjdGluZyBleHBpcmF0aW9uXG4gICAgbGV0IGJsb2NraGFzaDogc3RyaW5nO1xuICAgIGxldCBsYXN0VmFsaWRCbG9ja0hlaWdodDogbnVtYmVyO1xuXG4gICAgaWYgKGNvbmZpcm1hdGlvbkluZm8pIHtcbiAgICAgIGJsb2NraGFzaCA9IGNvbmZpcm1hdGlvbkluZm8uYmxvY2toYXNoO1xuICAgICAgbGFzdFZhbGlkQmxvY2tIZWlnaHQgPSBjb25maXJtYXRpb25JbmZvLmxhc3RWYWxpZEJsb2NrSGVpZ2h0O1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGYWxsYmFjazogZ2V0IGZyZXNoIGJsb2NraGFzaCAobWF5IHdhaXQgbG9uZ2VyIHRoYW4gbmVjZXNzYXJ5IGlmIHR4IGFscmVhZHkgZXhwaXJlZClcbiAgICAgIGNvbnN0IGxhdGVzdEJsb2NraGFzaCA9IGF3YWl0IHByb3ZpZGVyLmNvbm5lY3Rpb24uZ2V0TGF0ZXN0QmxvY2toYXNoKCdjb25maXJtZWQnKTtcbiAgICAgIGJsb2NraGFzaCA9IGxhdGVzdEJsb2NraGFzaC5ibG9ja2hhc2g7XG4gICAgICBsYXN0VmFsaWRCbG9ja0hlaWdodCA9IGxhdGVzdEJsb2NraGFzaC5sYXN0VmFsaWRCbG9ja0hlaWdodDtcbiAgICB9XG5cbiAgICBjb25zdCBzaWduYXR1cmUgPSBhd2FpdCBwcm92aWRlci5jb25uZWN0aW9uLnNlbmRUcmFuc2FjdGlvbihzaWduZWRUeCwge1xuICAgICAgc2tpcFByZWZsaWdodDogZmFsc2UsXG4gICAgICBwcmVmbGlnaHRDb21taXRtZW50OiAnY29uZmlybWVkJyxcbiAgICB9KTtcblxuICAgIC8vIFVzZSBibG9ja2hhc2gtYmFzZWQgY29uZmlybWF0aW9uIHdoaWNoIHdhaXRzIHVudGlsIGVpdGhlcjpcbiAgICAvLyAxLiBUcmFuc2FjdGlvbiBpcyBjb25maXJtZWRcbiAgICAvLyAyLiBCbG9ja2hhc2ggZXhwaXJlcyAobGFzdFZhbGlkQmxvY2tIZWlnaHQgcGFzc2VkKVxuICAgIC8vIFRoaXMgaXMgbW9yZSByb2J1c3QgdGhhbiBhIGZpeGVkIHRpbWVvdXQgb24gY29uZ2VzdGVkIG5ldHdvcmtzXG4gICAgYXdhaXQgcHJvdmlkZXIuY29ubmVjdGlvbi5jb25maXJtVHJhbnNhY3Rpb24oe1xuICAgICAgc2lnbmF0dXJlLFxuICAgICAgYmxvY2toYXNoLFxuICAgICAgbGFzdFZhbGlkQmxvY2tIZWlnaHQsXG4gICAgfSwgJ2NvbmZpcm1lZCcpO1xuXG4gICAgcmV0dXJuIHNpZ25hdHVyZTtcbiAgfVxuXG4gIC8qIEFkZHJlc3MgTG9va3VwIFRhYmxlICovXG5cbiAgYXN5bmMgY3JlYXRlUHJvcG9zYWxBTFQoXG4gICAgY3JlYXRvcjogUHVibGljS2V5LFxuICAgIG1vZGVyYXRvclBkYTogUHVibGljS2V5LFxuICAgIG51bU9wdGlvbnM6IG51bWJlciA9IDIsXG4gICk6IFByb21pc2U8eyBhbHRBZGRyZXNzOiBQdWJsaWNLZXkgfT4ge1xuICAgIGNvbnN0IHByb3ZpZGVyID0gdGhpcy5wcm9ncmFtLnByb3ZpZGVyIGFzIEFuY2hvclByb3ZpZGVyO1xuICAgIGNvbnN0IG1vZGVyYXRvciA9IGF3YWl0IHRoaXMuZmV0Y2hNb2RlcmF0b3IobW9kZXJhdG9yUGRhKTtcbiAgICBjb25zdCBwcm9wb3NhbElkID0gbW9kZXJhdG9yLnByb3Bvc2FsSWRDb3VudGVyO1xuICAgIGNvbnN0IFtwcm9wb3NhbFBkYV0gPSB0aGlzLmRlcml2ZVByb3Bvc2FsUERBKG1vZGVyYXRvclBkYSwgcHJvcG9zYWxJZCk7XG4gICAgY29uc3QgW3ZhdWx0UGRhXSA9IGRlcml2ZVZhdWx0UERBKHByb3Bvc2FsUGRhLCBwcm9wb3NhbElkLCB0aGlzLnZhdWx0LnByb2dyYW1JZCk7XG5cbiAgICBjb25zdCBhZGRyZXNzZXM6IFB1YmxpY0tleVtdID0gW1xuICAgICAgLy8gUHJvZ3JhbXNcbiAgICAgIHRoaXMucHJvZ3JhbUlkLFxuICAgICAgdGhpcy52YXVsdC5wcm9ncmFtSWQsXG4gICAgICB0aGlzLmFtbS5wcm9ncmFtSWQsXG4gICAgICBTeXN0ZW1Qcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgIFRPS0VOX1BST0dSQU1fSUQsXG4gICAgICBBU1NPQ0lBVEVEX1RPS0VOX1BST0dSQU1fSUQsXG4gICAgICAvLyBDb3JlIGFjY291bnRzXG4gICAgICBtb2RlcmF0b3JQZGEsXG4gICAgICBwcm9wb3NhbFBkYSxcbiAgICAgIHZhdWx0UGRhLFxuICAgICAgbW9kZXJhdG9yLmJhc2VNaW50LFxuICAgICAgbW9kZXJhdG9yLnF1b3RlTWludCxcbiAgICAgIEZFRV9BVVRIT1JJVFksXG4gICAgICAvLyBWYXVsdCB0b2tlbiBhY2NvdW50c1xuICAgICAgZ2V0QXNzb2NpYXRlZFRva2VuQWRkcmVzc1N5bmMobW9kZXJhdG9yLmJhc2VNaW50LCB2YXVsdFBkYSwgdHJ1ZSksXG4gICAgICBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyhtb2RlcmF0b3IucXVvdGVNaW50LCB2YXVsdFBkYSwgdHJ1ZSksXG4gICAgICAvLyBDcmVhdG9yJ3MgYmFzZS9xdW90ZSBBVEFzXG4gICAgICBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyhtb2RlcmF0b3IuYmFzZU1pbnQsIGNyZWF0b3IpLFxuICAgICAgZ2V0QXNzb2NpYXRlZFRva2VuQWRkcmVzc1N5bmMobW9kZXJhdG9yLnF1b3RlTWludCwgY3JlYXRvciksXG4gICAgXTtcblxuICAgIC8vIFBlci1vcHRpb24gYWNjb3VudHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bU9wdGlvbnM7IGkrKykge1xuICAgICAgY29uc3QgW2NvbmRCYXNlTWludF0gPSBkZXJpdmVDb25kaXRpb25hbE1pbnQodmF1bHRQZGEsIFZhdWx0VHlwZS5CYXNlLCBpLCB0aGlzLnZhdWx0LnByb2dyYW1JZCk7XG4gICAgICBjb25zdCBbY29uZFF1b3RlTWludF0gPSBkZXJpdmVDb25kaXRpb25hbE1pbnQodmF1bHRQZGEsIFZhdWx0VHlwZS5RdW90ZSwgaSwgdGhpcy52YXVsdC5wcm9ncmFtSWQpO1xuICAgICAgY29uc3QgW3Bvb2xdID0gZGVyaXZlUG9vbFBEQShwcm9wb3NhbFBkYSwgY29uZFF1b3RlTWludCwgY29uZEJhc2VNaW50LCB0aGlzLmFtbS5wcm9ncmFtSWQpO1xuICAgICAgY29uc3QgW3Jlc2VydmVBXSA9IGRlcml2ZVJlc2VydmVQREEocG9vbCwgY29uZFF1b3RlTWludCwgdGhpcy5hbW0ucHJvZ3JhbUlkKTtcbiAgICAgIGNvbnN0IFtyZXNlcnZlQl0gPSBkZXJpdmVSZXNlcnZlUERBKHBvb2wsIGNvbmRCYXNlTWludCwgdGhpcy5hbW0ucHJvZ3JhbUlkKTtcbiAgICAgIGNvbnN0IFtmZWVWYXVsdF0gPSBkZXJpdmVGZWVWYXVsdFBEQShwb29sLCB0aGlzLmFtbS5wcm9ncmFtSWQpO1xuXG4gICAgICBhZGRyZXNzZXMucHVzaChcbiAgICAgICAgY29uZEJhc2VNaW50LFxuICAgICAgICBjb25kUXVvdGVNaW50LFxuICAgICAgICBwb29sLFxuICAgICAgICByZXNlcnZlQSxcbiAgICAgICAgcmVzZXJ2ZUIsXG4gICAgICAgIGZlZVZhdWx0LFxuICAgICAgICAvLyBDcmVhdG9yJ3MgY29uZGl0aW9uYWwgdG9rZW4gQVRBc1xuICAgICAgICBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyhjb25kQmFzZU1pbnQsIGNyZWF0b3IpLFxuICAgICAgICBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyhjb25kUXVvdGVNaW50LCBjcmVhdG9yKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gR2V0IHRoZSBtb3N0IHJlY2VudCBzbG90IHVzaW5nIFwiZmluYWxpemVkXCIgY29tbWl0bWVudCBmb3Igc3RhYmlsaXR5XG4gICAgY29uc3Qgc2xvdCA9IGF3YWl0IHByb3ZpZGVyLmNvbm5lY3Rpb24uZ2V0U2xvdChcImZpbmFsaXplZFwiKTtcblxuICAgIGNvbnN0IFtjcmVhdGVJeCwgYWx0QWRkcmVzc10gPSBBZGRyZXNzTG9va3VwVGFibGVQcm9ncmFtLmNyZWF0ZUxvb2t1cFRhYmxlKHtcbiAgICAgIGF1dGhvcml0eTogY3JlYXRvcixcbiAgICAgIHBheWVyOiBjcmVhdG9yLFxuICAgICAgcmVjZW50U2xvdDogc2xvdCxcbiAgICB9KTtcblxuICAgIC8vIFNlbmQgY3JlYXRlIHRyYW5zYWN0aW9uIGltbWVkaWF0ZWx5LCBza2lwIHByZWZsaWdodCB0byBhdm9pZCBzbG90IHRpbWluZyBpc3N1ZXNcbiAgICBjb25zdCBjcmVhdGVUeCA9IG5ldyBUcmFuc2FjdGlvbigpLmFkZChjcmVhdGVJeCk7XG4gICAgY29uc3QgeyBibG9ja2hhc2g6IGNyZWF0ZUJsb2NraGFzaCwgbGFzdFZhbGlkQmxvY2tIZWlnaHQ6IGNyZWF0ZUxhc3RWYWxpZEJsb2NrSGVpZ2h0IH0gPVxuICAgICAgYXdhaXQgcHJvdmlkZXIuY29ubmVjdGlvbi5nZXRMYXRlc3RCbG9ja2hhc2goJ2NvbmZpcm1lZCcpO1xuICAgIGNyZWF0ZVR4LnJlY2VudEJsb2NraGFzaCA9IGNyZWF0ZUJsb2NraGFzaDtcbiAgICBjcmVhdGVUeC5mZWVQYXllciA9IGNyZWF0b3I7XG4gICAgY29uc3Qgc2lnbmVkVHggPSBhd2FpdCBwcm92aWRlci53YWxsZXQuc2lnblRyYW5zYWN0aW9uKGNyZWF0ZVR4KTtcbiAgICBjb25zdCBzaWcgPSBhd2FpdCBwcm92aWRlci5jb25uZWN0aW9uLnNlbmRSYXdUcmFuc2FjdGlvbihzaWduZWRUeC5zZXJpYWxpemUoKSwge1xuICAgICAgc2tpcFByZWZsaWdodDogdHJ1ZSxcbiAgICB9KTtcbiAgICBhd2FpdCBwcm92aWRlci5jb25uZWN0aW9uLmNvbmZpcm1UcmFuc2FjdGlvbih7XG4gICAgICBzaWduYXR1cmU6IHNpZyxcbiAgICAgIGJsb2NraGFzaDogY3JlYXRlQmxvY2toYXNoLFxuICAgICAgbGFzdFZhbGlkQmxvY2tIZWlnaHQ6IGNyZWF0ZUxhc3RWYWxpZEJsb2NrSGVpZ2h0LFxuICAgIH0sIFwiY29uZmlybWVkXCIpO1xuXG4gICAgLy8gU3BsaXQgYWRkcmVzc2VzIGludG8gY2h1bmtzIHRvIGF2b2lkIHRyYW5zYWN0aW9uIHNpemUgbGltaXRzXG4gICAgLy8gRWFjaCBhZGRyZXNzIGlzIDMyIGJ5dGVzLCB+MjAgYWRkcmVzc2VzIHBlciBleHRlbmQgaW5zdHJ1Y3Rpb24gaXMgc2FmZVxuICAgIC8vIFVzZSBza2lwUHJlZmxpZ2h0IHRvIGF2b2lkIHJhY2UgY29uZGl0aW9uIHdoZXJlIHNpbXVsYXRpb24gc2VlcyBzdGFsZSBzdGF0ZVxuICAgIC8vIGJlZm9yZSBwcmV2aW91cyBleHRlbmQgaGFzIHByb3BhZ2F0ZWQgKHNhbWUgcGF0dGVybiBhcyBDUkVBVEUgYWJvdmUpXG4gICAgY29uc3QgQ0hVTktfU0laRSA9IDIwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWRkcmVzc2VzLmxlbmd0aDsgaSArPSBDSFVOS19TSVpFKSB7XG4gICAgICBjb25zdCBjaHVuayA9IGFkZHJlc3Nlcy5zbGljZShpLCBpICsgQ0hVTktfU0laRSk7XG4gICAgICBjb25zdCBleHRlbmRJeCA9IEFkZHJlc3NMb29rdXBUYWJsZVByb2dyYW0uZXh0ZW5kTG9va3VwVGFibGUoe1xuICAgICAgICBwYXllcjogY3JlYXRvcixcbiAgICAgICAgYXV0aG9yaXR5OiBjcmVhdG9yLFxuICAgICAgICBsb29rdXBUYWJsZTogYWx0QWRkcmVzcyxcbiAgICAgICAgYWRkcmVzc2VzOiBjaHVuayxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZXh0ZW5kVHggPSBuZXcgVHJhbnNhY3Rpb24oKS5hZGQoZXh0ZW5kSXgpO1xuICAgICAgY29uc3QgeyBibG9ja2hhc2g6IGV4dGVuZEJsb2NraGFzaCwgbGFzdFZhbGlkQmxvY2tIZWlnaHQ6IGV4dGVuZExhc3RWYWxpZEJsb2NrSGVpZ2h0IH0gPVxuICAgICAgICBhd2FpdCBwcm92aWRlci5jb25uZWN0aW9uLmdldExhdGVzdEJsb2NraGFzaCgnY29uZmlybWVkJyk7XG4gICAgICBleHRlbmRUeC5yZWNlbnRCbG9ja2hhc2ggPSBleHRlbmRCbG9ja2hhc2g7XG4gICAgICBleHRlbmRUeC5mZWVQYXllciA9IGNyZWF0b3I7XG4gICAgICBjb25zdCBzaWduZWRFeHRlbmRUeCA9IGF3YWl0IHByb3ZpZGVyLndhbGxldC5zaWduVHJhbnNhY3Rpb24oZXh0ZW5kVHgpO1xuICAgICAgY29uc3QgZXh0ZW5kU2lnID0gYXdhaXQgcHJvdmlkZXIuY29ubmVjdGlvbi5zZW5kUmF3VHJhbnNhY3Rpb24oc2lnbmVkRXh0ZW5kVHguc2VyaWFsaXplKCksIHtcbiAgICAgICAgc2tpcFByZWZsaWdodDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgcHJvdmlkZXIuY29ubmVjdGlvbi5jb25maXJtVHJhbnNhY3Rpb24oe1xuICAgICAgICBzaWduYXR1cmU6IGV4dGVuZFNpZyxcbiAgICAgICAgYmxvY2toYXNoOiBleHRlbmRCbG9ja2hhc2gsXG4gICAgICAgIGxhc3RWYWxpZEJsb2NrSGVpZ2h0OiBleHRlbmRMYXN0VmFsaWRCbG9ja0hlaWdodCxcbiAgICAgIH0sIFwiY29uZmlybWVkXCIpO1xuICAgIH1cblxuICAgIHJldHVybiB7IGFsdEFkZHJlc3MgfTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoQUxUKGFsdEFkZHJlc3M6IFB1YmxpY0tleSk6IFByb21pc2U8QWRkcmVzc0xvb2t1cFRhYmxlQWNjb3VudD4ge1xuICAgIGNvbnN0IGFsdCA9IGF3YWl0IHRoaXMucHJvZ3JhbS5wcm92aWRlci5jb25uZWN0aW9uLmdldEFkZHJlc3NMb29rdXBUYWJsZShhbHRBZGRyZXNzKTtcbiAgICBpZiAoIWFsdC52YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQUxUIG5vdCBmb3VuZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIGFsdC52YWx1ZTtcbiAgfVxuXG4gIGFzeW5jIGJ1aWxkVmVyc2lvbmVkVHgoXG4gICAgcGF5ZXI6IFB1YmxpY0tleSxcbiAgICBpbnN0cnVjdGlvbnM6IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb25bXSxcbiAgICBhbHRBZGRyZXNzOiBQdWJsaWNLZXksXG4gICk6IFByb21pc2U8e1xuICAgIHZlcnNpb25lZFR4OiBWZXJzaW9uZWRUcmFuc2FjdGlvbjtcbiAgICBibG9ja2hhc2g6IHN0cmluZztcbiAgICBsYXN0VmFsaWRCbG9ja0hlaWdodDogbnVtYmVyO1xuICB9PiB7XG4gICAgY29uc3QgcHJvdmlkZXIgPSB0aGlzLnByb2dyYW0ucHJvdmlkZXIgYXMgQW5jaG9yUHJvdmlkZXI7XG4gICAgY29uc3QgYWx0ID0gYXdhaXQgdGhpcy5mZXRjaEFMVChhbHRBZGRyZXNzKTtcbiAgICBjb25zdCB7IGJsb2NraGFzaCwgbGFzdFZhbGlkQmxvY2tIZWlnaHQgfSA9IGF3YWl0IHByb3ZpZGVyLmNvbm5lY3Rpb24uZ2V0TGF0ZXN0QmxvY2toYXNoKCdjb25maXJtZWQnKTtcbiAgICBjb25zdCB2ZXJzaW9uZWRUeCA9IHRoaXMuYnVpbGRWZXJzaW9uZWRUeFdpdGhBTFQocGF5ZXIsIGluc3RydWN0aW9ucywgYWx0LCBibG9ja2hhc2gpO1xuICAgIHJldHVybiB7IHZlcnNpb25lZFR4LCBibG9ja2hhc2gsIGxhc3RWYWxpZEJsb2NrSGVpZ2h0IH07XG4gIH1cblxuICBidWlsZFZlcnNpb25lZFR4V2l0aEFMVChcbiAgICBwYXllcjogUHVibGljS2V5LFxuICAgIGluc3RydWN0aW9uczogVHJhbnNhY3Rpb25JbnN0cnVjdGlvbltdLFxuICAgIGFsdDogQWRkcmVzc0xvb2t1cFRhYmxlQWNjb3VudCxcbiAgICBibG9ja2hhc2g6IHN0cmluZyxcbiAgKTogVmVyc2lvbmVkVHJhbnNhY3Rpb24ge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBuZXcgVHJhbnNhY3Rpb25NZXNzYWdlKHtcbiAgICAgIHBheWVyS2V5OiBwYXllcixcbiAgICAgIHJlY2VudEJsb2NraGFzaDogYmxvY2toYXNoLFxuICAgICAgaW5zdHJ1Y3Rpb25zLFxuICAgIH0pLmNvbXBpbGVUb1YwTWVzc2FnZShbYWx0XSk7XG5cbiAgICByZXR1cm4gbmV3IFZlcnNpb25lZFRyYW5zYWN0aW9uKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyogREFPIE1ldGhvZHMgKi9cblxuICBkZXJpdmVNaW50Q3JlYXRlS2V5UERBKGRhb1BkYTogUHVibGljS2V5LCBuYW1lOiBzdHJpbmcpOiBbUHVibGljS2V5LCBudW1iZXJdIHtcbiAgICByZXR1cm4gZGVyaXZlTWludENyZWF0ZUtleVBEQShkYW9QZGEsIG5hbWUsIHRoaXMucHJvZ3JhbUlkKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hTcXVhZHNQcm9ncmFtQ29uZmlnKCkge1xuICAgIGNvbnN0IFtwcm9ncmFtQ29uZmlnUGRhXSA9IG11bHRpc2lnLmdldFByb2dyYW1Db25maWdQZGEoe1xuICAgICAgcHJvZ3JhbUlkOiBTUVVBRFNfUFJPR1JBTV9JRCxcbiAgICB9KTtcbiAgICBjb25zdCBwcm9ncmFtQ29uZmlnID0gYXdhaXQgbXVsdGlzaWcuYWNjb3VudHMuUHJvZ3JhbUNvbmZpZy5mcm9tQWNjb3VudEFkZHJlc3MoXG4gICAgICB0aGlzLnByb2dyYW0ucHJvdmlkZXIuY29ubmVjdGlvbixcbiAgICAgIHByb2dyYW1Db25maWdQZGFcbiAgICApO1xuICAgIHJldHVybiB7XG4gICAgICBwcm9ncmFtQ29uZmlnOiBwcm9ncmFtQ29uZmlnUGRhLFxuICAgICAgcHJvZ3JhbUNvbmZpZ1RyZWFzdXJ5OiBwcm9ncmFtQ29uZmlnLnRyZWFzdXJ5LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGRlcml2ZU11bHRpc2lnUGRhKGNyZWF0ZUtleTogUHVibGljS2V5KTogUHVibGljS2V5IHtcbiAgICBjb25zdCBbbXVsdGlzaWdQZGFdID0gbXVsdGlzaWcuZ2V0TXVsdGlzaWdQZGEoe1xuICAgICAgY3JlYXRlS2V5LFxuICAgICAgcHJvZ3JhbUlkOiBTUVVBRFNfUFJPR1JBTV9JRCxcbiAgICB9KTtcbiAgICByZXR1cm4gbXVsdGlzaWdQZGE7XG4gIH1cblxuICBhc3luYyBpbml0aWFsaXplUGFyZW50REFPKFxuICAgIGFkbWluOiBQdWJsaWNLZXksXG4gICAgcGFyZW50QWRtaW46IFB1YmxpY0tleSxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgYmFzZU1pbnQ6IFB1YmxpY0tleSxcbiAgICBxdW90ZU1pbnQ6IFB1YmxpY0tleSxcbiAgICB0cmVhc3VyeUNvc2lnbmVyOiBQdWJsaWNLZXksXG4gICAgcG9vbDogUHVibGljS2V5LFxuICAgIHBvb2xUeXBlOiBQb29sVHlwZSxcbiAgICBvcHRpb25zPzogVHhPcHRpb25zXG4gICkge1xuICAgIGNvbnN0IFtkYW9QZGFdID0gdGhpcy5kZXJpdmVEQU9QREEobmFtZSk7XG4gICAgY29uc3QgW21vZGVyYXRvclBkYV0gPSB0aGlzLmRlcml2ZU1vZGVyYXRvclBEQShuYW1lKTtcbiAgICBjb25zdCBbbWludENyZWF0ZUtleVBkYV0gPSB0aGlzLmRlcml2ZU1pbnRDcmVhdGVLZXlQREEoZGFvUGRhLCBuYW1lKTtcblxuICAgIC8vIERlcml2ZSBTcXVhZHMgYWNjb3VudHMgKHNpbmdsZSBSUEMgY2FsbClcbiAgICBjb25zdCBzcXVhZHNDb25maWcgPSBhd2FpdCB0aGlzLmZldGNoU3F1YWRzUHJvZ3JhbUNvbmZpZygpO1xuICAgIGNvbnN0IHRyZWFzdXJ5TXVsdGlzaWdQZGEgPSB0aGlzLmRlcml2ZU11bHRpc2lnUGRhKGRhb1BkYSk7XG4gICAgY29uc3QgbWludE11bHRpc2lnUGRhID0gdGhpcy5kZXJpdmVNdWx0aXNpZ1BkYShtaW50Q3JlYXRlS2V5UGRhKTtcblxuICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0aWFsaXplUGFyZW50REFPKFxuICAgICAgdGhpcy5wcm9ncmFtLFxuICAgICAgYWRtaW4sXG4gICAgICBwYXJlbnRBZG1pbixcbiAgICAgIGRhb1BkYSxcbiAgICAgIG1vZGVyYXRvclBkYSxcbiAgICAgIGJhc2VNaW50LFxuICAgICAgcXVvdGVNaW50LFxuICAgICAgc3F1YWRzQ29uZmlnLnByb2dyYW1Db25maWcsXG4gICAgICBzcXVhZHNDb25maWcucHJvZ3JhbUNvbmZpZ1RyZWFzdXJ5LFxuICAgICAgdHJlYXN1cnlNdWx0aXNpZ1BkYSxcbiAgICAgIG1pbnRNdWx0aXNpZ1BkYSxcbiAgICAgIG1pbnRDcmVhdGVLZXlQZGEsXG4gICAgICBTUVVBRFNfUFJPR1JBTV9JRCxcbiAgICAgIG5hbWUsXG4gICAgICB0cmVhc3VyeUNvc2lnbmVyLFxuICAgICAgcG9vbCxcbiAgICAgIHBvb2xUeXBlXG4gICAgKS5wcmVJbnN0cnVjdGlvbnModGhpcy5tYXliZUFkZENvbXB1dGVCdWRnZXQob3B0aW9ucykpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJ1aWxkZXIsXG4gICAgICBkYW9QZGEsXG4gICAgICBtb2RlcmF0b3JQZGEsXG4gICAgICB0cmVhc3VyeU11bHRpc2lnOiB0cmVhc3VyeU11bHRpc2lnUGRhLFxuICAgICAgbWludE11bHRpc2lnOiBtaW50TXVsdGlzaWdQZGEsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGluaXRpYWxpemVDaGlsZERBTyhcbiAgICBhZG1pbjogUHVibGljS2V5LFxuICAgIHBhcmVudEFkbWluOiBQdWJsaWNLZXksXG4gICAgcGFyZW50RGFvTmFtZTogc3RyaW5nLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB0b2tlbk1pbnQ6IFB1YmxpY0tleSxcbiAgICB0cmVhc3VyeUNvc2lnbmVyOiBQdWJsaWNLZXksXG4gICAgb3B0aW9ucz86IFR4T3B0aW9uc1xuICApIHtcbiAgICBjb25zdCBbZGFvUGRhXSA9IHRoaXMuZGVyaXZlREFPUERBKG5hbWUpO1xuICAgIGNvbnN0IFtwYXJlbnREYW9QZGFdID0gdGhpcy5kZXJpdmVEQU9QREEocGFyZW50RGFvTmFtZSk7XG4gICAgY29uc3QgW21pbnRDcmVhdGVLZXlQZGFdID0gdGhpcy5kZXJpdmVNaW50Q3JlYXRlS2V5UERBKGRhb1BkYSwgbmFtZSk7XG5cbiAgICAvLyBEZXJpdmUgU3F1YWRzIGFjY291bnRzIChzaW5nbGUgUlBDIGNhbGwpXG4gICAgY29uc3Qgc3F1YWRzQ29uZmlnID0gYXdhaXQgdGhpcy5mZXRjaFNxdWFkc1Byb2dyYW1Db25maWcoKTtcbiAgICBjb25zdCB0cmVhc3VyeU11bHRpc2lnUGRhID0gdGhpcy5kZXJpdmVNdWx0aXNpZ1BkYShkYW9QZGEpO1xuICAgIGNvbnN0IG1pbnRNdWx0aXNpZ1BkYSA9IHRoaXMuZGVyaXZlTXVsdGlzaWdQZGEobWludENyZWF0ZUtleVBkYSk7XG5cbiAgICBjb25zdCBidWlsZGVyID0gaW5pdGlhbGl6ZUNoaWxkREFPKFxuICAgICAgdGhpcy5wcm9ncmFtLFxuICAgICAgYWRtaW4sXG4gICAgICBwYXJlbnRBZG1pbixcbiAgICAgIGRhb1BkYSxcbiAgICAgIHBhcmVudERhb1BkYSxcbiAgICAgIHRva2VuTWludCxcbiAgICAgIHNxdWFkc0NvbmZpZy5wcm9ncmFtQ29uZmlnLFxuICAgICAgc3F1YWRzQ29uZmlnLnByb2dyYW1Db25maWdUcmVhc3VyeSxcbiAgICAgIHRyZWFzdXJ5TXVsdGlzaWdQZGEsXG4gICAgICBtaW50TXVsdGlzaWdQZGEsXG4gICAgICBtaW50Q3JlYXRlS2V5UGRhLFxuICAgICAgU1FVQURTX1BST0dSQU1fSUQsXG4gICAgICBuYW1lLFxuICAgICAgdHJlYXN1cnlDb3NpZ25lclxuICAgICkucHJlSW5zdHJ1Y3Rpb25zKHRoaXMubWF5YmVBZGRDb21wdXRlQnVkZ2V0KG9wdGlvbnMpKTtcblxuICAgIHJldHVybiB7XG4gICAgICBidWlsZGVyLFxuICAgICAgZGFvUGRhLFxuICAgICAgcGFyZW50RGFvUGRhLFxuICAgICAgdHJlYXN1cnlNdWx0aXNpZzogdHJlYXN1cnlNdWx0aXNpZ1BkYSxcbiAgICAgIG1pbnRNdWx0aXNpZzogbWludE11bHRpc2lnUGRhLFxuICAgIH07XG4gIH1cblxuICBhc3luYyB1cGdyYWRlREFPKFxuICAgIGFkbWluOiBQdWJsaWNLZXksXG4gICAgcGFyZW50QWRtaW46IFB1YmxpY0tleSxcbiAgICBkYW9OYW1lOiBzdHJpbmcsXG4gICAgcGFyZW50RGFvTmFtZTogc3RyaW5nLFxuICAgIGJhc2VNaW50OiBQdWJsaWNLZXksXG4gICAgcXVvdGVNaW50OiBQdWJsaWNLZXksXG4gICAgcG9vbDogUHVibGljS2V5LFxuICAgIHBvb2xUeXBlOiBQb29sVHlwZSxcbiAgICBvcHRpb25zPzogVHhPcHRpb25zXG4gICkge1xuICAgIGNvbnN0IFtkYW9QZGFdID0gdGhpcy5kZXJpdmVEQU9QREEoZGFvTmFtZSk7XG4gICAgY29uc3QgW3BhcmVudERhb1BkYV0gPSB0aGlzLmRlcml2ZURBT1BEQShwYXJlbnREYW9OYW1lKTtcbiAgICBjb25zdCBbbW9kZXJhdG9yUGRhXSA9IHRoaXMuZGVyaXZlTW9kZXJhdG9yUERBKGRhb05hbWUpO1xuXG4gICAgY29uc3QgYnVpbGRlciA9IHVwZ3JhZGVEQU8oXG4gICAgICB0aGlzLnByb2dyYW0sXG4gICAgICBhZG1pbixcbiAgICAgIHBhcmVudEFkbWluLFxuICAgICAgZGFvUGRhLFxuICAgICAgcGFyZW50RGFvUGRhLFxuICAgICAgbW9kZXJhdG9yUGRhLFxuICAgICAgYmFzZU1pbnQsXG4gICAgICBxdW90ZU1pbnQsXG4gICAgICBwb29sLFxuICAgICAgcG9vbFR5cGVcbiAgICApLnByZUluc3RydWN0aW9ucyh0aGlzLm1heWJlQWRkQ29tcHV0ZUJ1ZGdldChvcHRpb25zKSk7XG5cbiAgICByZXR1cm4geyBidWlsZGVyLCBkYW9QZGEsIG1vZGVyYXRvclBkYSB9O1xuICB9XG5cbiAgYXN5bmMgYWRkSGlzdG9yaWNhbFBhcmVudERBTyhcbiAgICBhZG1pbjogUHVibGljS2V5LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBiYXNlTWludDogUHVibGljS2V5LFxuICAgIHF1b3RlTWludDogUHVibGljS2V5LFxuICAgIHRyZWFzdXJ5TXVsdGlzaWc6IFB1YmxpY0tleSxcbiAgICBtaW50QXV0aE11bHRpc2lnOiBQdWJsaWNLZXksXG4gICAgY29zaWduZXI6IFB1YmxpY0tleSxcbiAgICBwb29sOiBQdWJsaWNLZXksXG4gICAgcG9vbFR5cGU6IFBvb2xUeXBlLFxuICAgIHByb3Bvc2FsSWRDb3VudGVyOiBudW1iZXIsXG4gICAgYWRtaW5QdWJrZXk6IFB1YmxpY0tleSxcbiAgICBvcHRpb25zPzogVHhPcHRpb25zXG4gICkge1xuICAgIGNvbnN0IFtkYW9QZGFdID0gdGhpcy5kZXJpdmVEQU9QREEobmFtZSk7XG4gICAgY29uc3QgW21vZGVyYXRvclBkYV0gPSB0aGlzLmRlcml2ZU1vZGVyYXRvclBEQShuYW1lKTtcblxuICAgIGNvbnN0IGJ1aWxkZXIgPSBhZGRIaXN0b3JpY2FsUGFyZW50REFPKFxuICAgICAgdGhpcy5wcm9ncmFtLFxuICAgICAgYWRtaW4sXG4gICAgICBkYW9QZGEsXG4gICAgICBtb2RlcmF0b3JQZGEsXG4gICAgICB0cmVhc3VyeU11bHRpc2lnLFxuICAgICAgbWludEF1dGhNdWx0aXNpZyxcbiAgICAgIGJhc2VNaW50LFxuICAgICAgcXVvdGVNaW50LFxuICAgICAgbmFtZSxcbiAgICAgIGNvc2lnbmVyLFxuICAgICAgcG9vbCxcbiAgICAgIHBvb2xUeXBlLFxuICAgICAgcHJvcG9zYWxJZENvdW50ZXIsXG4gICAgICBhZG1pblB1YmtleVxuICAgICkucHJlSW5zdHJ1Y3Rpb25zKHRoaXMubWF5YmVBZGRDb21wdXRlQnVkZ2V0KG9wdGlvbnMpKTtcblxuICAgIHJldHVybiB7XG4gICAgICBidWlsZGVyLFxuICAgICAgZGFvUGRhLFxuICAgICAgbW9kZXJhdG9yUGRhLFxuICAgIH07XG4gIH1cblxuICBhc3luYyB0cmFuc2ZlckFkbWluKFxuICAgIGFkbWluOiBQdWJsaWNLZXksXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIG5ld0FkbWluOiBQdWJsaWNLZXksXG4gICAgb3B0aW9ucz86IFR4T3B0aW9uc1xuICApIHtcbiAgICBjb25zdCBbZGFvUGRhXSA9IHRoaXMuZGVyaXZlREFPUERBKG5hbWUpO1xuICAgIGNvbnN0IFttb2RlcmF0b3JQZGFdID0gdGhpcy5kZXJpdmVNb2RlcmF0b3JQREEobmFtZSk7XG5cbiAgICBjb25zdCBidWlsZGVyID0gdHJhbnNmZXJBZG1pbihcbiAgICAgIHRoaXMucHJvZ3JhbSxcbiAgICAgIGFkbWluLFxuICAgICAgZGFvUGRhLFxuICAgICAgbW9kZXJhdG9yUGRhLFxuICAgICAgbmV3QWRtaW5cbiAgICApLnByZUluc3RydWN0aW9ucyh0aGlzLm1heWJlQWRkQ29tcHV0ZUJ1ZGdldChvcHRpb25zKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgYnVpbGRlcixcbiAgICAgIGRhb1BkYSxcbiAgICAgIG1vZGVyYXRvclBkYSxcbiAgICB9O1xuICB9XG59XG4iXX0=
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i);var r=Object.getOwnPropertyDescriptor(t,i);r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,r)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i);return t},e(t)};return function(t){if(t&&t.__esModule)return t;var i={};if(null!=t)for(var s=e(t),r=0;r<s.length;r++)"default"!==s[r]&&__createBinding(i,t,s[r]);return __setModuleDefault(i,t),i}}();Object.defineProperty(exports,"__esModule",{value:!0}),exports.FutarchyClient=void 0;const anchor_1=require("@coral-xyz/anchor"),web3_js_1=require("@solana/web3.js"),spl_token_1=require("@solana/spl-token"),constants_1=require("./constants"),utils_1=require("./utils"),instructions_1=require("./instructions"),vault_1=require("../vault"),amm_1=require("../amm"),idls_1=require("../generated/idls"),multisig=__importStar(require("@sqds/multisig")),DEFAULT_COMPUTE_UNITS=5e5;class FutarchyClient{constructor(e,t,i){this.programId=t??constants_1.PROGRAM_ID,this.program=new anchor_1.Program(idls_1.FutarchyIDL,e),this.vault=new vault_1.VaultClient(e),this.amm=new amm_1.AMMClient(e),this.defaultComputeUnits=i??5e5}deriveDAOPDA(e){return(0,utils_1.deriveDAOPDA)(e,this.programId)}deriveModeratorPDA(e){return(0,utils_1.deriveModeratorPDA)(e,this.programId)}deriveProposalPDA(e,t){return(0,utils_1.deriveProposalPDA)(e,t,this.programId)}async fetchDAO(e){return(0,utils_1.fetchDAOAccount)(this.program,e)}async fetchModerator(e){return(0,utils_1.fetchModeratorAccount)(this.program,e)}async fetchProposal(e){return(0,utils_1.fetchProposalAccount)(this.program,e)}isProposalExpired(e){return(0,utils_1.isProposalExpired)(e)}getTimeRemaining(e){return(0,utils_1.getTimeRemaining)(e)}getComputeUnits(e){return e?.computeUnits??this.defaultComputeUnits}maybeAddComputeBudget(e){if(!1===e?.includeCuBudget)return[];const t=[web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({units:this.getComputeUnits(e)})];return void 0!==e?.priorityFeeMicroLamports&&e.priorityFeeMicroLamports>0&&t.push(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({microLamports:e.priorityFeeMicroLamports})),t}async initializeModerator(e,t,i,s,r){const[a]=this.deriveModeratorPDA(s);return{builder:(0,instructions_1.initializeModerator)(this.program,e,t,i,a,s).preInstructions(this.maybeAddComputeBudget(r)),moderatorPda:a,name:s}}async addHistoricalProposal(e,t,i,s,r,a,o,n){const d=(await this.fetchModerator(t)).proposalIdCounter,[l]=this.deriveProposalPDA(t,d);return{builder:(0,instructions_1.addHistoricalProposal)(this.program,e,t,l,i,s,r,a,o).preInstructions(this.maybeAddComputeBudget(n)),proposalPda:l,proposalId:d}}async initializeProposal(e,t,i,s,r){const a=await this.fetchModerator(t),o=a.proposalIdCounter,[n]=this.deriveProposalPDA(t,o),[d]=(0,vault_1.deriveVaultPDA)(n,o,this.vault.programId),[l]=(0,vault_1.deriveConditionalMint)(d,vault_1.VaultType.Base,0,this.vault.programId),[u]=(0,vault_1.deriveConditionalMint)(d,vault_1.VaultType.Base,1,this.vault.programId),[c]=(0,vault_1.deriveConditionalMint)(d,vault_1.VaultType.Quote,0,this.vault.programId),[p]=(0,vault_1.deriveConditionalMint)(d,vault_1.VaultType.Quote,1,this.vault.programId),[m]=(0,amm_1.derivePoolPDA)(n,c,l,this.amm.programId),[g]=(0,amm_1.derivePoolPDA)(n,p,u,this.amm.programId),[h]=(0,amm_1.deriveReservePDA)(m,c,this.amm.programId),[_]=(0,amm_1.deriveReservePDA)(m,l,this.amm.programId),[b]=(0,amm_1.deriveFeeVaultPDA)(m,this.amm.programId),[A]=(0,amm_1.deriveReservePDA)(g,p,this.amm.programId),[k]=(0,amm_1.deriveReservePDA)(g,u,this.amm.programId),[y]=(0,amm_1.deriveFeeVaultPDA)(g,this.amm.programId),v=(0,spl_token_1.getAssociatedTokenAddressSync)(a.baseMint,d,!0),P=(0,spl_token_1.getAssociatedTokenAddressSync)(a.quoteMint,d,!0),f=[{pubkey:a.baseMint,isSigner:!1,isWritable:!1},{pubkey:a.quoteMint,isSigner:!1,isWritable:!1},{pubkey:d,isSigner:!1,isWritable:!0},{pubkey:v,isSigner:!1,isWritable:!0},{pubkey:P,isSigner:!1,isWritable:!0},{pubkey:l,isSigner:!1,isWritable:!0},{pubkey:u,isSigner:!1,isWritable:!0},{pubkey:c,isSigner:!1,isWritable:!0},{pubkey:p,isSigner:!1,isWritable:!0},{pubkey:m,isSigner:!1,isWritable:!0},{pubkey:h,isSigner:!1,isWritable:!0},{pubkey:_,isSigner:!1,isWritable:!0},{pubkey:amm_1.FEE_AUTHORITY,isSigner:!1,isWritable:!1},{pubkey:b,isSigner:!1,isWritable:!0},{pubkey:g,isSigner:!1,isWritable:!0},{pubkey:A,isSigner:!1,isWritable:!0},{pubkey:k,isSigner:!1,isWritable:!0},{pubkey:y,isSigner:!1,isWritable:!0}];return{builder:(0,instructions_1.initializeProposal)(this.program,e,t,n,i,s??null,f).preInstructions(this.maybeAddComputeBudget(r)),proposalPda:n,proposalId:o,vaultPda:d,pools:[m,g],condBaseMints:[l,u],condQuoteMints:[c,p]}}async addOption(e,t,i){const s=await this.fetchProposal(t),r=s.numOptions,[a]=(0,vault_1.deriveConditionalMint)(s.vault,vault_1.VaultType.Base,r,this.vault.programId),[o]=(0,vault_1.deriveConditionalMint)(s.vault,vault_1.VaultType.Quote,r,this.vault.programId),[n]=(0,amm_1.derivePoolPDA)(t,o,a,this.amm.programId),[d]=(0,amm_1.deriveReservePDA)(n,o,this.amm.programId),[l]=(0,amm_1.deriveReservePDA)(n,a,this.amm.programId),[u]=(0,amm_1.deriveFeeVaultPDA)(n,this.amm.programId),c=[{pubkey:s.vault,isSigner:!1,isWritable:!0},{pubkey:a,isSigner:!1,isWritable:!0},{pubkey:o,isSigner:!1,isWritable:!0},{pubkey:n,isSigner:!1,isWritable:!0},{pubkey:d,isSigner:!1,isWritable:!0},{pubkey:l,isSigner:!1,isWritable:!0},{pubkey:amm_1.FEE_AUTHORITY,isSigner:!1,isWritable:!1},{pubkey:u,isSigner:!1,isWritable:!0}];return{builder:(0,instructions_1.addOption)(this.program,e,t,c).preInstructions(this.maybeAddComputeBudget(i)),optionIndex:r,pool:n,condBaseMint:a,condQuoteMint:o}}async launchProposal(e,t,i,s,r){const a=await this.fetchProposal(t),o=await this.vault.fetchVault(a.vault),n=a.numOptions,d=o.condBaseMints.slice(0,n),l=o.condQuoteMints.slice(0,n);(r?.ensureATAs??n>=3)&&await this._createConditionalATAs(e,d,l);const u=a.pools.slice(0,n),c=d.map(t=>(0,spl_token_1.getAssociatedTokenAddressSync)(t,e)),p=l.map(t=>(0,spl_token_1.getAssociatedTokenAddressSync)(t,e)),m=[],g=[];for(let e=0;e<n;e++){const[t]=(0,amm_1.deriveReservePDA)(u[e],l[e],this.amm.programId),[i]=(0,amm_1.deriveReservePDA)(u[e],d[e],this.amm.programId);m.push(t),g.push(i)}const h=[{pubkey:o.baseMint.address,isSigner:!1,isWritable:!1},{pubkey:o.quoteMint.address,isSigner:!1,isWritable:!1},{pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(o.baseMint.address,a.vault,!0),isSigner:!1,isWritable:!0},{pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(o.quoteMint.address,a.vault,!0),isSigner:!1,isWritable:!0},{pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(o.baseMint.address,e),isSigner:!1,isWritable:!0},{pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(o.quoteMint.address,e),isSigner:!1,isWritable:!0}];for(const e of d)h.push({pubkey:e,isSigner:!1,isWritable:!0});for(const e of l)h.push({pubkey:e,isSigner:!1,isWritable:!0});for(const e of c)h.push({pubkey:e,isSigner:!1,isWritable:!0});for(const e of p)h.push({pubkey:e,isSigner:!1,isWritable:!0});for(const e of u)h.push({pubkey:e,isSigner:!1,isWritable:!0});for(const e of m)h.push({pubkey:e,isSigner:!1,isWritable:!0});for(const e of g)h.push({pubkey:e,isSigner:!1,isWritable:!0});return{builder:(0,instructions_1.launchProposal)(this.program,e,t,a.vault,i,s,h).preInstructions(this.maybeAddComputeBudget(r))}}async ensureConditionalATAs(e,t){const i=await this.fetchProposal(t),s=await this.vault.fetchVault(i.vault),r=s.condBaseMints.slice(0,i.numOptions),a=s.condQuoteMints.slice(0,i.numOptions);return this._createConditionalATAs(e,r,a)}async _createConditionalATAs(e,t,i){const s=this.program.provider,r=[];for(let s=0;s<t.length;s++){const a=(0,spl_token_1.getAssociatedTokenAddressSync)(t[s],e),o=(0,spl_token_1.getAssociatedTokenAddressSync)(i[s],e);r.push((0,spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(e,a,e,t[s]),(0,spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(e,o,e,i[s]))}const a=(new web3_js_1.Transaction).add(...r);return s.sendAndConfirm(a)}async finalizeProposal(e,t,i){const s=await this.fetchProposal(t),r=await this.vault.fetchVault(s.vault),a=s.numOptions,o=[];for(let e=0;e<a;e++){const t=s.pools[e],[i]=(0,amm_1.deriveReservePDA)(t,r.condQuoteMints[e],this.amm.programId),[a]=(0,amm_1.deriveReservePDA)(t,r.condBaseMints[e],this.amm.programId);o.push({pubkey:t,isSigner:!1,isWritable:!0}),o.push({pubkey:i,isSigner:!1,isWritable:!1}),o.push({pubkey:a,isSigner:!1,isWritable:!1})}return{builder:(0,instructions_1.finalizeProposal)(this.program,e,t,s.vault,o).preInstructions(this.maybeAddComputeBudget(i))}}async redeemLiquidity(e,t,i){const s=await this.fetchProposal(t),r=await this.vault.fetchVault(s.vault),a=s.numOptions,{winningIdx:o}=(0,utils_1.parseProposalState)(s.state);if(null===o)throw new Error("Proposal not finalized");const n=s.pools[o],[d]=(0,amm_1.deriveReservePDA)(n,r.condQuoteMints[o],this.amm.programId),[l]=(0,amm_1.deriveReservePDA)(n,r.condBaseMints[o],this.amm.programId),u=[{pubkey:d,isSigner:!1,isWritable:!0},{pubkey:l,isSigner:!1,isWritable:!0},{pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(r.condQuoteMints[o],e),isSigner:!1,isWritable:!0},{pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(r.condBaseMints[o],e),isSigner:!1,isWritable:!0},{pubkey:r.baseMint.address,isSigner:!1,isWritable:!1},{pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(r.baseMint.address,s.vault,!0),isSigner:!1,isWritable:!0},{pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(r.baseMint.address,e),isSigner:!1,isWritable:!0}];for(let t=0;t<a;t++)u.push({pubkey:r.condBaseMints[t],isSigner:!1,isWritable:!0}),u.push({pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(r.condBaseMints[t],e),isSigner:!1,isWritable:!0});u.push({pubkey:r.quoteMint.address,isSigner:!1,isWritable:!1}),u.push({pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(r.quoteMint.address,s.vault,!0),isSigner:!1,isWritable:!0}),u.push({pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(r.quoteMint.address,e),isSigner:!1,isWritable:!0});for(let t=0;t<a;t++)u.push({pubkey:r.condQuoteMints[t],isSigner:!1,isWritable:!0}),u.push({pubkey:(0,spl_token_1.getAssociatedTokenAddressSync)(r.condQuoteMints[t],e),isSigner:!1,isWritable:!0});return{builder:(0,instructions_1.redeemLiquidity)(this.program,e,t,s.vault,n,u).preInstructions(this.maybeAddComputeBudget(i)),numOptions:a}}async createRedemptionALT(e,t,i=0){const s=this.program.provider,r=await this.fetchProposal(t),a=await this.vault.fetchVault(r.vault),o=r.numOptions,{winningIdx:n}=(0,utils_1.parseProposalState)(r.state);if(null===n)throw new Error("Proposal not finalized");const d=[this.programId,this.vault.programId,this.amm.programId,web3_js_1.SystemProgram.programId,spl_token_1.TOKEN_PROGRAM_ID,spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,t,r.vault,r.moderator,a.baseMint.address,a.quoteMint.address,r.pools[n],(0,spl_token_1.getAssociatedTokenAddressSync)(a.baseMint.address,r.vault,!0),(0,spl_token_1.getAssociatedTokenAddressSync)(a.quoteMint.address,r.vault,!0),(0,spl_token_1.getAssociatedTokenAddressSync)(a.baseMint.address,e),(0,spl_token_1.getAssociatedTokenAddressSync)(a.quoteMint.address,e)],[l]=(0,amm_1.deriveReservePDA)(r.pools[n],a.condQuoteMints[n],this.amm.programId),[u]=(0,amm_1.deriveReservePDA)(r.pools[n],a.condBaseMints[n],this.amm.programId);d.push(l,u);for(let t=0;t<o;t++)d.push(a.condBaseMints[t],a.condQuoteMints[t],(0,spl_token_1.getAssociatedTokenAddressSync)(a.condBaseMints[t],e),(0,spl_token_1.getAssociatedTokenAddressSync)(a.condQuoteMints[t],e));const c=await s.connection.getSlot("finalized"),[p,m]=web3_js_1.AddressLookupTableProgram.createLookupTable({authority:e,payer:e,recentSlot:c}),g=new web3_js_1.Transaction;i>0&&g.add(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({microLamports:i})),g.add(p);const{blockhash:h,lastValidBlockHeight:_}=await s.connection.getLatestBlockhash("confirmed");g.recentBlockhash=h,g.feePayer=e;const b=await s.wallet.signTransaction(g),A=await s.connection.sendRawTransaction(b.serialize(),{skipPreflight:!0});await s.connection.confirmTransaction({signature:A,blockhash:h,lastValidBlockHeight:_},"confirmed");for(let t=0;t<d.length;t+=20){const r=d.slice(t,t+20),a=web3_js_1.AddressLookupTableProgram.extendLookupTable({payer:e,authority:e,lookupTable:m,addresses:r}),o=new web3_js_1.Transaction;i>0&&o.add(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({microLamports:i})),o.add(a);const{blockhash:n,lastValidBlockHeight:l}=await s.connection.getLatestBlockhash("confirmed");o.recentBlockhash=n,o.feePayer=e;const u=await s.wallet.signTransaction(o),c=await s.connection.sendRawTransaction(u.serialize(),{skipPreflight:!0});await s.connection.confirmTransaction({signature:c,blockhash:n,lastValidBlockHeight:l},"confirmed")}return{altAddress:m}}async redeemLiquidityVersioned(e,t,i,s){const r=this.program.provider,{builder:a,numOptions:o}=await this.redeemLiquidity(e,t);let n=i,d=null;if(!n&&o>=3){console.log(` Creating redemption ALT for ${o} options...`);n=(await this.createRedemptionALT(e,t)).altAddress,console.log(` ✓ Redemption ALT created: ${n.toBase58()}`),console.log(" Waiting for ALT propagation...");const i=18+4*o;let s=0;for(await new Promise(e=>setTimeout(e,2e3));s<30;){const e=await r.connection.getAddressLookupTable(n,{commitment:"confirmed"});if(e.value){const t=e.value.state.addresses.length;if(console.log(` Attempt ${s+1}: ALT has ${t}/${i} addresses`),t>=i){d=e.value,console.log(` ✓ ALT verified with ${t} addresses`);break}}await new Promise(e=>setTimeout(e,1e3)),s++}if(!d)throw new Error(`ALT failed to populate with expected ${i} addresses after ${s} attempts`)}if(!n)throw new Error("ALT address required for multi-option redemption");d||(d=await this.fetchALT(n));const l=await a.instruction(),u=[web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({units:5e5})];void 0!==s?.priorityFeeMicroLamports&&s.priorityFeeMicroLamports>0&&u.push(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({microLamports:s.priorityFeeMicroLamports}));const{blockhash:c,lastValidBlockHeight:p}=await r.connection.getLatestBlockhash("confirmed");return{versionedTx:this.buildVersionedTxWithALT(e,[...u,l],d,c),altAddress:n,numOptions:o,blockhash:c,lastValidBlockHeight:p}}async sendVersionedTransaction(e,t){const i=this.program.provider;let s,r;if(t)s=t.blockhash,r=t.lastValidBlockHeight;else{const e=await i.connection.getLatestBlockhash("confirmed");s=e.blockhash,r=e.lastValidBlockHeight}const a=await i.connection.sendTransaction(e,{skipPreflight:!1,preflightCommitment:"confirmed"});return await i.connection.confirmTransaction({signature:a,blockhash:s,lastValidBlockHeight:r},"confirmed"),a}async createProposalALT(e,t,i=2,s=0){const r=this.program.provider,a=await this.fetchModerator(t),o=a.proposalIdCounter,[n]=this.deriveProposalPDA(t,o),[d]=(0,vault_1.deriveVaultPDA)(n,o,this.vault.programId),l=[this.programId,this.vault.programId,this.amm.programId,web3_js_1.SystemProgram.programId,spl_token_1.TOKEN_PROGRAM_ID,spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,t,n,d,a.baseMint,a.quoteMint,amm_1.FEE_AUTHORITY,(0,spl_token_1.getAssociatedTokenAddressSync)(a.baseMint,d,!0),(0,spl_token_1.getAssociatedTokenAddressSync)(a.quoteMint,d,!0),(0,spl_token_1.getAssociatedTokenAddressSync)(a.baseMint,e),(0,spl_token_1.getAssociatedTokenAddressSync)(a.quoteMint,e)];for(let t=0;t<i;t++){const[i]=(0,vault_1.deriveConditionalMint)(d,vault_1.VaultType.Base,t,this.vault.programId),[s]=(0,vault_1.deriveConditionalMint)(d,vault_1.VaultType.Quote,t,this.vault.programId),[r]=(0,amm_1.derivePoolPDA)(n,s,i,this.amm.programId),[a]=(0,amm_1.deriveReservePDA)(r,s,this.amm.programId),[o]=(0,amm_1.deriveReservePDA)(r,i,this.amm.programId),[u]=(0,amm_1.deriveFeeVaultPDA)(r,this.amm.programId);l.push(i,s,r,a,o,u,(0,spl_token_1.getAssociatedTokenAddressSync)(i,e),(0,spl_token_1.getAssociatedTokenAddressSync)(s,e))}const u=await r.connection.getSlot("finalized"),[c,p]=web3_js_1.AddressLookupTableProgram.createLookupTable({authority:e,payer:e,recentSlot:u}),m=new web3_js_1.Transaction;s>0&&m.add(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({microLamports:s})),m.add(c);const{blockhash:g,lastValidBlockHeight:h}=await r.connection.getLatestBlockhash("confirmed");m.recentBlockhash=g,m.feePayer=e;const _=await r.wallet.signTransaction(m),b=await r.connection.sendRawTransaction(_.serialize(),{skipPreflight:!0});await r.connection.confirmTransaction({signature:b,blockhash:g,lastValidBlockHeight:h},"confirmed");for(let t=0;t<l.length;t+=20){const i=l.slice(t,t+20),a=web3_js_1.AddressLookupTableProgram.extendLookupTable({payer:e,authority:e,lookupTable:p,addresses:i}),o=new web3_js_1.Transaction;s>0&&o.add(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({microLamports:s})),o.add(a);const{blockhash:n,lastValidBlockHeight:d}=await r.connection.getLatestBlockhash("confirmed");o.recentBlockhash=n,o.feePayer=e;const u=await r.wallet.signTransaction(o),c=await r.connection.sendRawTransaction(u.serialize(),{skipPreflight:!0});await r.connection.confirmTransaction({signature:c,blockhash:n,lastValidBlockHeight:d},"confirmed")}return{altAddress:p}}async fetchALT(e){const t=await this.program.provider.connection.getAddressLookupTable(e);if(!t.value)throw new Error("ALT not found");return t.value}async buildVersionedTx(e,t,i){const s=this.program.provider,r=await this.fetchALT(i),{blockhash:a,lastValidBlockHeight:o}=await s.connection.getLatestBlockhash("confirmed");return{versionedTx:this.buildVersionedTxWithALT(e,t,r,a),blockhash:a,lastValidBlockHeight:o}}buildVersionedTxWithALT(e,t,i,s){const r=new web3_js_1.TransactionMessage({payerKey:e,recentBlockhash:s,instructions:t}).compileToV0Message([i]);return new web3_js_1.VersionedTransaction(r)}deriveMintCreateKeyPDA(e,t){return(0,utils_1.deriveMintCreateKeyPDA)(e,t,this.programId)}async fetchSquadsProgramConfig(){const[e]=multisig.getProgramConfigPda({programId:constants_1.SQUADS_PROGRAM_ID});return{programConfig:e,programConfigTreasury:(await multisig.accounts.ProgramConfig.fromAccountAddress(this.program.provider.connection,e)).treasury}}deriveMultisigPda(e){const[t]=multisig.getMultisigPda({createKey:e,programId:constants_1.SQUADS_PROGRAM_ID});return t}async initializeParentDAO(e,t,i,s,r,a,o,n,d){const[l]=this.deriveDAOPDA(i),[u]=this.deriveModeratorPDA(i),[c]=this.deriveMintCreateKeyPDA(l,i),p=await this.fetchSquadsProgramConfig(),m=this.deriveMultisigPda(l),g=this.deriveMultisigPda(c);return{builder:(0,instructions_1.initializeParentDAO)(this.program,e,t,l,u,s,r,p.programConfig,p.programConfigTreasury,m,g,c,constants_1.SQUADS_PROGRAM_ID,i,a,o,n).preInstructions(this.maybeAddComputeBudget(d)),daoPda:l,moderatorPda:u,treasuryMultisig:m,mintMultisig:g}}async initializeChildDAO(e,t,i,s,r,a,o){const[n]=this.deriveDAOPDA(s),[d]=this.deriveDAOPDA(i),[l]=this.deriveMintCreateKeyPDA(n,s),u=await this.fetchSquadsProgramConfig(),c=this.deriveMultisigPda(n),p=this.deriveMultisigPda(l);return{builder:(0,instructions_1.initializeChildDAO)(this.program,e,t,n,d,r,u.programConfig,u.programConfigTreasury,c,p,l,constants_1.SQUADS_PROGRAM_ID,s,a).preInstructions(this.maybeAddComputeBudget(o)),daoPda:n,parentDaoPda:d,treasuryMultisig:c,mintMultisig:p}}async upgradeDAO(e,t,i,s,r,a,o,n,d){const[l]=this.deriveDAOPDA(i),[u]=this.deriveDAOPDA(s),[c]=this.deriveModeratorPDA(i);return{builder:(0,instructions_1.upgradeDAO)(this.program,e,t,l,u,c,r,a,o,n).preInstructions(this.maybeAddComputeBudget(d)),daoPda:l,moderatorPda:c}}async addHistoricalParentDAO(e,t,i,s,r,a,o,n,d,l,u,c){const[p]=this.deriveDAOPDA(t),[m]=this.deriveModeratorPDA(t);return{builder:(0,instructions_1.addHistoricalParentDAO)(this.program,e,p,m,r,a,i,s,t,o,n,d,l,u).preInstructions(this.maybeAddComputeBudget(c)),daoPda:p,moderatorPda:m}}async transferAdmin(e,t,i,s){const[r]=this.deriveDAOPDA(t),[a]=this.deriveModeratorPDA(t);return{builder:(0,instructions_1.transferAdmin)(this.program,e,r,a,i).preInstructions(this.maybeAddComputeBudget(s)),daoPda:r,moderatorPda:a}}}exports.FutarchyClient=FutarchyClient;