@ethlete/cdk 4.45.0 → 4.46.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/CHANGELOG.md +6 -0
- package/esm2022/lib/components/bracket/components/new-bracket/bracket-new.mjs +782 -0
- package/esm2022/lib/components/bracket/components/new-bracket/draw-man.mjs +66 -0
- package/esm2022/lib/components/bracket/components/new-bracket/grid-definitions.mjs +47 -0
- package/esm2022/lib/components/bracket/components/new-bracket/grid-placements.mjs +97 -0
- package/esm2022/lib/components/bracket/components/new-bracket/index.mjs +8 -0
- package/esm2022/lib/components/bracket/components/new-bracket/new-bracket-default-match.component.mjs +17 -0
- package/esm2022/lib/components/bracket/components/new-bracket/new-bracket-default-round-header.component.mjs +16 -0
- package/esm2022/lib/components/bracket/components/new-bracket/new-bracket.component.mjs +54 -0
- package/esm2022/lib/components/bracket/public-api/index.mjs +2 -1
- package/fesm2022/ethlete-cdk.mjs +1096 -3
- package/fesm2022/ethlete-cdk.mjs.map +1 -1
- package/lib/components/bracket/components/new-bracket/bracket-new.d.ts +238 -0
- package/lib/components/bracket/components/new-bracket/draw-man.d.ts +12 -0
- package/lib/components/bracket/components/new-bracket/grid-definitions.d.ts +9 -0
- package/lib/components/bracket/components/new-bracket/grid-placements.d.ts +56 -0
- package/lib/components/bracket/components/new-bracket/index.d.ts +7 -0
- package/lib/components/bracket/components/new-bracket/new-bracket-default-match.component.d.ts +8 -0
- package/lib/components/bracket/components/new-bracket/new-bracket-default-round-header.component.d.ts +7 -0
- package/lib/components/bracket/components/new-bracket/new-bracket.component.d.ts +26 -0
- package/lib/components/bracket/public-api/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,782 @@
|
|
|
1
|
+
export const FALLBACK_MATCH_POSITION = -1;
|
|
2
|
+
export const TOURNAMENT_MODE = {
|
|
3
|
+
SINGLE_ELIMINATION: 'single-elimination',
|
|
4
|
+
DOUBLE_ELIMINATION: 'double-elimination',
|
|
5
|
+
GROUP: 'group',
|
|
6
|
+
SWISS: 'swiss',
|
|
7
|
+
SWISS_WITH_ELIMINATION: 'swiss-with-elimination',
|
|
8
|
+
};
|
|
9
|
+
export const COMMON_BRACKET_ROUND_TYPE = {
|
|
10
|
+
THIRD_PLACE: 'third-place',
|
|
11
|
+
FINAL: 'final',
|
|
12
|
+
};
|
|
13
|
+
export const SINGLE_ELIMINATION_BRACKET_ROUND_TYPE = {
|
|
14
|
+
SINGLE_ELIMINATION_BRACKET: 'single-elimination-bracket',
|
|
15
|
+
};
|
|
16
|
+
export const DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE = {
|
|
17
|
+
UPPER_BRACKET: 'upper-bracket',
|
|
18
|
+
LOWER_BRACKET: 'lower-bracket',
|
|
19
|
+
REVERSE_FINAL: 'reverse-final',
|
|
20
|
+
};
|
|
21
|
+
export const SWISS_BRACKET_ROUND_TYPE = {
|
|
22
|
+
SWISS: 'swiss',
|
|
23
|
+
};
|
|
24
|
+
export const GROUP_BRACKET_ROUND_TYPE = {
|
|
25
|
+
GROUP: 'group',
|
|
26
|
+
};
|
|
27
|
+
export const generateRoundTypeFromEthleteRoundType = (type, tournamentMode) => {
|
|
28
|
+
switch (type) {
|
|
29
|
+
case 'normal':
|
|
30
|
+
switch (tournamentMode) {
|
|
31
|
+
case 'single-elimination':
|
|
32
|
+
return SINGLE_ELIMINATION_BRACKET_ROUND_TYPE.SINGLE_ELIMINATION_BRACKET;
|
|
33
|
+
case 'group':
|
|
34
|
+
return GROUP_BRACKET_ROUND_TYPE.GROUP;
|
|
35
|
+
case 'swiss':
|
|
36
|
+
return SWISS_BRACKET_ROUND_TYPE.SWISS;
|
|
37
|
+
default:
|
|
38
|
+
throw new Error(`Unsupported tournament mode for a normal type round: ${tournamentMode}`);
|
|
39
|
+
}
|
|
40
|
+
case 'third_place':
|
|
41
|
+
return COMMON_BRACKET_ROUND_TYPE.THIRD_PLACE;
|
|
42
|
+
case 'final':
|
|
43
|
+
return COMMON_BRACKET_ROUND_TYPE.FINAL;
|
|
44
|
+
case 'reverse_final':
|
|
45
|
+
return DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.REVERSE_FINAL;
|
|
46
|
+
case 'winner_bracket':
|
|
47
|
+
return DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.UPPER_BRACKET;
|
|
48
|
+
case 'loser_bracket':
|
|
49
|
+
return DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.LOWER_BRACKET;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
export const generateTournamentModeFormEthleteRounds = (source) => {
|
|
53
|
+
const firstRound = source[0];
|
|
54
|
+
const firstMatch = firstRound?.matches[0];
|
|
55
|
+
if (!firstRound)
|
|
56
|
+
throw new Error('No rounds found');
|
|
57
|
+
if (!firstMatch)
|
|
58
|
+
throw new Error('No matches found');
|
|
59
|
+
switch (firstMatch.matchType) {
|
|
60
|
+
case 'groups':
|
|
61
|
+
return TOURNAMENT_MODE.GROUP;
|
|
62
|
+
case 'fifa_swiss': {
|
|
63
|
+
const lastRound = source[source.length - 1];
|
|
64
|
+
if (!lastRound)
|
|
65
|
+
throw new Error('No last round found');
|
|
66
|
+
if (lastRound.matches.length !== firstRound.matches.length) {
|
|
67
|
+
return TOURNAMENT_MODE.SWISS_WITH_ELIMINATION;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return TOURNAMENT_MODE.SWISS;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
case 'double_elimination':
|
|
74
|
+
return TOURNAMENT_MODE.DOUBLE_ELIMINATION;
|
|
75
|
+
case 'single_elimination':
|
|
76
|
+
return TOURNAMENT_MODE.SINGLE_ELIMINATION;
|
|
77
|
+
default:
|
|
78
|
+
throw new Error(`Unsupported tournament mode: ${firstMatch.matchType}`);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
export const generateBracketDataForEthlete = (source) => {
|
|
82
|
+
const tournamentMode = generateTournamentModeFormEthleteRounds(source);
|
|
83
|
+
const bracketData = {
|
|
84
|
+
rounds: new Map(),
|
|
85
|
+
matches: new Map(),
|
|
86
|
+
participants: new Map(),
|
|
87
|
+
mode: tournamentMode,
|
|
88
|
+
};
|
|
89
|
+
let currentUpperBracketIndex = 0;
|
|
90
|
+
let currentLowerBracketIndex = 0;
|
|
91
|
+
for (const currentItem of source) {
|
|
92
|
+
if (bracketData.rounds.has(currentItem.round.id)) {
|
|
93
|
+
throw new Error(`Round with id ${currentItem.round.id} already exists in the bracket data.`);
|
|
94
|
+
}
|
|
95
|
+
const roundType = generateRoundTypeFromEthleteRoundType(currentItem.round.type, tournamentMode);
|
|
96
|
+
const isLowerBracket = roundType === DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.LOWER_BRACKET;
|
|
97
|
+
const bracketRound = {
|
|
98
|
+
type: roundType,
|
|
99
|
+
id: currentItem.round.id,
|
|
100
|
+
index: isLowerBracket ? currentLowerBracketIndex : currentUpperBracketIndex,
|
|
101
|
+
data: currentItem.round,
|
|
102
|
+
position: currentItem.round.number,
|
|
103
|
+
name: currentItem.round.name || currentItem.round.type,
|
|
104
|
+
matchCount: currentItem.matches.length,
|
|
105
|
+
matches: new Map(),
|
|
106
|
+
};
|
|
107
|
+
bracketData.rounds.set(currentItem.round.id, bracketRound);
|
|
108
|
+
for (const [matchIndex, match] of currentItem.matches.entries()) {
|
|
109
|
+
if (bracketData.matches.has(match.id)) {
|
|
110
|
+
throw new Error(`Match with id ${match.id} already exists in the bracket data.`);
|
|
111
|
+
}
|
|
112
|
+
const bracketMatch = {
|
|
113
|
+
id: match.id,
|
|
114
|
+
indexInRound: matchIndex,
|
|
115
|
+
position: (matchIndex + 1),
|
|
116
|
+
data: match,
|
|
117
|
+
round: bracketRound,
|
|
118
|
+
home: match.home?.id || null,
|
|
119
|
+
away: match.away?.id || null,
|
|
120
|
+
winner: match.winningSide,
|
|
121
|
+
status: match.status === 'published' ? 'completed' : 'pending',
|
|
122
|
+
};
|
|
123
|
+
bracketData.matches.set(match.id, bracketMatch);
|
|
124
|
+
bracketRound.matches.set(match.id, bracketMatch);
|
|
125
|
+
const participants = [match.home, match.away];
|
|
126
|
+
for (const participant of participants) {
|
|
127
|
+
if (!participant)
|
|
128
|
+
continue;
|
|
129
|
+
const participantId = participant.id;
|
|
130
|
+
if (!bracketData.participants.has(participantId)) {
|
|
131
|
+
bracketData.participants.set(participantId, {
|
|
132
|
+
id: participantId,
|
|
133
|
+
name: participant.name || 'Unknown',
|
|
134
|
+
matches: new Map(),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const participantData = bracketData.participants.get(participantId);
|
|
138
|
+
if (!participantData.matches.has(match.id)) {
|
|
139
|
+
participantData.matches.set(match.id, {
|
|
140
|
+
side: match.home?.id === participantId ? 'home' : 'away',
|
|
141
|
+
bracketMatch,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (isLowerBracket) {
|
|
147
|
+
currentLowerBracketIndex++;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
currentUpperBracketIndex++;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return bracketData;
|
|
154
|
+
};
|
|
155
|
+
export const generateMatchPositionMaps = (bracketData) => {
|
|
156
|
+
const matchPositionMaps = new Map();
|
|
157
|
+
for (const round of bracketData.rounds.values()) {
|
|
158
|
+
const matchMap = new Map([...round.matches.values()].map((m) => [m.position, m]));
|
|
159
|
+
matchPositionMaps.set(round.id, matchMap);
|
|
160
|
+
}
|
|
161
|
+
return matchPositionMaps;
|
|
162
|
+
};
|
|
163
|
+
export const generateBracketRoundTypeMap = (bracketData) => {
|
|
164
|
+
const roundAmountMap = new Map();
|
|
165
|
+
for (const round of bracketData.rounds.values()) {
|
|
166
|
+
if (!roundAmountMap.has(round.type)) {
|
|
167
|
+
roundAmountMap.set(round.type, new Map([[round.id, round]]));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
171
|
+
roundAmountMap.set(round.type, roundAmountMap.get(round.type).set(round.id, round));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return roundAmountMap;
|
|
175
|
+
};
|
|
176
|
+
const UPPER_LOOP_ORDER = [
|
|
177
|
+
SINGLE_ELIMINATION_BRACKET_ROUND_TYPE.SINGLE_ELIMINATION_BRACKET,
|
|
178
|
+
DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.UPPER_BRACKET,
|
|
179
|
+
SWISS_BRACKET_ROUND_TYPE.SWISS,
|
|
180
|
+
GROUP_BRACKET_ROUND_TYPE.GROUP,
|
|
181
|
+
COMMON_BRACKET_ROUND_TYPE.FINAL,
|
|
182
|
+
DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.REVERSE_FINAL,
|
|
183
|
+
COMMON_BRACKET_ROUND_TYPE.THIRD_PLACE,
|
|
184
|
+
];
|
|
185
|
+
const LOWER_LOOP_ORDER = [DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.LOWER_BRACKET];
|
|
186
|
+
export const generateRoundRelations = (bracketData) => {
|
|
187
|
+
const roundRelations = new Map();
|
|
188
|
+
const sortedRoundsByType = new Map();
|
|
189
|
+
for (const round of bracketData.rounds.values()) {
|
|
190
|
+
if (!sortedRoundsByType.has(round.type)) {
|
|
191
|
+
sortedRoundsByType.set(round.type, [round]);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
sortedRoundsByType.get(round.type)?.push(round);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
for (const rounds of sortedRoundsByType.values()) {
|
|
198
|
+
if (rounds.length === 1)
|
|
199
|
+
continue;
|
|
200
|
+
rounds.sort((a, b) => a.position - b.position);
|
|
201
|
+
}
|
|
202
|
+
const sortedUpperRounds = UPPER_LOOP_ORDER.map((t) => sortedRoundsByType.get(t))
|
|
203
|
+
.filter((r) => !!r)
|
|
204
|
+
.flat();
|
|
205
|
+
const sortedLowerRounds = LOWER_LOOP_ORDER.map((t) => sortedRoundsByType.get(t))
|
|
206
|
+
.filter((r) => !!r)
|
|
207
|
+
.flat();
|
|
208
|
+
const firstUpperRound = sortedUpperRounds[0] || null;
|
|
209
|
+
const firstLowerRound = sortedLowerRounds[0] || null;
|
|
210
|
+
if (!firstUpperRound)
|
|
211
|
+
throw new Error('firstUpperRound is null');
|
|
212
|
+
const hasLowerRounds = sortedLowerRounds.length > 0;
|
|
213
|
+
const lastLowerRound = sortedLowerRounds[sortedLowerRounds.length - 1] || null;
|
|
214
|
+
for (const [currentUpperRoundIndex, currentUpperRound] of sortedUpperRounds.entries()) {
|
|
215
|
+
const previousUpperRound = sortedUpperRounds[currentUpperRoundIndex - 1] || null;
|
|
216
|
+
const nextUpperRound = sortedUpperRounds[currentUpperRoundIndex + 1] || null;
|
|
217
|
+
const currentLowerRound = sortedLowerRounds[currentUpperRoundIndex] || null;
|
|
218
|
+
const previousLowerRound = sortedLowerRounds[currentUpperRoundIndex - 1] || null;
|
|
219
|
+
const nextLowerRound = sortedLowerRounds[currentUpperRoundIndex + 1] || null;
|
|
220
|
+
const isFirstRound = currentUpperRoundIndex === 0;
|
|
221
|
+
const isLastUpperRound = currentUpperRoundIndex === sortedUpperRounds.length - 1;
|
|
222
|
+
const isFinal = currentUpperRound.type === COMMON_BRACKET_ROUND_TYPE.FINAL;
|
|
223
|
+
if (isFinal && hasLowerRounds) {
|
|
224
|
+
// two to one relation
|
|
225
|
+
if (!lastLowerRound || !currentLowerRound || !previousUpperRound)
|
|
226
|
+
throw new Error('lastLowerRound or currentLowerRound or previousUpperRound is null');
|
|
227
|
+
// in a sync double elimination bracket, the final round has the same index as the last lower round
|
|
228
|
+
// in an async one, there is always one more round in the lower bracket since we only display a section of the whole tournament
|
|
229
|
+
const isAsyncBracket = currentLowerRound.id !== lastLowerRound.id;
|
|
230
|
+
const finalLowerRound = isAsyncBracket ? nextLowerRound : currentLowerRound;
|
|
231
|
+
if (!finalLowerRound)
|
|
232
|
+
throw new Error('finalLowerRound is null');
|
|
233
|
+
if (!firstLowerRound)
|
|
234
|
+
throw new Error('firstLowerRound is null');
|
|
235
|
+
if (finalLowerRound.id !== lastLowerRound.id)
|
|
236
|
+
throw new Error('finalLowerRound is not the last lower round');
|
|
237
|
+
// if we have a reverse final
|
|
238
|
+
if (nextUpperRound) {
|
|
239
|
+
// for the final
|
|
240
|
+
roundRelations.set(currentUpperRound.id, {
|
|
241
|
+
type: 'two-to-one',
|
|
242
|
+
previousUpperRound: previousUpperRound,
|
|
243
|
+
previousLowerRound: finalLowerRound,
|
|
244
|
+
nextRound: nextUpperRound,
|
|
245
|
+
currentRound: currentUpperRound,
|
|
246
|
+
nextRoundMatchFactor: nextUpperRound.matchCount / currentUpperRound.matchCount,
|
|
247
|
+
previousUpperRoundMatchFactor: previousUpperRound.matchCount / currentUpperRound.matchCount,
|
|
248
|
+
previousLowerRoundMatchFactor: finalLowerRound.matchCount / currentUpperRound.matchCount,
|
|
249
|
+
upperRootRoundMatchFactor: firstUpperRound.matchCount / currentUpperRound.matchCount,
|
|
250
|
+
lowerRootRoundMatchFactor: firstLowerRound.matchCount / currentUpperRound.matchCount,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
// no reverse final means the final is the last round
|
|
255
|
+
// for the final
|
|
256
|
+
roundRelations.set(currentUpperRound.id, {
|
|
257
|
+
type: 'two-to-nothing',
|
|
258
|
+
previousUpperRound: previousUpperRound,
|
|
259
|
+
previousLowerRound: finalLowerRound,
|
|
260
|
+
currentRound: currentUpperRound,
|
|
261
|
+
previousLowerRoundMatchFactor: finalLowerRound.matchCount / currentUpperRound.matchCount,
|
|
262
|
+
previousUpperRoundMatchFactor: previousUpperRound.matchCount / currentUpperRound.matchCount,
|
|
263
|
+
lowerRootRoundMatchFactor: firstLowerRound.matchCount / currentUpperRound.matchCount,
|
|
264
|
+
upperRootRoundMatchFactor: firstUpperRound.matchCount / currentUpperRound.matchCount,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
if (isAsyncBracket) {
|
|
268
|
+
// if this is an async bracket, we need to set the relations for the 2 last lower rounds since they will be skipped by the default one to one logic
|
|
269
|
+
const preFinalLowerRound = sortedLowerRounds[sortedLowerRounds.length - 2] || null;
|
|
270
|
+
const prePreFinalLowerRound = sortedLowerRounds[sortedLowerRounds.length - 3] || null;
|
|
271
|
+
if (!preFinalLowerRound)
|
|
272
|
+
throw new Error('preFinalLowerRound is null');
|
|
273
|
+
if (!firstLowerRound)
|
|
274
|
+
throw new Error('firstLowerRound is null');
|
|
275
|
+
// for the last lower round
|
|
276
|
+
roundRelations.set(finalLowerRound.id, {
|
|
277
|
+
type: 'one-to-one',
|
|
278
|
+
previousRound: preFinalLowerRound,
|
|
279
|
+
nextRound: currentUpperRound,
|
|
280
|
+
currentRound: finalLowerRound,
|
|
281
|
+
nextRoundMatchFactor: currentUpperRound.matchCount / finalLowerRound.matchCount,
|
|
282
|
+
previousRoundMatchFactor: preFinalLowerRound.matchCount / finalLowerRound.matchCount,
|
|
283
|
+
rootRoundMatchFactor: firstLowerRound.matchCount / finalLowerRound.matchCount,
|
|
284
|
+
});
|
|
285
|
+
if (prePreFinalLowerRound) {
|
|
286
|
+
// for the pre final lower round
|
|
287
|
+
roundRelations.set(preFinalLowerRound.id, {
|
|
288
|
+
type: 'one-to-one',
|
|
289
|
+
previousRound: prePreFinalLowerRound,
|
|
290
|
+
nextRound: finalLowerRound,
|
|
291
|
+
currentRound: preFinalLowerRound,
|
|
292
|
+
nextRoundMatchFactor: finalLowerRound.matchCount / preFinalLowerRound.matchCount,
|
|
293
|
+
previousRoundMatchFactor: prePreFinalLowerRound.matchCount / preFinalLowerRound.matchCount,
|
|
294
|
+
rootRoundMatchFactor: firstLowerRound.matchCount / preFinalLowerRound.matchCount,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
// for the first lower round
|
|
299
|
+
roundRelations.set(preFinalLowerRound.id, {
|
|
300
|
+
type: 'nothing-to-one',
|
|
301
|
+
nextRound: finalLowerRound,
|
|
302
|
+
currentRound: preFinalLowerRound,
|
|
303
|
+
nextRoundMatchFactor: finalLowerRound.matchCount / preFinalLowerRound.matchCount,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
// this is a sync bracket, we only need to set the relation for the last lower round
|
|
309
|
+
if (!previousLowerRound)
|
|
310
|
+
throw new Error('previousLowerRound is null');
|
|
311
|
+
if (!firstLowerRound)
|
|
312
|
+
throw new Error('firstLowerRound is null');
|
|
313
|
+
// for the last lower round
|
|
314
|
+
roundRelations.set(finalLowerRound.id, {
|
|
315
|
+
type: 'one-to-one',
|
|
316
|
+
previousRound: previousLowerRound,
|
|
317
|
+
nextRound: currentUpperRound,
|
|
318
|
+
currentRound: finalLowerRound,
|
|
319
|
+
nextRoundMatchFactor: currentUpperRound.matchCount / finalLowerRound.matchCount,
|
|
320
|
+
previousRoundMatchFactor: previousLowerRound.matchCount / finalLowerRound.matchCount,
|
|
321
|
+
rootRoundMatchFactor: firstLowerRound.matchCount / finalLowerRound.matchCount,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
else if (isLastUpperRound) {
|
|
326
|
+
// one to nothing relation
|
|
327
|
+
if (!previousUpperRound)
|
|
328
|
+
throw new Error('previousUpperRound is null');
|
|
329
|
+
roundRelations.set(currentUpperRound.id, {
|
|
330
|
+
type: 'one-to-nothing',
|
|
331
|
+
previousRound: previousUpperRound,
|
|
332
|
+
currentRound: currentUpperRound,
|
|
333
|
+
previousRoundMatchFactor: previousUpperRound.matchCount / currentUpperRound.matchCount,
|
|
334
|
+
rootRoundMatchFactor: firstUpperRound.matchCount / currentUpperRound.matchCount,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
else if (isFirstRound) {
|
|
338
|
+
// nothing to one relation
|
|
339
|
+
if (!nextUpperRound)
|
|
340
|
+
throw new Error('nextUpperRound is null');
|
|
341
|
+
roundRelations.set(currentUpperRound.id, {
|
|
342
|
+
type: 'nothing-to-one',
|
|
343
|
+
nextRound: nextUpperRound,
|
|
344
|
+
currentRound: currentUpperRound,
|
|
345
|
+
nextRoundMatchFactor: nextUpperRound.matchCount / currentUpperRound.matchCount,
|
|
346
|
+
});
|
|
347
|
+
if (currentLowerRound) {
|
|
348
|
+
if (!nextLowerRound)
|
|
349
|
+
throw new Error('nextLowerRound is null');
|
|
350
|
+
roundRelations.set(currentLowerRound.id, {
|
|
351
|
+
type: 'nothing-to-one',
|
|
352
|
+
nextRound: nextLowerRound,
|
|
353
|
+
currentRound: currentLowerRound,
|
|
354
|
+
nextRoundMatchFactor: nextLowerRound.matchCount / currentLowerRound.matchCount,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
// one to one relation
|
|
360
|
+
if (!previousUpperRound)
|
|
361
|
+
throw new Error('previousUpperRound is null');
|
|
362
|
+
if (!nextUpperRound)
|
|
363
|
+
throw new Error('nextUpperRound is null');
|
|
364
|
+
roundRelations.set(currentUpperRound.id, {
|
|
365
|
+
type: 'one-to-one',
|
|
366
|
+
previousRound: previousUpperRound,
|
|
367
|
+
nextRound: nextUpperRound,
|
|
368
|
+
currentRound: currentUpperRound,
|
|
369
|
+
nextRoundMatchFactor: nextUpperRound.matchCount / currentUpperRound.matchCount,
|
|
370
|
+
previousRoundMatchFactor: previousUpperRound.matchCount / currentUpperRound.matchCount,
|
|
371
|
+
rootRoundMatchFactor: firstUpperRound.matchCount / currentUpperRound.matchCount,
|
|
372
|
+
});
|
|
373
|
+
// we only want to set lower rounds here until the special merging point of the final.
|
|
374
|
+
// lower bracket rounds after and including the final will be set in the final round block
|
|
375
|
+
if (currentLowerRound && currentUpperRound.type === DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.UPPER_BRACKET) {
|
|
376
|
+
if (!previousLowerRound)
|
|
377
|
+
throw new Error('previousLowerRound is null');
|
|
378
|
+
if (!nextLowerRound)
|
|
379
|
+
throw new Error('nextLowerRound is null');
|
|
380
|
+
if (!firstLowerRound)
|
|
381
|
+
throw new Error('firstLowerRound is null');
|
|
382
|
+
roundRelations.set(currentLowerRound.id, {
|
|
383
|
+
type: 'one-to-one',
|
|
384
|
+
previousRound: previousLowerRound,
|
|
385
|
+
nextRound: nextLowerRound,
|
|
386
|
+
currentRound: currentLowerRound,
|
|
387
|
+
nextRoundMatchFactor: nextLowerRound.matchCount / currentLowerRound.matchCount,
|
|
388
|
+
previousRoundMatchFactor: previousLowerRound.matchCount / currentLowerRound.matchCount,
|
|
389
|
+
rootRoundMatchFactor: firstLowerRound.matchCount / currentLowerRound.matchCount,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return roundRelations;
|
|
395
|
+
};
|
|
396
|
+
export const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps) => {
|
|
397
|
+
const matchRelations = new Map();
|
|
398
|
+
for (const match of bracketData.matches.values()) {
|
|
399
|
+
const currentRelation = roundRelations.get(match.round.id);
|
|
400
|
+
if (!currentRelation)
|
|
401
|
+
throw new Error('Match round not found');
|
|
402
|
+
const { nextRoundMatchPosition, previousLowerRoundMatchPosition, previousUpperRoundMatchPosition } = generateMatchRelationPositions(currentRelation, match);
|
|
403
|
+
switch (currentRelation.type) {
|
|
404
|
+
case 'nothing-to-one': {
|
|
405
|
+
const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
|
|
406
|
+
if (!nextMatch)
|
|
407
|
+
throw new Error('Next round match not found');
|
|
408
|
+
// means left is nothing. right is one
|
|
409
|
+
matchRelations.set(match.id, {
|
|
410
|
+
type: 'nothing-to-one',
|
|
411
|
+
currentMatch: match,
|
|
412
|
+
currentRound: currentRelation.currentRound,
|
|
413
|
+
nextRound: currentRelation.nextRound,
|
|
414
|
+
nextMatch,
|
|
415
|
+
});
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
case 'one-to-nothing': {
|
|
419
|
+
const previousUpperMatch = matchPositionMaps
|
|
420
|
+
.get(currentRelation.previousRound.id)
|
|
421
|
+
?.get(previousUpperRoundMatchPosition);
|
|
422
|
+
const previousLowerMatch = matchPositionMaps
|
|
423
|
+
.get(currentRelation.previousRound.id)
|
|
424
|
+
?.get(previousLowerRoundMatchPosition);
|
|
425
|
+
if (!previousUpperMatch)
|
|
426
|
+
throw new Error('Previous round match not found');
|
|
427
|
+
if (previousUpperRoundMatchPosition !== previousLowerRoundMatchPosition) {
|
|
428
|
+
// means left is two. right is one
|
|
429
|
+
if (!previousLowerMatch)
|
|
430
|
+
throw new Error('Previous lower round match not found');
|
|
431
|
+
matchRelations.set(match.id, {
|
|
432
|
+
type: 'two-to-nothing',
|
|
433
|
+
currentMatch: match,
|
|
434
|
+
currentRound: currentRelation.currentRound,
|
|
435
|
+
previousUpperMatch,
|
|
436
|
+
previousUpperRound: currentRelation.previousRound,
|
|
437
|
+
previousLowerMatch,
|
|
438
|
+
previousLowerRound: currentRelation.previousRound,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
// means left is one. right is nothing
|
|
443
|
+
matchRelations.set(match.id, {
|
|
444
|
+
type: 'one-to-nothing',
|
|
445
|
+
currentMatch: match,
|
|
446
|
+
currentRound: currentRelation.currentRound,
|
|
447
|
+
previousMatch: previousUpperMatch,
|
|
448
|
+
previousRound: currentRelation.previousRound,
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
case 'one-to-one': {
|
|
454
|
+
const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
|
|
455
|
+
const previousUpperMatch = matchPositionMaps
|
|
456
|
+
.get(currentRelation.previousRound.id)
|
|
457
|
+
?.get(previousUpperRoundMatchPosition);
|
|
458
|
+
const previousLowerMatch = matchPositionMaps
|
|
459
|
+
.get(currentRelation.previousRound.id)
|
|
460
|
+
?.get(previousLowerRoundMatchPosition);
|
|
461
|
+
if (!nextMatch)
|
|
462
|
+
throw new Error('Next round match not found');
|
|
463
|
+
if (!previousUpperMatch)
|
|
464
|
+
throw new Error(`Previous upper round match not found`);
|
|
465
|
+
if (!previousLowerMatch)
|
|
466
|
+
throw new Error('Previous lower round match not found');
|
|
467
|
+
// can be either one to one or two to one
|
|
468
|
+
const isLeftOne = previousUpperRoundMatchPosition === previousLowerRoundMatchPosition;
|
|
469
|
+
if (isLeftOne) {
|
|
470
|
+
// one-to-one
|
|
471
|
+
matchRelations.set(match.id, {
|
|
472
|
+
type: 'one-to-one',
|
|
473
|
+
currentMatch: match,
|
|
474
|
+
currentRound: currentRelation.currentRound,
|
|
475
|
+
previousMatch: previousUpperMatch,
|
|
476
|
+
previousRound: currentRelation.previousRound,
|
|
477
|
+
nextMatch,
|
|
478
|
+
nextRound: currentRelation.nextRound,
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
// two-to-one
|
|
483
|
+
matchRelations.set(match.id, {
|
|
484
|
+
type: 'two-to-one',
|
|
485
|
+
currentMatch: match,
|
|
486
|
+
currentRound: currentRelation.currentRound,
|
|
487
|
+
previousUpperMatch,
|
|
488
|
+
previousUpperRound: currentRelation.previousRound,
|
|
489
|
+
previousLowerMatch,
|
|
490
|
+
previousLowerRound: currentRelation.previousRound,
|
|
491
|
+
nextMatch,
|
|
492
|
+
nextRound: currentRelation.nextRound,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
case 'two-to-one': {
|
|
498
|
+
const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
|
|
499
|
+
const previousUpperMatch = matchPositionMaps
|
|
500
|
+
.get(currentRelation.previousUpperRound.id)
|
|
501
|
+
?.get(previousUpperRoundMatchPosition);
|
|
502
|
+
const previousLowerMatch = matchPositionMaps
|
|
503
|
+
.get(currentRelation.previousLowerRound.id)
|
|
504
|
+
?.get(previousLowerRoundMatchPosition);
|
|
505
|
+
if (!nextMatch)
|
|
506
|
+
throw new Error('Next round match not found');
|
|
507
|
+
if (!previousUpperMatch)
|
|
508
|
+
throw new Error(`Previous upper round match not found`);
|
|
509
|
+
if (!previousLowerMatch)
|
|
510
|
+
throw new Error('Previous lower round match not found');
|
|
511
|
+
matchRelations.set(match.id, {
|
|
512
|
+
type: 'two-to-one',
|
|
513
|
+
currentMatch: match,
|
|
514
|
+
currentRound: currentRelation.currentRound,
|
|
515
|
+
previousUpperMatch,
|
|
516
|
+
previousUpperRound: currentRelation.previousUpperRound,
|
|
517
|
+
previousLowerMatch,
|
|
518
|
+
previousLowerRound: currentRelation.previousLowerRound,
|
|
519
|
+
nextMatch,
|
|
520
|
+
nextRound: currentRelation.nextRound,
|
|
521
|
+
});
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
case 'two-to-nothing': {
|
|
525
|
+
const previousUpperMatch = matchPositionMaps
|
|
526
|
+
.get(currentRelation.previousUpperRound.id)
|
|
527
|
+
?.get(previousUpperRoundMatchPosition);
|
|
528
|
+
const previousLowerMatch = matchPositionMaps
|
|
529
|
+
.get(currentRelation.previousUpperRound.id)
|
|
530
|
+
?.get(previousLowerRoundMatchPosition);
|
|
531
|
+
if (!previousUpperMatch)
|
|
532
|
+
throw new Error(`Previous upper round match not found`);
|
|
533
|
+
if (!previousLowerMatch)
|
|
534
|
+
throw new Error('Previous lower round match not found');
|
|
535
|
+
matchRelations.set(match.id, {
|
|
536
|
+
type: 'two-to-nothing',
|
|
537
|
+
currentMatch: match,
|
|
538
|
+
currentRound: currentRelation.currentRound,
|
|
539
|
+
previousUpperMatch,
|
|
540
|
+
previousUpperRound: currentRelation.previousUpperRound,
|
|
541
|
+
previousLowerMatch,
|
|
542
|
+
previousLowerRound: currentRelation.previousUpperRound,
|
|
543
|
+
});
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return matchRelations;
|
|
549
|
+
};
|
|
550
|
+
export const generateMatchRelationPositions = (currentRelation, match) => {
|
|
551
|
+
switch (currentRelation.type) {
|
|
552
|
+
case 'nothing-to-one': {
|
|
553
|
+
return {
|
|
554
|
+
nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
|
|
555
|
+
previousUpperRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
556
|
+
previousLowerRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
case 'one-to-nothing': {
|
|
560
|
+
const previousRoundHasDoubleTheMatchCount = currentRelation.previousRoundMatchFactor === 2;
|
|
561
|
+
const doubleUpperMatchCountShift = previousRoundHasDoubleTheMatchCount ? 1 : 0;
|
|
562
|
+
return {
|
|
563
|
+
nextRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
564
|
+
previousUpperRoundMatchPosition: (generateMatchPosition(match, currentRelation.previousRoundMatchFactor) -
|
|
565
|
+
doubleUpperMatchCountShift),
|
|
566
|
+
previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousRoundMatchFactor),
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
case 'one-to-one': {
|
|
570
|
+
const previousRoundHasDoubleTheMatchCount = currentRelation.previousRoundMatchFactor === 2;
|
|
571
|
+
const doubleUpperMatchCountShift = previousRoundHasDoubleTheMatchCount ? 1 : 0;
|
|
572
|
+
return {
|
|
573
|
+
nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
|
|
574
|
+
previousUpperRoundMatchPosition: (generateMatchPosition(match, currentRelation.previousRoundMatchFactor) -
|
|
575
|
+
doubleUpperMatchCountShift),
|
|
576
|
+
previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousRoundMatchFactor),
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
case 'two-to-one': {
|
|
580
|
+
return {
|
|
581
|
+
nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
|
|
582
|
+
previousUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.previousUpperRoundMatchFactor),
|
|
583
|
+
previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousLowerRoundMatchFactor),
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
case 'two-to-nothing': {
|
|
587
|
+
return {
|
|
588
|
+
nextRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
589
|
+
previousUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.previousUpperRoundMatchFactor),
|
|
590
|
+
previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousLowerRoundMatchFactor),
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
export const generateMatchPosition = (match, factor) => {
|
|
596
|
+
return Math.ceil(match.position * factor);
|
|
597
|
+
};
|
|
598
|
+
export const logRoundRelations = (roundRelations, bracketData) => {
|
|
599
|
+
for (const [roundId, relation] of roundRelations.entries()) {
|
|
600
|
+
const round = bracketData.rounds.get(roundId);
|
|
601
|
+
if (!round) {
|
|
602
|
+
console.error(`Round with id ${roundId} not found in bracket data. The bracket will be malformed.`);
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
605
|
+
switch (relation.type) {
|
|
606
|
+
case 'nothing-to-one':
|
|
607
|
+
console.log(`START: ${round.name} -> ${relation.nextRound.name} (F: ${relation.nextRoundMatchFactor})`);
|
|
608
|
+
break;
|
|
609
|
+
case 'one-to-nothing':
|
|
610
|
+
console.log(`${relation.previousRound.name} (F: ${relation.previousRoundMatchFactor}) <- ENDING: ${round.name}`);
|
|
611
|
+
break;
|
|
612
|
+
case 'one-to-one':
|
|
613
|
+
console.log(`${relation.previousRound.name} (F: ${relation.previousRoundMatchFactor}) <- ${round.name} -> ${relation.nextRound.name} (F: ${relation.nextRoundMatchFactor})`);
|
|
614
|
+
break;
|
|
615
|
+
case 'two-to-one':
|
|
616
|
+
console.log(`MERGER: ${relation.previousUpperRound.name} (F: ${relation.previousUpperRoundMatchFactor}) AND ${relation.previousLowerRound.name} (F: ${relation.previousLowerRoundMatchFactor}) <- ${round.name} -> ${relation.nextRound.name} (F: ${relation.nextRoundMatchFactor})`);
|
|
617
|
+
break;
|
|
618
|
+
case 'two-to-nothing':
|
|
619
|
+
console.log(`MERGER: ${relation.previousUpperRound.name} (F: ${relation.previousUpperRoundMatchFactor}) AND ${relation.previousLowerRound.name} (F: ${relation.previousLowerRoundMatchFactor}) <- ENDING: ${round.name}`);
|
|
620
|
+
break;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
export const generateMatchParticipantMap = (bracketData) => {
|
|
625
|
+
const matchParticipantMap = new Map();
|
|
626
|
+
const hasElimination = bracketData.mode === TOURNAMENT_MODE.SINGLE_ELIMINATION ||
|
|
627
|
+
bracketData.mode === TOURNAMENT_MODE.DOUBLE_ELIMINATION ||
|
|
628
|
+
bracketData.mode === TOURNAMENT_MODE.SWISS_WITH_ELIMINATION;
|
|
629
|
+
for (const participant of bracketData.participants.values()) {
|
|
630
|
+
let winsTilNow = 0;
|
|
631
|
+
let lossesTilNow = 0;
|
|
632
|
+
let tiesTilNow = 0;
|
|
633
|
+
for (const matchParticipantMatch of participant.matches.values()) {
|
|
634
|
+
const isWinner = matchParticipantMatch.bracketMatch.winner === matchParticipantMatch.side;
|
|
635
|
+
const isLooser = matchParticipantMatch.bracketMatch.winner &&
|
|
636
|
+
matchParticipantMatch.bracketMatch.winner !== matchParticipantMatch.side;
|
|
637
|
+
const isTie = matchParticipantMatch.bracketMatch.status === 'completed' && !matchParticipantMatch.bracketMatch.winner;
|
|
638
|
+
if (isWinner) {
|
|
639
|
+
winsTilNow++;
|
|
640
|
+
}
|
|
641
|
+
else if (isLooser) {
|
|
642
|
+
lossesTilNow++;
|
|
643
|
+
}
|
|
644
|
+
else if (isTie) {
|
|
645
|
+
tiesTilNow++;
|
|
646
|
+
}
|
|
647
|
+
let isEliminated = false;
|
|
648
|
+
let isEliminationMatch = false;
|
|
649
|
+
if (hasElimination) {
|
|
650
|
+
// TODO: Implement elimination logic
|
|
651
|
+
// Means the current match is loss and it's the last match of the participant
|
|
652
|
+
isEliminated = false;
|
|
653
|
+
// Always true for single elimination, never for e.g. groups, depends on the round for double elimination, depends on the loss count for swiss with elimination
|
|
654
|
+
isEliminationMatch = false;
|
|
655
|
+
}
|
|
656
|
+
// TODO: Implement round logic
|
|
657
|
+
// true if its the first round of the bracket
|
|
658
|
+
const isFirstRound = false;
|
|
659
|
+
// true if its the last round of the bracket (eg. final for single elimination)
|
|
660
|
+
const isLastRound = false;
|
|
661
|
+
const participantMatchData = {
|
|
662
|
+
bracketMatch: matchParticipantMatch.bracketMatch,
|
|
663
|
+
result: isWinner ? 'win' : isLooser ? 'loss' : isTie ? 'tie' : null,
|
|
664
|
+
isEliminated,
|
|
665
|
+
isEliminationMatch,
|
|
666
|
+
isFirstRound,
|
|
667
|
+
isLastRound,
|
|
668
|
+
tieCount: tiesTilNow,
|
|
669
|
+
winCount: winsTilNow,
|
|
670
|
+
lossCount: lossesTilNow,
|
|
671
|
+
};
|
|
672
|
+
if (!matchParticipantMap.has(participant.id)) {
|
|
673
|
+
matchParticipantMap.set(participant.id, {
|
|
674
|
+
id: participant.id,
|
|
675
|
+
name: participant.name,
|
|
676
|
+
matches: new Map(),
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
const participantData = matchParticipantMap.get(participant.id);
|
|
680
|
+
participantData.matches.set(matchParticipantMatch.bracketMatch.id, participantMatchData);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return matchParticipantMap;
|
|
684
|
+
};
|
|
685
|
+
const factorialCache = new Map();
|
|
686
|
+
export const getAvailableSwissGroupsForRound = (roundNumber, totalMatchesInRound) => {
|
|
687
|
+
const ADVANCE_WINS = 3;
|
|
688
|
+
const ELIMINATE_LOSSES = 3;
|
|
689
|
+
// Cache factorial calculations
|
|
690
|
+
const getFactorial = (n) => {
|
|
691
|
+
if (n <= 1)
|
|
692
|
+
return 1;
|
|
693
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
694
|
+
if (factorialCache.has(n))
|
|
695
|
+
return factorialCache.get(n);
|
|
696
|
+
const result = n * getFactorial(n - 1);
|
|
697
|
+
factorialCache.set(n, result);
|
|
698
|
+
return result;
|
|
699
|
+
};
|
|
700
|
+
// Pre-calculate roundFactorial
|
|
701
|
+
const roundFact = getFactorial(roundNumber);
|
|
702
|
+
let totalCombinations = 0;
|
|
703
|
+
const validGroups = [];
|
|
704
|
+
// Single loop to gather valid groups and total combinations
|
|
705
|
+
for (let wins = roundNumber; wins >= 0; wins--) {
|
|
706
|
+
const losses = roundNumber - wins;
|
|
707
|
+
const remainingGames = ADVANCE_WINS + ELIMINATE_LOSSES - (wins + losses) - 1;
|
|
708
|
+
const notYetEliminated = losses < ELIMINATE_LOSSES;
|
|
709
|
+
const canStillAdvance = wins < ADVANCE_WINS && remainingGames >= 0;
|
|
710
|
+
if (!canStillAdvance || !notYetEliminated)
|
|
711
|
+
continue;
|
|
712
|
+
const combinations = roundFact / (getFactorial(wins) * getFactorial(losses));
|
|
713
|
+
totalCombinations += combinations;
|
|
714
|
+
validGroups.push({ wins, losses, combinations });
|
|
715
|
+
}
|
|
716
|
+
// Create final groups with calculated proportions
|
|
717
|
+
return validGroups.map(({ wins, losses, combinations }) => ({
|
|
718
|
+
id: `${wins}-${losses}`,
|
|
719
|
+
name: `${wins}-${losses}`,
|
|
720
|
+
matchesInGroup: Math.round((combinations / totalCombinations) * totalMatchesInRound),
|
|
721
|
+
}));
|
|
722
|
+
};
|
|
723
|
+
export const generateBracketRoundSwissGroupMaps = (bracketData, matchParticipantMap) => {
|
|
724
|
+
if (bracketData.mode !== TOURNAMENT_MODE.SWISS_WITH_ELIMINATION) {
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
const roundsWithSwissGroups = new Map();
|
|
728
|
+
let roundNumber = 0;
|
|
729
|
+
for (const bracketRound of bracketData.rounds.values()) {
|
|
730
|
+
const availableGroups = getAvailableSwissGroupsForRound(roundNumber, bracketRound.matchCount);
|
|
731
|
+
const roundSwissData = {
|
|
732
|
+
groups: new Map(),
|
|
733
|
+
};
|
|
734
|
+
for (const group of availableGroups) {
|
|
735
|
+
const subGroup = {
|
|
736
|
+
id: group.id,
|
|
737
|
+
name: group.name,
|
|
738
|
+
matches: new Map(),
|
|
739
|
+
allowedMatchCount: group.matchesInGroup,
|
|
740
|
+
};
|
|
741
|
+
roundSwissData.groups.set(group.id, subGroup);
|
|
742
|
+
}
|
|
743
|
+
const emptyMatchIds = [];
|
|
744
|
+
for (const match of bracketRound.matches.values()) {
|
|
745
|
+
const participantHome = match.home ? (matchParticipantMap.get(match.home) ?? null) : null;
|
|
746
|
+
const participantAway = match.away ? (matchParticipantMap.get(match.away) ?? null) : null;
|
|
747
|
+
const anyParticipant = participantHome || participantAway;
|
|
748
|
+
if (!anyParticipant) {
|
|
749
|
+
emptyMatchIds.push(match.id);
|
|
750
|
+
continue;
|
|
751
|
+
}
|
|
752
|
+
const matchParticipantMatch = anyParticipant.matches.get(match.id);
|
|
753
|
+
if (!matchParticipantMatch)
|
|
754
|
+
throw new Error('Match participant match not found');
|
|
755
|
+
const wins = matchParticipantMatch.winCount;
|
|
756
|
+
const losses = matchParticipantMatch.lossCount;
|
|
757
|
+
const group = roundSwissData.groups.get(`${wins}-${losses}`);
|
|
758
|
+
if (!group)
|
|
759
|
+
throw new Error('Group not found for match: ' + match.id);
|
|
760
|
+
group.matches.set(match.id, match);
|
|
761
|
+
}
|
|
762
|
+
for (const emptyMatchId of emptyMatchIds) {
|
|
763
|
+
const match = bracketRound.matches.get(emptyMatchId);
|
|
764
|
+
if (!match)
|
|
765
|
+
throw new Error('Empty match not found');
|
|
766
|
+
let groupFound = false;
|
|
767
|
+
for (const group of roundSwissData.groups.values()) {
|
|
768
|
+
if (group.matches.size < group.allowedMatchCount) {
|
|
769
|
+
group.matches.set(match.id, match);
|
|
770
|
+
groupFound = true;
|
|
771
|
+
break;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
if (!groupFound) {
|
|
775
|
+
throw new Error('No group found for empty match');
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
roundNumber++;
|
|
779
|
+
}
|
|
780
|
+
return roundsWithSwissGroups;
|
|
781
|
+
};
|
|
782
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJhY2tldC1uZXcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2Nkay9zcmMvbGliL2NvbXBvbmVudHMvYnJhY2tldC9jb21wb25lbnRzL25ldy1icmFja2V0L2JyYWNrZXQtbmV3LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWtCQSxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLENBQXlCLENBQUM7QUFFbEUsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHO0lBQzdCLGtCQUFrQixFQUFFLG9CQUFvQjtJQUN4QyxrQkFBa0IsRUFBRSxvQkFBb0I7SUFDeEMsS0FBSyxFQUFFLE9BQU87SUFDZCxLQUFLLEVBQUUsT0FBTztJQUNkLHNCQUFzQixFQUFFLHdCQUF3QjtDQUN4QyxDQUFDO0FBSVgsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUc7SUFDdkMsV0FBVyxFQUFFLGFBQWE7SUFDMUIsS0FBSyxFQUFFLE9BQU87Q0FDTixDQUFDO0FBRVgsTUFBTSxDQUFDLE1BQU0scUNBQXFDLEdBQUc7SUFDbkQsMEJBQTBCLEVBQUUsNEJBQTRCO0NBQ2hELENBQUM7QUFFWCxNQUFNLENBQUMsTUFBTSxxQ0FBcUMsR0FBRztJQUNuRCxhQUFhLEVBQUUsZUFBZTtJQUM5QixhQUFhLEVBQUUsZUFBZTtJQUM5QixhQUFhLEVBQUUsZUFBZTtDQUN0QixDQUFDO0FBRVgsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUc7SUFDdEMsS0FBSyxFQUFFLE9BQU87Q0FDTixDQUFDO0FBRVgsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUc7SUFDdEMsS0FBSyxFQUFFLE9BQU87Q0FDTixDQUFDO0FBcVFYLE1BQU0sQ0FBQyxNQUFNLHFDQUFxQyxHQUFHLENBQ25ELElBQWUsRUFDZixjQUE4QixFQUNaLEVBQUU7SUFDcEIsUUFBUSxJQUFJLEVBQUUsQ0FBQztRQUNiLEtBQUssUUFBUTtZQUNYLFFBQVEsY0FB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QUNuRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO29CQUNqRCxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUNuQyxVQUFVLEdBQUcsSUFBSSxDQUFDO29CQUNsQixNQUFNO2dCQUNSLENBQUM7WUFDSCxDQUFDO1lBRUQsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7WUFDcEQsQ0FBQztRQUNILENBQUM7UUFFRCxXQUFXLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRUQsT0FBTyxxQkFBcUIsQ0FBQztBQUMvQixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBNYXRjaExpc3RWaWV3VW5pb24sXG4gIE9wcG9uZW50U2lkZSxcbiAgUm91bmRTdGFnZVN0cnVjdHVyZVZpZXcsXG4gIFJvdW5kU3RhZ2VTdHJ1Y3R1cmVXaXRoTWF0Y2hlc1ZpZXcsXG4gIFJvdW5kVHlwZSxcbn0gZnJvbSAnQGV0aGxldGUvdHlwZXMnO1xuXG5leHBvcnQgdHlwZSBCcmFja2V0Um91bmRJZCA9IHN0cmluZyAmIHsgX19icmFuZDogJ0JyYWNrZXRSb3VuZElkJyB9O1xuZXhwb3J0IHR5cGUgQnJhY2tldE1hdGNoSWQgPSBzdHJpbmcgJiB7IF9fYnJhbmQ6ICdCcmFja2V0TWF0Y2hJZCcgfTtcbmV4cG9ydCB0eXBlIEJyYWNrZXRSb3VuZFBvc2l0aW9uID0gbnVtYmVyICYgeyBfX2JyYW5kOiAnQnJhY2tldFJvdW5kUG9zaXRpb24nIH07XG5leHBvcnQgdHlwZSBCcmFja2V0TWF0Y2hQb3NpdGlvbiA9IG51bWJlciAmIHsgX19icmFuZDogJ0JyYWNrZXRNYXRjaFBvc2l0aW9uJyB9O1xuZXhwb3J0IHR5cGUgTWF0Y2hQYXJ0aWNpcGFudElkID0gc3RyaW5nICYgeyBfX2JyYW5kOiAnTWF0Y2hQYXJ0aWNpcGFudElkJyB9O1xuZXhwb3J0IHR5cGUgQnJhY2tldFJvdW5kU3dpc3NHcm91cElkID0gc3RyaW5nICYgeyBfX2JyYW5kOiAnQnJhY2tldFJvdW5kU3dpc3NHcm91cElkJyB9O1xuXG4vLyBXaWxsIHVzdWFsbHkgYmUgMC41LCAxIG9yIDIuIEluIFN3aXNzIHRoaXMgdmFsdWUgd2lsbCBiZSBnaWJiZXJpc2hcbmV4cG9ydCB0eXBlIE1hdGNoRmFjdG9yID0gbnVtYmVyO1xuXG5leHBvcnQgY29uc3QgRkFMTEJBQ0tfTUFUQ0hfUE9TSVRJT04gPSAtMSBhcyBCcmFja2V0TWF0Y2hQb3NpdGlvbjtcblxuZXhwb3J0IGNvbnN0IFRPVVJOQU1FTlRfTU9ERSA9IHtcbiAgU0lOR0xFX0VMSU1JTkFUSU9OOiAnc2luZ2xlLWVsaW1pbmF0aW9uJyxcbiAgRE9VQkxFX0VMSU1JTkFUSU9OOiAnZG91YmxlLWVsaW1pbmF0aW9uJyxcbiAgR1JPVVA6ICdncm91cCcsXG4gIFNXSVNTOiAnc3dpc3MnLFxuICBTV0lTU19XSVRIX0VMSU1JTkFUSU9OOiAnc3dpc3Mtd2l0aC1lbGltaW5hdGlvbicsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBUb3VybmFtZW50TW9kZSA9ICh0eXBlb2YgVE9VUk5BTUVOVF9NT0RFKVtrZXlvZiB0eXBlb2YgVE9VUk5BTUVOVF9NT0RFXTtcblxuZXhwb3J0IGNvbnN0IENPTU1PTl9CUkFDS0VUX1JPVU5EX1RZUEUgPSB7XG4gIFRISVJEX1BMQUNFOiAndGhpcmQtcGxhY2UnLFxuICBGSU5BTDogJ2ZpbmFsJyxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBTSU5HTEVfRUxJTUlOQVRJT05fQlJBQ0tFVF9ST1VORF9UWVBFID0ge1xuICBTSU5HTEVfRUxJTUlOQVRJT05fQlJBQ0tFVDogJ3NpbmdsZS1lbGltaW5hdGlvbi1icmFja2V0Jyxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBET1VCTEVfRUxJTUlOQVRJT05fQlJBQ0tFVF9ST1VORF9UWVBFID0ge1xuICBVUFBFUl9CUkFDS0VUOiAndXBwZXItYnJhY2tldCcsXG4gIExPV0VSX0JSQUNLRVQ6ICdsb3dlci1icmFja2V0JyxcbiAgUkVWRVJTRV9GSU5BTDogJ3JldmVyc2UtZmluYWwnLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IGNvbnN0IFNXSVNTX0JSQUNLRVRfUk9VTkRfVFlQRSA9IHtcbiAgU1dJU1M6ICdzd2lzcycsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgR1JPVVBfQlJBQ0tFVF9ST1VORF9UWVBFID0ge1xuICBHUk9VUDogJ2dyb3VwJyxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCB0eXBlIENvbW1vbkJyYWNrZXRSb3VuZFR5cGUgPSAodHlwZW9mIENPTU1PTl9CUkFDS0VUX1JPVU5EX1RZUEUpW2tleW9mIHR5cGVvZiBDT01NT05fQlJBQ0tFVF9ST1VORF9UWVBFXTtcbmV4cG9ydCB0eXBlIFNpbmdsZUVsaW1pbmF0aW9uQnJhY2tldFJvdW5kVHlwZSA9XG4gIHwgQ29tbW9uQnJhY2tldFJvdW5kVHlwZVxuICB8ICh0eXBlb2YgU0lOR0xFX0VMSU1JTkFUSU9OX0JSQUNLRVRfUk9VTkRfVFlQRSlba2V5b2YgdHlwZW9mIFNJTkdMRV9FTElNSU5BVElPTl9CUkFDS0VUX1JPVU5EX1RZUEVdO1xuZXhwb3J0IHR5cGUgRG91YmxlRWxpbWluYXRpb25CcmFja2V0Um91bmRUeXBlID1cbiAgfCBDb21tb25CcmFja2V0Um91bmRUeXBlXG4gIHwgKHR5cGVvZiBET1VCTEVfRUxJTUlOQVRJT05fQlJBQ0tFVF9ST1VORF9UWVBFKVtrZXlvZiB0eXBlb2YgRE9VQkxFX0VMSU1JTkFUSU9OX0JSQUNLRVRfUk9VTkRfVFlQRV07XG5leHBvcnQgdHlwZSBTd2lzc0JyYWNrZXRSb3VuZFR5cGUgPSAodHlwZW9mIFNXSVNTX0JSQUNLRVRfUk9VTkRfVFlQRSlba2V5b2YgdHlwZW9mIFNXSVNTX0JSQUNLRVRfUk9VTkRfVFlQRV07XG5leHBvcnQgdHlwZSBHcm91cEJyYWNrZXRSb3VuZFR5cGUgPSAodHlwZW9mIEdST1VQX0JSQUNLRVRfUk9VTkRfVFlQRSlba2V5b2YgdHlwZW9mIEdST1VQX0JSQUNLRVRfUk9VTkRfVFlQRV07XG5cbmV4cG9ydCB0eXBlIEJyYWNrZXRSb3VuZFR5cGUgPVxuICB8IFNpbmdsZUVsaW1pbmF0aW9uQnJhY2tldFJvdW5kVHlwZVxuICB8IERvdWJsZUVsaW1pbmF0aW9uQnJhY2tldFJvdW5kVHlwZVxuICB8IFN3aXNzQnJhY2tldFJvdW5kVHlwZVxuICB8IEdyb3VwQnJhY2tldFJvdW5kVHlwZTtcblxuZXhwb3J0IHR5cGUgQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICAvLyBOT1RFOiBUaGlzIGlzIHRoZSBsb2dpY2FsIGluZGV4IGluc2lkZSB0aGUgYnJhY2tldC5cbiAgLy8gSW4gYSBkb3VibGUgZWxpbWluYXRpb24gYnJhY2tldCwgdGhlIGZpcnN0IHJvdW5kIG9mIHRoZSBsb3dlciBicmFja2V0IHdpbGwgaGF2ZSB0aGUgc2FtZSBpbmRleCBhcyB0aGUgZmluYWwgcm91bmQgb2YgdGhlIHVwcGVyIGJyYWNrZXRcbiAgaW5kZXg6IG51bWJlcjtcbiAgdHlwZTogQnJhY2tldFJvdW5kVHlwZTtcbiAgaWQ6IEJyYWNrZXRSb3VuZElkO1xuICBkYXRhOiBUUm91bmREYXRhO1xuICBwb3NpdGlvbjogQnJhY2tldFJvdW5kUG9zaXRpb247XG4gIG5hbWU6IHN0cmluZztcbiAgbWF0Y2hDb3VudDogbnVtYmVyO1xuICBtYXRjaGVzOiBCcmFja2V0TWF0Y2hNYXA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG59O1xuXG5leHBvcnQgdHlwZSBCcmFja2V0TWF0Y2hTdGF0dXMgPSAnY29tcGxldGVkJyB8ICdwZW5kaW5nJztcblxuZXhwb3J0IHR5cGUgQnJhY2tldE1hdGNoPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICBkYXRhOiBUTWF0Y2hEYXRhO1xuICBpbmRleEluUm91bmQ6IG51bWJlcjtcbiAgaWQ6IEJyYWNrZXRNYXRjaElkO1xuICByb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBwb3NpdGlvbjogQnJhY2tldE1hdGNoUG9zaXRpb247XG4gIGhvbWU6IE1hdGNoUGFydGljaXBhbnRJZCB8IG51bGw7XG4gIGF3YXk6IE1hdGNoUGFydGljaXBhbnRJZCB8IG51bGw7XG4gIHdpbm5lcjogT3Bwb25lbnRTaWRlIHwgbnVsbDtcbiAgc3RhdHVzOiBCcmFja2V0TWF0Y2hTdGF0dXM7XG59O1xuXG5leHBvcnQgdHlwZSBCcmFja2V0Um91bmRNYXA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSBNYXA8QnJhY2tldFJvdW5kSWQsIEJyYWNrZXRSb3VuZDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPj47XG5leHBvcnQgdHlwZSBCcmFja2V0TWF0Y2hNYXA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSBNYXA8QnJhY2tldE1hdGNoSWQsIEJyYWNrZXRNYXRjaDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPj47XG5cbmV4cG9ydCB0eXBlIEJyYWNrZXREYXRhPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICByb3VuZHM6IEJyYWNrZXRSb3VuZE1hcDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgbWF0Y2hlczogQnJhY2tldE1hdGNoTWFwPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBwYXJ0aWNpcGFudHM6IEJyYWNrZXRQYXJ0aWNpcGFudE1hcDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgbW9kZTogVG91cm5hbWVudE1vZGU7XG59O1xuXG5leHBvcnQgdHlwZSBBbnlCcmFja2V0RGF0YSA9IEJyYWNrZXREYXRhPHVua25vd24sIHVua25vd24+O1xuXG4vLyBPbmUgbWF0Y2ggaGFzIG9uZSBwcmV2aW91cyBtYXRjaCBhbmQgb25lIG5leHQgbWF0Y2ggKHRoaXMgd291bGQgYmUgdGhlIGNhc2UsIGlmIGEgZ3JvdXAgdG91cm5hbWVudCBpcyBiZWluZyBkaXNwbGF5ZWQgdmlhIGEgYnJhY2tldClcbmV4cG9ydCB0eXBlIEJyYWNrZXRNYXRjaFJlbGF0aW9uT25lVG9PbmU8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSB7XG4gIHR5cGU6ICdvbmUtdG8tb25lJztcbiAgY3VycmVudE1hdGNoOiBCcmFja2V0TWF0Y2g8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIGN1cnJlbnRSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBwcmV2aW91c01hdGNoOiBCcmFja2V0TWF0Y2g8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIHByZXZpb3VzUm91bmQ6IEJyYWNrZXRSb3VuZDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgbmV4dE1hdGNoOiBCcmFja2V0TWF0Y2g8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIG5leHRSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xufTtcblxuLy8gVGhlIG1hdGNoIGhhcyBubyBwcmV2aW91cyBtYXRjaCBidXQgYSBzaW5nbGUgbmV4dCBtYXRjaCAoZWcuIHRoZSBzdGFydCBvZiB0aGUgYnJhY2tldClcbmV4cG9ydCB0eXBlIEJyYWNrZXRNYXRjaFJlbGF0aW9uTm90aGluZ1RvT25lPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICB0eXBlOiAnbm90aGluZy10by1vbmUnO1xuICBjdXJyZW50TWF0Y2g6IEJyYWNrZXRNYXRjaDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgY3VycmVudFJvdW5kOiBCcmFja2V0Um91bmQ8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIG5leHRNYXRjaDogQnJhY2tldE1hdGNoPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBuZXh0Um91bmQ6IEJyYWNrZXRSb3VuZDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbn07XG5cbi8vIFRoZSBtYXRjaCBoYXMgbm8gbmV4dCBtYXRjaCBidXQgYSBzaW5nbGUgcHJldmlvdXMgbWF0Y2ggKGVnLiByZXZlcnNlIGZpbmFscylcbmV4cG9ydCB0eXBlIEJyYWNrZXRNYXRjaFJlbGF0aW9uT25lVG9Ob3RoaW5nPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICB0eXBlOiAnb25lLXRvLW5vdGhpbmcnO1xuICBjdXJyZW50TWF0Y2g6IEJyYWNrZXRNYXRjaDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgY3VycmVudFJvdW5kOiBCcmFja2V0Um91bmQ8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIHByZXZpb3VzTWF0Y2g6IEJyYWNrZXRNYXRjaDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgcHJldmlvdXNSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xufTtcblxuLy8gVGhlIG1hdGNoIGhhcyB0d28gcHJldmlvdXMgbWF0Y2hlcyBhbmQgb25lIG5leHQgbWF0Y2ggKGVnLiBhIG5vcm1hbCBtYXRjaCBpbiB0aGUgYnJhY2tldCB0aGF0IGlzIG5laXRoZXIgdGhlIHN0YXJ0IG5vciB0aGUgZW5kKVxuZXhwb3J0IHR5cGUgQnJhY2tldE1hdGNoUmVsYXRpb25Ud29Ub09uZTxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPiA9IHtcbiAgdHlwZTogJ3R3by10by1vbmUnO1xuICBjdXJyZW50TWF0Y2g6IEJyYWNrZXRNYXRjaDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgY3VycmVudFJvdW5kOiBCcmFja2V0Um91bmQ8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIHByZXZpb3VzVXBwZXJNYXRjaDogQnJhY2tldE1hdGNoPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBwcmV2aW91c1VwcGVyUm91bmQ6IEJyYWNrZXRSb3VuZDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgcHJldmlvdXNMb3dlck1hdGNoOiBCcmFja2V0TWF0Y2g8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIHByZXZpb3VzTG93ZXJSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBuZXh0TWF0Y2g6IEJyYWNrZXRNYXRjaDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgbmV4dFJvdW5kOiBCcmFja2V0Um91bmQ8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG59O1xuXG4vLyBUaGUgbWF0Y2ggaGFzIHR3byBwcmV2aW91cyBtYXRjaGVzIGFuZCBubyBuZXh0IG1hdGNoIChlZy4gdGhlIGZpbmFscyBpbiBhIHNpbmdsZSBlbGltaW5hdGlvbiBicmFja2V0KVxuZXhwb3J0IHR5cGUgQnJhY2tldE1hdGNoUmVsYXRpb25Ud29Ub05vdGhpbmc8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSB7XG4gIHR5cGU6ICd0d28tdG8tbm90aGluZyc7XG4gIGN1cnJlbnRNYXRjaDogQnJhY2tldE1hdGNoPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBjdXJyZW50Um91bmQ6IEJyYWNrZXRSb3VuZDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgcHJldmlvdXNVcHBlck1hdGNoOiBCcmFja2V0TWF0Y2g8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIHByZXZpb3VzVXBwZXJSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBwcmV2aW91c0xvd2VyTWF0Y2g6IEJyYWNrZXRNYXRjaDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgcHJldmlvdXNMb3dlclJvdW5kOiBCcmFja2V0Um91bmQ8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG59O1xuXG5leHBvcnQgdHlwZSBCcmFja2V0TWF0Y2hSZWxhdGlvbjxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPiA9XG4gIHwgQnJhY2tldE1hdGNoUmVsYXRpb25PbmVUb09uZTxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPlxuICB8IEJyYWNrZXRNYXRjaFJlbGF0aW9uVHdvVG9PbmU8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT5cbiAgfCBCcmFja2V0TWF0Y2hSZWxhdGlvbk5vdGhpbmdUb09uZTxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPlxuICB8IEJyYWNrZXRNYXRjaFJlbGF0aW9uT25lVG9Ob3RoaW5nPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+XG4gIHwgQnJhY2tldE1hdGNoUmVsYXRpb25Ud29Ub05vdGhpbmc8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG5cbmV4cG9ydCB0eXBlIEJyYWNrZXRNYXRjaFJlbGF0aW9uc01hcDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPiA9IE1hcDxcbiAgQnJhY2tldE1hdGNoSWQsXG4gIEJyYWNrZXRNYXRjaFJlbGF0aW9uPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+XG4+O1xuXG4vLyBPbmUgcm91bmQgaGFzIG9uZSBuZXh0IHJvdW5kICh0aGUgZmlyc3Qgcm91bmQgb2YgdGhlIGJyYWNrZXQpXG5leHBvcnQgdHlwZSBCcmFja2V0Um91bmRSZWxhdGlvbk5vdGhpbmdUb09uZTxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPiA9IHtcbiAgdHlwZTogJ25vdGhpbmctdG8tb25lJztcbiAgY3VycmVudFJvdW5kOiBCcmFja2V0Um91bmQ8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIG5leHRSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBuZXh0Um91bmRNYXRjaEZhY3RvcjogbnVtYmVyO1xufTtcblxuLy8gT25lIHJvdW5kIGhhcyBvbmUgcHJldmlvdXMgcm91bmQgKGVnLiB0aGUgZmluYWxzIHJvdW5kIG9mIHRoZSBicmFja2V0IGluIGNhc2Ugb2YgYSBzaW5nbGUgZWxpbWluYXRpb24gYnJhY2tldClcbmV4cG9ydCB0eXBlIEJyYWNrZXRSb3VuZFJlbGF0aW9uT25lVG9Ob3RoaW5nPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICB0eXBlOiAnb25lLXRvLW5vdGhpbmcnO1xuICBjdXJyZW50Um91bmQ6IEJyYWNrZXRSb3VuZDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgcHJldmlvdXNSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBwcmV2aW91c1JvdW5kTWF0Y2hGYWN0b3I6IG51bWJlcjtcbiAgcm9vdFJvdW5kTWF0Y2hGYWN0b3I6IG51bWJlcjtcbn07XG5cbi8vIE9uZSByb3VuZCBoYXMgb25lIHByZXZpb3VzIHJvdW5kIGFuZCBvbmUgbmV4dCByb3VuZCAoZWcuIGEgbm9ybWFsIHJvdW5kIGluIHRoZSBicmFja2V0IHRoYXQgaXMgbmVpdGhlciB0aGUgc3RhcnQgbm9yIHRoZSBlbmQpXG5leHBvcnQgdHlwZSBCcmFja2V0Um91bmRSZWxhdGlvbk9uZVRvT25lPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICB0eXBlOiAnb25lLXRvLW9uZSc7XG4gIGN1cnJlbnRSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBwcmV2aW91c1JvdW5kOiBCcmFja2V0Um91bmQ8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIG5leHRSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBuZXh0Um91bmRNYXRjaEZhY3RvcjogbnVtYmVyO1xuICBwcmV2aW91c1JvdW5kTWF0Y2hGYWN0b3I6IG51bWJlcjtcbiAgcm9vdFJvdW5kTWF0Y2hGYWN0b3I6IG51bWJlcjtcbn07XG5cbi8vIE9uZSByb3VuZCBoYXMgdHdvIHByZXZpb3VzIHJvdW5kcyBhbmQgb25lIG5leHQgcm91bmQgKGVnLiB0aGUgZmluYWxzIHJvdW5kIGluIGEgZG91YmxlIGVsaW1pbmF0aW9uIGJyYWNrZXQgd2hlbiB0aGUgcmV2ZXJzZSBmaW5hbHMgaXMgYWxzbyBiZWluZyBwbGF5ZWQpXG5leHBvcnQgdHlwZSBCcmFja2V0Um91bmRSZWxhdGlvblR3b1RvT25lPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICB0eXBlOiAndHdvLXRvLW9uZSc7XG4gIGN1cnJlbnRSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBwcmV2aW91c1VwcGVyUm91bmQ6IEJyYWNrZXRSb3VuZDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgcHJldmlvdXNMb3dlclJvdW5kOiBCcmFja2V0Um91bmQ8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIG5leHRSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBuZXh0Um91bmRNYXRjaEZhY3RvcjogbnVtYmVyO1xuICBwcmV2aW91c1VwcGVyUm91bmRNYXRjaEZhY3RvcjogbnVtYmVyO1xuICBwcmV2aW91c0xvd2VyUm91bmRNYXRjaEZhY3RvcjogbnVtYmVyO1xuICB1cHBlclJvb3RSb3VuZE1hdGNoRmFjdG9yOiBudW1iZXI7XG4gIGxvd2VyUm9vdFJvdW5kTWF0Y2hGYWN0b3I6IG51bWJlcjtcbn07XG5cbi8vIE9uZSByb3VuZCBoYXMgdHdvIHByZXZpb3VzIHJvdW5kcyBhbmQgbm8gbmV4dCByb3VuZCAoZWcuIHRoZSBmaW5hbHMgcm91bmQgaW4gYSBkb3VibGUgZWxpbWluYXRpb24gYnJhY2tldCB3aGVuIHRoZSByZXZlcnNlIGZpbmFscyBpcyBub3QgYmVpbmcgcGxheWVkKVxuZXhwb3J0IHR5cGUgQnJhY2tldFJvdW5kUmVsYXRpb25Ud29Ub05vdGhpbmc8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSB7XG4gIHR5cGU6ICd0d28tdG8tbm90aGluZyc7XG4gIGN1cnJlbnRSb3VuZDogQnJhY2tldFJvdW5kPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICBwcmV2aW91c1VwcGVyUm91bmQ6IEJyYWNrZXRSb3VuZDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgcHJldmlvdXNMb3dlclJvdW5kOiBCcmFja2V0Um91bmQ8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG4gIHByZXZpb3VzVXBwZXJSb3VuZE1hdGNoRmFjdG9yOiBudW1iZXI7XG4gIHByZXZpb3VzTG93ZXJSb3VuZE1hdGNoRmFjdG9yOiBudW1iZXI7XG4gIHVwcGVyUm9vdFJvdW5kTWF0Y2hGYWN0b3I6IG51bWJlcjtcbiAgbG93ZXJSb290Um91bmRNYXRjaEZhY3RvcjogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgQnJhY2tldFJvdW5kUmVsYXRpb248VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPVxuICB8IEJyYWNrZXRSb3VuZFJlbGF0aW9uTm90aGluZ1RvT25lPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+XG4gIHwgQnJhY2tldFJvdW5kUmVsYXRpb25PbmVUb05vdGhpbmc8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT5cbiAgfCBCcmFja2V0Um91bmRSZWxhdGlvbk9uZVRvT25lPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+XG4gIHwgQnJhY2tldFJvdW5kUmVsYXRpb25Ud29Ub09uZTxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPlxuICB8IEJyYWNrZXRSb3VuZFJlbGF0aW9uVHdvVG9Ob3RoaW5nPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuXG5leHBvcnQgdHlwZSBCcmFja2V0Um91bmRSZWxhdGlvbnM8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSBNYXA8XG4gIEJyYWNrZXRSb3VuZElkLFxuICBCcmFja2V0Um91bmRSZWxhdGlvbjxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPlxuPjtcblxuZXhwb3J0IHR5cGUgTWF0Y2hQb3NpdGlvbk1hcHM8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSBNYXA8XG4gIEJyYWNrZXRSb3VuZElkLFxuICBNYXA8QnJhY2tldE1hdGNoUG9zaXRpb24sIEJyYWNrZXRNYXRjaDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPj5cbj47XG5cbmV4cG9ydCB0eXBlIFBhcnRpY2lwYW50TWF0Y2hSZXN1bHQgPSAnd2luJyB8ICdsb3NzJyB8ICd0aWUnO1xuZXhwb3J0IHR5cGUgUGFydGljaXBhbnRNYXRjaFR5cGUgPSBCcmFja2V0Um91bmRUeXBlO1xuXG5leHBvcnQgdHlwZSBNYXRjaFBhcnRpY2lwYW50TWF0Y2g8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSB7XG4gIGJyYWNrZXRNYXRjaDogQnJhY2tldE1hdGNoPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xuICByZXN1bHQ6IFBhcnRpY2lwYW50TWF0Y2hSZXN1bHQgfCBudWxsO1xuICBpc0VsaW1pbmF0ZWQ6IGJvb2xlYW47XG4gIGlzRWxpbWluYXRpb25NYXRjaDogYm9vbGVhbjtcbiAgaXNGaXJzdFJvdW5kOiBib29sZWFuO1xuICBpc0xhc3RSb3VuZDogYm9vbGVhbjtcbiAgdGllQ291bnQ6IG51bWJlcjtcbiAgd2luQ291bnQ6IG51bWJlcjtcbiAgbG9zc0NvdW50OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBNYXRjaFBhcnRpY2lwYW50PFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICBpZDogTWF0Y2hQYXJ0aWNpcGFudElkO1xuICBuYW1lOiBzdHJpbmc7XG4gIG1hdGNoZXM6IE1hcDxCcmFja2V0TWF0Y2hJZCwgTWF0Y2hQYXJ0aWNpcGFudE1hdGNoPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+Pjtcbn07XG5cbmV4cG9ydCB0eXBlIEJyYWNrZXRQYXJ0aWNpcGFudE1hdGNoPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICBzaWRlOiBPcHBvbmVudFNpZGU7XG4gIGJyYWNrZXRNYXRjaDogQnJhY2tldE1hdGNoPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+O1xufTtcblxuZXhwb3J0IHR5cGUgQnJhY2tldFBhcnRpY2lwYW50PFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICBpZDogTWF0Y2hQYXJ0aWNpcGFudElkO1xuICBuYW1lOiBzdHJpbmc7XG4gIG1hdGNoZXM6IE1hcDxCcmFja2V0TWF0Y2hJZCwgQnJhY2tldFBhcnRpY2lwYW50TWF0Y2g8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4+O1xufTtcblxuZXhwb3J0IHR5cGUgQnJhY2tldFBhcnRpY2lwYW50TWFwPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0gTWFwPFxuICBNYXRjaFBhcnRpY2lwYW50SWQsXG4gIEJyYWNrZXRQYXJ0aWNpcGFudDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPlxuPjtcblxuZXhwb3J0IHR5cGUgTWF0Y2hQYXJ0aWNpcGFudE1hcDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPiA9IE1hcDxcbiAgTWF0Y2hQYXJ0aWNpcGFudElkLFxuICBNYXRjaFBhcnRpY2lwYW50PFRSb3VuZERhdGEsIFRNYXRjaERhdGE+XG4+O1xuXG5leHBvcnQgdHlwZSBCcmFja2V0Um91bmRTd2lzc0dyb3VwPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICBpZDogQnJhY2tldFJvdW5kU3dpc3NHcm91cElkO1xuICBuYW1lOiBzdHJpbmc7XG4gIG1hdGNoZXM6IEJyYWNrZXRNYXRjaE1hcDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgYWxsb3dlZE1hdGNoQ291bnQ6IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIEJyYWNrZXRSb3VuZFN3aXNzR3JvdXBNYXA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSBNYXA8XG4gIEJyYWNrZXRSb3VuZFN3aXNzR3JvdXBJZCxcbiAgQnJhY2tldFJvdW5kU3dpc3NHcm91cDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPlxuPjtcblxuZXhwb3J0IHR5cGUgQnJhY2tldFJvdW5kU3dpc3NEYXRhPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICBncm91cHM6IEJyYWNrZXRSb3VuZFN3aXNzR3JvdXBNYXA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT47XG59O1xuXG5leHBvcnQgdHlwZSBCcmFja2V0Um91bmRNYXBXaXRoU3dpc3NEYXRhPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0gTWFwPFxuICBCcmFja2V0Um91bmRJZCxcbiAgQnJhY2tldFJvdW5kU3dpc3NEYXRhPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+XG4+O1xuXG5leHBvcnQgdHlwZSBCcmFja2V0Um91bmRUeXBlTWFwPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0gTWFwPFxuICBCcmFja2V0Um91bmRUeXBlLFxuICBCcmFja2V0Um91bmRNYXA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT5cbj47XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZVJvdW5kVHlwZUZyb21FdGhsZXRlUm91bmRUeXBlID0gKFxuICB0eXBlOiBSb3VuZFR5cGUsXG4gIHRvdXJuYW1lbnRNb2RlOiBUb3VybmFtZW50TW9kZSxcbik6IEJyYWNrZXRSb3VuZFR5cGUgPT4ge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdub3JtYWwnOlxuICAgICAgc3dpdGNoICh0b3VybmFtZW50TW9kZSkge1xuICAgICAgICBjYXNlICdzaW5nbGUtZWxpbWluYXRpb24nOlxuICAgICAgICAgIHJldHVybiBTSU5HTEVfRUxJTUlOQVRJT05fQlJBQ0tFVF9ST1VORF9UWVBFLlNJTkdMRV9FTElNSU5BVElPTl9CUkFDS0VUO1xuICAgICAgICBjYXNlICdncm91cCc6XG4gICAgICAgICAgcmV0dXJuIEdST1VQX0JSQUNLRVRfUk9VTkRfVFlQRS5HUk9VUDtcbiAgICAgICAgY2FzZSAnc3dpc3MnOlxuICAgICAgICAgIHJldHVybiBTV0lTU19CUkFDS0VUX1JPVU5EX1RZUEUuU1dJU1M7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCB0b3VybmFtZW50IG1vZGUgZm9yIGEgbm9ybWFsIHR5cGUgcm91bmQ6ICR7dG91cm5hbWVudE1vZGV9YCk7XG4gICAgICB9XG4gICAgY2FzZSAndGhpcmRfcGxhY2UnOlxuICAgICAgcmV0dXJuIENPTU1PTl9CUkFDS0VUX1JPVU5EX1RZUEUuVEhJUkRfUExBQ0U7XG4gICAgY2FzZSAnZmluYWwnOlxuICAgICAgcmV0dXJuIENPTU1PTl9CUkFDS0VUX1JPVU5EX1RZUEUuRklOQUw7XG4gICAgY2FzZSAncmV2ZXJzZV9maW5hbCc6XG4gICAgICByZXR1cm4gRE9VQkxFX0VMSU1JTkFUSU9OX0JSQUNLRVRfUk9VTkRfVFlQRS5SRVZFUlNFX0ZJTkFMO1xuICAgIGNhc2UgJ3dpbm5lcl9icmFja2V0JzpcbiAgICAgIHJldHVybiBET1VCTEVfRUxJTUlOQVRJT05fQlJBQ0tFVF9ST1VORF9UWVBFLlVQUEVSX0JSQUNLRVQ7XG4gICAgY2FzZSAnbG9zZXJfYnJhY2tldCc6XG4gICAgICByZXR1cm4gRE9VQkxFX0VMSU1JTkFUSU9OX0JSQUNLRVRfUk9VTkRfVFlQRS5MT1dFUl9CUkFDS0VUO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZ2VuZXJhdGVUb3VybmFtZW50TW9kZUZvcm1FdGhsZXRlUm91bmRzID0gKFxuICBzb3VyY2U6IFJvdW5kU3RhZ2VTdHJ1Y3R1cmVXaXRoTWF0Y2hlc1ZpZXdbXSxcbik6IFRvdXJuYW1lbnRNb2RlID0+IHtcbiAgY29uc3QgZmlyc3RSb3VuZCA9IHNvdXJjZVswXTtcbiAgY29uc3QgZmlyc3RNYXRjaCA9IGZpcnN0Um91bmQ/Lm1hdGNoZXNbMF07XG5cbiAgaWYgKCFmaXJzdFJvdW5kKSB0aHJvdyBuZXcgRXJyb3IoJ05vIHJvdW5kcyBmb3VuZCcpO1xuICBpZiAoIWZpcnN0TWF0Y2gpIHRocm93IG5ldyBFcnJvcignTm8gbWF0Y2hlcyBmb3VuZCcpO1xuXG4gIHN3aXRjaCAoZmlyc3RNYXRjaC5tYXRjaFR5cGUpIHtcbiAgICBjYXNlICdncm91cHMnOlxuICAgICAgcmV0dXJuIFRPVVJOQU1FTlRfTU9ERS5HUk9VUDtcbiAgICBjYXNlICdmaWZhX3N3aXNzJzoge1xuICAgICAgY29uc3QgbGFzdFJvdW5kID0gc291cmNlW3NvdXJjZS5sZW5ndGggLSAxXTtcblxuICAgICAgaWYgKCFsYXN0Um91bmQpIHRocm93IG5ldyBFcnJvcignTm8gbGFzdCByb3VuZCBmb3VuZCcpO1xuXG4gICAgICBpZiAobGFzdFJvdW5kLm1hdGNoZXMubGVuZ3RoICE9PSBmaXJzdFJvdW5kLm1hdGNoZXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBUT1VSTkFNRU5UX01PREUuU1dJU1NfV0lUSF9FTElNSU5BVElPTjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBUT1VSTkFNRU5UX01PREUuU1dJU1M7XG4gICAgICB9XG4gICAgfVxuICAgIGNhc2UgJ2RvdWJsZV9lbGltaW5hdGlvbic6XG4gICAgICByZXR1cm4gVE9VUk5BTUVOVF9NT0RFLkRPVUJMRV9FTElNSU5BVElPTjtcbiAgICBjYXNlICdzaW5nbGVfZWxpbWluYXRpb24nOlxuICAgICAgcmV0dXJuIFRPVVJOQU1FTlRfTU9ERS5TSU5HTEVfRUxJTUlOQVRJT047XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdG91cm5hbWVudCBtb2RlOiAke2ZpcnN0TWF0Y2gubWF0Y2hUeXBlfWApO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZ2VuZXJhdGVCcmFja2V0RGF0YUZvckV0aGxldGUgPSAoc291cmNlOiBSb3VuZFN0YWdlU3RydWN0dXJlV2l0aE1hdGNoZXNWaWV3W10pID0+IHtcbiAgY29uc3QgdG91cm5hbWVudE1vZGUgPSBnZW5lcmF0ZVRvdXJuYW1lbnRNb2RlRm9ybUV0aGxldGVSb3VuZHMoc291cmNlKTtcblxuICBjb25zdCBicmFja2V0RGF0YTogQnJhY2tldERhdGE8Um91bmRTdGFnZVN0cnVjdHVyZVZpZXcsIE1hdGNoTGlzdFZpZXdVbmlvbj4gPSB7XG4gICAgcm91bmRzOiBuZXcgTWFwKCksXG4gICAgbWF0Y2hlczogbmV3IE1hcCgpLFxuICAgIHBhcnRpY2lwYW50czogbmV3IE1hcCgpLFxuICAgIG1vZGU6IHRvdXJuYW1lbnRNb2RlLFxuICB9O1xuXG4gIGxldCBjdXJyZW50VXBwZXJCcmFja2V0SW5kZXggPSAwO1xuICBsZXQgY3VycmVudExvd2VyQnJhY2tldEluZGV4ID0gMDtcblxuICBmb3IgKGNvbnN0IGN1cnJlbnRJdGVtIG9mIHNvdXJjZSkge1xuICAgIGlmIChicmFja2V0RGF0YS5yb3VuZHMuaGFzKGN1cnJlbnRJdGVtLnJvdW5kLmlkIGFzIEJyYWNrZXRSb3VuZElkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSb3VuZCB3aXRoIGlkICR7Y3VycmVudEl0ZW0ucm91bmQuaWR9IGFscmVhZHkgZXhpc3RzIGluIHRoZSBicmFja2V0IGRhdGEuYCk7XG4gICAgfVxuXG4gICAgY29uc3Qgcm91bmRUeXBlID0gZ2VuZXJhdGVSb3VuZFR5cGVGcm9tRXRobGV0ZVJvdW5kVHlwZShjdXJyZW50SXRlbS5yb3VuZC50eXBlLCB0b3VybmFtZW50TW9kZSk7XG4gICAgY29uc3QgaXNMb3dlckJyYWNrZXQgPSByb3VuZFR5cGUgPT09IERPVUJMRV9FTElNSU5BVElPTl9CUkFDS0VUX1JPVU5EX1RZUEUuTE9XRVJfQlJBQ0tFVDtcblxuICAgIGNvbnN0IGJyYWNrZXRSb3VuZDogQnJhY2tldFJvdW5kPFJvdW5kU3RhZ2VTdHJ1Y3R1cmVWaWV3LCBNYXRjaExpc3RWaWV3VW5pb24+ID0ge1xuICAgICAgdHlwZTogcm91bmRUeXBlLFxuICAgICAgaWQ6IGN1cnJlbnRJdGVtLnJvdW5kLmlkIGFzIEJyYWNrZXRSb3VuZElkLFxuICAgICAgaW5kZXg6IGlzTG93ZXJCcmFja2V0ID8gY3VycmVudExvd2VyQnJhY2tldEluZGV4IDogY3VycmVudFVwcGVyQnJhY2tldEluZGV4LFxuICAgICAgZGF0YTogY3VycmVudEl0ZW0ucm91bmQsXG4gICAgICBwb3NpdGlvbjogY3VycmVudEl0ZW0ucm91bmQubnVtYmVyIGFzIEJyYWNrZXRSb3VuZFBvc2l0aW9uLFxuICAgICAgbmFtZTogY3VycmVudEl0ZW0ucm91bmQubmFtZSB8fCBjdXJyZW50SXRlbS5yb3VuZC50eXBlLFxuICAgICAgbWF0Y2hDb3VudDogY3VycmVudEl0ZW0ubWF0Y2hlcy5sZW5ndGgsXG4gICAgICBtYXRjaGVzOiBuZXcgTWFwKCksXG4gICAgfTtcblxuICAgIGJyYWNrZXREYXRhLnJvdW5kcy5zZXQoY3VycmVudEl0ZW0ucm91bmQuaWQgYXMgQnJhY2tldFJvdW5kSWQsIGJyYWNrZXRSb3VuZCk7XG5cbiAgICBmb3IgKGNvbnN0IFttYXRjaEluZGV4LCBtYXRjaF0gb2YgY3VycmVudEl0ZW0ubWF0Y2hlcy5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChicmFja2V0RGF0YS5tYXRjaGVzLmhhcyhtYXRjaC5pZCBhcyBCcmFja2V0TWF0Y2hJZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNYXRjaCB3aXRoIGlkICR7bWF0Y2guaWR9IGFscmVhZHkgZXhpc3RzIGluIHRoZSBicmFja2V0IGRhdGEuYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJyYWNrZXRNYXRjaDogQnJhY2tldE1hdGNoPFJvdW5kU3RhZ2VTdHJ1Y3R1cmVWaWV3LCBNYXRjaExpc3RWaWV3VW5pb24+ID0ge1xuICAgICAgICBpZDogbWF0Y2guaWQgYXMgQnJhY2tldE1hdGNoSWQsXG4gICAgICAgIGluZGV4SW5Sb3VuZDogbWF0Y2hJbmRleCxcbiAgICAgICAgcG9zaXRpb246IChtYXRjaEluZGV4ICsgMSkgYXMgQnJhY2tldE1hdGNoUG9zaXRpb24sXG4gICAgICAgIGRhdGE6IG1hdGNoLFxuICAgICAgICByb3VuZDogYnJhY2tldFJvdW5kLFxuICAgICAgICBob21lOiAobWF0Y2guaG9tZT8uaWQgYXMgTWF0Y2hQYXJ0aWNpcGFudElkKSB8fCBudWxsLFxuICAgICAgICBhd2F5OiAobWF0Y2guYXdheT8uaWQgYXMgTWF0Y2hQYXJ0aWNpcGFudElkKSB8fCBudWxsLFxuICAgICAgICB3aW5uZXI6IG1hdGNoLndpbm5pbmdTaWRlLFxuICAgICAgICBzdGF0dXM6IG1hdGNoLnN0YXR1cyA9PT0gJ3B1Ymxpc2hlZCcgPyAnY29tcGxldGVkJyA6ICdwZW5kaW5nJyxcbiAgICAgIH07XG5cbiAgICAgIGJyYWNrZXREYXRhLm1hdGNoZXMuc2V0KG1hdGNoLmlkIGFzIEJyYWNrZXRNYXRjaElkLCBicmFja2V0TWF0Y2gpO1xuICAgICAgYnJhY2tldFJvdW5kLm1hdGNoZXMuc2V0KG1hdGNoLmlkIGFzIEJyYWNrZXRNYXRjaElkLCBicmFja2V0TWF0Y2gpO1xuXG4gICAgICBjb25zdCBwYXJ0aWNpcGFudHMgPSBbbWF0Y2guaG9tZSwgbWF0Y2guYXdheV07XG5cbiAgICAgIGZvciAoY29uc3QgcGFydGljaXBhbnQgb2YgcGFydGljaXBhbnRzKSB7XG4gICAgICAgIGlmICghcGFydGljaXBhbnQpIGNvbnRpbnVlO1xuXG4gICAgICAgIGNvbnN0IHBhcnRpY2lwYW50SWQgPSBwYXJ0aWNpcGFudC5pZCBhcyBNYXRjaFBhcnRpY2lwYW50SWQ7XG5cbiAgICAgICAgaWYgKCFicmFja2V0RGF0YS5wYXJ0aWNpcGFudHMuaGFzKHBhcnRpY2lwYW50SWQpKSB7XG4gICAgICAgICAgYnJhY2tldERhdGEucGFydGljaXBhbnRzLnNldChwYXJ0aWNpcGFudElkLCB7XG4gICAgICAgICAgICBpZDogcGFydGljaXBhbnRJZCxcbiAgICAgICAgICAgIG5hbWU6IHBhcnRpY2lwYW50Lm5hbWUgfHwgJ1Vua25vd24nLFxuICAgICAgICAgICAgbWF0Y2hlczogbmV3IE1hcCgpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGFydGljaXBhbnREYXRhID0gYnJhY2tldERhdGEucGFydGljaXBhbnRzLmdldChwYXJ0aWNpcGFudElkKSBhcyBCcmFja2V0UGFydGljaXBhbnQ8XG4gICAgICAgICAgUm91bmRTdGFnZVN0cnVjdHVyZVZpZXcsXG4gICAgICAgICAgTWF0Y2hMaXN0Vmlld1VuaW9uXG4gICAgICAgID47XG5cbiAgICAgICAgaWYgKCFwYXJ0aWNpcGFudERhdGEubWF0Y2hlcy5oYXMobWF0Y2guaWQgYXMgQnJhY2tldE1hdGNoSWQpKSB7XG4gICAgICAgICAgcGFydGljaXBhbnREYXRhLm1hdGNoZXMuc2V0KG1hdGNoLmlkIGFzIEJyYWNrZXRNYXRjaElkLCB7XG4gICAgICAgICAgICBzaWRlOiBtYXRjaC5ob21lPy5pZCA9PT0gcGFydGljaXBhbnRJZCA/ICdob21lJyA6ICdhd2F5JyxcbiAgICAgICAgICAgIGJyYWNrZXRNYXRjaCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc0xvd2VyQnJhY2tldCkge1xuICAgICAgY3VycmVudExvd2VyQnJhY2tldEluZGV4Kys7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJlbnRVcHBlckJyYWNrZXRJbmRleCsrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBicmFja2V0RGF0YTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZU1hdGNoUG9zaXRpb25NYXBzID0gPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+KGJyYWNrZXREYXRhOiBCcmFja2V0RGF0YTxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPikgPT4ge1xuICBjb25zdCBtYXRjaFBvc2l0aW9uTWFwczogTWF0Y2hQb3NpdGlvbk1hcHM8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSBuZXcgTWFwKCk7XG5cbiAgZm9yIChjb25zdCByb3VuZCBvZiBicmFja2V0RGF0YS5yb3VuZHMudmFsdWVzKCkpIHtcbiAgICBjb25zdCBtYXRjaE1hcCA9IG5ldyBNYXAoWy4uLnJvdW5kLm1hdGNoZXMudmFsdWVzKCldLm1hcCgobSkgPT4gW20ucG9zaXRpb24sIG1dKSk7XG5cbiAgICBtYXRjaFBvc2l0aW9uTWFwcy5zZXQocm91bmQuaWQsIG1hdGNoTWFwKTtcbiAgfVxuXG4gIHJldHVybiBtYXRjaFBvc2l0aW9uTWFwcztcbn07XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZUJyYWNrZXRSb3VuZFR5cGVNYXAgPSA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4oXG4gIGJyYWNrZXREYXRhOiBCcmFja2V0RGF0YTxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPixcbikgPT4ge1xuICBjb25zdCByb3VuZEFtb3VudE1hcDogQnJhY2tldFJvdW5kVHlwZU1hcDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPiA9IG5ldyBNYXAoKTtcblxuICBmb3IgKGNvbnN0IHJvdW5kIG9mIGJyYWNrZXREYXRhLnJvdW5kcy52YWx1ZXMoKSkge1xuICAgIGlmICghcm91bmRBbW91bnRNYXAuaGFzKHJvdW5kLnR5cGUpKSB7XG4gICAgICByb3VuZEFtb3VudE1hcC5zZXQocm91bmQudHlwZSwgbmV3IE1hcChbW3JvdW5kLmlkLCByb3VuZF1dKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICByb3VuZEFtb3VudE1hcC5zZXQocm91bmQudHlwZSwgcm91bmRBbW91bnRNYXAuZ2V0KHJvdW5kLnR5cGUpIS5zZXQocm91bmQuaWQsIHJvdW5kKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJvdW5kQW1vdW50TWFwO1xufTtcblxuY29uc3QgVVBQRVJfTE9PUF9PUkRFUjogQnJhY2tldFJvdW5kVHlwZVtdID0gW1xuICBTSU5HTEVfRUxJTUlOQVRJT05fQlJBQ0tFVF9ST1VORF9UWVBFLlNJTkdMRV9FTElNSU5BVElPTl9CUkFDS0VULFxuICBET1VCTEVfRUxJTUlOQVRJT05fQlJBQ0tFVF9ST1VORF9UWVBFLlVQUEVSX0JSQUNLRVQsXG4gIFNXSVNTX0JSQUNLRVRfUk9VTkRfVFlQRS5TV0lTUyxcbiAgR1JPVVBfQlJBQ0tFVF9ST1VORF9UWVBFLkdST1VQLFxuICBDT01NT05fQlJBQ0tFVF9ST1VORF9UWVBFLkZJTkFMLFxuICBET1VCTEVfRUxJTUlOQVRJT05fQlJBQ0tFVF9ST1VORF9UWVBFLlJFVkVSU0VfRklOQUwsXG4gIENPTU1PTl9CUkFDS0VUX1JPVU5EX1RZUEUuVEhJUkRfUExBQ0UsXG5dO1xuXG5jb25zdCBMT1dFUl9MT09QX09SREVSOiBCcmFja2V0Um91bmRUeXBlW10gPSBbRE9VQkxFX0VMSU1JTkFUSU9OX0JSQUNLRVRfUk9VTkRfVFlQRS5MT1dFUl9CUkFDS0VUXTtcblxuZXhwb3J0IGNvbnN0IGdlbmVyYXRlUm91bmRSZWxhdGlvbnMgPSA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4oYnJhY2tldERhdGE6IEJyYWNrZXREYXRhPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+KSA9PiB7XG4gIGNvbnN0IHJvdW5kUmVsYXRpb25zOiBCcmFja2V0Um91bmRSZWxhdGlvbnM8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSBuZXcgTWFwKCk7XG5cbiAgY29uc3Qgc29ydGVkUm91bmRzQnlUeXBlID0gbmV3IE1hcDxCcmFja2V0Um91bmRUeXBlLCBCcmFja2V0Um91bmQ8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT5bXT4oKTtcblxuICBmb3IgKGNvbnN0IHJvdW5kIG9mIGJyYWNrZXREYXRhLnJvdW5kcy52YWx1ZXMoKSkge1xuICAgIGlmICghc29ydGVkUm91bmRzQnlUeXBlLmhhcyhyb3VuZC50eXBlKSkge1xuICAgICAgc29ydGVkUm91bmRzQnlUeXBlLnNldChyb3VuZC50eXBlLCBbcm91bmRdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc29ydGVkUm91bmRzQnlUeXBlLmdldChyb3VuZC50eXBlKT8ucHVzaChyb3VuZCk7XG4gICAgfVxuICB9XG5cbiAgZm9yIChjb25zdCByb3VuZHMgb2Ygc29ydGVkUm91bmRzQnlUeXBlLnZhbHVlcygpKSB7XG4gICAgaWYgKHJvdW5kcy5sZW5ndGggPT09IDEpIGNvbnRpbnVlO1xuXG4gICAgcm91bmRzLnNvcnQoKGEsIGIpID0+IGEucG9zaXRpb24gLSBiLnBvc2l0aW9uKTtcbiAgfVxuXG4gIGNvbnN0IHNvcnRlZFVwcGVyUm91bmRzID0gVVBQRVJfTE9PUF9PUkRFUi5tYXAoKHQpID0+IHNvcnRlZFJvdW5kc0J5VHlwZS5nZXQodCkpXG4gICAgLmZpbHRlcigocikgPT4gISFyKVxuICAgIC5mbGF0KCk7XG4gIGNvbnN0IHNvcnRlZExvd2VyUm91bmRzID0gTE9XRVJfTE9PUF9PUkRFUi5tYXAoKHQpID0+IHNvcnRlZFJvdW5kc0J5VHlwZS5nZXQodCkpXG4gICAgLmZpbHRlcigocikgPT4gISFyKVxuICAgIC5mbGF0KCk7XG5cbiAgY29uc3QgZmlyc3RVcHBlclJvdW5kID0gc29ydGVkVXBwZXJSb3VuZHNbMF0gfHwgbnVsbDtcbiAgY29uc3QgZmlyc3RMb3dlclJvdW5kID0gc29ydGVkTG93ZXJSb3VuZHNbMF0gfHwgbnVsbDtcblxuICBpZiAoIWZpcnN0VXBwZXJSb3VuZCkgdGhyb3cgbmV3IEVycm9yKCdmaXJzdFVwcGVyUm91bmQgaXMgbnVsbCcpO1xuXG4gIGNvbnN0IGhhc0xvd2VyUm91bmRzID0gc29ydGVkTG93ZXJSb3VuZHMubGVuZ3RoID4gMDtcbiAgY29uc3QgbGFzdExvd2VyUm91bmQgPSBzb3J0ZWRMb3dlclJvdW5kc1tzb3J0ZWRMb3dlclJvdW5kcy5sZW5ndGggLSAxXSB8fCBudWxsO1xuXG4gIGZvciAoY29uc3QgW2N1cnJlbnRVcHBlclJvdW5kSW5kZXgsIGN1cnJlbnRVcHBlclJvdW5kXSBvZiBzb3J0ZWRVcHBlclJvdW5kcy5lbnRyaWVzKCkpIHtcbiAgICBjb25zdCBwcmV2aW91c1VwcGVyUm91bmQgPSBzb3J0ZWRVcHBlclJvdW5kc1tjdXJyZW50VXBwZXJSb3VuZEluZGV4IC0gMV0gfHwgbnVsbDtcbiAgICBjb25zdCBuZXh0VXBwZXJSb3VuZCA9IHNvcnRlZFVwcGVyUm91bmRzW2N1cnJlbnRVcHBlclJvdW5kSW5kZXggKyAxXSB8fCBudWxsO1xuXG4gICAgY29uc3QgY3VycmVudExvd2VyUm91bmQgPSBzb3J0ZWRMb3dlclJvdW5kc1tjdXJyZW50VXBwZXJSb3VuZEluZGV4XSB8fCBudWxsO1xuICAgIGNvbnN0IHByZXZpb3VzTG93ZXJSb3VuZCA9IHNvcnRlZExvd2VyUm91bmRzW2N1cnJlbnRVcHBlclJvdW5kSW5kZXggLSAxXSB8fCBudWxsO1xuICAgIGNvbnN0IG5leHRMb3dlclJvdW5kID0gc29ydGVkTG93ZXJSb3VuZHNbY3VycmVudFVwcGVyUm91bmRJbmRleCArIDFdIHx8IG51bGw7XG5cbiAgICBjb25zdCBpc0ZpcnN0Um91bmQgPSBjdXJyZW50VXBwZXJSb3VuZEluZGV4ID09PSAwO1xuICAgIGNvbnN0IGlzTGFzdFVwcGVyUm91bmQgPSBjdXJyZW50VXBwZXJSb3VuZEluZGV4ID09PSBzb3J0ZWRVcHBlclJvdW5kcy5sZW5ndGggLSAxO1xuXG4gICAgY29uc3QgaXNGaW5hbCA9IGN1cnJlbnRVcHBlclJvdW5kLnR5cGUgPT09IENPTU1PTl9CUkFDS0VUX1JPVU5EX1RZUEUuRklOQUw7XG5cbiAgICBpZiAoaXNGaW5hbCAmJiBoYXNMb3dlclJvdW5kcykge1xuICAgICAgLy8gdHdvIHRvIG9uZSByZWxhdGlvblxuXG4gICAgICBpZiAoIWxhc3RMb3dlclJvdW5kIHx8ICFjdXJyZW50TG93ZXJSb3VuZCB8fCAhcHJldmlvdXNVcHBlclJvdW5kKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xhc3RMb3dlclJvdW5kIG9yIGN1cnJlbnRMb3dlclJvdW5kIG9yIHByZXZpb3VzVXBwZXJSb3VuZCBpcyBudWxsJyk7XG5cbiAgICAgIC8vIGluIGEgc3luYyBkb3VibGUgZWxpbWluYXRpb24gYnJhY2tldCwgdGhlIGZpbmFsIHJvdW5kIGhhcyB0aGUgc2FtZSBpbmRleCBhcyB0aGUgbGFzdCBsb3dlciByb3VuZFxuICAgICAgLy8gaW4gYW4gYXN5bmMgb25lLCB0aGVyZSBpcyBhbHdheXMgb25lIG1vcmUgcm91bmQgaW4gdGhlIGxvd2VyIGJyYWNrZXQgc2luY2Ugd2Ugb25seSBkaXNwbGF5IGEgc2VjdGlvbiBvZiB0aGUgd2hvbGUgdG91cm5hbWVudFxuICAgICAgY29uc3QgaXNBc3luY0JyYWNrZXQgPSBjdXJyZW50TG93ZXJSb3VuZC5pZCAhPT0gbGFzdExvd2VyUm91bmQuaWQ7XG4gICAgICBjb25zdCBmaW5hbExvd2VyUm91bmQgPSBpc0FzeW5jQnJhY2tldCA/IG5leHRMb3dlclJvdW5kIDogY3VycmVudExvd2VyUm91bmQ7XG5cbiAgICAgIGlmICghZmluYWxMb3dlclJvdW5kKSB0aHJvdyBuZXcgRXJyb3IoJ2ZpbmFsTG93ZXJSb3VuZCBpcyBudWxsJyk7XG4gICAgICBpZiAoIWZpcnN0TG93ZXJSb3VuZCkgdGhyb3cgbmV3IEVycm9yKCdmaXJzdExvd2VyUm91bmQgaXMgbnVsbCcpO1xuXG4gICAgICBpZiAoZmluYWxMb3dlclJvdW5kLmlkICE9PSBsYXN0TG93ZXJSb3VuZC5pZCkgdGhyb3cgbmV3IEVycm9yKCdmaW5hbExvd2VyUm91bmQgaXMgbm90IHRoZSBsYXN0IGxvd2VyIHJvdW5kJyk7XG5cbiAgICAgIC8vIGlmIHdlIGhhdmUgYSByZXZlcnNlIGZpbmFsXG4gICAgICBpZiAobmV4dFVwcGVyUm91bmQpIHtcbiAgICAgICAgLy8gZm9yIHRoZSBmaW5hbFxuICAgICAgICByb3VuZFJlbGF0aW9ucy5zZXQoY3VycmVudFVwcGVyUm91bmQuaWQsIHtcbiAgICAgICAgICB0eXBlOiAndHdvLXRvLW9uZScsXG4gICAgICAgICAgcHJldmlvdXNVcHBlclJvdW5kOiBwcmV2aW91c1VwcGVyUm91bmQsXG4gICAgICAgICAgcHJldmlvdXNMb3dlclJvdW5kOiBmaW5hbExvd2VyUm91bmQsXG4gICAgICAgICAgbmV4dFJvdW5kOiBuZXh0VXBwZXJSb3VuZCxcbiAgICAgICAgICBjdXJyZW50Um91bmQ6IGN1cnJlbnRVcHBlclJvdW5kLFxuICAgICAgICAgIG5leHRSb3VuZE1hdGNoRmFjdG9yOiBuZXh0VXBwZXJSb3VuZC5tYXRjaENvdW50IC8gY3VycmVudFVwcGVyUm91bmQubWF0Y2hDb3VudCxcbiAgICAgICAgICBwcmV2aW91c1VwcGVyUm91bmRNYXRjaEZhY3RvcjogcHJldmlvdXNVcHBlclJvdW5kLm1hdGNoQ291bnQgLyBjdXJyZW50VXBwZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICAgIHByZXZpb3VzTG93ZXJSb3VuZE1hdGNoRmFjdG9yOiBmaW5hbExvd2VyUm91bmQubWF0Y2hDb3VudCAvIGN1cnJlbnRVcHBlclJvdW5kLm1hdGNoQ291bnQsXG4gICAgICAgICAgdXBwZXJSb290Um91bmRNYXRjaEZhY3RvcjogZmlyc3RVcHBlclJvdW5kLm1hdGNoQ291bnQgLyBjdXJyZW50VXBwZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICAgIGxvd2VyUm9vdFJvdW5kTWF0Y2hGYWN0b3I6IGZpcnN0TG93ZXJSb3VuZC5tYXRjaENvdW50IC8gY3VycmVudFVwcGVyUm91bmQubWF0Y2hDb3VudCxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBubyByZXZlcnNlIGZpbmFsIG1lYW5zIHRoZSBmaW5hbCBpcyB0aGUgbGFzdCByb3VuZFxuXG4gICAgICAgIC8vIGZvciB0aGUgZmluYWxcbiAgICAgICAgcm91bmRSZWxhdGlvbnMuc2V0KGN1cnJlbnRVcHBlclJvdW5kLmlkLCB7XG4gICAgICAgICAgdHlwZTogJ3R3by10by1ub3RoaW5nJyxcbiAgICAgICAgICBwcmV2aW91c1VwcGVyUm91bmQ6IHByZXZpb3VzVXBwZXJSb3VuZCxcbiAgICAgICAgICBwcmV2aW91c0xvd2VyUm91bmQ6IGZpbmFsTG93ZXJSb3VuZCxcbiAgICAgICAgICBjdXJyZW50Um91bmQ6IGN1cnJlbnRVcHBlclJvdW5kLFxuICAgICAgICAgIHByZXZpb3VzTG93ZXJSb3VuZE1hdGNoRmFjdG9yOiBmaW5hbExvd2VyUm91bmQubWF0Y2hDb3VudCAvIGN1cnJlbnRVcHBlclJvdW5kLm1hdGNoQ291bnQsXG4gICAgICAgICAgcHJldmlvdXNVcHBlclJvdW5kTWF0Y2hGYWN0b3I6IHByZXZpb3VzVXBwZXJSb3VuZC5tYXRjaENvdW50IC8gY3VycmVudFVwcGVyUm91bmQubWF0Y2hDb3VudCxcbiAgICAgICAgICBsb3dlclJvb3RSb3VuZE1hdGNoRmFjdG9yOiBmaXJzdExvd2VyUm91bmQubWF0Y2hDb3VudCAvIGN1cnJlbnRVcHBlclJvdW5kLm1hdGNoQ291bnQsXG4gICAgICAgICAgdXBwZXJSb290Um91bmRNYXRjaEZhY3RvcjogZmlyc3RVcHBlclJvdW5kLm1hdGNoQ291bnQgLyBjdXJyZW50VXBwZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXN5bmNCcmFja2V0KSB7XG4gICAgICAgIC8vIGlmIHRoaXMgaXMgYW4gYXN5bmMgYnJhY2tldCwgd2UgbmVlZCB0byBzZXQgdGhlIHJlbGF0aW9ucyBmb3IgdGhlIDIgbGFzdCBsb3dlciByb3VuZHMgc2luY2UgdGhleSB3aWxsIGJlIHNraXBwZWQgYnkgdGhlIGRlZmF1bHQgb25lIHRvIG9uZSBsb2dpY1xuICAgICAgICBjb25zdCBwcmVGaW5hbExvd2VyUm91bmQgPSBzb3J0ZWRMb3dlclJvdW5kc1tzb3J0ZWRMb3dlclJvdW5kcy5sZW5ndGggLSAyXSB8fCBudWxsO1xuICAgICAgICBjb25zdCBwcmVQcmVGaW5hbExvd2VyUm91bmQgPSBzb3J0ZWRMb3dlclJvdW5kc1tzb3J0ZWRMb3dlclJvdW5kcy5sZW5ndGggLSAzXSB8fCBudWxsO1xuXG4gICAgICAgIGlmICghcHJlRmluYWxMb3dlclJvdW5kKSB0aHJvdyBuZXcgRXJyb3IoJ3ByZUZpbmFsTG93ZXJSb3VuZCBpcyBudWxsJyk7XG5cbiAgICAgICAgaWYgKCFmaXJzdExvd2VyUm91bmQpIHRocm93IG5ldyBFcnJvcignZmlyc3RMb3dlclJvdW5kIGlzIG51bGwnKTtcblxuICAgICAgICAvLyBmb3IgdGhlIGxhc3QgbG93ZXIgcm91bmRcbiAgICAgICAgcm91bmRSZWxhdGlvbnMuc2V0KGZpbmFsTG93ZXJSb3VuZC5pZCwge1xuICAgICAgICAgIHR5cGU6ICdvbmUtdG8tb25lJyxcbiAgICAgICAgICBwcmV2aW91c1JvdW5kOiBwcmVGaW5hbExvd2VyUm91bmQsXG4gICAgICAgICAgbmV4dFJvdW5kOiBjdXJyZW50VXBwZXJSb3VuZCxcbiAgICAgICAgICBjdXJyZW50Um91bmQ6IGZpbmFsTG93ZXJSb3VuZCxcbiAgICAgICAgICBuZXh0Um91bmRNYXRjaEZhY3RvcjogY3VycmVudFVwcGVyUm91bmQubWF0Y2hDb3VudCAvIGZpbmFsTG93ZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICAgIHByZXZpb3VzUm91bmRNYXRjaEZhY3RvcjogcHJlRmluYWxMb3dlclJvdW5kLm1hdGNoQ291bnQgLyBmaW5hbExvd2VyUm91bmQubWF0Y2hDb3VudCxcbiAgICAgICAgICByb290Um91bmRNYXRjaEZhY3RvcjogZmlyc3RMb3dlclJvdW5kLm1hdGNoQ291bnQgLyBmaW5hbExvd2VyUm91bmQubWF0Y2hDb3VudCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHByZVByZUZpbmFsTG93ZXJSb3VuZCkge1xuICAgICAgICAgIC8vIGZvciB0aGUgcHJlIGZpbmFsIGxvd2VyIHJvdW5kXG4gICAgICAgICAgcm91bmRSZWxhdGlvbnMuc2V0KHByZUZpbmFsTG93ZXJSb3VuZC5pZCwge1xuICAgICAgICAgICAgdHlwZTogJ29uZS10by1vbmUnLFxuICAgICAgICAgICAgcHJldmlvdXNSb3VuZDogcHJlUHJlRmluYWxMb3dlclJvdW5kLFxuICAgICAgICAgICAgbmV4dFJvdW5kOiBmaW5hbExvd2VyUm91bmQsXG4gICAgICAgICAgICBjdXJyZW50Um91bmQ6IHByZUZpbmFsTG93ZXJSb3VuZCxcbiAgICAgICAgICAgIG5leHRSb3VuZE1hdGNoRmFjdG9yOiBmaW5hbExvd2VyUm91bmQubWF0Y2hDb3VudCAvIHByZUZpbmFsTG93ZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICAgICAgcHJldmlvdXNSb3VuZE1hdGNoRmFjdG9yOiBwcmVQcmVGaW5hbExvd2VyUm91bmQubWF0Y2hDb3VudCAvIHByZUZpbmFsTG93ZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICAgICAgcm9vdFJvdW5kTWF0Y2hGYWN0b3I6IGZpcnN0TG93ZXJSb3VuZC5tYXRjaENvdW50IC8gcHJlRmluYWxMb3dlclJvdW5kLm1hdGNoQ291bnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZm9yIHRoZSBmaXJzdCBsb3dlciByb3VuZFxuICAgICAgICAgIHJvdW5kUmVsYXRpb25zLnNldChwcmVGaW5hbExvd2VyUm91bmQuaWQsIHtcbiAgICAgICAgICAgIHR5cGU6ICdub3RoaW5nLXRvLW9uZScsXG4gICAgICAgICAgICBuZXh0Um91bmQ6IGZpbmFsTG93ZXJSb3VuZCxcbiAgICAgICAgICAgIGN1cnJlbnRSb3VuZDogcHJlRmluYWxMb3dlclJvdW5kLFxuICAgICAgICAgICAgbmV4dFJvdW5kTWF0Y2hGYWN0b3I6IGZpbmFsTG93ZXJSb3VuZC5tYXRjaENvdW50IC8gcHJlRmluYWxMb3dlclJvdW5kLm1hdGNoQ291bnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHRoaXMgaXMgYSBzeW5jIGJyYWNrZXQsIHdlIG9ubHkgbmVlZCB0byBzZXQgdGhlIHJlbGF0aW9uIGZvciB0aGUgbGFzdCBsb3dlciByb3VuZFxuICAgICAgICBpZiAoIXByZXZpb3VzTG93ZXJSb3VuZCkgdGhyb3cgbmV3IEVycm9yKCdwcmV2aW91c0xvd2VyUm91bmQgaXMgbnVsbCcpO1xuICAgICAgICBpZiAoIWZpcnN0TG93ZXJSb3VuZCkgdGhyb3cgbmV3IEVycm9yKCdmaXJzdExvd2VyUm91bmQgaXMgbnVsbCcpO1xuXG4gICAgICAgIC8vIGZvciB0aGUgbGFzdCBsb3dlciByb3VuZFxuICAgICAgICByb3VuZFJlbGF0aW9ucy5zZXQoZmluYWxMb3dlclJvdW5kLmlkLCB7XG4gICAgICAgICAgdHlwZTogJ29uZS10by1vbmUnLFxuICAgICAgICAgIHByZXZpb3VzUm91bmQ6IHByZXZpb3VzTG93ZXJSb3VuZCxcbiAgICAgICAgICBuZXh0Um91bmQ6IGN1cnJlbnRVcHBlclJvdW5kLFxuICAgICAgICAgIGN1cnJlbnRSb3VuZDogZmluYWxMb3dlclJvdW5kLFxuICAgICAgICAgIG5leHRSb3VuZE1hdGNoRmFjdG9yOiBjdXJyZW50VXBwZXJSb3VuZC5tYXRjaENvdW50IC8gZmluYWxMb3dlclJvdW5kLm1hdGNoQ291bnQsXG4gICAgICAgICAgcHJldmlvdXNSb3VuZE1hdGNoRmFjdG9yOiBwcmV2aW91c0xvd2VyUm91bmQubWF0Y2hDb3VudCAvIGZpbmFsTG93ZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICAgIHJvb3RSb3VuZE1hdGNoRmFjdG9yOiBmaXJzdExvd2VyUm91bmQubWF0Y2hDb3VudCAvIGZpbmFsTG93ZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzTGFzdFVwcGVyUm91bmQpIHtcbiAgICAgIC8vIG9uZSB0byBub3RoaW5nIHJlbGF0aW9uXG5cbiAgICAgIGlmICghcHJldmlvdXNVcHBlclJvdW5kKSB0aHJvdyBuZXcgRXJyb3IoJ3ByZXZpb3VzVXBwZXJSb3VuZCBpcyBudWxsJyk7XG5cbiAgICAgIHJvdW5kUmVsYXRpb25zLnNldChjdXJyZW50VXBwZXJSb3VuZC5pZCwge1xuICAgICAgICB0eXBlOiAnb25lLXRvLW5vdGhpbmcnLFxuICAgICAgICBwcmV2aW91c1JvdW5kOiBwcmV2aW91c1VwcGVyUm91bmQsXG4gICAgICAgIGN1cnJlbnRSb3VuZDogY3VycmVudFVwcGVyUm91bmQsXG4gICAgICAgIHByZXZpb3VzUm91bmRNYXRjaEZhY3RvcjogcHJldmlvdXNVcHBlclJvdW5kLm1hdGNoQ291bnQgLyBjdXJyZW50VXBwZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICByb290Um91bmRNYXRjaEZhY3RvcjogZmlyc3RVcHBlclJvdW5kLm1hdGNoQ291bnQgLyBjdXJyZW50VXBwZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChpc0ZpcnN0Um91bmQpIHtcbiAgICAgIC8vIG5vdGhpbmcgdG8gb25lIHJlbGF0aW9uXG5cbiAgICAgIGlmICghbmV4dFVwcGVyUm91bmQpIHRocm93IG5ldyBFcnJvcignbmV4dFVwcGVyUm91bmQgaXMgbnVsbCcpO1xuXG4gICAgICByb3VuZFJlbGF0aW9ucy5zZXQoY3VycmVudFVwcGVyUm91bmQuaWQsIHtcbiAgICAgICAgdHlwZTogJ25vdGhpbmctdG8tb25lJyxcbiAgICAgICAgbmV4dFJvdW5kOiBuZXh0VXBwZXJSb3VuZCxcbiAgICAgICAgY3VycmVudFJvdW5kOiBjdXJyZW50VXBwZXJSb3VuZCxcbiAgICAgICAgbmV4dFJvdW5kTWF0Y2hGYWN0b3I6IG5leHRVcHBlclJvdW5kLm1hdGNoQ291bnQgLyBjdXJyZW50VXBwZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChjdXJyZW50TG93ZXJSb3VuZCkge1xuICAgICAgICBpZiAoIW5leHRMb3dlclJvdW5kKSB0aHJvdyBuZXcgRXJyb3IoJ25leHRMb3dlclJvdW5kIGlzIG51bGwnKTtcblxuICAgICAgICByb3VuZFJlbGF0aW9ucy5zZXQoY3VycmVudExvd2VyUm91bmQuaWQsIHtcbiAgICAgICAgICB0eXBlOiAnbm90aGluZy10by1vbmUnLFxuICAgICAgICAgIG5leHRSb3VuZDogbmV4dExvd2VyUm91bmQsXG4gICAgICAgICAgY3VycmVudFJvdW5kOiBjdXJyZW50TG93ZXJSb3VuZCxcbiAgICAgICAgICBuZXh0Um91bmRNYXRjaEZhY3RvcjogbmV4dExvd2VyUm91bmQubWF0Y2hDb3VudCAvIGN1cnJlbnRMb3dlclJvdW5kLm1hdGNoQ291bnQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBvbmUgdG8gb25lIHJlbGF0aW9uXG5cbiAgICAgIGlmICghcHJldmlvdXNVcHBlclJvdW5kKSB0aHJvdyBuZXcgRXJyb3IoJ3ByZXZpb3VzVXBwZXJSb3VuZCBpcyBudWxsJyk7XG4gICAgICBpZiAoIW5leHRVcHBlclJvdW5kKSB0aHJvdyBuZXcgRXJyb3IoJ25leHRVcHBlclJvdW5kIGlzIG51bGwnKTtcblxuICAgICAgcm91bmRSZWxhdGlvbnMuc2V0KGN1cnJlbnRVcHBlclJvdW5kLmlkLCB7XG4gICAgICAgIHR5cGU6ICdvbmUtdG8tb25lJyxcbiAgICAgICAgcHJldmlvdXNSb3VuZDogcHJldmlvdXNVcHBlclJvdW5kLFxuICAgICAgICBuZXh0Um91bmQ6IG5leHRVcHBlclJvdW5kLFxuICAgICAgICBjdXJyZW50Um91bmQ6IGN1cnJlbnRVcHBlclJvdW5kLFxuICAgICAgICBuZXh0Um91bmRNYXRjaEZhY3RvcjogbmV4dFVwcGVyUm91bmQubWF0Y2hDb3VudCAvIGN1cnJlbnRVcHBlclJvdW5kLm1hdGNoQ291bnQsXG4gICAgICAgIHByZXZpb3VzUm91bmRNYXRjaEZhY3RvcjogcHJldmlvdXNVcHBlclJvdW5kLm1hdGNoQ291bnQgLyBjdXJyZW50VXBwZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICByb290Um91bmRNYXRjaEZhY3RvcjogZmlyc3RVcHBlclJvdW5kLm1hdGNoQ291bnQgLyBjdXJyZW50VXBwZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgfSk7XG5cbiAgICAgIC8vIHdlIG9ubHkgd2FudCB0byBzZXQgbG93ZXIgcm91bmRzIGhlcmUgdW50aWwgdGhlIHNwZWNpYWwgbWVyZ2luZyBwb2ludCBvZiB0aGUgZmluYWwuXG4gICAgICAvLyBsb3dlciBicmFja2V0IHJvdW5kcyBhZnRlciBhbmQgaW5jbHVkaW5nIHRoZSBmaW5hbCB3aWxsIGJlIHNldCBpbiB0aGUgZmluYWwgcm91bmQgYmxvY2tcbiAgICAgIGlmIChjdXJyZW50TG93ZXJSb3VuZCAmJiBjdXJyZW50VXBwZXJSb3VuZC50eXBlID09PSBET1VCTEVfRUxJTUlOQVRJT05fQlJBQ0tFVF9ST1VORF9UWVBFLlVQUEVSX0JSQUNLRVQpIHtcbiAgICAgICAgaWYgKCFwcmV2aW91c0xvd2VyUm91bmQpIHRocm93IG5ldyBFcnJvcigncHJldmlvdXNMb3dlclJvdW5kIGlzIG51bGwnKTtcbiAgICAgICAgaWYgKCFuZXh0TG93ZXJSb3VuZCkgdGhyb3cgbmV3IEVycm9yKCduZXh0TG93ZXJSb3VuZCBpcyBudWxsJyk7XG4gICAgICAgIGlmICghZmlyc3RMb3dlclJvdW5kKSB0aHJvdyBuZXcgRXJyb3IoJ2ZpcnN0TG93ZXJSb3VuZCBpcyBudWxsJyk7XG5cbiAgICAgICAgcm91bmRSZWxhdGlvbnMuc2V0KGN1cnJlbnRMb3dlclJvdW5kLmlkLCB7XG4gICAgICAgICAgdHlwZTogJ29uZS10by1vbmUnLFxuICAgICAgICAgIHByZXZpb3VzUm91bmQ6IHByZXZpb3VzTG93ZXJSb3VuZCxcbiAgICAgICAgICBuZXh0Um91bmQ6IG5leHRMb3dlclJvdW5kLFxuICAgICAgICAgIGN1cnJlbnRSb3VuZDogY3VycmVudExvd2VyUm91bmQsXG4gICAgICAgICAgbmV4dFJvdW5kTWF0Y2hGYWN0b3I6IG5leHRMb3dlclJvdW5kLm1hdGNoQ291bnQgLyBjdXJyZW50TG93ZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICAgIHByZXZpb3VzUm91bmRNYXRjaEZhY3RvcjogcHJldmlvdXNMb3dlclJvdW5kLm1hdGNoQ291bnQgLyBjdXJyZW50TG93ZXJSb3VuZC5tYXRjaENvdW50LFxuICAgICAgICAgIHJvb3RSb3VuZE1hdGNoRmFjdG9yOiBmaXJzdExvd2VyUm91bmQubWF0Y2hDb3VudCAvIGN1cnJlbnRMb3dlclJvdW5kLm1hdGNoQ291bnQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByb3VuZFJlbGF0aW9ucztcbn07XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZU1hdGNoUmVsYXRpb25zID0gPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+KFxuICBicmFja2V0RGF0YTogQnJhY2tldERhdGE8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4sXG4gIHJvdW5kUmVsYXRpb25zOiBCcmFja2V0Um91bmRSZWxhdGlvbnM8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4sXG4gIG1hdGNoUG9zaXRpb25NYXBzOiBNYXRjaFBvc2l0aW9uTWFwczxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPixcbikgPT4ge1xuICBjb25zdCBtYXRjaFJlbGF0aW9uczogQnJhY2tldE1hdGNoUmVsYXRpb25zTWFwPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0gbmV3IE1hcCgpO1xuXG4gIGZvciAoY29uc3QgbWF0Y2ggb2YgYnJhY2tldERhdGEubWF0Y2hlcy52YWx1ZXMoKSkge1xuICAgIGNvbnN0IGN1cnJlbnRSZWxhdGlvbiA9IHJvdW5kUmVsYXRpb25zLmdldChtYXRjaC5yb3VuZC5pZCk7XG5cbiAgICBpZiAoIWN1cnJlbnRSZWxhdGlvbikgdGhyb3cgbmV3IEVycm9yKCdNYXRjaCByb3VuZCBub3QgZm91bmQnKTtcblxuICAgIGNvbnN0IHsgbmV4dFJvdW5kTWF0Y2hQb3NpdGlvbiwgcHJldmlvdXNMb3dlclJvdW5kTWF0Y2hQb3NpdGlvbiwgcHJldmlvdXNVcHBlclJvdW5kTWF0Y2hQb3NpdGlvbiB9ID1cbiAgICAgIGdlbmVyYXRlTWF0Y2hSZWxhdGlvblBvc2l0aW9ucyhjdXJyZW50UmVsYXRpb24sIG1hdGNoKTtcblxuICAgIHN3aXRjaCAoY3VycmVudFJlbGF0aW9uLnR5cGUpIHtcbiAgICAgIGNhc2UgJ25vdGhpbmctdG8tb25lJzoge1xuICAgICAgICBjb25zdCBuZXh0TWF0Y2ggPSBtYXRjaFBvc2l0aW9uTWFwcy5nZXQoY3VycmVudFJlbGF0aW9uLm5leHRSb3VuZC5pZCk/LmdldChuZXh0Um91bmRNYXRjaFBvc2l0aW9uKTtcblxuICAgICAgICBpZiAoIW5leHRNYXRjaCkgdGhyb3cgbmV3IEVycm9yKCdOZXh0IHJvdW5kIG1hdGNoIG5vdCBmb3VuZCcpO1xuXG4gICAgICAgIC8vIG1lYW5zIGxlZnQgaXMgbm90aGluZy4gcmlnaHQgaXMgb25lXG4gICAgICAgIG1hdGNoUmVsYXRpb25zLnNldChtYXRjaC5pZCwge1xuICAgICAgICAgIHR5cGU6ICdub3RoaW5nLXRvLW9uZScsXG4gICAgICAgICAgY3VycmVudE1hdGNoOiBtYXRjaCxcbiAgICAgICAgICBjdXJyZW50Um91bmQ6IGN1cnJlbnRSZWxhdGlvbi5jdXJyZW50Um91bmQsXG4gICAgICAgICAgbmV4dFJvdW5kOiBjdXJyZW50UmVsYXRpb24ubmV4dFJvdW5kLFxuICAgICAgICAgIG5leHRNYXRjaCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdvbmUtdG8tbm90aGluZyc6IHtcbiAgICAgICAgY29uc3QgcHJldmlvdXNVcHBlck1hdGNoID0gbWF0Y2hQb3NpdGlvbk1hcHNcbiAgICAgICAgICAuZ2V0KGN1cnJlbnRSZWxhdGlvbi5wcmV2aW91c1JvdW5kLmlkKVxuICAgICAgICAgID8uZ2V0KHByZXZpb3VzVXBwZXJSb3VuZE1hdGNoUG9zaXRpb24pO1xuICAgICAgICBjb25zdCBwcmV2aW91c0xvd2VyTWF0Y2ggPSBtYXRjaFBvc2l0aW9uTWFwc1xuICAgICAgICAgIC5nZXQoY3VycmVudFJlbGF0aW9uLnByZXZpb3VzUm91bmQuaWQpXG4gICAgICAgICAgPy5nZXQocHJldmlvdXNMb3dlclJvdW5kTWF0Y2hQb3NpdGlvbik7XG5cbiAgICAgICAgaWYgKCFwcmV2aW91c1VwcGVyTWF0Y2gpIHRocm93IG5ldyBFcnJvcignUHJldmlvdXMgcm91bmQgbWF0Y2ggbm90IGZvdW5kJyk7XG5cbiAgICAgICAgaWYgKHByZXZpb3VzVXBwZXJSb3VuZE1hdGNoUG9zaXRpb24gIT09IHByZXZpb3VzTG93ZXJSb3VuZE1hdGNoUG9zaXRpb24pIHtcbiAgICAgICAgICAvLyBtZWFucyBsZWZ0IGlzIHR3by4gcmlnaHQgaXMgb25lXG5cbiAgICAgICAgICBpZiAoIXByZXZpb3VzTG93ZXJNYXRjaCkgdGhyb3cgbmV3IEVycm9yKCdQcmV2aW91cyBsb3dlciByb3VuZCBtYXRjaCBub3QgZm91bmQnKTtcblxuICAgICAgICAgIG1hdGNoUmVsYXRpb25zLnNldChtYXRjaC5pZCwge1xuICAgICAgICAgICAgdHlwZTogJ3R3by10by1ub3RoaW5nJyxcbiAgICAgICAgICAgIGN1cnJlbnRNYXRjaDogbWF0Y2gsXG4gICAgICAgICAgICBjdXJyZW50Um91bmQ6IGN1cnJlbnRSZWxhdGlvbi5jdXJyZW50Um91bmQsXG4gICAgICAgICAgICBwcmV2aW91c1VwcGVyTWF0Y2gsXG4gICAgICAgICAgICBwcmV2aW91c1VwcGVyUm91bmQ6IGN1cnJlbnRSZWxhdGlvbi5wcmV2aW91c1JvdW5kLFxuICAgICAgICAgICAgcHJldmlvdXNMb3dlck1hdGNoLFxuICAgICAgICAgICAgcHJldmlvdXNMb3dlclJvdW5kOiBjdXJyZW50UmVsYXRpb24ucHJldmlvdXNSb3VuZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBtZWFucyBsZWZ0IGlzIG9uZS4gcmlnaHQgaXMgbm90aGluZ1xuICAgICAgICAgIG1hdGNoUmVsYXRpb25zLnNldChtYXRjaC5pZCwge1xuICAgICAgICAgICAgdHlwZTogJ29uZS10by1ub3RoaW5nJyxcbiAgICAgICAgICAgIGN1cnJlbnRNYXRjaDogbWF0Y2gsXG4gICAgICAgICAgICBjdXJyZW50Um91bmQ6IGN1cnJlbnRSZWxhdGlvbi5jdXJyZW50Um91bmQsXG4gICAgICAgICAgICBwcmV2aW91c01hdGNoOiBwcmV2aW91c1VwcGVyTWF0Y2gsXG4gICAgICAgICAgICBwcmV2aW91c1JvdW5kOiBjdXJyZW50UmVsYXRpb24ucHJldmlvdXNSb3VuZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdvbmUtdG8tb25lJzoge1xuICAgICAgICBjb25zdCBuZXh0TWF0Y2ggPSBtYXRjaFBvc2l0aW9uTWFwcy5nZXQoY3VycmVudFJlbGF0aW9uLm5leHRSb3VuZC5pZCk/LmdldChuZXh0Um91bmRNYXRjaFBvc2l0aW9uKTtcbiAgICAgICAgY29uc3QgcHJldmlvdXNVcHBlck1hdGNoID0gbWF0Y2hQb3NpdGlvbk1hcHNcbiAgICAgICAgICAuZ2V0KGN1cnJlbnRSZWxhdGlvbi5wcmV2aW91c1JvdW5kLmlkKVxuICAgICAgICAgID8uZ2V0KHByZXZpb3VzVXBwZXJSb3VuZE1hdGNoUG9zaXRpb24pO1xuICAgICAgICBjb25zdCBwcmV2aW91c0xvd2VyTWF0Y2ggPSBtYXRjaFBvc2l0aW9uTWFwc1xuICAgICAgICAgIC5nZXQoY3VycmVudFJlbGF0aW9uLnByZXZpb3VzUm91bmQuaWQpXG4gICAgICAgICAgPy5nZXQocHJldmlvdXNMb3dlclJvdW5kTWF0Y2hQb3NpdGlvbik7XG5cbiAgICAgICAgaWYgKCFuZXh0TWF0Y2gpIHRocm93IG5ldyBFcnJvcignTmV4dCByb3VuZCBtYXRjaCBub3QgZm91bmQnKTtcbiAgICAgICAgaWYgKCFwcmV2aW91c1VwcGVyTWF0Y2gpIHRocm93IG5ldyBFcnJvcihgUHJldmlvdXMgdXBwZXIgcm91bmQgbWF0Y2ggbm90IGZvdW5kYCk7XG4gICAgICAgIGlmICghcHJldmlvdXNMb3dlck1hdGNoKSB0aHJvdyBuZXcgRXJyb3IoJ1ByZXZpb3VzIGxvd2VyIHJvdW5kIG1hdGNoIG5vdCBmb3VuZCcpO1xuXG4gICAgICAgIC8vIGNhbiBiZSBlaXRoZXIgb25lIHRvIG9uZSBvciB0d28gdG8gb25lXG4gICAgICAgIGNvbnN0IGlzTGVmdE9uZSA9IHByZXZpb3VzVXBwZXJSb3VuZE1hdGNoUG9zaXRpb24gPT09IHByZXZpb3VzTG93ZXJSb3VuZE1hdGNoUG9zaXRpb247XG5cbiAgICAgICAgaWYgKGlzTGVmdE9uZSkge1xuICAgICAgICAgIC8vIG9uZS10by1vbmVcbiAgICAgICAgICBtYXRjaFJlbGF0aW9ucy5zZXQobWF0Y2guaWQsIHtcbiAgICAgICAgICAgIHR5cGU6ICdvbmUtdG8tb25lJyxcbiAgICAgICAgICAgIGN1cnJlbnRNYXRjaDogbWF0Y2gsXG4gICAgICAgICAgICBjdXJyZW50Um91bmQ6IGN1cnJlbnRSZWxhdGlvbi5jdXJyZW50Um91bmQsXG4gICAgICAgICAgICBwcmV2aW91c01hdGNoOiBwcmV2aW91c1VwcGVyTWF0Y2gsXG4gICAgICAgICAgICBwcmV2aW91c1JvdW5kOiBjdXJyZW50UmVsYXRpb24ucHJldmlvdXNSb3VuZCxcbiAgICAgICAgICAgIG5leHRNYXRjaCxcbiAgICAgICAgICAgIG5leHRSb3VuZDogY3VycmVudFJlbGF0aW9uLm5leHRSb3VuZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyB0d28tdG8tb25lXG4gICAgICAgICAgbWF0Y2hSZWxhdGlvbnMuc2V0KG1hdGNoLmlkLCB7XG4gICAgICAgICAgICB0eXBlOiAndHdvLXRvLW9uZScsXG4gICAgICAgICAgICBjdXJyZW50TWF0Y2g6IG1hdGNoLFxuICAgICAgICAgICAgY3VycmVudFJvdW5kOiBjdXJyZW50UmVsYXRpb24uY3VycmVudFJvdW5kLFxuICAgICAgICAgICAgcHJldmlvdXNVcHBlck1hdGNoLFxuICAgICAgICAgICAgcHJldmlvdXNVcHBlclJvdW5kOiBjdXJyZW50UmVsYXRpb24ucHJldmlvdXNSb3VuZCxcbiAgICAgICAgICAgIHByZXZpb3VzTG93ZXJNYXRjaCxcbiAgICAgICAgICAgIHByZXZpb3VzTG93ZXJSb3VuZDogY3VycmVudFJlbGF0aW9uLnByZXZpb3VzUm91bmQsXG4gICAgICAgICAgICBuZXh0TWF0Y2gsXG4gICAgICAgICAgICBuZXh0Um91bmQ6IGN1cnJlbnRSZWxhdGlvbi5uZXh0Um91bmQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3R3by10by1vbmUnOiB7XG4gICAgICAgIGNvbnN0IG5leHRNYXRjaCA9IG1hdGNoUG9zaXRpb25NYXBzLmdldChjdXJyZW50UmVsYXRpb24ubmV4dFJvdW5kLmlkKT8uZ2V0KG5leHRSb3VuZE1hdGNoUG9zaXRpb24pO1xuXG4gICAgICAgIGNvbnN0IHByZXZpb3VzVXBwZXJNYXRjaCA9IG1hdGNoUG9zaXRpb25NYXBzXG4gICAgICAgICAgLmdldChjdXJyZW50UmVsYXRpb24ucHJldmlvdXNVcHBlclJvdW5kLmlkKVxuICAgICAgICAgID8uZ2V0KHByZXZpb3VzVXBwZXJSb3VuZE1hdGNoUG9zaXRpb24pO1xuICAgICAgICBjb25zdCBwcmV2aW91c0xvd2VyTWF0Y2ggPSBtYXRjaFBvc2l0aW9uTWFwc1xuICAgICAgICAgIC5nZXQoY3VycmVudFJlbGF0aW9uLnByZXZpb3VzTG93ZXJSb3VuZC5pZClcbiAgICAgICAgICA/LmdldChwcmV2aW91c0xvd2VyUm91bmRNYXRjaFBvc2l0aW9uKTtcblxuICAgICAgICBpZiAoIW5leHRNYXRjaCkgdGhyb3cgbmV3IEVycm9yKCdOZXh0IHJvdW5kIG1hdGNoIG5vdCBmb3VuZCcpO1xuICAgICAgICBpZiAoIXByZXZpb3VzVXBwZXJNYXRjaCkgdGhyb3cgbmV3IEVycm9yKGBQcmV2aW91cyB1cHBlciByb3VuZCBtYXRjaCBub3QgZm91bmRgKTtcbiAgICAgICAgaWYgKCFwcmV2aW91c0xvd2VyTWF0Y2gpIHRocm93IG5ldyBFcnJvcignUHJldmlvdXMgbG93ZXIgcm91bmQgbWF0Y2ggbm90IGZvdW5kJyk7XG5cbiAgICAgICAgbWF0Y2hSZWxhdGlvbnMuc2V0KG1hdGNoLmlkLCB7XG4gICAgICAgICAgdHlwZTogJ3R3by10by1vbmUnLFxuICAgICAgICAgIGN1cnJlbnRNYXRjaDogbWF0Y2gsXG4gICAgICAgICAgY3VycmVudFJvdW5kOiBjdXJyZW50UmVsYXRpb24uY3VycmVudFJvdW5kLFxuICAgICAgICAgIHByZXZpb3VzVXBwZXJNYXRjaCxcbiAgICAgICAgICBwcmV2aW91c1VwcGVyUm91bmQ6IGN1cnJlbnRSZWxhdGlvbi5wcmV2aW91c1VwcGVyUm91bmQsXG4gICAgICAgICAgcHJldmlvdXNMb3dlck1hdGNoLFxuICAgICAgICAgIHByZXZpb3VzTG93ZXJSb3VuZDogY3VycmVudFJlbGF0aW9uLnByZXZpb3VzTG93ZXJSb3VuZCxcbiAgICAgICAgICBuZXh0TWF0Y2gsXG4gICAgICAgICAgbmV4dFJvdW5kOiBjdXJyZW50UmVsYXRpb24ubmV4dFJvdW5kLFxuICAgICAgICB9KTtcblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3R3by10by1ub3RoaW5nJzoge1xuICAgICAgICBjb25zdCBwcmV2aW91c1VwcGVyTWF0Y2ggPSBtYXRjaFBvc2l0aW9uTWFwc1xuICAgICAgICAgIC5nZXQoY3VycmVudFJlbGF0aW9uLnByZXZpb3VzVXBwZXJSb3VuZC5pZClcbiAgICAgICAgICA/LmdldChwcmV2aW91c1VwcGVyUm91bmRNYXRjaFBvc2l0aW9uKTtcbiAgICAgICAgY29uc3QgcHJldmlvdXNMb3dlck1hdGNoID0gbWF0Y2hQb3NpdGlvbk1hcHNcbiAgICAgICAgICAuZ2V0KGN1cnJlbnRSZWxhdGlvbi5wcmV2aW91c1VwcGVyUm91bmQuaWQpXG4gICAgICAgICAgPy5nZXQocHJldmlvdXNMb3dlclJvdW5kTWF0Y2hQb3NpdGlvbik7XG5cbiAgICAgICAgaWYgKCFwcmV2aW91c1VwcGVyTWF0Y2gpIHRocm93IG5ldyBFcnJvcihgUHJldmlvdXMgdXBwZXIgcm91bmQgbWF0Y2ggbm90IGZvdW5kYCk7XG4gICAgICAgIGlmICghcHJldmlvdXNMb3dlck1hdGNoKSB0aHJvdyBuZXcgRXJyb3IoJ1ByZXZpb3VzIGxvd2VyIHJvdW5kIG1hdGNoIG5vdCBmb3VuZCcpO1xuXG4gICAgICAgIG1hdGNoUmVsYXRpb25zLnNldChtYXRjaC5pZCwge1xuICAgICAgICAgIHR5cGU6ICd0d28tdG8tbm90aGluZycsXG4gICAgICAgICAgY3VycmVudE1hdGNoOiBtYXRjaCxcbiAgICAgICAgICBjdXJyZW50Um91bmQ6IGN1cnJlbnRSZWxhdGlvbi5jdXJyZW50Um91bmQsXG4gICAgICAgICAgcHJldmlvdXNVcHBlck1hdGNoLFxuICAgICAgICAgIHByZXZpb3VzVXBwZXJSb3VuZDogY3VycmVudFJlbGF0aW9uLnByZXZpb3VzVXBwZXJSb3VuZCxcbiAgICAgICAgICBwcmV2aW91c0xvd2VyTWF0Y2gsXG4gICAgICAgICAgcHJldmlvdXNMb3dlclJvdW5kOiBjdXJyZW50UmVsYXRpb24ucHJldmlvdXNVcHBlclJvdW5kLFxuICAgICAgICB9KTtcblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWF0Y2hSZWxhdGlvbnM7XG59O1xuXG5leHBvcnQgY29uc3QgZ2VuZXJhdGVNYXRjaFJlbGF0aW9uUG9zaXRpb25zID0gPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+KFxuICBjdXJyZW50UmVsYXRpb246IEJyYWNrZXRSb3VuZFJlbGF0aW9uPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+LFxuICBtYXRjaDogQnJhY2tldE1hdGNoPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+LFxuKSA9PiB7XG4gIHN3aXRjaCAoY3VycmVudFJlbGF0aW9uLnR5cGUpIHtcbiAgICBjYXNlICdub3RoaW5nLXRvLW9uZSc6IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5leHRSb3VuZE1hdGNoUG9zaXRpb246IGdlbmVyYXRlTWF0Y2hQb3NpdGlvbihtYXRjaCwgY3VycmVudFJlbGF0aW9uLm5leHRSb3VuZE1hdGNoRmFjdG9yKSxcbiAgICAgICAgcHJldmlvdXNVcHBlclJvdW5kTWF0Y2hQb3NpdGlvbjogRkFMTEJBQ0tfTUFUQ0hfUE9TSVRJT04sXG4gICAgICAgIHByZXZpb3VzTG93ZXJSb3VuZE1hdGNoUG9zaXRpb246IEZBTExCQUNLX01BVENIX1BPU0lUSU9OLFxuICAgICAgfTtcbiAgICB9XG4gICAgY2FzZSAnb25lLXRvLW5vdGhpbmcnOiB7XG4gICAgICBjb25zdCBwcmV2aW91c1JvdW5kSGFzRG91YmxlVGhlTWF0Y2hDb3VudCA9IGN1cnJlbnRSZWxhdGlvbi5wcmV2aW91c1JvdW5kTWF0Y2hGYWN0b3IgPT09IDI7XG4gICAgICBjb25zdCBkb3VibGVVcHBlck1hdGNoQ291bnRTaGlmdCA9IHByZXZpb3VzUm91bmRIYXNEb3VibGVUaGVNYXRjaENvdW50ID8gMSA6IDA7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5leHRSb3VuZE1hdGNoUG9zaXRpb246IEZBTExCQUNLX01BVENIX1BPU0lUSU9OLFxuICAgICAgICBwcmV2aW91c1VwcGVyUm91bmRNYXRjaFBvc2l0aW9uOiAoZ2VuZXJhdGVNYXRjaFBvc2l0aW9uKG1hdGNoLCBjdXJyZW50UmVsYXRpb24ucHJldmlvdXNSb3VuZE1hdGNoRmFjdG9yKSAtXG4gICAgICAgICAgZG91YmxlVXBwZXJNYXRjaENvdW50U2hpZnQpIGFzIEJyYWNrZXRNYXRjaFBvc2l0aW9uLFxuICAgICAgICBwcmV2aW91c0xvd2VyUm91bmRNYXRjaFBvc2l0aW9uOiBnZW5lcmF0ZU1hdGNoUG9zaXRpb24obWF0Y2gsIGN1cnJlbnRSZWxhdGlvbi5wcmV2aW91c1JvdW5kTWF0Y2hGYWN0b3IpLFxuICAgICAgfTtcbiAgICB9XG4gICAgY2FzZSAnb25lLXRvLW9uZSc6IHtcbiAgICAgIGNvbnN0IHByZXZpb3VzUm91bmRIYXNEb3VibGVUaGVNYXRjaENvdW50ID0gY3VycmVudFJlbGF0aW9uLnByZXZpb3VzUm91bmRNYXRjaEZhY3RvciA9PT0gMjtcbiAgICAgIGNvbnN0IGRvdWJsZVVwcGVyTWF0Y2hDb3VudFNoaWZ0ID0gcHJldmlvdXNSb3VuZEhhc0RvdWJsZVRoZU1hdGNoQ291bnQgPyAxIDogMDtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmV4dFJvdW5kTWF0Y2hQb3NpdGlvbjogZ2VuZXJhdGVNYXRjaFBvc2l0aW9uKG1hdGNoLCBjdXJyZW50UmVsYXRpb24ubmV4dFJvdW5kTWF0Y2hGYWN0b3IpLFxuICAgICAgICBwcmV2aW91c1VwcGVyUm91bmRNYXRjaFBvc2l0aW9uOiAoZ2VuZXJhdGVNYXRjaFBvc2l0aW9uKG1hdGNoLCBjdXJyZW50UmVsYXRpb24ucHJldmlvdXNSb3VuZE1hdGNoRmFjdG9yKSAtXG4gICAgICAgICAgZG91YmxlVXBwZXJNYXRjaENvdW50U2hpZnQpIGFzIEJyYWNrZXRNYXRjaFBvc2l0aW9uLFxuICAgICAgICBwcmV2aW91c0xvd2VyUm91bmRNYXRjaFBvc2l0aW9uOiBnZW5lcmF0ZU1hdGNoUG9zaXRpb24obWF0Y2gsIGN1cnJlbnRSZWxhdGlvbi5wcmV2aW91c1JvdW5kTWF0Y2hGYWN0b3IpLFxuICAgICAgfTtcbiAgICB9XG4gICAgY2FzZSAndHdvLXRvLW9uZSc6IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5leHRSb3VuZE1hdGNoUG9zaXRpb246IGdlbmVyYXRlTWF0Y2hQb3NpdGlvbihtYXRjaCwgY3VycmVudFJlbGF0aW9uLm5leHRSb3VuZE1hdGNoRmFjdG9yKSxcbiAgICAgICAgcHJldmlvdXNVcHBlclJvdW5kTWF0Y2hQb3NpdGlvbjogZ2VuZXJhdGVNYXRjaFBvc2l0aW9uKG1hdGNoLCBjdXJyZW50UmVsYXRpb24ucHJldmlvdXNVcHBlclJvdW5kTWF0Y2hGYWN0b3IpLFxuICAgICAgICBwcmV2aW91c0xvd2VyUm91bmRNYXRjaFBvc2l0aW9uOiBnZW5lcmF0ZU1hdGNoUG9zaXRpb24obWF0Y2gsIGN1cnJlbnRSZWxhdGlvbi5wcmV2aW91c0xvd2VyUm91bmRNYXRjaEZhY3RvciksXG4gICAgICB9O1xuICAgIH1cbiAgICBjYXNlICd0d28tdG8tbm90aGluZyc6IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5leHRSb3VuZE1hdGNoUG9zaXRpb246IEZBTExCQUNLX01BVENIX1BPU0lUSU9OLFxuICAgICAgICBwcmV2aW91c1VwcGVyUm91bmRNYXRjaFBvc2l0aW9uOiBnZW5lcmF0ZU1hdGNoUG9zaXRpb24obWF0Y2gsIGN1cnJlbnRSZWxhdGlvbi5wcmV2aW91c1VwcGVyUm91bmRNYXRjaEZhY3RvciksXG4gICAgICAgIHByZXZpb3VzTG93ZXJSb3VuZE1hdGNoUG9zaXRpb246IGdlbmVyYXRlTWF0Y2hQb3NpdGlvbihtYXRjaCwgY3VycmVudFJlbGF0aW9uLnByZXZpb3VzTG93ZXJSb3VuZE1hdGNoRmFjdG9yKSxcbiAgICAgIH07XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZ2VuZXJhdGVNYXRjaFBvc2l0aW9uID0gKG1hdGNoOiBCcmFja2V0TWF0Y2g8dW5rbm93biwgdW5rbm93bj4sIGZhY3RvcjogTWF0Y2hGYWN0b3IpID0+IHtcbiAgcmV0dXJuIE1hdGguY2VpbChtYXRjaC5wb3NpdGlvbiAqIGZhY3RvcikgYXMgQnJhY2tldE1hdGNoUG9zaXRpb247XG59O1xuXG5leHBvcnQgY29uc3QgbG9nUm91bmRSZWxhdGlvbnMgPSAoXG4gIHJvdW5kUmVsYXRpb25zOiBCcmFja2V0Um91bmRSZWxhdGlvbnM8dW5rbm93biwgdW5rbm93bj4sXG4gIGJyYWNrZXREYXRhOiBCcmFja2V0RGF0YTx1bmtub3duLCB1bmtub3duPixcbikgPT4ge1xuICBmb3IgKGNvbnN0IFtyb3VuZElkLCByZWxhdGlvbl0gb2Ygcm91bmRSZWxhdGlvbnMuZW50cmllcygpKSB7XG4gICAgY29uc3Qgcm91bmQgPSBicmFja2V0RGF0YS5yb3VuZHMuZ2V0KHJvdW5kSWQpO1xuXG4gICAgaWYgKCFyb3VuZCkge1xuICAgICAgY29uc29sZS5lcnJvcihgUm91bmQgd2l0aCBpZCAke3JvdW5kSWR9IG5vdCBmb3VuZCBpbiBicmFja2V0IGRhdGEuIFRoZSBicmFja2V0IHdpbGwgYmUgbWFsZm9ybWVkLmApO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgc3dpdGNoIChyZWxhdGlvbi50eXBlKSB7XG4gICAgICBjYXNlICdub3RoaW5nLXRvLW9uZSc6XG4gICAgICAgIGNvbnNvbGUubG9nKGBTVEFSVDogJHtyb3VuZC5uYW1lfSAtPiAke3JlbGF0aW9uLm5leHRSb3VuZC5uYW1lfSAoRjogJHtyZWxhdGlvbi5uZXh0Um91bmRNYXRjaEZhY3Rvcn0pYCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnb25lLXRvLW5vdGhpbmcnOlxuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICBgJHtyZWxhdGlvbi5wcmV2aW91c1JvdW5kLm5hbWV9IChGOiAke3JlbGF0aW9uLnByZXZpb3VzUm91bmRNYXRjaEZhY3Rvcn0pIDwtIEVORElORzogJHtyb3VuZC5uYW1lfWAsXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnb25lLXRvLW9uZSc6XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGAke3JlbGF0aW9uLnByZXZpb3VzUm91bmQubmFtZX0gKEY6ICR7cmVsYXRpb24ucHJldmlvdXNSb3VuZE1hdGNoRmFjdG9yfSkgPC0gJHtyb3VuZC5uYW1lfSAtPiAke3JlbGF0aW9uLm5leHRSb3VuZC5uYW1lfSAoRjogJHtyZWxhdGlvbi5uZXh0Um91bmRNYXRjaEZhY3Rvcn0pYCxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd0d28tdG8tb25lJzpcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgYE1FUkdFUjogJHtyZWxhdGlvbi5wcmV2aW91c1VwcGVyUm91bmQubmFtZX0gKEY6ICR7cmVsYXRpb24ucHJldmlvdXNVcHBlclJvdW5kTWF0Y2hGYWN0b3J9KSBBTkQgJHtyZWxhdGlvbi5wcmV2aW91c0xvd2VyUm91bmQubmFtZX0gKEY6ICR7cmVsYXRpb24ucHJldmlvdXNMb3dlclJvdW5kTWF0Y2hGYWN0b3J9KSA8LSAke3JvdW5kLm5hbWV9IC0+ICR7cmVsYXRpb24ubmV4dFJvdW5kLm5hbWV9IChGOiAke3JlbGF0aW9uLm5leHRSb3VuZE1hdGNoRmFjdG9yfSlgLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3R3by10by1ub3RoaW5nJzpcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgYE1FUkdFUjogJHtyZWxhdGlvbi5wcmV2aW91c1VwcGVyUm91bmQubmFtZX0gKEY6ICR7cmVsYXRpb24ucHJldmlvdXNVcHBlclJvdW5kTWF0Y2hGYWN0b3J9KSBBTkQgJHtyZWxhdGlvbi5wcmV2aW91c0xvd2VyUm91bmQubmFtZX0gKEY6ICR7cmVsYXRpb24ucHJldmlvdXNMb3dlclJvdW5kTWF0Y2hGYWN0b3J9KSA8LSBFTkRJTkc6ICR7cm91bmQubmFtZX1gLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZU1hdGNoUGFydGljaXBhbnRNYXAgPSA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4oXG4gIGJyYWNrZXREYXRhOiBCcmFja2V0RGF0YTxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPixcbikgPT4ge1xuICBjb25zdCBtYXRjaFBhcnRpY2lwYW50TWFwOiBNYXRjaFBhcnRpY2lwYW50TWFwPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0IGhhc0VsaW1pbmF0aW9uID1cbiAgICBicmFja2V0RGF0YS5tb2RlID09PSBUT1VSTkFNRU5UX01PREUuU0lOR0xFX0VMSU1JTkFUSU9OIHx8XG4gICAgYnJhY2tldERhdGEubW9kZSA9PT0gVE9VUk5BTUVOVF9NT0RFLkRPVUJMRV9FTElNSU5BVElPTiB8fFxuICAgIGJyYWNrZXREYXRhLm1vZGUgPT09IFRPVVJOQU1FTlRfTU9ERS5TV0lTU19XSVRIX0VMSU1JTkFUSU9OO1xuXG4gIGZvciAoY29uc3QgcGFydGljaXBhbnQgb2YgYnJhY2tldERhdGEucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgbGV0IHdpbnNUaWxOb3cgPSAwO1xuICAgIGxldCBsb3NzZXNUaWxOb3cgPSAwO1xuICAgIGxldCB0aWVzVGlsTm93ID0gMDtcblxuICAgIGZvciAoY29uc3QgbWF0Y2hQYXJ0aWNpcGFudE1hdGNoIG9mIHBhcnRpY2lwYW50Lm1hdGNoZXMudmFsdWVzKCkpIHtcbiAgICAgIGNvbnN0IGlzV2lubmVyID0gbWF0Y2hQYXJ0aWNpcGFudE1hdGNoLmJyYWNrZXRNYXRjaC53aW5uZXIgPT09IG1hdGNoUGFydGljaXBhbnRNYXRjaC5zaWRlO1xuICAgICAgY29uc3QgaXNMb29zZXIgPVxuICAgICAgICBtYXRjaFBhcnRpY2lwYW50TWF0Y2guYnJhY2tldE1hdGNoLndpbm5lciAmJlxuICAgICAgICBtYXRjaFBhcnRpY2lwYW50TWF0Y2guYnJhY2tldE1hdGNoLndpbm5lciAhPT0gbWF0Y2hQYXJ0aWNpcGFudE1hdGNoLnNpZGU7XG4gICAgICBjb25zdCBpc1RpZSA9XG4gICAgICAgIG1hdGNoUGFydGljaXBhbnRNYXRjaC5icmFja2V0TWF0Y2guc3RhdHVzID09PSAnY29tcGxldGVkJyAmJiAhbWF0Y2hQYXJ0aWNpcGFudE1hdGNoLmJyYWNrZXRNYXRjaC53aW5uZXI7XG5cbiAgICAgIGlmIChpc1dpbm5lcikge1xuICAgICAgICB3aW5zVGlsTm93Kys7XG4gICAgICB9IGVsc2UgaWYgKGlzTG9vc2VyKSB7XG4gICAgICAgIGxvc3Nlc1RpbE5vdysrO1xuICAgICAgfSBlbHNlIGlmIChpc1RpZSkge1xuICAgICAgICB0aWVzVGlsTm93Kys7XG4gICAgICB9XG5cbiAgICAgIGxldCBpc0VsaW1pbmF0ZWQgPSBmYWxzZTtcbiAgICAgIGxldCBpc0VsaW1pbmF0aW9uTWF0Y2ggPSBmYWxzZTtcblxuICAgICAgaWYgKGhhc0VsaW1pbmF0aW9uKSB7XG4gICAgICAgIC8vIFRPRE86IEltcGxlbWVudCBlbGltaW5hdGlvbiBsb2dpY1xuXG4gICAgICAgIC8vIE1lYW5zIHRoZSBjdXJyZW50IG1hdGNoIGlzIGxvc3MgYW5kIGl0J3MgdGhlIGxhc3QgbWF0Y2ggb2YgdGhlIHBhcnRpY2lwYW50XG4gICAgICAgIGlzRWxpbWluYXRlZCA9IGZhbHNlO1xuXG4gICAgICAgIC8vIEFsd2F5cyB0cnVlIGZvciBzaW5nbGUgZWxpbWluYXRpb24sIG5ldmVyIGZvciBlLmcuIGdyb3VwcywgZGVwZW5kcyBvbiB0aGUgcm91bmQgZm9yIGRvdWJsZSBlbGltaW5hdGlvbiwgZGVwZW5kcyBvbiB0aGUgbG9zcyBjb3VudCBmb3Igc3dpc3Mgd2l0aCBlbGltaW5hdGlvblxuICAgICAgICBpc0VsaW1pbmF0aW9uTWF0Y2ggPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gVE9ETzogSW1wbGVtZW50IHJvdW5kIGxvZ2ljXG4gICAgICAvLyB0cnVlIGlmIGl0cyB0aGUgZmlyc3Qgcm91bmQgb2YgdGhlIGJyYWNrZXRcbiAgICAgIGNvbnN0IGlzRmlyc3RSb3VuZCA9IGZhbHNlO1xuXG4gICAgICAvLyB0cnVlIGlmIGl0cyB0aGUgbGFzdCByb3VuZCBvZiB0aGUgYnJhY2tldCAoZWcuIGZpbmFsIGZvciBzaW5nbGUgZWxpbWluYXRpb24pXG4gICAgICBjb25zdCBpc0xhc3RSb3VuZCA9IGZhbHNlO1xuXG4gICAgICBjb25zdCBwYXJ0aWNpcGFudE1hdGNoRGF0YTogTWF0Y2hQYXJ0aWNpcGFudE1hdGNoPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+ID0ge1xuICAgICAgICBicmFja2V0TWF0Y2g6IG1hdGNoUGFydGljaXBhbnRNYXRjaC5icmFja2V0TWF0Y2gsXG4gICAgICAgIHJlc3VsdDogaXNXaW5uZXIgPyAnd2luJyA6IGlzTG9vc2VyID8gJ2xvc3MnIDogaXNUaWUgPyAndGllJyA6IG51bGwsXG4gICAgICAgIGlzRWxpbWluYXRlZCxcbiAgICAgICAgaXNFbGltaW5hdGlvbk1hdGNoLFxuICAgICAgICBpc0ZpcnN0Um91bmQsXG4gICAgICAgIGlzTGFzdFJvdW5kLFxuICAgICAgICB0aWVDb3VudDogdGllc1RpbE5vdyxcbiAgICAgICAgd2luQ291bnQ6IHdpbnNUaWxOb3csXG4gICAgICAgIGxvc3NDb3VudDogbG9zc2VzVGlsTm93LFxuICAgICAgfTtcblxuICAgICAgaWYgKCFtYXRjaFBhcnRpY2lwYW50TWFwLmhhcyhwYXJ0aWNpcGFudC5pZCkpIHtcbiAgICAgICAgbWF0Y2hQYXJ0aWNpcGFudE1hcC5zZXQocGFydGljaXBhbnQuaWQsIHtcbiAgICAgICAgICBpZDogcGFydGljaXBhbnQuaWQsXG4gICAgICAgICAgbmFtZTogcGFydGljaXBhbnQubmFtZSxcbiAgICAgICAgICBtYXRjaGVzOiBuZXcgTWFwKCksXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYXJ0aWNpcGFudERhdGEgPSBtYXRjaFBhcnRpY2lwYW50TWFwLmdldChwYXJ0aWNpcGFudC5pZCkgYXMgTWF0Y2hQYXJ0aWNpcGFudDxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPjtcbiAgICAgIHBhcnRpY2lwYW50RGF0YS5tYXRjaGVzLnNldChtYXRjaFBhcnRpY2lwYW50TWF0Y2guYnJhY2tldE1hdGNoLmlkLCBwYXJ0aWNpcGFudE1hdGNoRGF0YSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1hdGNoUGFydGljaXBhbnRNYXA7XG59O1xuXG5jb25zdCBmYWN0b3JpYWxDYWNoZSA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCk7XG5cbmV4cG9ydCBjb25zdCBnZXRBdmFpbGFibGVTd2lzc0dyb3Vwc0ZvclJvdW5kID0gKHJvdW5kTnVtYmVyOiBudW1iZXIsIHRvdGFsTWF0Y2hlc0luUm91bmQ6IG51bWJlcikgPT4ge1xuICBjb25zdCBBRFZBTkNFX1dJTlMgPSAzO1xuICBjb25zdCBFTElNSU5BVEVfTE9TU0VTID0gMztcblxuICAvLyBDYWNoZSBmYWN0b3JpYWwgY2FsY3VsYXRpb25zXG4gIGNvbnN0IGdldEZhY3RvcmlhbCA9IChuOiBudW1iZXIpOiBudW1iZXIgPT4ge1xuICAgIGlmIChuIDw9IDEpIHJldHVybiAxO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgaWYgKGZhY3RvcmlhbENhY2hlLmhhcyhuKSkgcmV0dXJuIGZhY3RvcmlhbENhY2hlLmdldChuKSE7XG5cbiAgICBjb25zdCByZXN1bHQgPSBuICogZ2V0RmFjdG9yaWFsKG4gLSAxKTtcbiAgICBmYWN0b3JpYWxDYWNoZS5zZXQobiwgcmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFByZS1jYWxjdWxhdGUgcm91bmRGYWN0b3JpYWxcbiAgY29uc3Qgcm91bmRGYWN0ID0gZ2V0RmFjdG9yaWFsKHJvdW5kTnVtYmVyKTtcblxuICBsZXQgdG90YWxDb21iaW5hdGlvbnMgPSAwO1xuICBjb25zdCB2YWxpZEdyb3VwczogeyB3aW5zOiBudW1iZXI7IGxvc3NlczogbnVtYmVyOyBjb21iaW5hdGlvbnM6IG51bWJlciB9W10gPSBbXTtcblxuICAvLyBTaW5nbGUgbG9vcCB0byBnYXRoZXIgdmFsaWQgZ3JvdXBzIGFuZCB0b3RhbCBjb21iaW5hdGlvbnNcbiAgZm9yIChsZXQgd2lucyA9IHJvdW5kTnVtYmVyOyB3aW5zID49IDA7IHdpbnMtLSkge1xuICAgIGNvbnN0IGxvc3NlcyA9IHJvdW5kTnVtYmVyIC0gd2lucztcbiAgICBjb25zdCByZW1haW5pbmdHYW1lcyA9IEFEVkFOQ0VfV0lOUyArIEVMSU1JTkFURV9MT1NTRVMgLSAod2lucyArIGxvc3NlcykgLSAxO1xuICAgIGNvbnN0IG5vdFlldEVsaW1pbmF0ZWQgPSBsb3NzZXMgPCBFTElNSU5BVEVfTE9TU0VTO1xuICAgIGNvbnN0IGNhblN0aWxsQWR2YW5jZSA9IHdpbnMgPCBBRFZBTkNFX1dJTlMgJiYgcmVtYWluaW5nR2FtZXMgPj0gMDtcblxuICAgIGlmICghY2FuU3RpbGxBZHZhbmNlIHx8ICFub3RZZXRFbGltaW5hdGVkKSBjb250aW51ZTtcblxuICAgIGNvbnN0IGNvbWJpbmF0aW9ucyA9IHJvdW5kRmFjdCAvIChnZXRGYWN0b3JpYWwod2lucykgKiBnZXRGYWN0b3JpYWwobG9zc2VzKSk7XG4gICAgdG90YWxDb21iaW5hdGlvbnMgKz0gY29tYmluYXRpb25zO1xuICAgIHZhbGlkR3JvdXBzLnB1c2goeyB3aW5zLCBsb3NzZXMsIGNvbWJpbmF0aW9ucyB9KTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBmaW5hbCBncm91cHMgd2l0aCBjYWxjdWxhdGVkIHByb3BvcnRpb25zXG4gIHJldHVybiB2YWxpZEdyb3Vwcy5tYXAoKHsgd2lucywgbG9zc2VzLCBjb21iaW5hdGlvbnMgfSkgPT4gKHtcbiAgICBpZDogYCR7d2luc30tJHtsb3NzZXN9YCBhcyBCcmFja2V0Um91bmRTd2lzc0dyb3VwSWQsXG4gICAgbmFtZTogYCR7d2luc30tJHtsb3NzZXN9YCxcbiAgICBtYXRjaGVzSW5Hcm91cDogTWF0aC5yb3VuZCgoY29tYmluYXRpb25zIC8gdG90YWxDb21iaW5hdGlvbnMpICogdG90YWxNYXRjaGVzSW5Sb3VuZCksXG4gIH0pKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZW5lcmF0ZUJyYWNrZXRSb3VuZFN3aXNzR3JvdXBNYXBzID0gPFRSb3VuZERhdGEsIFRNYXRjaERhdGE+KFxuICBicmFja2V0RGF0YTogQnJhY2tldERhdGE8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4sXG4gIG1hdGNoUGFydGljaXBhbnRNYXA6IE1hdGNoUGFydGljaXBhbnRNYXA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4sXG4pID0+IHtcbiAgaWYgKGJyYWNrZXREYXRhLm1vZGUgIT09IFRPVVJOQU1FTlRfTU9ERS5TV0lTU19XSVRIX0VMSU1JTkFUSU9OKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCByb3VuZHNXaXRoU3dpc3NHcm91cHM6IEJyYWNrZXRSb3VuZE1hcFdpdGhTd2lzc0RhdGE8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSBuZXcgTWFwKCk7XG5cbiAgbGV0IHJvdW5kTnVtYmVyID0gMDtcbiAgZm9yIChjb25zdCBicmFja2V0Um91bmQgb2YgYnJhY2tldERhdGEucm91bmRzLnZhbHVlcygpKSB7XG4gICAgY29uc3QgYXZhaWxhYmxlR3JvdXBzID0gZ2V0QXZhaWxhYmxlU3dpc3NHcm91cHNGb3JSb3VuZChyb3VuZE51bWJlciwgYnJhY2tldFJvdW5kLm1hdGNoQ291bnQpO1xuXG4gICAgY29uc3Qgcm91bmRTd2lzc0RhdGE6IEJyYWNrZXRSb3VuZFN3aXNzRGF0YTxUUm91bmREYXRhLCBUTWF0Y2hEYXRhPiA9IHtcbiAgICAgIGdyb3VwczogbmV3IE1hcCgpLFxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIGF2YWlsYWJsZUdyb3Vwcykge1xuICAgICAgY29uc3Qgc3ViR3JvdXA6IEJyYWNrZXRSb3VuZFN3aXNzR3JvdXA8VFJvdW5kRGF0YSwgVE1hdGNoRGF0YT4gPSB7XG4gICAgICAgIGlkOiBncm91cC5pZCxcbiAgICAgICAgbmFtZTogZ3JvdXAubmFtZSxcbiAgICAgICAgbWF0Y2hlczogbmV3IE1hcCgpLFxuICAgICAgICBhbGxvd2VkTWF0Y2hDb3VudDogZ3JvdXAubWF0Y2hlc0luR3JvdXAsXG4gICAgICB9O1xuXG4gICAgICByb3VuZFN3aXNzRGF0YS5ncm91cHMuc2V0KGdyb3VwLmlkLCBzdWJHcm91cCk7XG4gICAgfVxuXG4gICAgY29uc3QgZW1wdHlNYXRjaElkczogQnJhY2tldE1hdGNoSWRbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBtYXRjaCBvZiBicmFja2V0Um91bmQubWF0Y2hlcy52YWx1ZXMoKSkge1xuICAgICAgY29uc3QgcGFydGljaXBhbnRIb21lID0gbWF0Y2guaG9tZSA/IChtYXRjaFBhcnRpY2lwYW50TWFwLmdldChtYXRjaC5ob21lKSA/PyBudWxsKSA6IG51bGw7XG4gICAgICBjb25zdCBwYXJ0aWNpcGFudEF3YXkgPSBtYXRjaC5hd2F5ID8gKG1hdGNoUGFydGljaXBhbnRNYXAuZ2V0KG1hdGNoLmF3YXkpID8/IG51bGwpIDogbnVsbDtcblxuICAgICAgY29uc3QgYW55UGFydGljaXBhbnQgPSBwYXJ0aWNpcGFudEhvbWUgfHwgcGFydGljaXBhbnRBd2F5O1xuXG4gICAgICBpZiAoIWFueVBhcnRpY2lwYW50KSB7XG4gICAgICAgIGVtcHR5TWF0Y2hJZHMucHVzaChtYXRjaC5pZCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtYXRjaFBhcnRpY2lwYW50TWF0Y2ggPSBhbnlQYXJ0aWNpcGFudC5tYXRjaGVzLmdldChtYXRjaC5pZCk7XG5cbiAgICAgIGlmICghbWF0Y2hQYXJ0aWNpcGFudE1hdGNoKSB0aHJvdyBuZXcgRXJyb3IoJ01hdGNoIHBhcnRpY2lwYW50IG1hdGNoIG5vdCBmb3VuZCcpO1xuXG4gICAgICBjb25zdCB3aW5zID0gbWF0Y2hQYXJ0aWNpcGFudE1hdGNoLndpbkNvdW50O1xuICAgICAgY29uc3QgbG9zc2VzID0gbWF0Y2hQYXJ0aWNpcGFudE1hdGNoLmxvc3NDb3VudDtcblxuICAgICAgY29uc3QgZ3JvdXAgPSByb3VuZFN3aXNzRGF0YS5ncm91cHMuZ2V0KGAke3dpbnN9LSR7bG9zc2VzfWAgYXMgQnJhY2tldFJvdW5kU3dpc3NHcm91cElkKTtcblxuICAgICAgaWYgKCFncm91cCkgdGhyb3cgbmV3IEVycm9yKCdHcm91cCBub3QgZm91bmQgZm9yIG1hdGNoOiAnICsgbWF0Y2guaWQpO1xuXG4gICAgICBncm91cC5tYXRjaGVzLnNldChtYXRjaC5pZCwgbWF0Y2gpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZW1wdHlNYXRjaElkIG9mIGVtcHR5TWF0Y2hJZHMpIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gYnJhY2tldFJvdW5kLm1hdGNoZXMuZ2V0KGVtcHR5TWF0Y2hJZCk7XG5cbiAgICAgIGlmICghbWF0Y2gpIHRocm93IG5ldyBFcnJvcignRW1wdHkgbWF0Y2ggbm90IGZvdW5kJyk7XG5cbiAgICAgIGxldCBncm91cEZvdW5kID0gZmFsc2U7XG4gICAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIHJvdW5kU3dpc3NEYXRhLmdyb3Vwcy52YWx1ZXMoKSkge1xuICAgICAgICBpZiAoZ3JvdXAubWF0Y2hlcy5zaXplIDwgZ3JvdXAuYWxsb3dlZE1hdGNoQ291bnQpIHtcbiAgICAgICAgICBncm91cC5tYXRjaGVzLnNldChtYXRjaC5pZCwgbWF0Y2gpO1xuICAgICAgICAgIGdyb3VwRm91bmQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghZ3JvdXBGb3VuZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGdyb3VwIGZvdW5kIGZvciBlbXB0eSBtYXRjaCcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJvdW5kTnVtYmVyKys7XG4gIH1cblxuICByZXR1cm4gcm91bmRzV2l0aFN3aXNzR3JvdXBzO1xufTtcbiJdfQ==
|