drama-pm-client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +521 -0
- package/dist/idl.d.ts +208 -0
- package/dist/idl.js +1067 -0
- package/dist/idl.json +1066 -0
- package/dist/index.d.ts +153 -0
- package/dist/index.js +232 -0
- package/dist/types.d.ts +1072 -0
- package/dist/types.js +2 -0
- package/dist/utils.d.ts +19 -0
- package/dist/utils.js +37 -0
- package/package.json +35 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { BN, Program } from "@coral-xyz/anchor";
|
|
2
|
+
import anchor from "@coral-xyz/anchor";
|
|
3
|
+
import { Connection, PublicKey, Transaction, TransactionInstruction } from "@solana/web3.js";
|
|
4
|
+
import { IDL } from "./idl.js";
|
|
5
|
+
import { DramaPm } from "./types.js";
|
|
6
|
+
export * from "./utils.js";
|
|
7
|
+
export { DramaPm, IDL };
|
|
8
|
+
export type Outcome = "Yes" | "No";
|
|
9
|
+
export interface CreateMarketParams {
|
|
10
|
+
admin: PublicKey;
|
|
11
|
+
marketId: number | BN;
|
|
12
|
+
yesPrice: number | BN;
|
|
13
|
+
noPrice: number | BN;
|
|
14
|
+
endTime: number | BN;
|
|
15
|
+
bettingToken: PublicKey;
|
|
16
|
+
}
|
|
17
|
+
export interface PlaceBetParams {
|
|
18
|
+
user: PublicKey;
|
|
19
|
+
admin: PublicKey;
|
|
20
|
+
marketId: number | BN;
|
|
21
|
+
amount: number | BN;
|
|
22
|
+
outcome: Outcome;
|
|
23
|
+
bettingToken: PublicKey;
|
|
24
|
+
createAta?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface ClaimRewardsParams {
|
|
27
|
+
user: PublicKey;
|
|
28
|
+
admin: PublicKey;
|
|
29
|
+
marketId: number | BN;
|
|
30
|
+
bettingToken: PublicKey;
|
|
31
|
+
winningOutcome: Outcome;
|
|
32
|
+
}
|
|
33
|
+
export interface RefundParams {
|
|
34
|
+
user: PublicKey;
|
|
35
|
+
admin: PublicKey;
|
|
36
|
+
marketId: number | BN;
|
|
37
|
+
bettingToken: PublicKey;
|
|
38
|
+
outcome: Outcome;
|
|
39
|
+
}
|
|
40
|
+
export declare class DramaPmClient {
|
|
41
|
+
program: Program<DramaPm>;
|
|
42
|
+
provider: anchor.AnchorProvider;
|
|
43
|
+
connection: Connection;
|
|
44
|
+
constructor(connection: Connection, wallet?: anchor.Wallet);
|
|
45
|
+
/**
|
|
46
|
+
* Check if an associated token account exists
|
|
47
|
+
*/
|
|
48
|
+
ataExists(ata: PublicKey): Promise<boolean>;
|
|
49
|
+
/**
|
|
50
|
+
* Create an instruction to initialize an associated token account
|
|
51
|
+
*/
|
|
52
|
+
createAtaInstruction(payer: PublicKey, owner: PublicKey, mint: PublicKey): TransactionInstruction;
|
|
53
|
+
/**
|
|
54
|
+
* Create a new prediction market instruction
|
|
55
|
+
*/
|
|
56
|
+
createMarket(params: CreateMarketParams): Promise<TransactionInstruction>;
|
|
57
|
+
/**
|
|
58
|
+
* Build a complete transaction to create a market
|
|
59
|
+
*/
|
|
60
|
+
buildCreateMarketTx(params: CreateMarketParams): Promise<Transaction>;
|
|
61
|
+
/**
|
|
62
|
+
* Place a bet instruction (without ATA creation)
|
|
63
|
+
*/
|
|
64
|
+
placeBet(params: PlaceBetParams): Promise<TransactionInstruction>;
|
|
65
|
+
/**
|
|
66
|
+
* Build a complete transaction to place a bet (with optional ATA creation)
|
|
67
|
+
*/
|
|
68
|
+
buildPlaceBetTx(params: PlaceBetParams): Promise<Transaction>;
|
|
69
|
+
/**
|
|
70
|
+
* Claim rewards after market resolution
|
|
71
|
+
*/
|
|
72
|
+
claimRewards(params: ClaimRewardsParams): Promise<TransactionInstruction>;
|
|
73
|
+
/**
|
|
74
|
+
* Build a complete transaction to claim rewards
|
|
75
|
+
*/
|
|
76
|
+
buildClaimRewardsTx(params: ClaimRewardsParams): Promise<Transaction>;
|
|
77
|
+
/**
|
|
78
|
+
* Refund bets if market is refunded
|
|
79
|
+
*/
|
|
80
|
+
refund(params: RefundParams): Promise<TransactionInstruction>;
|
|
81
|
+
/**
|
|
82
|
+
* Build a complete transaction to refund
|
|
83
|
+
*/
|
|
84
|
+
buildRefundTx(params: RefundParams): Promise<Transaction>;
|
|
85
|
+
/**
|
|
86
|
+
* Resolve a market (Admin only)
|
|
87
|
+
*/
|
|
88
|
+
resolveMarket(admin: PublicKey, marketId: number | BN, winningOutcome: "Yes" | "No" | null): Promise<TransactionInstruction>;
|
|
89
|
+
/**
|
|
90
|
+
* Build a complete transaction to resolve a market
|
|
91
|
+
*/
|
|
92
|
+
buildResolveMarketTx(admin: PublicKey, marketId: number | BN, winningOutcome: "Yes" | "No" | null): Promise<Transaction>;
|
|
93
|
+
/**
|
|
94
|
+
* Close a market (Admin only)
|
|
95
|
+
*/
|
|
96
|
+
closeMarket(admin: PublicKey, marketId: number | BN): Promise<TransactionInstruction>;
|
|
97
|
+
/**
|
|
98
|
+
* Build a complete transaction to close a market
|
|
99
|
+
*/
|
|
100
|
+
buildCloseMarketTx(admin: PublicKey, marketId: number | BN): Promise<Transaction>;
|
|
101
|
+
/**
|
|
102
|
+
* Fetch market account data
|
|
103
|
+
*/
|
|
104
|
+
getMarketAccount(admin: PublicKey, marketId: number | BN): Promise<{
|
|
105
|
+
admin: anchor.web3.PublicKey;
|
|
106
|
+
marketId: BN;
|
|
107
|
+
yesMint: anchor.web3.PublicKey;
|
|
108
|
+
noMint: anchor.web3.PublicKey;
|
|
109
|
+
bettingToken: anchor.web3.PublicKey;
|
|
110
|
+
vault: anchor.web3.PublicKey;
|
|
111
|
+
yesPrice: BN;
|
|
112
|
+
noPrice: BN;
|
|
113
|
+
createTime: BN;
|
|
114
|
+
endTime: BN;
|
|
115
|
+
status: ({
|
|
116
|
+
closed?: undefined;
|
|
117
|
+
resolved?: undefined;
|
|
118
|
+
refunded?: undefined;
|
|
119
|
+
} & {
|
|
120
|
+
active: Record<string, never>;
|
|
121
|
+
}) | ({
|
|
122
|
+
active?: undefined;
|
|
123
|
+
resolved?: undefined;
|
|
124
|
+
refunded?: undefined;
|
|
125
|
+
} & {
|
|
126
|
+
closed: Record<string, never>;
|
|
127
|
+
}) | ({
|
|
128
|
+
active?: undefined;
|
|
129
|
+
closed?: undefined;
|
|
130
|
+
refunded?: undefined;
|
|
131
|
+
} & {
|
|
132
|
+
resolved: Record<string, never>;
|
|
133
|
+
}) | ({
|
|
134
|
+
active?: undefined;
|
|
135
|
+
closed?: undefined;
|
|
136
|
+
resolved?: undefined;
|
|
137
|
+
} & {
|
|
138
|
+
refunded: Record<string, never>;
|
|
139
|
+
});
|
|
140
|
+
winningOutcome: (({
|
|
141
|
+
yes?: undefined;
|
|
142
|
+
} & {
|
|
143
|
+
no: Record<string, never>;
|
|
144
|
+
}) | ({
|
|
145
|
+
no?: undefined;
|
|
146
|
+
} & {
|
|
147
|
+
yes: Record<string, never>;
|
|
148
|
+
})) | null;
|
|
149
|
+
totalYesSupply: BN;
|
|
150
|
+
totalNoSupply: BN;
|
|
151
|
+
bump: number;
|
|
152
|
+
}>;
|
|
153
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import anchor from "@coral-xyz/anchor";
|
|
2
|
+
import { createAssociatedTokenAccountInstruction, getAccount, getAssociatedTokenAddressSync, TOKEN_PROGRAM_ID, } from "@solana/spl-token";
|
|
3
|
+
import { Keypair, Transaction } from "@solana/web3.js";
|
|
4
|
+
import { IDL } from "./idl.js";
|
|
5
|
+
import { getMarketPda, getMarketPdas } from "./utils.js";
|
|
6
|
+
const { BN: AnchorBN, Program: AnchorProgram } = anchor;
|
|
7
|
+
export * from "./utils.js";
|
|
8
|
+
export { IDL };
|
|
9
|
+
export class DramaPmClient {
|
|
10
|
+
constructor(connection, wallet) {
|
|
11
|
+
this.connection = connection;
|
|
12
|
+
this.provider = new anchor.AnchorProvider(connection, wallet || new anchor.Wallet(Keypair.generate()), { commitment: "confirmed" });
|
|
13
|
+
this.program = new AnchorProgram(IDL, this.provider);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Check if an associated token account exists
|
|
17
|
+
*/
|
|
18
|
+
async ataExists(ata) {
|
|
19
|
+
try {
|
|
20
|
+
await getAccount(this.connection, ata);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create an instruction to initialize an associated token account
|
|
29
|
+
*/
|
|
30
|
+
createAtaInstruction(payer, owner, mint) {
|
|
31
|
+
const ata = getAssociatedTokenAddressSync(mint, owner);
|
|
32
|
+
return createAssociatedTokenAccountInstruction(payer, ata, owner, mint, TOKEN_PROGRAM_ID);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a new prediction market instruction
|
|
36
|
+
*/
|
|
37
|
+
async createMarket(params) {
|
|
38
|
+
const { admin, marketId, yesPrice, noPrice, endTime, bettingToken } = params;
|
|
39
|
+
const marketIdBn = new AnchorBN(marketId);
|
|
40
|
+
const yesPriceBn = new AnchorBN(yesPrice);
|
|
41
|
+
const noPriceBn = new AnchorBN(noPrice);
|
|
42
|
+
const endTimeBn = new AnchorBN(endTime);
|
|
43
|
+
const pdas = getMarketPdas(this.program.programId, admin, marketIdBn);
|
|
44
|
+
return await this.program.methods
|
|
45
|
+
.createMarket({
|
|
46
|
+
marketId: marketIdBn,
|
|
47
|
+
yesPrice: yesPriceBn,
|
|
48
|
+
noPrice: noPriceBn,
|
|
49
|
+
endTime: endTimeBn,
|
|
50
|
+
})
|
|
51
|
+
.accountsPartial({
|
|
52
|
+
market: pdas.market,
|
|
53
|
+
yesMint: pdas.yesMint,
|
|
54
|
+
noMint: pdas.noMint,
|
|
55
|
+
bettingToken: bettingToken,
|
|
56
|
+
vault: pdas.vault,
|
|
57
|
+
admin: admin,
|
|
58
|
+
systemProgram: anchor.web3.SystemProgram.programId,
|
|
59
|
+
})
|
|
60
|
+
.instruction();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Build a complete transaction to create a market
|
|
64
|
+
*/
|
|
65
|
+
async buildCreateMarketTx(params) {
|
|
66
|
+
const ix = await this.createMarket(params);
|
|
67
|
+
return new Transaction().add(ix);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Place a bet instruction (without ATA creation)
|
|
71
|
+
*/
|
|
72
|
+
async placeBet(params) {
|
|
73
|
+
const { user, admin, marketId, amount, outcome, bettingToken } = params;
|
|
74
|
+
const marketIdBn = new AnchorBN(marketId);
|
|
75
|
+
const amountBn = new AnchorBN(amount);
|
|
76
|
+
const outcomeEnum = outcome === "Yes" ? { yes: {} } : { no: {} };
|
|
77
|
+
const pdas = getMarketPdas(this.program.programId, admin, marketIdBn);
|
|
78
|
+
const userBettingToken = getAssociatedTokenAddressSync(bettingToken, user);
|
|
79
|
+
// Determine which outcome token the user will receive
|
|
80
|
+
const targetMint = outcome === "Yes" ? pdas.yesMint : pdas.noMint;
|
|
81
|
+
const userOutcomeToken = getAssociatedTokenAddressSync(targetMint, user);
|
|
82
|
+
return await this.program.methods
|
|
83
|
+
.placeBet({
|
|
84
|
+
buyOutcome: outcomeEnum,
|
|
85
|
+
amount: amountBn,
|
|
86
|
+
})
|
|
87
|
+
.accountsPartial({
|
|
88
|
+
market: pdas.market,
|
|
89
|
+
yesMint: pdas.yesMint,
|
|
90
|
+
noMint: pdas.noMint,
|
|
91
|
+
vault: pdas.vault,
|
|
92
|
+
userOutcomeToken,
|
|
93
|
+
userBettingToken,
|
|
94
|
+
user,
|
|
95
|
+
})
|
|
96
|
+
.instruction();
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Build a complete transaction to place a bet (with optional ATA creation)
|
|
100
|
+
*/
|
|
101
|
+
async buildPlaceBetTx(params) {
|
|
102
|
+
const { user, admin, marketId, outcome, createAta = true } = params;
|
|
103
|
+
const tx = new Transaction();
|
|
104
|
+
const marketIdBn = new AnchorBN(marketId);
|
|
105
|
+
const pdas = getMarketPdas(this.program.programId, admin, marketIdBn);
|
|
106
|
+
const targetMint = outcome === "Yes" ? pdas.yesMint : pdas.noMint;
|
|
107
|
+
const userOutcomeToken = getAssociatedTokenAddressSync(targetMint, user);
|
|
108
|
+
// Check if ATA exists and create if needed
|
|
109
|
+
if (createAta) {
|
|
110
|
+
const exists = await this.ataExists(userOutcomeToken);
|
|
111
|
+
if (!exists) {
|
|
112
|
+
const createAtaIx = this.createAtaInstruction(user, user, targetMint);
|
|
113
|
+
tx.add(createAtaIx);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const placeBetIx = await this.placeBet(params);
|
|
117
|
+
tx.add(placeBetIx);
|
|
118
|
+
return tx;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Claim rewards after market resolution
|
|
122
|
+
*/
|
|
123
|
+
async claimRewards(params) {
|
|
124
|
+
const { user, admin, marketId, bettingToken, winningOutcome } = params;
|
|
125
|
+
const marketIdBn = new AnchorBN(marketId);
|
|
126
|
+
const pdas = getMarketPdas(this.program.programId, admin, marketIdBn);
|
|
127
|
+
const userBettingToken = getAssociatedTokenAddressSync(bettingToken, user);
|
|
128
|
+
const targetMint = winningOutcome === "Yes" ? pdas.yesMint : pdas.noMint;
|
|
129
|
+
const userOutcomeToken = getAssociatedTokenAddressSync(targetMint, user);
|
|
130
|
+
return await this.program.methods
|
|
131
|
+
.claimRewards()
|
|
132
|
+
.accountsPartial({
|
|
133
|
+
market: pdas.market,
|
|
134
|
+
userOutcomeToken,
|
|
135
|
+
userBettingToken,
|
|
136
|
+
user,
|
|
137
|
+
})
|
|
138
|
+
.instruction();
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Build a complete transaction to claim rewards
|
|
142
|
+
*/
|
|
143
|
+
async buildClaimRewardsTx(params) {
|
|
144
|
+
const ix = await this.claimRewards(params);
|
|
145
|
+
return new Transaction().add(ix);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Refund bets if market is refunded
|
|
149
|
+
*/
|
|
150
|
+
async refund(params) {
|
|
151
|
+
const { user, admin, marketId, bettingToken, outcome } = params;
|
|
152
|
+
const marketIdBn = new AnchorBN(marketId);
|
|
153
|
+
const outcomeEnum = outcome === "Yes" ? { yes: {} } : { no: {} };
|
|
154
|
+
const pdas = getMarketPdas(this.program.programId, admin, marketIdBn);
|
|
155
|
+
const userBettingToken = getAssociatedTokenAddressSync(bettingToken, user);
|
|
156
|
+
const targetMint = outcome === "Yes" ? pdas.yesMint : pdas.noMint;
|
|
157
|
+
const userOutcomeToken = getAssociatedTokenAddressSync(targetMint, user);
|
|
158
|
+
return await this.program.methods
|
|
159
|
+
.refund(outcomeEnum)
|
|
160
|
+
.accountsPartial({
|
|
161
|
+
market: pdas.market,
|
|
162
|
+
userOutcomeToken,
|
|
163
|
+
userBettingToken,
|
|
164
|
+
user,
|
|
165
|
+
})
|
|
166
|
+
.instruction();
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Build a complete transaction to refund
|
|
170
|
+
*/
|
|
171
|
+
async buildRefundTx(params) {
|
|
172
|
+
const ix = await this.refund(params);
|
|
173
|
+
return new Transaction().add(ix);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Resolve a market (Admin only)
|
|
177
|
+
*/
|
|
178
|
+
async resolveMarket(admin, marketId, winningOutcome) {
|
|
179
|
+
const marketIdBn = new AnchorBN(marketId);
|
|
180
|
+
const marketPda = getMarketPda(this.program.programId, admin, marketIdBn);
|
|
181
|
+
let outcomeEnum = null;
|
|
182
|
+
if (winningOutcome === "Yes") {
|
|
183
|
+
outcomeEnum = { yes: {} };
|
|
184
|
+
}
|
|
185
|
+
else if (winningOutcome === "No") {
|
|
186
|
+
outcomeEnum = { no: {} };
|
|
187
|
+
}
|
|
188
|
+
return await this.program.methods
|
|
189
|
+
.resolveMarket(outcomeEnum)
|
|
190
|
+
.accountsPartial({
|
|
191
|
+
market: marketPda,
|
|
192
|
+
admin,
|
|
193
|
+
})
|
|
194
|
+
.instruction();
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Build a complete transaction to resolve a market
|
|
198
|
+
*/
|
|
199
|
+
async buildResolveMarketTx(admin, marketId, winningOutcome) {
|
|
200
|
+
const ix = await this.resolveMarket(admin, marketId, winningOutcome);
|
|
201
|
+
return new Transaction().add(ix);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Close a market (Admin only)
|
|
205
|
+
*/
|
|
206
|
+
async closeMarket(admin, marketId) {
|
|
207
|
+
const marketIdBn = new AnchorBN(marketId);
|
|
208
|
+
const marketPda = getMarketPda(this.program.programId, admin, marketIdBn);
|
|
209
|
+
return await this.program.methods
|
|
210
|
+
.closeMarket()
|
|
211
|
+
.accountsPartial({
|
|
212
|
+
market: marketPda,
|
|
213
|
+
})
|
|
214
|
+
.instruction();
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Build a complete transaction to close a market
|
|
218
|
+
*/
|
|
219
|
+
async buildCloseMarketTx(admin, marketId) {
|
|
220
|
+
const ix = await this.closeMarket(admin, marketId);
|
|
221
|
+
return new Transaction().add(ix);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Fetch market account data
|
|
225
|
+
*/
|
|
226
|
+
async getMarketAccount(admin, marketId) {
|
|
227
|
+
const marketIdBn = new AnchorBN(marketId);
|
|
228
|
+
const marketPda = getMarketPda(this.program.programId, admin, marketIdBn);
|
|
229
|
+
return await this.program.account.market.fetch(marketPda);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxNQUFNLE1BQU0sbUJBQW1CLENBQUM7QUFDdkMsT0FBTyxFQUNILHVDQUF1QyxFQUN2QyxVQUFVLEVBQ1YsNkJBQTZCLEVBQzdCLGdCQUFnQixHQUNuQixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFFSCxPQUFPLEVBRVAsV0FBVyxFQUVkLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUUvQixPQUFPLEVBQ0gsWUFBWSxFQUNaLGFBQWEsRUFDaEIsTUFBTSxZQUFZLENBQUM7QUFDcEIsTUFBTSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxHQUFHLE1BQU0sQ0FBQztBQUV4RCxjQUFjLFlBQVksQ0FBQztBQUMzQixPQUFPLEVBQVcsR0FBRyxFQUFFLENBQUM7QUF1Q3hCLE1BQU0sT0FBTyxhQUFhO0lBS3hCLFlBQVksVUFBc0IsRUFBRSxNQUFzQjtRQUN4RCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksTUFBTSxDQUFDLGNBQWMsQ0FDdkMsVUFBVSxFQUNWLE1BQU0sSUFBSSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQy9DLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxDQUM1QixDQUFDO1FBQ0YsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLGFBQWEsQ0FBQyxHQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBZ0MsQ0FBQztJQUM3RixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQWM7UUFDNUIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUN2QyxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxvQkFBb0IsQ0FDbEIsS0FBZ0IsRUFDaEIsS0FBZ0IsRUFDaEIsSUFBZTtRQUVmLE1BQU0sR0FBRyxHQUFHLDZCQUE2QixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN2RCxPQUFPLHVDQUF1QyxDQUM1QyxLQUFLLEVBQ0wsR0FBRyxFQUNILEtBQUssRUFDTCxJQUFJLEVBQ0osZ0JBQWdCLENBQ2pCLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQTBCO1FBQzNDLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUU3RSxNQUFNLFVBQVUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQyxNQUFNLFVBQVUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQyxNQUFNLFNBQVMsR0FBRyxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN4QyxNQUFNLFNBQVMsR0FBRyxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUV4QyxNQUFNLElBQUksR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRXRFLE9BQU8sTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU87YUFDOUIsWUFBWSxDQUFDO1lBQ1YsUUFBUSxFQUFFLFVBQVU7WUFDcEIsUUFBUSxFQUFFLFVBQVU7WUFDcEIsT0FBTyxFQUFFLFNBQVM7WUFDbEIsT0FBTyxFQUFFLFNBQVM7U0FDbkIsQ0FBQzthQUNELGVBQWUsQ0FBQztZQUNmLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtZQUNuQixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87WUFDckIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFlBQVksRUFBRSxZQUFZO1lBQzFCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztZQUNqQixLQUFLLEVBQUUsS0FBSztZQUNaLGFBQWEsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTO1NBQ25ELENBQUM7YUFDRCxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsbUJBQW1CLENBQUMsTUFBMEI7UUFDbEQsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzNDLE9BQU8sSUFBSSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFzQjtRQUNuQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsR0FBRyxNQUFNLENBQUM7UUFFeEUsTUFBTSxVQUFVLEdBQUcsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUMsTUFBTSxRQUFRLEdBQUcsSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEMsTUFBTSxXQUFXLEdBQUcsT0FBTyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBR2pFLE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDdEUsTUFBTSxnQkFBZ0IsR0FBRyw2QkFBNkIsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFM0Usc0RBQXNEO1FBQ3RELE1BQU0sVUFBVSxHQUFHLE9BQU8sS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDbEUsTUFBTSxnQkFBZ0IsR0FBRyw2QkFBNkIsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFekUsT0FBTyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTzthQUM5QixRQUFRLENBQUM7WUFDUixVQUFVLEVBQUUsV0FBVztZQUN2QixNQUFNLEVBQUUsUUFBUTtTQUNqQixDQUFDO2FBQ0QsZUFBZSxDQUFDO1lBQ2YsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNyQixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO1lBQ2pCLGdCQUFnQjtZQUNoQixnQkFBZ0I7WUFDaEIsSUFBSTtTQUNMLENBQUM7YUFDRCxXQUFXLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsZUFBZSxDQUFDLE1BQXNCO1FBQzFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsU0FBUyxHQUFHLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUVwRSxNQUFNLEVBQUUsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQzdCLE1BQU0sVUFBVSxHQUFHLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFFdEUsTUFBTSxVQUFVLEdBQUcsT0FBTyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNsRSxNQUFNLGdCQUFnQixHQUFHLDZCQUE2QixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUV6RSwyQ0FBMkM7UUFDM0MsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3RELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDWixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFDdEUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUN0QixDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQyxFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRW5CLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUEwQjtRQUMzQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUV2RSxNQUFNLFVBQVUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQyxNQUFNLElBQUksR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sZ0JBQWdCLEdBQUcsNkJBQTZCLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTNFLE1BQU0sVUFBVSxHQUFHLGNBQWMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDekUsTUFBTSxnQkFBZ0IsR0FBRyw2QkFBNkIsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFekUsT0FBTyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTzthQUM5QixZQUFZLEVBQUU7YUFDZCxlQUFlLENBQUM7WUFDZixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsZ0JBQWdCO1lBQ2hCLGdCQUFnQjtZQUNoQixJQUFJO1NBQ0wsQ0FBQzthQUNELFdBQVcsRUFBRSxDQUFDO0lBQ25CLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxNQUEwQjtRQUNsRCxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0MsT0FBTyxJQUFJLFdBQVcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQW9CO1FBQy9CLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLEdBQUcsTUFBTSxDQUFDO1FBRWhFLE1BQU0sVUFBVSxHQUFHLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sV0FBVyxHQUFHLE9BQU8sS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNqRSxNQUFNLElBQUksR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sZ0JBQWdCLEdBQUcsNkJBQTZCLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTNFLE1BQU0sVUFBVSxHQUFHLE9BQU8sS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDbEUsTUFBTSxnQkFBZ0IsR0FBRyw2QkFBNkIsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFekUsT0FBTyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTzthQUM5QixNQUFNLENBQUMsV0FBVyxDQUFDO2FBQ25CLGVBQWUsQ0FBQztZQUNmLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtZQUNuQixnQkFBZ0I7WUFDaEIsZ0JBQWdCO1lBQ2hCLElBQUk7U0FDTCxDQUFDO2FBQ0QsV0FBVyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLGFBQWEsQ0FBQyxNQUFvQjtRQUN0QyxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckMsT0FBTyxJQUFJLFdBQVcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsYUFBYSxDQUNqQixLQUFnQixFQUNoQixRQUFxQixFQUNyQixjQUFtQztRQUVuQyxNQUFNLFVBQVUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQyxNQUFNLFNBQVMsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRTFFLElBQUksV0FBVyxHQUFRLElBQUksQ0FBQztRQUM1QixJQUFJLGNBQWMsS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUM3QixXQUFXLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDNUIsQ0FBQzthQUFNLElBQUksY0FBYyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ25DLFdBQVcsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUMzQixDQUFDO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTzthQUM5QixhQUFhLENBQUMsV0FBVyxDQUFDO2FBQzFCLGVBQWUsQ0FBQztZQUNmLE1BQU0sRUFBRSxTQUFTO1lBQ2pCLEtBQUs7U0FDTixDQUFDO2FBQ0QsV0FBVyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLG9CQUFvQixDQUN4QixLQUFnQixFQUNoQixRQUFxQixFQUNyQixjQUFtQztRQUVuQyxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxjQUFjLENBQUMsQ0FBQztRQUNyRSxPQUFPLElBQUksV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxXQUFXLENBQ2YsS0FBZ0IsRUFDaEIsUUFBcUI7UUFFckIsTUFBTSxVQUFVLEdBQUcsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUMsTUFBTSxTQUFTLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztRQUUxRSxPQUFPLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPO2FBQzlCLFdBQVcsRUFBRTthQUNiLGVBQWUsQ0FBQztZQUNmLE1BQU0sRUFBRSxTQUFTO1NBQ2xCLENBQUM7YUFDRCxXQUFXLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsa0JBQWtCLENBQ3RCLEtBQWdCLEVBQ2hCLFFBQXFCO1FBRXJCLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDbkQsT0FBTyxJQUFJLFdBQVcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsS0FBZ0IsRUFBRSxRQUFxQjtRQUM1RCxNQUFNLFVBQVUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQyxNQUFNLFNBQVMsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzFFLE9BQU8sTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzVELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQk4sIElkbCwgUHJvZ3JhbSB9IGZyb20gXCJAY29yYWwteHl6L2FuY2hvclwiO1xuaW1wb3J0IGFuY2hvciBmcm9tIFwiQGNvcmFsLXh5ei9hbmNob3JcIjtcbmltcG9ydCB7XG4gICAgY3JlYXRlQXNzb2NpYXRlZFRva2VuQWNjb3VudEluc3RydWN0aW9uLFxuICAgIGdldEFjY291bnQsXG4gICAgZ2V0QXNzb2NpYXRlZFRva2VuQWRkcmVzc1N5bmMsXG4gICAgVE9LRU5fUFJPR1JBTV9JRCxcbn0gZnJvbSBcIkBzb2xhbmEvc3BsLXRva2VuXCI7XG5pbXBvcnQge1xuICAgIENvbm5lY3Rpb24sXG4gICAgS2V5cGFpcixcbiAgICBQdWJsaWNLZXksXG4gICAgVHJhbnNhY3Rpb24sXG4gICAgVHJhbnNhY3Rpb25JbnN0cnVjdGlvblxufSBmcm9tIFwiQHNvbGFuYS93ZWIzLmpzXCI7XG5pbXBvcnQgeyBJREwgfSBmcm9tIFwiLi9pZGwuanNcIjtcbmltcG9ydCB7IERyYW1hUG0gfSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuaW1wb3J0IHtcbiAgICBnZXRNYXJrZXRQZGEsXG4gICAgZ2V0TWFya2V0UGRhc1xufSBmcm9tIFwiLi91dGlscy5qc1wiO1xuY29uc3QgeyBCTjogQW5jaG9yQk4sIFByb2dyYW06IEFuY2hvclByb2dyYW0gfSA9IGFuY2hvcjtcblxuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHMuanNcIjtcbmV4cG9ydCB7IERyYW1hUG0sIElETCB9O1xuXG5leHBvcnQgdHlwZSBPdXRjb21lID0gXCJZZXNcIiB8IFwiTm9cIjtcblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVNYXJrZXRQYXJhbXMge1xuICBhZG1pbjogUHVibGljS2V5O1xuICBtYXJrZXRJZDogbnVtYmVyIHwgQk47XG4gIHllc1ByaWNlOiBudW1iZXIgfCBCTjtcbiAgbm9QcmljZTogbnVtYmVyIHwgQk47XG4gIGVuZFRpbWU6IG51bWJlciB8IEJOO1xuICBiZXR0aW5nVG9rZW46IFB1YmxpY0tleTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQbGFjZUJldFBhcmFtcyB7XG4gIHVzZXI6IFB1YmxpY0tleTtcbiAgYWRtaW46IFB1YmxpY0tleTtcbiAgbWFya2V0SWQ6IG51bWJlciB8IEJOO1xuICBhbW91bnQ6IG51bWJlciB8IEJOO1xuICBvdXRjb21lOiBPdXRjb21lO1xuICBiZXR0aW5nVG9rZW46IFB1YmxpY0tleTtcbiAgY3JlYXRlQXRhPzogYm9vbGVhbjsgLy8gV2hldGhlciB0byBjcmVhdGUgQVRBIGluc3RydWN0aW9uIGF1dG9tYXRpY2FsbHlcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDbGFpbVJld2FyZHNQYXJhbXMge1xuICB1c2VyOiBQdWJsaWNLZXk7XG4gIGFkbWluOiBQdWJsaWNLZXk7XG4gIG1hcmtldElkOiBudW1iZXIgfCBCTjtcbiAgYmV0dGluZ1Rva2VuOiBQdWJsaWNLZXk7XG4gIHdpbm5pbmdPdXRjb21lOiBPdXRjb21lO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlZnVuZFBhcmFtcyB7XG4gIHVzZXI6IFB1YmxpY0tleTtcbiAgYWRtaW46IFB1YmxpY0tleTtcbiAgbWFya2V0SWQ6IG51bWJlciB8IEJOO1xuICBiZXR0aW5nVG9rZW46IFB1YmxpY0tleTtcbiAgb3V0Y29tZTogT3V0Y29tZTtcbn1cblxuZXhwb3J0IGNsYXNzIERyYW1hUG1DbGllbnQge1xuICBwcm9ncmFtOiBQcm9ncmFtPERyYW1hUG0+O1xuICBwcm92aWRlcjogYW5jaG9yLkFuY2hvclByb3ZpZGVyO1xuICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHdhbGxldD86IGFuY2hvci5XYWxsZXQpIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgIHRoaXMucHJvdmlkZXIgPSBuZXcgYW5jaG9yLkFuY2hvclByb3ZpZGVyKFxuICAgICAgY29ubmVjdGlvbixcbiAgICAgIHdhbGxldCB8fCBuZXcgYW5jaG9yLldhbGxldChLZXlwYWlyLmdlbmVyYXRlKCkpLFxuICAgICAgeyBjb21taXRtZW50OiBcImNvbmZpcm1lZFwiIH1cbiAgICApO1xuICAgIHRoaXMucHJvZ3JhbSA9IG5ldyBBbmNob3JQcm9ncmFtKElETCBhcyBJZGwsIHRoaXMucHJvdmlkZXIpIGFzIHVua25vd24gYXMgUHJvZ3JhbTxEcmFtYVBtPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhbiBhc3NvY2lhdGVkIHRva2VuIGFjY291bnQgZXhpc3RzXG4gICAqL1xuICBhc3luYyBhdGFFeGlzdHMoYXRhOiBQdWJsaWNLZXkpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZ2V0QWNjb3VudCh0aGlzLmNvbm5lY3Rpb24sIGF0YSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIGluc3RydWN0aW9uIHRvIGluaXRpYWxpemUgYW4gYXNzb2NpYXRlZCB0b2tlbiBhY2NvdW50XG4gICAqL1xuICBjcmVhdGVBdGFJbnN0cnVjdGlvbihcbiAgICBwYXllcjogUHVibGljS2V5LFxuICAgIG93bmVyOiBQdWJsaWNLZXksXG4gICAgbWludDogUHVibGljS2V5XG4gICk6IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb24ge1xuICAgIGNvbnN0IGF0YSA9IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKG1pbnQsIG93bmVyKTtcbiAgICByZXR1cm4gY3JlYXRlQXNzb2NpYXRlZFRva2VuQWNjb3VudEluc3RydWN0aW9uKFxuICAgICAgcGF5ZXIsXG4gICAgICBhdGEsXG4gICAgICBvd25lcixcbiAgICAgIG1pbnQsXG4gICAgICBUT0tFTl9QUk9HUkFNX0lEXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgcHJlZGljdGlvbiBtYXJrZXQgaW5zdHJ1Y3Rpb25cbiAgICovXG4gIGFzeW5jIGNyZWF0ZU1hcmtldChwYXJhbXM6IENyZWF0ZU1hcmtldFBhcmFtcyk6IFByb21pc2U8VHJhbnNhY3Rpb25JbnN0cnVjdGlvbj4ge1xuICAgIGNvbnN0IHsgYWRtaW4sIG1hcmtldElkLCB5ZXNQcmljZSwgbm9QcmljZSwgZW5kVGltZSwgYmV0dGluZ1Rva2VuIH0gPSBwYXJhbXM7XG4gICAgXG4gICAgY29uc3QgbWFya2V0SWRCbiA9IG5ldyBBbmNob3JCTihtYXJrZXRJZCk7XG4gICAgY29uc3QgeWVzUHJpY2VCbiA9IG5ldyBBbmNob3JCTih5ZXNQcmljZSk7XG4gICAgY29uc3Qgbm9QcmljZUJuID0gbmV3IEFuY2hvckJOKG5vUHJpY2UpO1xuICAgIGNvbnN0IGVuZFRpbWVCbiA9IG5ldyBBbmNob3JCTihlbmRUaW1lKTtcblxuICAgIGNvbnN0IHBkYXMgPSBnZXRNYXJrZXRQZGFzKHRoaXMucHJvZ3JhbS5wcm9ncmFtSWQsIGFkbWluLCBtYXJrZXRJZEJuKTtcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnByb2dyYW0ubWV0aG9kc1xuICAgICAgLmNyZWF0ZU1hcmtldCh7XG4gICAgICAgICAgbWFya2V0SWQ6IG1hcmtldElkQm4sXG4gICAgICAgICAgeWVzUHJpY2U6IHllc1ByaWNlQm4sXG4gICAgICAgICAgbm9QcmljZTogbm9QcmljZUJuLFxuICAgICAgICAgIGVuZFRpbWU6IGVuZFRpbWVCbixcbiAgICAgICAgfSlcbiAgICAgICAgLmFjY291bnRzUGFydGlhbCh7XG4gICAgICAgICAgbWFya2V0OiBwZGFzLm1hcmtldCxcbiAgICAgICAgICB5ZXNNaW50OiBwZGFzLnllc01pbnQsXG4gICAgICAgICAgbm9NaW50OiBwZGFzLm5vTWludCxcbiAgICAgICAgICBiZXR0aW5nVG9rZW46IGJldHRpbmdUb2tlbixcbiAgICAgICAgICB2YXVsdDogcGRhcy52YXVsdCxcbiAgICAgICAgICBhZG1pbjogYWRtaW4sXG4gICAgICAgICAgc3lzdGVtUHJvZ3JhbTogYW5jaG9yLndlYjMuU3lzdGVtUHJvZ3JhbS5wcm9ncmFtSWQsXG4gICAgICAgIH0pXG4gICAgICAgIC5pbnN0cnVjdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGEgY29tcGxldGUgdHJhbnNhY3Rpb24gdG8gY3JlYXRlIGEgbWFya2V0XG4gICAqL1xuICBhc3luYyBidWlsZENyZWF0ZU1hcmtldFR4KHBhcmFtczogQ3JlYXRlTWFya2V0UGFyYW1zKTogUHJvbWlzZTxUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IGl4ID0gYXdhaXQgdGhpcy5jcmVhdGVNYXJrZXQocGFyYW1zKTtcbiAgICByZXR1cm4gbmV3IFRyYW5zYWN0aW9uKCkuYWRkKGl4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQbGFjZSBhIGJldCBpbnN0cnVjdGlvbiAod2l0aG91dCBBVEEgY3JlYXRpb24pXG4gICAqL1xuICBhc3luYyBwbGFjZUJldChwYXJhbXM6IFBsYWNlQmV0UGFyYW1zKTogUHJvbWlzZTxUcmFuc2FjdGlvbkluc3RydWN0aW9uPiB7XG4gICAgY29uc3QgeyB1c2VyLCBhZG1pbiwgbWFya2V0SWQsIGFtb3VudCwgb3V0Y29tZSwgYmV0dGluZ1Rva2VuIH0gPSBwYXJhbXM7XG4gICAgXG4gICAgY29uc3QgbWFya2V0SWRCbiA9IG5ldyBBbmNob3JCTihtYXJrZXRJZCk7XG4gICAgY29uc3QgYW1vdW50Qm4gPSBuZXcgQW5jaG9yQk4oYW1vdW50KTtcbiAgICBjb25zdCBvdXRjb21lRW51bSA9IG91dGNvbWUgPT09IFwiWWVzXCIgPyB7IHllczoge30gfSA6IHsgbm86IHt9IH07XG5cblxuICAgIGNvbnN0IHBkYXMgPSBnZXRNYXJrZXRQZGFzKHRoaXMucHJvZ3JhbS5wcm9ncmFtSWQsIGFkbWluLCBtYXJrZXRJZEJuKTtcbiAgICBjb25zdCB1c2VyQmV0dGluZ1Rva2VuID0gZ2V0QXNzb2NpYXRlZFRva2VuQWRkcmVzc1N5bmMoYmV0dGluZ1Rva2VuLCB1c2VyKTtcbiAgICBcbiAgICAvLyBEZXRlcm1pbmUgd2hpY2ggb3V0Y29tZSB0b2tlbiB0aGUgdXNlciB3aWxsIHJlY2VpdmVcbiAgICBjb25zdCB0YXJnZXRNaW50ID0gb3V0Y29tZSA9PT0gXCJZZXNcIiA/IHBkYXMueWVzTWludCA6IHBkYXMubm9NaW50O1xuICAgIGNvbnN0IHVzZXJPdXRjb21lVG9rZW4gPSBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyh0YXJnZXRNaW50LCB1c2VyKTtcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnByb2dyYW0ubWV0aG9kc1xuICAgICAgLnBsYWNlQmV0KHtcbiAgICAgICAgYnV5T3V0Y29tZTogb3V0Y29tZUVudW0sXG4gICAgICAgIGFtb3VudDogYW1vdW50Qm4sXG4gICAgICB9KVxuICAgICAgLmFjY291bnRzUGFydGlhbCh7XG4gICAgICAgIG1hcmtldDogcGRhcy5tYXJrZXQsXG4gICAgICAgIHllc01pbnQ6IHBkYXMueWVzTWludCxcbiAgICAgICAgbm9NaW50OiBwZGFzLm5vTWludCxcbiAgICAgICAgdmF1bHQ6IHBkYXMudmF1bHQsXG4gICAgICAgIHVzZXJPdXRjb21lVG9rZW4sXG4gICAgICAgIHVzZXJCZXR0aW5nVG9rZW4sXG4gICAgICAgIHVzZXIsXG4gICAgICB9KVxuICAgICAgLmluc3RydWN0aW9uKCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBjb21wbGV0ZSB0cmFuc2FjdGlvbiB0byBwbGFjZSBhIGJldCAod2l0aCBvcHRpb25hbCBBVEEgY3JlYXRpb24pXG4gICAqL1xuICBhc3luYyBidWlsZFBsYWNlQmV0VHgocGFyYW1zOiBQbGFjZUJldFBhcmFtcyk6IFByb21pc2U8VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCB7IHVzZXIsIGFkbWluLCBtYXJrZXRJZCwgb3V0Y29tZSwgY3JlYXRlQXRhID0gdHJ1ZSB9ID0gcGFyYW1zO1xuICAgIFxuICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zYWN0aW9uKCk7XG4gICAgY29uc3QgbWFya2V0SWRCbiA9IG5ldyBBbmNob3JCTihtYXJrZXRJZCk7XG4gICAgY29uc3QgcGRhcyA9IGdldE1hcmtldFBkYXModGhpcy5wcm9ncmFtLnByb2dyYW1JZCwgYWRtaW4sIG1hcmtldElkQm4pO1xuICAgIFxuICAgIGNvbnN0IHRhcmdldE1pbnQgPSBvdXRjb21lID09PSBcIlllc1wiID8gcGRhcy55ZXNNaW50IDogcGRhcy5ub01pbnQ7XG4gICAgY29uc3QgdXNlck91dGNvbWVUb2tlbiA9IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHRhcmdldE1pbnQsIHVzZXIpO1xuXG4gICAgLy8gQ2hlY2sgaWYgQVRBIGV4aXN0cyBhbmQgY3JlYXRlIGlmIG5lZWRlZFxuICAgIGlmIChjcmVhdGVBdGEpIHtcbiAgICAgIGNvbnN0IGV4aXN0cyA9IGF3YWl0IHRoaXMuYXRhRXhpc3RzKHVzZXJPdXRjb21lVG9rZW4pO1xuICAgICAgaWYgKCFleGlzdHMpIHtcbiAgICAgICAgY29uc3QgY3JlYXRlQXRhSXggPSB0aGlzLmNyZWF0ZUF0YUluc3RydWN0aW9uKHVzZXIsIHVzZXIsIHRhcmdldE1pbnQpO1xuICAgICAgICB0eC5hZGQoY3JlYXRlQXRhSXgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHBsYWNlQmV0SXggPSBhd2FpdCB0aGlzLnBsYWNlQmV0KHBhcmFtcyk7XG4gICAgdHguYWRkKHBsYWNlQmV0SXgpO1xuXG4gICAgcmV0dXJuIHR4O1xuICB9XG5cbiAgLyoqXG4gICAqIENsYWltIHJld2FyZHMgYWZ0ZXIgbWFya2V0IHJlc29sdXRpb25cbiAgICovXG4gIGFzeW5jIGNsYWltUmV3YXJkcyhwYXJhbXM6IENsYWltUmV3YXJkc1BhcmFtcyk6IFByb21pc2U8VHJhbnNhY3Rpb25JbnN0cnVjdGlvbj4ge1xuICAgIGNvbnN0IHsgdXNlciwgYWRtaW4sIG1hcmtldElkLCBiZXR0aW5nVG9rZW4sIHdpbm5pbmdPdXRjb21lIH0gPSBwYXJhbXM7XG4gICAgXG4gICAgY29uc3QgbWFya2V0SWRCbiA9IG5ldyBBbmNob3JCTihtYXJrZXRJZCk7XG4gICAgY29uc3QgcGRhcyA9IGdldE1hcmtldFBkYXModGhpcy5wcm9ncmFtLnByb2dyYW1JZCwgYWRtaW4sIG1hcmtldElkQm4pO1xuICAgIGNvbnN0IHVzZXJCZXR0aW5nVG9rZW4gPSBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyhiZXR0aW5nVG9rZW4sIHVzZXIpO1xuICAgIFxuICAgIGNvbnN0IHRhcmdldE1pbnQgPSB3aW5uaW5nT3V0Y29tZSA9PT0gXCJZZXNcIiA/IHBkYXMueWVzTWludCA6IHBkYXMubm9NaW50O1xuICAgIGNvbnN0IHVzZXJPdXRjb21lVG9rZW4gPSBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyh0YXJnZXRNaW50LCB1c2VyKTtcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnByb2dyYW0ubWV0aG9kc1xuICAgICAgLmNsYWltUmV3YXJkcygpXG4gICAgICAuYWNjb3VudHNQYXJ0aWFsKHtcbiAgICAgICAgbWFya2V0OiBwZGFzLm1hcmtldCxcbiAgICAgICAgdXNlck91dGNvbWVUb2tlbixcbiAgICAgICAgdXNlckJldHRpbmdUb2tlbixcbiAgICAgICAgdXNlcixcbiAgICAgIH0pXG4gICAgICAuaW5zdHJ1Y3Rpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhIGNvbXBsZXRlIHRyYW5zYWN0aW9uIHRvIGNsYWltIHJld2FyZHNcbiAgICovXG4gIGFzeW5jIGJ1aWxkQ2xhaW1SZXdhcmRzVHgocGFyYW1zOiBDbGFpbVJld2FyZHNQYXJhbXMpOiBQcm9taXNlPFRyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgaXggPSBhd2FpdCB0aGlzLmNsYWltUmV3YXJkcyhwYXJhbXMpO1xuICAgIHJldHVybiBuZXcgVHJhbnNhY3Rpb24oKS5hZGQoaXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZnVuZCBiZXRzIGlmIG1hcmtldCBpcyByZWZ1bmRlZFxuICAgKi9cbiAgYXN5bmMgcmVmdW5kKHBhcmFtczogUmVmdW5kUGFyYW1zKTogUHJvbWlzZTxUcmFuc2FjdGlvbkluc3RydWN0aW9uPiB7XG4gICAgY29uc3QgeyB1c2VyLCBhZG1pbiwgbWFya2V0SWQsIGJldHRpbmdUb2tlbiwgb3V0Y29tZSB9ID0gcGFyYW1zO1xuICAgIFxuICAgIGNvbnN0IG1hcmtldElkQm4gPSBuZXcgQW5jaG9yQk4obWFya2V0SWQpO1xuICAgIGNvbnN0IG91dGNvbWVFbnVtID0gb3V0Y29tZSA9PT0gXCJZZXNcIiA/IHsgeWVzOiB7fSB9IDogeyBubzoge30gfTtcbiAgICBjb25zdCBwZGFzID0gZ2V0TWFya2V0UGRhcyh0aGlzLnByb2dyYW0ucHJvZ3JhbUlkLCBhZG1pbiwgbWFya2V0SWRCbik7XG4gICAgY29uc3QgdXNlckJldHRpbmdUb2tlbiA9IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKGJldHRpbmdUb2tlbiwgdXNlcik7XG4gICAgXG4gICAgY29uc3QgdGFyZ2V0TWludCA9IG91dGNvbWUgPT09IFwiWWVzXCIgPyBwZGFzLnllc01pbnQgOiBwZGFzLm5vTWludDtcbiAgICBjb25zdCB1c2VyT3V0Y29tZVRva2VuID0gZ2V0QXNzb2NpYXRlZFRva2VuQWRkcmVzc1N5bmModGFyZ2V0TWludCwgdXNlcik7XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wcm9ncmFtLm1ldGhvZHNcbiAgICAgIC5yZWZ1bmQob3V0Y29tZUVudW0pXG4gICAgICAuYWNjb3VudHNQYXJ0aWFsKHtcbiAgICAgICAgbWFya2V0OiBwZGFzLm1hcmtldCxcbiAgICAgICAgdXNlck91dGNvbWVUb2tlbixcbiAgICAgICAgdXNlckJldHRpbmdUb2tlbixcbiAgICAgICAgdXNlcixcbiAgICAgIH0pXG4gICAgICAuaW5zdHJ1Y3Rpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhIGNvbXBsZXRlIHRyYW5zYWN0aW9uIHRvIHJlZnVuZFxuICAgKi9cbiAgYXN5bmMgYnVpbGRSZWZ1bmRUeChwYXJhbXM6IFJlZnVuZFBhcmFtcyk6IFByb21pc2U8VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpeCA9IGF3YWl0IHRoaXMucmVmdW5kKHBhcmFtcyk7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbigpLmFkZChpeCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSBhIG1hcmtldCAoQWRtaW4gb25seSlcbiAgICovXG4gIGFzeW5jIHJlc29sdmVNYXJrZXQoXG4gICAgYWRtaW46IFB1YmxpY0tleSxcbiAgICBtYXJrZXRJZDogbnVtYmVyIHwgQk4sXG4gICAgd2lubmluZ091dGNvbWU6IFwiWWVzXCIgfCBcIk5vXCIgfCBudWxsXG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb25JbnN0cnVjdGlvbj4ge1xuICAgIGNvbnN0IG1hcmtldElkQm4gPSBuZXcgQW5jaG9yQk4obWFya2V0SWQpO1xuICAgIGNvbnN0IG1hcmtldFBkYSA9IGdldE1hcmtldFBkYSh0aGlzLnByb2dyYW0ucHJvZ3JhbUlkLCBhZG1pbiwgbWFya2V0SWRCbik7XG5cbiAgICBsZXQgb3V0Y29tZUVudW06IGFueSA9IG51bGw7XG4gICAgaWYgKHdpbm5pbmdPdXRjb21lID09PSBcIlllc1wiKSB7XG4gICAgICBvdXRjb21lRW51bSA9IHsgeWVzOiB7fSB9O1xuICAgIH0gZWxzZSBpZiAod2lubmluZ091dGNvbWUgPT09IFwiTm9cIikge1xuICAgICAgb3V0Y29tZUVudW0gPSB7IG5vOiB7fSB9O1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnByb2dyYW0ubWV0aG9kc1xuICAgICAgLnJlc29sdmVNYXJrZXQob3V0Y29tZUVudW0pXG4gICAgICAuYWNjb3VudHNQYXJ0aWFsKHtcbiAgICAgICAgbWFya2V0OiBtYXJrZXRQZGEsXG4gICAgICAgIGFkbWluLFxuICAgICAgfSlcbiAgICAgIC5pbnN0cnVjdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGEgY29tcGxldGUgdHJhbnNhY3Rpb24gdG8gcmVzb2x2ZSBhIG1hcmtldFxuICAgKi9cbiAgYXN5bmMgYnVpbGRSZXNvbHZlTWFya2V0VHgoXG4gICAgYWRtaW46IFB1YmxpY0tleSxcbiAgICBtYXJrZXRJZDogbnVtYmVyIHwgQk4sXG4gICAgd2lubmluZ091dGNvbWU6IFwiWWVzXCIgfCBcIk5vXCIgfCBudWxsXG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpeCA9IGF3YWl0IHRoaXMucmVzb2x2ZU1hcmtldChhZG1pbiwgbWFya2V0SWQsIHdpbm5pbmdPdXRjb21lKTtcbiAgICByZXR1cm4gbmV3IFRyYW5zYWN0aW9uKCkuYWRkKGl4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSBhIG1hcmtldCAoQWRtaW4gb25seSlcbiAgICovXG4gIGFzeW5jIGNsb3NlTWFya2V0KFxuICAgIGFkbWluOiBQdWJsaWNLZXksXG4gICAgbWFya2V0SWQ6IG51bWJlciB8IEJOXG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb25JbnN0cnVjdGlvbj4ge1xuICAgIGNvbnN0IG1hcmtldElkQm4gPSBuZXcgQW5jaG9yQk4obWFya2V0SWQpO1xuICAgIGNvbnN0IG1hcmtldFBkYSA9IGdldE1hcmtldFBkYSh0aGlzLnByb2dyYW0ucHJvZ3JhbUlkLCBhZG1pbiwgbWFya2V0SWRCbik7XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wcm9ncmFtLm1ldGhvZHNcbiAgICAgIC5jbG9zZU1hcmtldCgpXG4gICAgICAuYWNjb3VudHNQYXJ0aWFsKHtcbiAgICAgICAgbWFya2V0OiBtYXJrZXRQZGEsXG4gICAgICB9KVxuICAgICAgLmluc3RydWN0aW9uKCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBjb21wbGV0ZSB0cmFuc2FjdGlvbiB0byBjbG9zZSBhIG1hcmtldFxuICAgKi9cbiAgYXN5bmMgYnVpbGRDbG9zZU1hcmtldFR4KFxuICAgIGFkbWluOiBQdWJsaWNLZXksXG4gICAgbWFya2V0SWQ6IG51bWJlciB8IEJOXG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpeCA9IGF3YWl0IHRoaXMuY2xvc2VNYXJrZXQoYWRtaW4sIG1hcmtldElkKTtcbiAgICByZXR1cm4gbmV3IFRyYW5zYWN0aW9uKCkuYWRkKGl4KTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEZldGNoIG1hcmtldCBhY2NvdW50IGRhdGFcbiAgICovXG4gIGFzeW5jIGdldE1hcmtldEFjY291bnQoYWRtaW46IFB1YmxpY0tleSwgbWFya2V0SWQ6IG51bWJlciB8IEJOKSB7XG4gICAgY29uc3QgbWFya2V0SWRCbiA9IG5ldyBBbmNob3JCTihtYXJrZXRJZCk7XG4gICAgY29uc3QgbWFya2V0UGRhID0gZ2V0TWFya2V0UGRhKHRoaXMucHJvZ3JhbS5wcm9ncmFtSWQsIGFkbWluLCBtYXJrZXRJZEJuKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wcm9ncmFtLmFjY291bnQubWFya2V0LmZldGNoKG1hcmtldFBkYSk7XG4gIH1cbn1cbiJdfQ==
|