@algoux/standard-ranklist-renderer-component-angular 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/README.md +150 -0
- package/dist/esm2022/algoux-standard-ranklist-renderer-component-angular.mjs +5 -0
- package/dist/esm2022/lib/index.mjs +8 -0
- package/dist/esm2022/lib/modal/default-solution-modal.component.mjs +146 -0
- package/dist/esm2022/lib/modal/default-user-modal.component.mjs +172 -0
- package/dist/esm2022/lib/modal/modal-interactions.mjs +2 -0
- package/dist/esm2022/lib/modal/modal.component.mjs +263 -0
- package/dist/esm2022/lib/progress/progress-bar.component.mjs +247 -0
- package/dist/esm2022/lib/progress/progress-utils.mjs +45 -0
- package/dist/esm2022/lib/ranklist/ranklist-utils.mjs +110 -0
- package/dist/esm2022/lib/ranklist/ranklist.component.mjs +1010 -0
- package/dist/esm2022/lib/ranklist/status-cell-template.directive.mjs +18 -0
- package/dist/esm2022/lib/ranklist/user-cell-template.directive.mjs +18 -0
- package/dist/esm2022/lib/types.mjs +2 -0
- package/dist/esm2022/public-api.mjs +2 -0
- package/dist/fesm2022/algoux-standard-ranklist-renderer-component-angular.mjs +2002 -0
- package/dist/fesm2022/algoux-standard-ranklist-renderer-component-angular.mjs.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/lib/index.d.ts +8 -0
- package/dist/lib/modal/default-solution-modal.component.d.ts +30 -0
- package/dist/lib/modal/default-user-modal.component.d.ts +34 -0
- package/dist/lib/modal/modal-interactions.d.ts +1 -0
- package/dist/lib/modal/modal.component.d.ts +49 -0
- package/dist/lib/progress/progress-bar.component.d.ts +31 -0
- package/dist/lib/progress/progress-utils.d.ts +15 -0
- package/dist/lib/ranklist/ranklist-utils.d.ts +22 -0
- package/dist/lib/ranklist/ranklist.component.d.ts +87 -0
- package/dist/lib/ranklist/status-cell-template.directive.d.ts +26 -0
- package/dist/lib/ranklist/user-cell-template.directive.d.ts +22 -0
- package/dist/lib/types.d.ts +29 -0
- package/dist/public-api.d.ts +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,1010 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, ContentChild, EventEmitter, Input, Output, } from '@angular/core';
|
|
3
|
+
import { EnumTheme, formatTimeDuration, numberToAlphabet, resolveStyle, resolveText, resolveUserMarkers, } from '@algoux/standard-ranklist-utils';
|
|
4
|
+
import { calculateDirtPercentage, calculateProblemStatisticsFooter, calculateSEValue, caniuse, formatProblemStatisticsAcceptedMinute, formatProblemStatisticsAverageHardness, formatProblemStatisticsPercent, getMarkerPresentation, getProblemHeaderBackgroundImage, getRankProblemStatusCellPresentation, resolveSrkAssetUrl, shouldShowTimeColumn, srkSupportedVersions, } from '@algoux/standard-ranklist-renderer-component-core';
|
|
5
|
+
import { captureModalTriggerPointFromMouseEvent } from '../modal/modal-interactions';
|
|
6
|
+
import { SrkStatusCellTemplateDirective, } from './status-cell-template.directive';
|
|
7
|
+
import { SrkUserCellTemplateDirective, } from './user-cell-template.directive';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "@angular/common";
|
|
10
|
+
export class RanklistComponent {
|
|
11
|
+
data;
|
|
12
|
+
theme = EnumTheme.light;
|
|
13
|
+
rowBordered = false;
|
|
14
|
+
columnBordered = false;
|
|
15
|
+
rowStriped = false;
|
|
16
|
+
formatSrkAssetUrl;
|
|
17
|
+
splitOrganization = false;
|
|
18
|
+
columnTitles;
|
|
19
|
+
statusCellPreset = 'classic';
|
|
20
|
+
statusColorAsText = false;
|
|
21
|
+
showProblemStatisticsFooter = false;
|
|
22
|
+
showDirtColumn = false;
|
|
23
|
+
showSEColumn = false;
|
|
24
|
+
emptyStatusPlaceholder = null;
|
|
25
|
+
userAvatarPlacement = 'user';
|
|
26
|
+
userClick = new EventEmitter();
|
|
27
|
+
solutionClick = new EventEmitter();
|
|
28
|
+
statusCellTemplate;
|
|
29
|
+
userCellTemplate;
|
|
30
|
+
supportedVersions = srkSupportedVersions;
|
|
31
|
+
firstBloodStar = '\u2605';
|
|
32
|
+
statusSeparator = ' ';
|
|
33
|
+
problemStatisticsFooterRows = [
|
|
34
|
+
{
|
|
35
|
+
key: 'accepted',
|
|
36
|
+
label: 'Accepted',
|
|
37
|
+
tooltip: 'Number of participants who solved this problem',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: 'tried',
|
|
41
|
+
label: 'Tried',
|
|
42
|
+
tooltip: 'Number of participants who attempted this problem',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
key: 'submitted',
|
|
46
|
+
label: 'Submitted',
|
|
47
|
+
tooltip: 'Total number of valid submissions for this problem',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
key: 'dirt',
|
|
51
|
+
label: 'Dirt',
|
|
52
|
+
tooltip: 'Wrong submissions among participants who solved this problem',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
key: 'se',
|
|
56
|
+
label: 'SE',
|
|
57
|
+
tooltip: 'Average hardness, calculated as (participants - accepted) / participants',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
key: 'firstAccepted',
|
|
61
|
+
label: 'FB at',
|
|
62
|
+
tooltip: 'First Blood at, also known as first solve time, in minutes',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
key: 'lastAccepted',
|
|
66
|
+
label: 'LB at',
|
|
67
|
+
tooltip: 'Last Blood at, also known as last solve time, in minutes',
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
problemStatisticsSource;
|
|
71
|
+
problemStatisticsCache;
|
|
72
|
+
get problemStatistics() {
|
|
73
|
+
if (!this.showProblemStatisticsFooter && !this.showSEColumn) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
if (this.problemStatisticsSource !== this.data || !this.problemStatisticsCache) {
|
|
77
|
+
this.problemStatisticsSource = this.data;
|
|
78
|
+
this.problemStatisticsCache = calculateProblemStatisticsFooter(this.data);
|
|
79
|
+
}
|
|
80
|
+
return this.problemStatisticsCache;
|
|
81
|
+
}
|
|
82
|
+
isSupportedVersion() {
|
|
83
|
+
return caniuse(this.data.version);
|
|
84
|
+
}
|
|
85
|
+
showTimeColumn() {
|
|
86
|
+
return shouldShowTimeColumn(this.data.rows);
|
|
87
|
+
}
|
|
88
|
+
showAvatarInOrganization() {
|
|
89
|
+
return this.splitOrganization && this.userAvatarPlacement === 'organization';
|
|
90
|
+
}
|
|
91
|
+
leftFooterColumnCount() {
|
|
92
|
+
return this.data.series.length + 1 + 1 + (this.showTimeColumn() ? 1 : 0) + (this.splitOrganization ? 1 : 0);
|
|
93
|
+
}
|
|
94
|
+
getRankValues(row) {
|
|
95
|
+
return row.rankValues || this.data.series.map(() => ({ rank: null, segmentIndex: null }));
|
|
96
|
+
}
|
|
97
|
+
getRankText(rankValue, row) {
|
|
98
|
+
return rankValue.rank ? rankValue.rank : row.user.official === false ? '*' : '';
|
|
99
|
+
}
|
|
100
|
+
resolveDisplayText(text) {
|
|
101
|
+
return resolveText(text);
|
|
102
|
+
}
|
|
103
|
+
resolveSeriesColumnTitle(series, index) {
|
|
104
|
+
const seriesTitles = this.columnTitles?.series;
|
|
105
|
+
if (typeof seriesTitles === 'function') {
|
|
106
|
+
return seriesTitles(series, index) ?? series.title;
|
|
107
|
+
}
|
|
108
|
+
if (Array.isArray(seriesTitles)) {
|
|
109
|
+
return seriesTitles[index] ?? series.title;
|
|
110
|
+
}
|
|
111
|
+
return series.title;
|
|
112
|
+
}
|
|
113
|
+
resolveColumnTitle(key, fallback) {
|
|
114
|
+
return this.columnTitles?.[key] ?? fallback;
|
|
115
|
+
}
|
|
116
|
+
problemAlias(problem, problemIndex) {
|
|
117
|
+
return problem.alias || numberToAlphabet(problemIndex);
|
|
118
|
+
}
|
|
119
|
+
problemStatsTitle(statistics) {
|
|
120
|
+
const ratio = statistics.submitted ? ((statistics.accepted / statistics.submitted) * 100).toFixed(1) : 0;
|
|
121
|
+
return `${statistics.accepted} / ${statistics.submitted} (${ratio}%)`;
|
|
122
|
+
}
|
|
123
|
+
problemHeaderBackgroundImage(problem, gradientDirection = 180) {
|
|
124
|
+
return getProblemHeaderBackgroundImage(problem.style, this.theme, gradientDirection);
|
|
125
|
+
}
|
|
126
|
+
resolvedUserMarkers(user) {
|
|
127
|
+
return resolveUserMarkers(user, this.data.markers).map((marker) => ({
|
|
128
|
+
marker,
|
|
129
|
+
presentation: getMarkerPresentation(marker, this.theme),
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
formatAssetUrl(url, field) {
|
|
133
|
+
return resolveSrkAssetUrl(url, field, this.formatSrkAssetUrl);
|
|
134
|
+
}
|
|
135
|
+
formatTime(time) {
|
|
136
|
+
return formatTimeDuration(time, 'min', Math.floor);
|
|
137
|
+
}
|
|
138
|
+
calculateDirtPercentage(row) {
|
|
139
|
+
return calculateDirtPercentage(row);
|
|
140
|
+
}
|
|
141
|
+
calculateSEValue(row, problemStatistics) {
|
|
142
|
+
return calculateSEValue(row, problemStatistics);
|
|
143
|
+
}
|
|
144
|
+
statusPresentation(status) {
|
|
145
|
+
return getRankProblemStatusCellPresentation(status, this.data, this.statusCellPreset);
|
|
146
|
+
}
|
|
147
|
+
isNumber(value) {
|
|
148
|
+
return typeof value === 'number';
|
|
149
|
+
}
|
|
150
|
+
getStatusSolutions(status) {
|
|
151
|
+
return [...(status.solutions || [])].reverse();
|
|
152
|
+
}
|
|
153
|
+
statusCellClass(status) {
|
|
154
|
+
const classNames = ['srk-prest-status-block', 'srk--text-center', 'srk--nowrap'];
|
|
155
|
+
if (this.isStatusClickable(status)) {
|
|
156
|
+
classNames.push('srk--cursor-pointer');
|
|
157
|
+
}
|
|
158
|
+
if (this.statusColorAsText) {
|
|
159
|
+
classNames.push('srk-prest-status-block-color-text');
|
|
160
|
+
}
|
|
161
|
+
if (status.result === 'FB') {
|
|
162
|
+
classNames.push('srk-prest-status-block-fb');
|
|
163
|
+
}
|
|
164
|
+
else if (status.result === 'AC') {
|
|
165
|
+
classNames.push('srk-prest-status-block-accepted');
|
|
166
|
+
}
|
|
167
|
+
else if (status.result === '?') {
|
|
168
|
+
classNames.push('srk-prest-status-block-frozen');
|
|
169
|
+
}
|
|
170
|
+
else if (status.result === 'RJ') {
|
|
171
|
+
classNames.push('srk-prest-status-block-failed');
|
|
172
|
+
}
|
|
173
|
+
return classNames.join(' ');
|
|
174
|
+
}
|
|
175
|
+
isStatusClickable(status) {
|
|
176
|
+
return this.getStatusSolutions(status).length > 0;
|
|
177
|
+
}
|
|
178
|
+
statusCellRole(status) {
|
|
179
|
+
return this.isStatusClickable(status) ? 'button' : null;
|
|
180
|
+
}
|
|
181
|
+
statusCellTabIndex(status) {
|
|
182
|
+
return this.isStatusClickable(status) ? 0 : null;
|
|
183
|
+
}
|
|
184
|
+
buildUserCellContext(row, rowIndex) {
|
|
185
|
+
return {
|
|
186
|
+
$implicit: row.user,
|
|
187
|
+
user: row.user,
|
|
188
|
+
row,
|
|
189
|
+
rowIndex,
|
|
190
|
+
ranklist: this.data,
|
|
191
|
+
markers: this.data.markers,
|
|
192
|
+
hideOrganization: this.splitOrganization,
|
|
193
|
+
hideAvatar: this.showAvatarInOrganization(),
|
|
194
|
+
onClick: (event) => this.emitUserClick(event, row, rowIndex),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
buildStatusCellContext(row, rowIndex, status, problemIndex) {
|
|
198
|
+
return {
|
|
199
|
+
$implicit: status,
|
|
200
|
+
status,
|
|
201
|
+
problem: this.data.problems[problemIndex],
|
|
202
|
+
problemIndex,
|
|
203
|
+
user: row.user,
|
|
204
|
+
row,
|
|
205
|
+
rowIndex,
|
|
206
|
+
ranklist: this.data,
|
|
207
|
+
solutions: this.getStatusSolutions(status),
|
|
208
|
+
statusCellPreset: this.statusCellPreset,
|
|
209
|
+
statusColorAsText: this.statusColorAsText,
|
|
210
|
+
emptyStatusPlaceholder: this.emptyStatusPlaceholder,
|
|
211
|
+
onClick: (event) => this.emitSolutionClick(event, row, rowIndex, status, problemIndex),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
activateUserCellFromKeyboard(event, row, rowIndex) {
|
|
215
|
+
event.preventDefault();
|
|
216
|
+
this.emitUserClick(undefined, row, rowIndex);
|
|
217
|
+
}
|
|
218
|
+
activateStatusCellFromKeyboard(event, row, rowIndex, status, problemIndex) {
|
|
219
|
+
event.preventDefault();
|
|
220
|
+
this.emitSolutionClick(undefined, row, rowIndex, status, problemIndex);
|
|
221
|
+
}
|
|
222
|
+
emitUserClick(event, row, rowIndex) {
|
|
223
|
+
if (event) {
|
|
224
|
+
captureModalTriggerPointFromMouseEvent(event, {
|
|
225
|
+
source: 'user-cell',
|
|
226
|
+
context: {
|
|
227
|
+
rowIndex,
|
|
228
|
+
userId: row.user.id || null,
|
|
229
|
+
userName: this.resolveDisplayText(row.user.name),
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
this.userClick.emit({
|
|
234
|
+
user: row.user,
|
|
235
|
+
row,
|
|
236
|
+
rowIndex,
|
|
237
|
+
ranklist: this.data,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
emitSolutionClick(event, row, rowIndex, status, problemIndex) {
|
|
241
|
+
const solutions = this.getStatusSolutions(status);
|
|
242
|
+
if (!solutions.length) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (event) {
|
|
246
|
+
captureModalTriggerPointFromMouseEvent(event, {
|
|
247
|
+
source: 'status-cell',
|
|
248
|
+
context: {
|
|
249
|
+
rowIndex,
|
|
250
|
+
problemIndex,
|
|
251
|
+
problemAlias: this.data.problems[problemIndex]?.alias || null,
|
|
252
|
+
problemTitle: this.data.problems[problemIndex] ? this.resolveDisplayText(this.data.problems[problemIndex].title) : null,
|
|
253
|
+
userId: row.user.id || null,
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
this.solutionClick.emit({
|
|
258
|
+
user: row.user,
|
|
259
|
+
row,
|
|
260
|
+
rowIndex,
|
|
261
|
+
problemIndex,
|
|
262
|
+
problem: this.data.problems[problemIndex],
|
|
263
|
+
status,
|
|
264
|
+
solutions,
|
|
265
|
+
ranklist: this.data,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
resolveSeriesSegment(rankValue, series) {
|
|
269
|
+
const index = rankValue.segmentIndex || rankValue.segmentIndex === 0 ? rankValue.segmentIndex : -1;
|
|
270
|
+
return (series?.segments || [])[index] || {};
|
|
271
|
+
}
|
|
272
|
+
isSeriesSegmentedColumn(series) {
|
|
273
|
+
return (series?.segments || []).some((segment) => typeof segment.style === 'string');
|
|
274
|
+
}
|
|
275
|
+
getSeriesSegmentClass(rankValue, series) {
|
|
276
|
+
const segmentStyle = this.resolveSeriesSegment(rankValue, series).style;
|
|
277
|
+
return typeof segmentStyle === 'string' ? `srk-preset-series-segment-${segmentStyle}` : '';
|
|
278
|
+
}
|
|
279
|
+
getSeriesSegmentStyle(rankValue, series) {
|
|
280
|
+
const emptyColor = {
|
|
281
|
+
[EnumTheme.light]: undefined,
|
|
282
|
+
[EnumTheme.dark]: undefined,
|
|
283
|
+
};
|
|
284
|
+
const segmentStyle = this.resolveSeriesSegment(rankValue, series).style;
|
|
285
|
+
if (!segmentStyle || typeof segmentStyle === 'string') {
|
|
286
|
+
return {};
|
|
287
|
+
}
|
|
288
|
+
const style = resolveStyle(segmentStyle);
|
|
289
|
+
const textColor = style.textColor || emptyColor;
|
|
290
|
+
const backgroundColor = style.backgroundColor || emptyColor;
|
|
291
|
+
return {
|
|
292
|
+
color: textColor[this.theme],
|
|
293
|
+
backgroundColor: backgroundColor[this.theme],
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
getProblemStatisticsFooterCellPrimary(key, stat) {
|
|
297
|
+
switch (key) {
|
|
298
|
+
case 'accepted':
|
|
299
|
+
return stat.accepted;
|
|
300
|
+
case 'tried':
|
|
301
|
+
return stat.tried;
|
|
302
|
+
case 'submitted':
|
|
303
|
+
return stat.submitted;
|
|
304
|
+
case 'dirt':
|
|
305
|
+
return stat.dirt;
|
|
306
|
+
case 'se':
|
|
307
|
+
return formatProblemStatisticsAverageHardness(stat);
|
|
308
|
+
case 'firstAccepted':
|
|
309
|
+
return formatProblemStatisticsAcceptedMinute(stat.firstAcceptedTime);
|
|
310
|
+
case 'lastAccepted':
|
|
311
|
+
return formatProblemStatisticsAcceptedMinute(stat.lastAcceptedTime);
|
|
312
|
+
default:
|
|
313
|
+
return '';
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
getProblemStatisticsFooterCellSecondary(key, stat) {
|
|
317
|
+
switch (key) {
|
|
318
|
+
case 'accepted':
|
|
319
|
+
return formatProblemStatisticsPercent(stat.accepted, stat.participantCount);
|
|
320
|
+
case 'tried':
|
|
321
|
+
return formatProblemStatisticsPercent(stat.tried, stat.participantCount);
|
|
322
|
+
case 'dirt':
|
|
323
|
+
return formatProblemStatisticsPercent(stat.dirt, stat.dirtSubmitted);
|
|
324
|
+
default:
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RanklistComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
329
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: RanklistComponent, isStandalone: true, selector: "srk-ranklist", inputs: { data: "data", theme: "theme", rowBordered: "rowBordered", columnBordered: "columnBordered", rowStriped: "rowStriped", formatSrkAssetUrl: "formatSrkAssetUrl", splitOrganization: "splitOrganization", columnTitles: "columnTitles", statusCellPreset: "statusCellPreset", statusColorAsText: "statusColorAsText", showProblemStatisticsFooter: "showProblemStatisticsFooter", showDirtColumn: "showDirtColumn", showSEColumn: "showSEColumn", emptyStatusPlaceholder: "emptyStatusPlaceholder", userAvatarPlacement: "userAvatarPlacement" }, outputs: { userClick: "userClick", solutionClick: "solutionClick" }, queries: [{ propertyName: "statusCellTemplate", first: true, predicate: SrkStatusCellTemplateDirective, descendants: true }, { propertyName: "userCellTemplate", first: true, predicate: SrkUserCellTemplateDirective, descendants: true }], ngImport: i0, template: `
|
|
330
|
+
<div *ngIf="data.type !== 'general'; else versionState">
|
|
331
|
+
srk type "{{ data.type }}" is not supported
|
|
332
|
+
</div>
|
|
333
|
+
|
|
334
|
+
<ng-template #versionState>
|
|
335
|
+
<div *ngIf="!isSupportedVersion(); else ranklistTable">
|
|
336
|
+
srk version "{{ data.version }}" is not supported (current supported: {{ supportedVersions }})
|
|
337
|
+
</div>
|
|
338
|
+
</ng-template>
|
|
339
|
+
|
|
340
|
+
<ng-template #ranklistTable>
|
|
341
|
+
<div class="srk-common-table srk-main">
|
|
342
|
+
<table
|
|
343
|
+
[class.srk-table-row-bordered]="rowBordered"
|
|
344
|
+
[class.srk-table-column-bordered]="columnBordered"
|
|
345
|
+
[class.srk-table-row-striped]="rowStriped"
|
|
346
|
+
>
|
|
347
|
+
<thead>
|
|
348
|
+
<tr>
|
|
349
|
+
<th
|
|
350
|
+
*ngFor="let seriesItem of data.series; let seriesIndex = index"
|
|
351
|
+
class="srk-series-header srk--text-right srk--nowrap"
|
|
352
|
+
[class.srk-series-segmented-column]="isSeriesSegmentedColumn(seriesItem)"
|
|
353
|
+
>
|
|
354
|
+
{{ resolveSeriesColumnTitle(seriesItem, seriesIndex) }}
|
|
355
|
+
</th>
|
|
356
|
+
<th
|
|
357
|
+
*ngIf="splitOrganization"
|
|
358
|
+
class="srk-organization-header srk--text-left srk--nowrap"
|
|
359
|
+
>
|
|
360
|
+
{{ resolveColumnTitle('organization', 'Organization') }}
|
|
361
|
+
</th>
|
|
362
|
+
<th class="srk--text-left srk--nowrap">{{ resolveColumnTitle('user', 'Name') }}</th>
|
|
363
|
+
<th class="srk--text-right srk--nowrap">{{ resolveColumnTitle('score', 'Score') }}</th>
|
|
364
|
+
<th *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
|
|
365
|
+
{{ resolveColumnTitle('time', 'Time') }}
|
|
366
|
+
</th>
|
|
367
|
+
<th
|
|
368
|
+
*ngFor="let problem of data.problems; let problemIndex = index"
|
|
369
|
+
class="srk--nowrap srk-problem-header"
|
|
370
|
+
[style.background-image]="problemHeaderBackgroundImage(problem)"
|
|
371
|
+
>
|
|
372
|
+
<a
|
|
373
|
+
*ngIf="problem.link; else unlinkedProblemHeader"
|
|
374
|
+
[href]="problem.link"
|
|
375
|
+
target="_blank"
|
|
376
|
+
rel="noopener noreferrer"
|
|
377
|
+
style="color: unset"
|
|
378
|
+
>
|
|
379
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
380
|
+
<span
|
|
381
|
+
*ngIf="problem.statistics"
|
|
382
|
+
class="srk--display-block srk-problem-stats"
|
|
383
|
+
[title]="problemStatsTitle(problem.statistics)"
|
|
384
|
+
>
|
|
385
|
+
{{ problem.statistics.accepted }}
|
|
386
|
+
</span>
|
|
387
|
+
</a>
|
|
388
|
+
<ng-template #unlinkedProblemHeader>
|
|
389
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
390
|
+
<span
|
|
391
|
+
*ngIf="problem.statistics"
|
|
392
|
+
class="srk--display-block srk-problem-stats"
|
|
393
|
+
[title]="problemStatsTitle(problem.statistics)"
|
|
394
|
+
>
|
|
395
|
+
{{ problem.statistics.accepted }}
|
|
396
|
+
</span>
|
|
397
|
+
</ng-template>
|
|
398
|
+
</th>
|
|
399
|
+
<th *ngIf="showDirtColumn" class="srk-dirt-header srk--text-right srk--nowrap">
|
|
400
|
+
{{ resolveColumnTitle('dirt', 'Dirt') }}
|
|
401
|
+
</th>
|
|
402
|
+
<th *ngIf="showSEColumn" class="srk-se-header srk--text-right srk--nowrap">
|
|
403
|
+
{{ resolveColumnTitle('se', 'SE') }}
|
|
404
|
+
</th>
|
|
405
|
+
</tr>
|
|
406
|
+
</thead>
|
|
407
|
+
<tbody>
|
|
408
|
+
<tr *ngFor="let row of data.rows; let rowIndex = index">
|
|
409
|
+
<td
|
|
410
|
+
*ngFor="let rankValue of getRankValues(row); let seriesIndex = index"
|
|
411
|
+
class="srk--text-right srk--nowrap"
|
|
412
|
+
[ngClass]="getSeriesSegmentClass(rankValue, data.series[seriesIndex])"
|
|
413
|
+
[class.srk-series-segmented-column]="isSeriesSegmentedColumn(data.series[seriesIndex])"
|
|
414
|
+
[ngStyle]="getSeriesSegmentStyle(rankValue, data.series[seriesIndex])"
|
|
415
|
+
>
|
|
416
|
+
{{ getRankText(rankValue, row) }}
|
|
417
|
+
</td>
|
|
418
|
+
|
|
419
|
+
<td
|
|
420
|
+
*ngIf="splitOrganization"
|
|
421
|
+
class="srk-organization-cell srk--text-left srk--nowrap"
|
|
422
|
+
[class.srk-organization-cell-avatar]="showAvatarInOrganization() && !!row.user.avatar"
|
|
423
|
+
>
|
|
424
|
+
<div class="srk-organization-cell-content">
|
|
425
|
+
<div *ngIf="showAvatarInOrganization() && row.user.avatar" class="srk-user-avatar">
|
|
426
|
+
<img
|
|
427
|
+
[src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
|
|
428
|
+
alt="User Avatar"
|
|
429
|
+
/>
|
|
430
|
+
</div>
|
|
431
|
+
<span
|
|
432
|
+
class="srk-organization-name-text"
|
|
433
|
+
[title]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
|
|
434
|
+
[textContent]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
|
|
435
|
+
></span>
|
|
436
|
+
</div>
|
|
437
|
+
</td>
|
|
438
|
+
|
|
439
|
+
<ng-container *ngIf="userCellTemplate; else defaultUserCell">
|
|
440
|
+
<ng-container
|
|
441
|
+
[ngTemplateOutlet]="userCellTemplate.templateRef"
|
|
442
|
+
[ngTemplateOutletContext]="buildUserCellContext(row, rowIndex)"
|
|
443
|
+
/>
|
|
444
|
+
</ng-container>
|
|
445
|
+
<ng-template #defaultUserCell>
|
|
446
|
+
<td
|
|
447
|
+
class="srk--text-left srk--nowrap srk-user-cell srk--cursor-pointer"
|
|
448
|
+
role="button"
|
|
449
|
+
tabindex="0"
|
|
450
|
+
(click)="emitUserClick($event, row, rowIndex)"
|
|
451
|
+
(keydown.enter)="activateUserCellFromKeyboard($event, row, rowIndex)"
|
|
452
|
+
(keydown.space)="activateUserCellFromKeyboard($event, row, rowIndex)"
|
|
453
|
+
>
|
|
454
|
+
<div class="srk-user-cell-content">
|
|
455
|
+
<div *ngIf="row.user.avatar && !showAvatarInOrganization()" class="srk-user-avatar">
|
|
456
|
+
<img
|
|
457
|
+
[src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
|
|
458
|
+
alt="User Avatar"
|
|
459
|
+
/>
|
|
460
|
+
</div>
|
|
461
|
+
<div class="srk-user-body">
|
|
462
|
+
<div class="srk-user-name-row">
|
|
463
|
+
<span
|
|
464
|
+
class="srk-user-name-text"
|
|
465
|
+
[title]="resolveDisplayText(row.user.name)"
|
|
466
|
+
>
|
|
467
|
+
{{ resolveDisplayText(row.user.name) }}
|
|
468
|
+
</span>
|
|
469
|
+
<span class="srk-marker-dot-group">
|
|
470
|
+
<span
|
|
471
|
+
*ngFor="let marker of resolvedUserMarkers(row.user)"
|
|
472
|
+
class="srk-marker srk-marker-dot srk--c-tooltip"
|
|
473
|
+
[ngClass]="marker.presentation.className"
|
|
474
|
+
[ngStyle]="marker.presentation.style"
|
|
475
|
+
[attr.data-tooltip]="resolveDisplayText(marker.marker.label)"
|
|
476
|
+
></span>
|
|
477
|
+
</span>
|
|
478
|
+
</div>
|
|
479
|
+
<p
|
|
480
|
+
*ngIf="row.user.organization && !splitOrganization"
|
|
481
|
+
class="srk-user-secondary-text srk--text-ellipsis"
|
|
482
|
+
title=""
|
|
483
|
+
>
|
|
484
|
+
{{ resolveDisplayText(row.user.organization) }}
|
|
485
|
+
</p>
|
|
486
|
+
</div>
|
|
487
|
+
</div>
|
|
488
|
+
</td>
|
|
489
|
+
</ng-template>
|
|
490
|
+
|
|
491
|
+
<td class="srk--text-right srk--nowrap">{{ row.score.value }}</td>
|
|
492
|
+
<td *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
|
|
493
|
+
{{ row.score.time ? formatTime(row.score.time) : '-' }}
|
|
494
|
+
</td>
|
|
495
|
+
|
|
496
|
+
<ng-container *ngFor="let status of row.statuses; let problemIndex = index">
|
|
497
|
+
<ng-container *ngIf="statusCellTemplate; else defaultStatusCell">
|
|
498
|
+
<ng-container
|
|
499
|
+
[ngTemplateOutlet]="statusCellTemplate.templateRef"
|
|
500
|
+
[ngTemplateOutletContext]="buildStatusCellContext(row, rowIndex, status, problemIndex)"
|
|
501
|
+
/>
|
|
502
|
+
</ng-container>
|
|
503
|
+
<ng-template #defaultStatusCell>
|
|
504
|
+
<td
|
|
505
|
+
*ngIf="status.result === 'FB' || status.result === 'AC'; else failedOrFrozenStatus"
|
|
506
|
+
[ngClass]="statusCellClass(status)"
|
|
507
|
+
[attr.role]="statusCellRole(status)"
|
|
508
|
+
[attr.tabindex]="statusCellTabIndex(status)"
|
|
509
|
+
(click)="emitSolutionClick($event, row, rowIndex, status, problemIndex)"
|
|
510
|
+
(keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
511
|
+
(keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
512
|
+
>
|
|
513
|
+
<span
|
|
514
|
+
*ngIf="statusColorAsText && status.result === 'FB'"
|
|
515
|
+
class="srk-prest-status-block-fb-star"
|
|
516
|
+
[textContent]="firstBloodStar"
|
|
517
|
+
></span>
|
|
518
|
+
<ng-container *ngIf="statusPresentation(status) as presentation">
|
|
519
|
+
<ng-container *ngIf="isNumber(presentation.score); else statusText">
|
|
520
|
+
<span class="srk-prest-status-block-score">{{ presentation.score }}</span>
|
|
521
|
+
<span class="srk-prest-status-block-score-details">
|
|
522
|
+
{{ presentation.scoreDetails }}
|
|
523
|
+
</span>
|
|
524
|
+
</ng-container>
|
|
525
|
+
<ng-template #statusText>
|
|
526
|
+
<ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
|
|
527
|
+
<span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
|
|
528
|
+
<span [textContent]="statusSeparator"></span>
|
|
529
|
+
<span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
|
|
530
|
+
</ng-container>
|
|
531
|
+
<ng-template #singleStatus>{{ presentation.primary }}</ng-template>
|
|
532
|
+
</ng-template>
|
|
533
|
+
</ng-container>
|
|
534
|
+
</td>
|
|
535
|
+
<ng-template #failedOrFrozenStatus>
|
|
536
|
+
<td
|
|
537
|
+
*ngIf="status.result === '?' || status.result === 'RJ'; else emptyStatus"
|
|
538
|
+
[ngClass]="statusCellClass(status)"
|
|
539
|
+
[attr.role]="statusCellRole(status)"
|
|
540
|
+
[attr.tabindex]="statusCellTabIndex(status)"
|
|
541
|
+
(click)="emitSolutionClick($event, row, rowIndex, status, problemIndex)"
|
|
542
|
+
(keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
543
|
+
(keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
544
|
+
>
|
|
545
|
+
<ng-container *ngIf="statusPresentation(status) as presentation">
|
|
546
|
+
<ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
|
|
547
|
+
<span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
|
|
548
|
+
<span [textContent]="statusSeparator"></span>
|
|
549
|
+
<span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
|
|
550
|
+
</ng-container>
|
|
551
|
+
<ng-template #singleStatus>{{ presentation.primary }}</ng-template>
|
|
552
|
+
</ng-container>
|
|
553
|
+
</td>
|
|
554
|
+
</ng-template>
|
|
555
|
+
<ng-template #emptyStatus>
|
|
556
|
+
<td class="srk-status-placeholder-cell srk--text-center srk--nowrap">
|
|
557
|
+
{{ emptyStatusPlaceholder }}
|
|
558
|
+
</td>
|
|
559
|
+
</ng-template>
|
|
560
|
+
</ng-template>
|
|
561
|
+
</ng-container>
|
|
562
|
+
|
|
563
|
+
<td *ngIf="showDirtColumn" class="srk-dirt-cell srk--text-right srk--nowrap">
|
|
564
|
+
{{ calculateDirtPercentage(row) }}
|
|
565
|
+
</td>
|
|
566
|
+
<td *ngIf="showSEColumn" class="srk-se-cell srk--text-right srk--nowrap">
|
|
567
|
+
{{ calculateSEValue(row, problemStatistics) }}
|
|
568
|
+
</td>
|
|
569
|
+
</tr>
|
|
570
|
+
</tbody>
|
|
571
|
+
<tfoot *ngIf="showProblemStatisticsFooter">
|
|
572
|
+
<tr
|
|
573
|
+
*ngFor="let footerRow of problemStatisticsFooterRows"
|
|
574
|
+
class="srk-problem-statistics-footer-row"
|
|
575
|
+
>
|
|
576
|
+
<td
|
|
577
|
+
class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
|
|
578
|
+
[attr.colspan]="leftFooterColumnCount()"
|
|
579
|
+
>
|
|
580
|
+
<span
|
|
581
|
+
class="srk-problem-statistics-footer-label srk--c-tooltip"
|
|
582
|
+
[attr.data-tooltip]="footerRow.tooltip"
|
|
583
|
+
>
|
|
584
|
+
{{ footerRow.label }}
|
|
585
|
+
</span>
|
|
586
|
+
</td>
|
|
587
|
+
<td
|
|
588
|
+
*ngFor="let stat of problemStatistics"
|
|
589
|
+
class="srk-problem-statistics-footer-cell srk--text-center srk--nowrap"
|
|
590
|
+
>
|
|
591
|
+
<span class="srk-problem-statistics-footer-primary">
|
|
592
|
+
{{ getProblemStatisticsFooterCellPrimary(footerRow.key, stat) }}
|
|
593
|
+
</span>
|
|
594
|
+
<ng-container *ngIf="getProblemStatisticsFooterCellSecondary(footerRow.key, stat) !== undefined">
|
|
595
|
+
<span> </span>
|
|
596
|
+
<span class="srk-problem-statistics-footer-secondary">
|
|
597
|
+
{{ getProblemStatisticsFooterCellSecondary(footerRow.key, stat) }}
|
|
598
|
+
</span>
|
|
599
|
+
</ng-container>
|
|
600
|
+
</td>
|
|
601
|
+
<td
|
|
602
|
+
*ngIf="showDirtColumn"
|
|
603
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
|
|
604
|
+
>
|
|
605
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
606
|
+
</td>
|
|
607
|
+
<td
|
|
608
|
+
*ngIf="showSEColumn"
|
|
609
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
|
|
610
|
+
>
|
|
611
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
612
|
+
</td>
|
|
613
|
+
</tr>
|
|
614
|
+
<tr class="srk-problem-statistics-footer-row srk-problem-statistics-footer-problem-label-row">
|
|
615
|
+
<td
|
|
616
|
+
class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
|
|
617
|
+
[attr.colspan]="leftFooterColumnCount()"
|
|
618
|
+
></td>
|
|
619
|
+
<td
|
|
620
|
+
*ngFor="let problem of data.problems; let problemIndex = index"
|
|
621
|
+
class="srk-problem-statistics-footer-cell srk-problem-statistics-footer-problem-header srk-problem-header srk--text-center srk--nowrap"
|
|
622
|
+
[style.background-image]="problemHeaderBackgroundImage(problem, 0)"
|
|
623
|
+
>
|
|
624
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
625
|
+
</td>
|
|
626
|
+
<td
|
|
627
|
+
*ngIf="showDirtColumn"
|
|
628
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
|
|
629
|
+
>
|
|
630
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
631
|
+
</td>
|
|
632
|
+
<td
|
|
633
|
+
*ngIf="showSEColumn"
|
|
634
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
|
|
635
|
+
>
|
|
636
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
637
|
+
</td>
|
|
638
|
+
</tr>
|
|
639
|
+
</tfoot>
|
|
640
|
+
</table>
|
|
641
|
+
</div>
|
|
642
|
+
</ng-template>
|
|
643
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
644
|
+
}
|
|
645
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RanklistComponent, decorators: [{
|
|
646
|
+
type: Component,
|
|
647
|
+
args: [{
|
|
648
|
+
selector: 'srk-ranklist',
|
|
649
|
+
standalone: true,
|
|
650
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
651
|
+
imports: [CommonModule],
|
|
652
|
+
template: `
|
|
653
|
+
<div *ngIf="data.type !== 'general'; else versionState">
|
|
654
|
+
srk type "{{ data.type }}" is not supported
|
|
655
|
+
</div>
|
|
656
|
+
|
|
657
|
+
<ng-template #versionState>
|
|
658
|
+
<div *ngIf="!isSupportedVersion(); else ranklistTable">
|
|
659
|
+
srk version "{{ data.version }}" is not supported (current supported: {{ supportedVersions }})
|
|
660
|
+
</div>
|
|
661
|
+
</ng-template>
|
|
662
|
+
|
|
663
|
+
<ng-template #ranklistTable>
|
|
664
|
+
<div class="srk-common-table srk-main">
|
|
665
|
+
<table
|
|
666
|
+
[class.srk-table-row-bordered]="rowBordered"
|
|
667
|
+
[class.srk-table-column-bordered]="columnBordered"
|
|
668
|
+
[class.srk-table-row-striped]="rowStriped"
|
|
669
|
+
>
|
|
670
|
+
<thead>
|
|
671
|
+
<tr>
|
|
672
|
+
<th
|
|
673
|
+
*ngFor="let seriesItem of data.series; let seriesIndex = index"
|
|
674
|
+
class="srk-series-header srk--text-right srk--nowrap"
|
|
675
|
+
[class.srk-series-segmented-column]="isSeriesSegmentedColumn(seriesItem)"
|
|
676
|
+
>
|
|
677
|
+
{{ resolveSeriesColumnTitle(seriesItem, seriesIndex) }}
|
|
678
|
+
</th>
|
|
679
|
+
<th
|
|
680
|
+
*ngIf="splitOrganization"
|
|
681
|
+
class="srk-organization-header srk--text-left srk--nowrap"
|
|
682
|
+
>
|
|
683
|
+
{{ resolveColumnTitle('organization', 'Organization') }}
|
|
684
|
+
</th>
|
|
685
|
+
<th class="srk--text-left srk--nowrap">{{ resolveColumnTitle('user', 'Name') }}</th>
|
|
686
|
+
<th class="srk--text-right srk--nowrap">{{ resolveColumnTitle('score', 'Score') }}</th>
|
|
687
|
+
<th *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
|
|
688
|
+
{{ resolveColumnTitle('time', 'Time') }}
|
|
689
|
+
</th>
|
|
690
|
+
<th
|
|
691
|
+
*ngFor="let problem of data.problems; let problemIndex = index"
|
|
692
|
+
class="srk--nowrap srk-problem-header"
|
|
693
|
+
[style.background-image]="problemHeaderBackgroundImage(problem)"
|
|
694
|
+
>
|
|
695
|
+
<a
|
|
696
|
+
*ngIf="problem.link; else unlinkedProblemHeader"
|
|
697
|
+
[href]="problem.link"
|
|
698
|
+
target="_blank"
|
|
699
|
+
rel="noopener noreferrer"
|
|
700
|
+
style="color: unset"
|
|
701
|
+
>
|
|
702
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
703
|
+
<span
|
|
704
|
+
*ngIf="problem.statistics"
|
|
705
|
+
class="srk--display-block srk-problem-stats"
|
|
706
|
+
[title]="problemStatsTitle(problem.statistics)"
|
|
707
|
+
>
|
|
708
|
+
{{ problem.statistics.accepted }}
|
|
709
|
+
</span>
|
|
710
|
+
</a>
|
|
711
|
+
<ng-template #unlinkedProblemHeader>
|
|
712
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
713
|
+
<span
|
|
714
|
+
*ngIf="problem.statistics"
|
|
715
|
+
class="srk--display-block srk-problem-stats"
|
|
716
|
+
[title]="problemStatsTitle(problem.statistics)"
|
|
717
|
+
>
|
|
718
|
+
{{ problem.statistics.accepted }}
|
|
719
|
+
</span>
|
|
720
|
+
</ng-template>
|
|
721
|
+
</th>
|
|
722
|
+
<th *ngIf="showDirtColumn" class="srk-dirt-header srk--text-right srk--nowrap">
|
|
723
|
+
{{ resolveColumnTitle('dirt', 'Dirt') }}
|
|
724
|
+
</th>
|
|
725
|
+
<th *ngIf="showSEColumn" class="srk-se-header srk--text-right srk--nowrap">
|
|
726
|
+
{{ resolveColumnTitle('se', 'SE') }}
|
|
727
|
+
</th>
|
|
728
|
+
</tr>
|
|
729
|
+
</thead>
|
|
730
|
+
<tbody>
|
|
731
|
+
<tr *ngFor="let row of data.rows; let rowIndex = index">
|
|
732
|
+
<td
|
|
733
|
+
*ngFor="let rankValue of getRankValues(row); let seriesIndex = index"
|
|
734
|
+
class="srk--text-right srk--nowrap"
|
|
735
|
+
[ngClass]="getSeriesSegmentClass(rankValue, data.series[seriesIndex])"
|
|
736
|
+
[class.srk-series-segmented-column]="isSeriesSegmentedColumn(data.series[seriesIndex])"
|
|
737
|
+
[ngStyle]="getSeriesSegmentStyle(rankValue, data.series[seriesIndex])"
|
|
738
|
+
>
|
|
739
|
+
{{ getRankText(rankValue, row) }}
|
|
740
|
+
</td>
|
|
741
|
+
|
|
742
|
+
<td
|
|
743
|
+
*ngIf="splitOrganization"
|
|
744
|
+
class="srk-organization-cell srk--text-left srk--nowrap"
|
|
745
|
+
[class.srk-organization-cell-avatar]="showAvatarInOrganization() && !!row.user.avatar"
|
|
746
|
+
>
|
|
747
|
+
<div class="srk-organization-cell-content">
|
|
748
|
+
<div *ngIf="showAvatarInOrganization() && row.user.avatar" class="srk-user-avatar">
|
|
749
|
+
<img
|
|
750
|
+
[src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
|
|
751
|
+
alt="User Avatar"
|
|
752
|
+
/>
|
|
753
|
+
</div>
|
|
754
|
+
<span
|
|
755
|
+
class="srk-organization-name-text"
|
|
756
|
+
[title]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
|
|
757
|
+
[textContent]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
|
|
758
|
+
></span>
|
|
759
|
+
</div>
|
|
760
|
+
</td>
|
|
761
|
+
|
|
762
|
+
<ng-container *ngIf="userCellTemplate; else defaultUserCell">
|
|
763
|
+
<ng-container
|
|
764
|
+
[ngTemplateOutlet]="userCellTemplate.templateRef"
|
|
765
|
+
[ngTemplateOutletContext]="buildUserCellContext(row, rowIndex)"
|
|
766
|
+
/>
|
|
767
|
+
</ng-container>
|
|
768
|
+
<ng-template #defaultUserCell>
|
|
769
|
+
<td
|
|
770
|
+
class="srk--text-left srk--nowrap srk-user-cell srk--cursor-pointer"
|
|
771
|
+
role="button"
|
|
772
|
+
tabindex="0"
|
|
773
|
+
(click)="emitUserClick($event, row, rowIndex)"
|
|
774
|
+
(keydown.enter)="activateUserCellFromKeyboard($event, row, rowIndex)"
|
|
775
|
+
(keydown.space)="activateUserCellFromKeyboard($event, row, rowIndex)"
|
|
776
|
+
>
|
|
777
|
+
<div class="srk-user-cell-content">
|
|
778
|
+
<div *ngIf="row.user.avatar && !showAvatarInOrganization()" class="srk-user-avatar">
|
|
779
|
+
<img
|
|
780
|
+
[src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
|
|
781
|
+
alt="User Avatar"
|
|
782
|
+
/>
|
|
783
|
+
</div>
|
|
784
|
+
<div class="srk-user-body">
|
|
785
|
+
<div class="srk-user-name-row">
|
|
786
|
+
<span
|
|
787
|
+
class="srk-user-name-text"
|
|
788
|
+
[title]="resolveDisplayText(row.user.name)"
|
|
789
|
+
>
|
|
790
|
+
{{ resolveDisplayText(row.user.name) }}
|
|
791
|
+
</span>
|
|
792
|
+
<span class="srk-marker-dot-group">
|
|
793
|
+
<span
|
|
794
|
+
*ngFor="let marker of resolvedUserMarkers(row.user)"
|
|
795
|
+
class="srk-marker srk-marker-dot srk--c-tooltip"
|
|
796
|
+
[ngClass]="marker.presentation.className"
|
|
797
|
+
[ngStyle]="marker.presentation.style"
|
|
798
|
+
[attr.data-tooltip]="resolveDisplayText(marker.marker.label)"
|
|
799
|
+
></span>
|
|
800
|
+
</span>
|
|
801
|
+
</div>
|
|
802
|
+
<p
|
|
803
|
+
*ngIf="row.user.organization && !splitOrganization"
|
|
804
|
+
class="srk-user-secondary-text srk--text-ellipsis"
|
|
805
|
+
title=""
|
|
806
|
+
>
|
|
807
|
+
{{ resolveDisplayText(row.user.organization) }}
|
|
808
|
+
</p>
|
|
809
|
+
</div>
|
|
810
|
+
</div>
|
|
811
|
+
</td>
|
|
812
|
+
</ng-template>
|
|
813
|
+
|
|
814
|
+
<td class="srk--text-right srk--nowrap">{{ row.score.value }}</td>
|
|
815
|
+
<td *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
|
|
816
|
+
{{ row.score.time ? formatTime(row.score.time) : '-' }}
|
|
817
|
+
</td>
|
|
818
|
+
|
|
819
|
+
<ng-container *ngFor="let status of row.statuses; let problemIndex = index">
|
|
820
|
+
<ng-container *ngIf="statusCellTemplate; else defaultStatusCell">
|
|
821
|
+
<ng-container
|
|
822
|
+
[ngTemplateOutlet]="statusCellTemplate.templateRef"
|
|
823
|
+
[ngTemplateOutletContext]="buildStatusCellContext(row, rowIndex, status, problemIndex)"
|
|
824
|
+
/>
|
|
825
|
+
</ng-container>
|
|
826
|
+
<ng-template #defaultStatusCell>
|
|
827
|
+
<td
|
|
828
|
+
*ngIf="status.result === 'FB' || status.result === 'AC'; else failedOrFrozenStatus"
|
|
829
|
+
[ngClass]="statusCellClass(status)"
|
|
830
|
+
[attr.role]="statusCellRole(status)"
|
|
831
|
+
[attr.tabindex]="statusCellTabIndex(status)"
|
|
832
|
+
(click)="emitSolutionClick($event, row, rowIndex, status, problemIndex)"
|
|
833
|
+
(keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
834
|
+
(keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
835
|
+
>
|
|
836
|
+
<span
|
|
837
|
+
*ngIf="statusColorAsText && status.result === 'FB'"
|
|
838
|
+
class="srk-prest-status-block-fb-star"
|
|
839
|
+
[textContent]="firstBloodStar"
|
|
840
|
+
></span>
|
|
841
|
+
<ng-container *ngIf="statusPresentation(status) as presentation">
|
|
842
|
+
<ng-container *ngIf="isNumber(presentation.score); else statusText">
|
|
843
|
+
<span class="srk-prest-status-block-score">{{ presentation.score }}</span>
|
|
844
|
+
<span class="srk-prest-status-block-score-details">
|
|
845
|
+
{{ presentation.scoreDetails }}
|
|
846
|
+
</span>
|
|
847
|
+
</ng-container>
|
|
848
|
+
<ng-template #statusText>
|
|
849
|
+
<ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
|
|
850
|
+
<span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
|
|
851
|
+
<span [textContent]="statusSeparator"></span>
|
|
852
|
+
<span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
|
|
853
|
+
</ng-container>
|
|
854
|
+
<ng-template #singleStatus>{{ presentation.primary }}</ng-template>
|
|
855
|
+
</ng-template>
|
|
856
|
+
</ng-container>
|
|
857
|
+
</td>
|
|
858
|
+
<ng-template #failedOrFrozenStatus>
|
|
859
|
+
<td
|
|
860
|
+
*ngIf="status.result === '?' || status.result === 'RJ'; else emptyStatus"
|
|
861
|
+
[ngClass]="statusCellClass(status)"
|
|
862
|
+
[attr.role]="statusCellRole(status)"
|
|
863
|
+
[attr.tabindex]="statusCellTabIndex(status)"
|
|
864
|
+
(click)="emitSolutionClick($event, row, rowIndex, status, problemIndex)"
|
|
865
|
+
(keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
866
|
+
(keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
867
|
+
>
|
|
868
|
+
<ng-container *ngIf="statusPresentation(status) as presentation">
|
|
869
|
+
<ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
|
|
870
|
+
<span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
|
|
871
|
+
<span [textContent]="statusSeparator"></span>
|
|
872
|
+
<span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
|
|
873
|
+
</ng-container>
|
|
874
|
+
<ng-template #singleStatus>{{ presentation.primary }}</ng-template>
|
|
875
|
+
</ng-container>
|
|
876
|
+
</td>
|
|
877
|
+
</ng-template>
|
|
878
|
+
<ng-template #emptyStatus>
|
|
879
|
+
<td class="srk-status-placeholder-cell srk--text-center srk--nowrap">
|
|
880
|
+
{{ emptyStatusPlaceholder }}
|
|
881
|
+
</td>
|
|
882
|
+
</ng-template>
|
|
883
|
+
</ng-template>
|
|
884
|
+
</ng-container>
|
|
885
|
+
|
|
886
|
+
<td *ngIf="showDirtColumn" class="srk-dirt-cell srk--text-right srk--nowrap">
|
|
887
|
+
{{ calculateDirtPercentage(row) }}
|
|
888
|
+
</td>
|
|
889
|
+
<td *ngIf="showSEColumn" class="srk-se-cell srk--text-right srk--nowrap">
|
|
890
|
+
{{ calculateSEValue(row, problemStatistics) }}
|
|
891
|
+
</td>
|
|
892
|
+
</tr>
|
|
893
|
+
</tbody>
|
|
894
|
+
<tfoot *ngIf="showProblemStatisticsFooter">
|
|
895
|
+
<tr
|
|
896
|
+
*ngFor="let footerRow of problemStatisticsFooterRows"
|
|
897
|
+
class="srk-problem-statistics-footer-row"
|
|
898
|
+
>
|
|
899
|
+
<td
|
|
900
|
+
class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
|
|
901
|
+
[attr.colspan]="leftFooterColumnCount()"
|
|
902
|
+
>
|
|
903
|
+
<span
|
|
904
|
+
class="srk-problem-statistics-footer-label srk--c-tooltip"
|
|
905
|
+
[attr.data-tooltip]="footerRow.tooltip"
|
|
906
|
+
>
|
|
907
|
+
{{ footerRow.label }}
|
|
908
|
+
</span>
|
|
909
|
+
</td>
|
|
910
|
+
<td
|
|
911
|
+
*ngFor="let stat of problemStatistics"
|
|
912
|
+
class="srk-problem-statistics-footer-cell srk--text-center srk--nowrap"
|
|
913
|
+
>
|
|
914
|
+
<span class="srk-problem-statistics-footer-primary">
|
|
915
|
+
{{ getProblemStatisticsFooterCellPrimary(footerRow.key, stat) }}
|
|
916
|
+
</span>
|
|
917
|
+
<ng-container *ngIf="getProblemStatisticsFooterCellSecondary(footerRow.key, stat) !== undefined">
|
|
918
|
+
<span> </span>
|
|
919
|
+
<span class="srk-problem-statistics-footer-secondary">
|
|
920
|
+
{{ getProblemStatisticsFooterCellSecondary(footerRow.key, stat) }}
|
|
921
|
+
</span>
|
|
922
|
+
</ng-container>
|
|
923
|
+
</td>
|
|
924
|
+
<td
|
|
925
|
+
*ngIf="showDirtColumn"
|
|
926
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
|
|
927
|
+
>
|
|
928
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
929
|
+
</td>
|
|
930
|
+
<td
|
|
931
|
+
*ngIf="showSEColumn"
|
|
932
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
|
|
933
|
+
>
|
|
934
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
935
|
+
</td>
|
|
936
|
+
</tr>
|
|
937
|
+
<tr class="srk-problem-statistics-footer-row srk-problem-statistics-footer-problem-label-row">
|
|
938
|
+
<td
|
|
939
|
+
class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
|
|
940
|
+
[attr.colspan]="leftFooterColumnCount()"
|
|
941
|
+
></td>
|
|
942
|
+
<td
|
|
943
|
+
*ngFor="let problem of data.problems; let problemIndex = index"
|
|
944
|
+
class="srk-problem-statistics-footer-cell srk-problem-statistics-footer-problem-header srk-problem-header srk--text-center srk--nowrap"
|
|
945
|
+
[style.background-image]="problemHeaderBackgroundImage(problem, 0)"
|
|
946
|
+
>
|
|
947
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
948
|
+
</td>
|
|
949
|
+
<td
|
|
950
|
+
*ngIf="showDirtColumn"
|
|
951
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
|
|
952
|
+
>
|
|
953
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
954
|
+
</td>
|
|
955
|
+
<td
|
|
956
|
+
*ngIf="showSEColumn"
|
|
957
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
|
|
958
|
+
>
|
|
959
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
960
|
+
</td>
|
|
961
|
+
</tr>
|
|
962
|
+
</tfoot>
|
|
963
|
+
</table>
|
|
964
|
+
</div>
|
|
965
|
+
</ng-template>
|
|
966
|
+
`,
|
|
967
|
+
}]
|
|
968
|
+
}], propDecorators: { data: [{
|
|
969
|
+
type: Input,
|
|
970
|
+
args: [{ required: true }]
|
|
971
|
+
}], theme: [{
|
|
972
|
+
type: Input
|
|
973
|
+
}], rowBordered: [{
|
|
974
|
+
type: Input
|
|
975
|
+
}], columnBordered: [{
|
|
976
|
+
type: Input
|
|
977
|
+
}], rowStriped: [{
|
|
978
|
+
type: Input
|
|
979
|
+
}], formatSrkAssetUrl: [{
|
|
980
|
+
type: Input
|
|
981
|
+
}], splitOrganization: [{
|
|
982
|
+
type: Input
|
|
983
|
+
}], columnTitles: [{
|
|
984
|
+
type: Input
|
|
985
|
+
}], statusCellPreset: [{
|
|
986
|
+
type: Input
|
|
987
|
+
}], statusColorAsText: [{
|
|
988
|
+
type: Input
|
|
989
|
+
}], showProblemStatisticsFooter: [{
|
|
990
|
+
type: Input
|
|
991
|
+
}], showDirtColumn: [{
|
|
992
|
+
type: Input
|
|
993
|
+
}], showSEColumn: [{
|
|
994
|
+
type: Input
|
|
995
|
+
}], emptyStatusPlaceholder: [{
|
|
996
|
+
type: Input
|
|
997
|
+
}], userAvatarPlacement: [{
|
|
998
|
+
type: Input
|
|
999
|
+
}], userClick: [{
|
|
1000
|
+
type: Output
|
|
1001
|
+
}], solutionClick: [{
|
|
1002
|
+
type: Output
|
|
1003
|
+
}], statusCellTemplate: [{
|
|
1004
|
+
type: ContentChild,
|
|
1005
|
+
args: [SrkStatusCellTemplateDirective]
|
|
1006
|
+
}], userCellTemplate: [{
|
|
1007
|
+
type: ContentChild,
|
|
1008
|
+
args: [SrkUserCellTemplateDirective]
|
|
1009
|
+
}] } });
|
|
1010
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFua2xpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9yYW5rbGlzdC9yYW5rbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsU0FBUyxFQUNULGtCQUFrQixFQUNsQixnQkFBZ0IsRUFDaEIsWUFBWSxFQUNaLFdBQVcsRUFDWCxrQkFBa0IsR0FDbkIsTUFBTSxpQ0FBaUMsQ0FBQztBQUV6QyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGdDQUFnQyxFQUNoQyxnQkFBZ0IsRUFDaEIsT0FBTyxFQUNQLHFDQUFxQyxFQUNyQyxzQ0FBc0MsRUFDdEMsOEJBQThCLEVBQzlCLHFCQUFxQixFQUNyQiwrQkFBK0IsRUFDL0Isb0NBQW9DLEVBQ3BDLGtCQUFrQixFQUNsQixvQkFBb0IsRUFDcEIsb0JBQW9CLEdBQ3JCLE1BQU0sbURBQW1ELENBQUM7QUFPM0QsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFRckYsT0FBTyxFQUNMLDhCQUE4QixHQUUvQixNQUFNLGtDQUFrQyxDQUFDO0FBQzFDLE9BQU8sRUFDTCw0QkFBNEIsR0FFN0IsTUFBTSxnQ0FBZ0MsQ0FBQzs7O0FBbVV4QyxNQUFNLE9BQU8saUJBQWlCO0lBQ0QsSUFBSSxDQUFrQjtJQUN4QyxLQUFLLEdBQWMsU0FBUyxDQUFDLEtBQUssQ0FBQztJQUNuQyxXQUFXLEdBQUcsS0FBSyxDQUFDO0lBQ3BCLGNBQWMsR0FBRyxLQUFLLENBQUM7SUFDdkIsVUFBVSxHQUFHLEtBQUssQ0FBQztJQUNuQixpQkFBaUIsQ0FBMEM7SUFD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QUUsSUFBSSxFQUFFO2dCQUNoQixLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0csMkJBQTJCO3NCQUFuQyxLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxzQkFBc0I7c0JBQTlCLEtBQUs7Z0JBQ0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUVJLFNBQVM7c0JBQWxCLE1BQU07Z0JBQ0csYUFBYTtzQkFBdEIsTUFBTTtnQkFHUCxrQkFBa0I7c0JBRGpCLFlBQVk7dUJBQUMsOEJBQThCO2dCQUk1QyxnQkFBZ0I7c0JBRGYsWUFBWTt1QkFBQyw0QkFBNEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSAqIGFzIHNyayBmcm9tICdAYWxnb3V4L3N0YW5kYXJkLXJhbmtsaXN0JztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE91dHB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBFbnVtVGhlbWUsXG4gIGZvcm1hdFRpbWVEdXJhdGlvbixcbiAgbnVtYmVyVG9BbHBoYWJldCxcbiAgcmVzb2x2ZVN0eWxlLFxuICByZXNvbHZlVGV4dCxcbiAgcmVzb2x2ZVVzZXJNYXJrZXJzLFxufSBmcm9tICdAYWxnb3V4L3N0YW5kYXJkLXJhbmtsaXN0LXV0aWxzJztcbmltcG9ydCB0eXBlIHsgVGhlbWVDb2xvciB9IGZyb20gJ0BhbGdvdXgvc3RhbmRhcmQtcmFua2xpc3QtdXRpbHMnO1xuaW1wb3J0IHtcbiAgY2FsY3VsYXRlRGlydFBlcmNlbnRhZ2UsXG4gIGNhbGN1bGF0ZVByb2JsZW1TdGF0aXN0aWNzRm9vdGVyLFxuICBjYWxjdWxhdGVTRVZhbHVlLFxuICBjYW5pdXNlLFxuICBmb3JtYXRQcm9ibGVtU3RhdGlzdGljc0FjY2VwdGVkTWludXRlLFxuICBmb3JtYXRQcm9ibGVtU3RhdGlzdGljc0F2ZXJhZ2VIYXJkbmVzcyxcbiAgZm9ybWF0UHJvYmxlbVN0YXRpc3RpY3NQZXJjZW50LFxuICBnZXRNYXJrZXJQcmVzZW50YXRpb24sXG4gIGdldFByb2JsZW1IZWFkZXJCYWNrZ3JvdW5kSW1hZ2UsXG4gIGdldFJhbmtQcm9ibGVtU3RhdHVzQ2VsbFByZXNlbnRhdGlvbixcbiAgcmVzb2x2ZVNya0Fzc2V0VXJsLFxuICBzaG91bGRTaG93VGltZUNvbHVtbixcbiAgc3JrU3VwcG9ydGVkVmVyc2lvbnMsXG59IGZyb20gJ0BhbGdvdXgvc3RhbmRhcmQtcmFua2xpc3QtcmVuZGVyZXItY29tcG9uZW50LWNvcmUnO1xuaW1wb3J0IHR5cGUge1xuICBQcm9ibGVtU3RhdGlzdGljc0Zvb3RlcixcbiAgUmFua2xpc3RDb2x1bW5UaXRsZXMsXG4gIFJhbmtsaXN0U3RhdHVzQ2VsbFByZXNldCxcbiAgUmFua2xpc3RVc2VyQXZhdGFyUGxhY2VtZW50LFxufSBmcm9tICdAYWxnb3V4L3N0YW5kYXJkLXJhbmtsaXN0LXJlbmRlcmVyLWNvbXBvbmVudC1jb3JlJztcbmltcG9ydCB7IGNhcHR1cmVNb2RhbFRyaWdnZXJQb2ludEZyb21Nb3VzZUV2ZW50IH0gZnJvbSAnLi4vbW9kYWwvbW9kYWwtaW50ZXJhY3Rpb25zJztcbmltcG9ydCB0eXBlIHtcbiAgUmFua1ZhbHVlLFxuICBTb2x1dGlvbkNsaWNrUGF5bG9hZCxcbiAgU3RhdGljUmFua2xpc3QsXG4gIFN0YXRpY1JhbmtsaXN0Um93LFxuICBVc2VyQ2xpY2tQYXlsb2FkLFxufSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge1xuICBTcmtTdGF0dXNDZWxsVGVtcGxhdGVEaXJlY3RpdmUsXG4gIHR5cGUgU3RhdHVzQ2VsbFRlbXBsYXRlQ29udGV4dCxcbn0gZnJvbSAnLi9zdGF0dXMtY2VsbC10ZW1wbGF0ZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHtcbiAgU3JrVXNlckNlbGxUZW1wbGF0ZURpcmVjdGl2ZSxcbiAgdHlwZSBVc2VyQ2VsbFRlbXBsYXRlQ29udGV4dCxcbn0gZnJvbSAnLi91c2VyLWNlbGwtdGVtcGxhdGUuZGlyZWN0aXZlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3JrLXJhbmtsaXN0JyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgKm5nSWY9XCJkYXRhLnR5cGUgIT09ICdnZW5lcmFsJzsgZWxzZSB2ZXJzaW9uU3RhdGVcIj5cbiAgICAgIHNyayB0eXBlIFwie3sgZGF0YS50eXBlIH19XCIgaXMgbm90IHN1cHBvcnRlZFxuICAgIDwvZGl2PlxuXG4gICAgPG5nLXRlbXBsYXRlICN2ZXJzaW9uU3RhdGU+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIWlzU3VwcG9ydGVkVmVyc2lvbigpOyBlbHNlIHJhbmtsaXN0VGFibGVcIj5cbiAgICAgICAgc3JrIHZlcnNpb24gXCJ7eyBkYXRhLnZlcnNpb24gfX1cIiBpcyBub3Qgc3VwcG9ydGVkIChjdXJyZW50IHN1cHBvcnRlZDoge3sgc3VwcG9ydGVkVmVyc2lvbnMgfX0pXG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPG5nLXRlbXBsYXRlICNyYW5rbGlzdFRhYmxlPlxuICAgICAgPGRpdiBjbGFzcz1cInNyay1jb21tb24tdGFibGUgc3JrLW1haW5cIj5cbiAgICAgICAgPHRhYmxlXG4gICAgICAgICAgW2NsYXNzLnNyay10YWJsZS1yb3ctYm9yZGVyZWRdPVwicm93Qm9yZGVyZWRcIlxuICAgICAgICAgIFtjbGFzcy5zcmstdGFibGUtY29sdW1uLWJvcmRlcmVkXT1cImNvbHVtbkJvcmRlcmVkXCJcbiAgICAgICAgICBbY2xhc3Muc3JrLXRhYmxlLXJvdy1zdHJpcGVkXT1cInJvd1N0cmlwZWRcIlxuICAgICAgICA+XG4gICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgc2VyaWVzSXRlbSBvZiBkYXRhLnNlcmllczsgbGV0IHNlcmllc0luZGV4ID0gaW5kZXhcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLXNlcmllcy1oZWFkZXIgc3JrLS10ZXh0LXJpZ2h0IHNyay0tbm93cmFwXCJcbiAgICAgICAgICAgICAgICBbY2xhc3Muc3JrLXNlcmllcy1zZWdtZW50ZWQtY29sdW1uXT1cImlzU2VyaWVzU2VnbWVudGVkQ29sdW1uKHNlcmllc0l0ZW0pXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IHJlc29sdmVTZXJpZXNDb2x1bW5UaXRsZShzZXJpZXNJdGVtLCBzZXJpZXNJbmRleCkgfX1cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJzcGxpdE9yZ2FuaXphdGlvblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstb3JnYW5pemF0aW9uLWhlYWRlciBzcmstLXRleHQtbGVmdCBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyByZXNvbHZlQ29sdW1uVGl0bGUoJ29yZ2FuaXphdGlvbicsICdPcmdhbml6YXRpb24nKSB9fVxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJzcmstLXRleHQtbGVmdCBzcmstLW5vd3JhcFwiPnt7IHJlc29sdmVDb2x1bW5UaXRsZSgndXNlcicsICdOYW1lJykgfX08L3RoPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJzcmstLXRleHQtcmlnaHQgc3JrLS1ub3dyYXBcIj57eyByZXNvbHZlQ29sdW1uVGl0bGUoJ3Njb3JlJywgJ1Njb3JlJykgfX08L3RoPlxuICAgICAgICAgICAgICA8dGggKm5nSWY9XCJzaG93VGltZUNvbHVtbigpXCIgY2xhc3M9XCJzcmstLXRleHQtcmlnaHQgc3JrLS1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgICB7eyByZXNvbHZlQ29sdW1uVGl0bGUoJ3RpbWUnLCAnVGltZScpIH19XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBwcm9ibGVtIG9mIGRhdGEucHJvYmxlbXM7IGxldCBwcm9ibGVtSW5kZXggPSBpbmRleFwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstLW5vd3JhcCBzcmstcHJvYmxlbS1oZWFkZXJcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWltYWdlXT1cInByb2JsZW1IZWFkZXJCYWNrZ3JvdW5kSW1hZ2UocHJvYmxlbSlcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwicHJvYmxlbS5saW5rOyBlbHNlIHVubGlua2VkUHJvYmxlbUhlYWRlclwiXG4gICAgICAgICAgICAgICAgICBbaHJlZl09XCJwcm9ibGVtLmxpbmtcIlxuICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgICAgIHJlbD1cIm5vb3BlbmVyIG5vcmVmZXJyZXJcIlxuICAgICAgICAgICAgICAgICAgc3R5bGU9XCJjb2xvcjogdW5zZXRcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JrLS1kaXNwbGF5LWJsb2NrXCI+e3sgcHJvYmxlbUFsaWFzKHByb2JsZW0sIHByb2JsZW1JbmRleCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInByb2JsZW0uc3RhdGlzdGljc1wiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLS1kaXNwbGF5LWJsb2NrIHNyay1wcm9ibGVtLXN0YXRzXCJcbiAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cInByb2JsZW1TdGF0c1RpdGxlKHByb2JsZW0uc3RhdGlzdGljcylcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7eyBwcm9ibGVtLnN0YXRpc3RpY3MuYWNjZXB0ZWQgfX1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICN1bmxpbmtlZFByb2JsZW1IZWFkZXI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyay0tZGlzcGxheS1ibG9ja1wiPnt7IHByb2JsZW1BbGlhcyhwcm9ibGVtLCBwcm9ibGVtSW5kZXgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJwcm9ibGVtLnN0YXRpc3RpY3NcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay0tZGlzcGxheS1ibG9jayBzcmstcHJvYmxlbS1zdGF0c1wiXG4gICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCJwcm9ibGVtU3RhdHNUaXRsZShwcm9ibGVtLnN0YXRpc3RpY3MpXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge3sgcHJvYmxlbS5zdGF0aXN0aWNzLmFjY2VwdGVkIH19XG4gICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoICpuZ0lmPVwic2hvd0RpcnRDb2x1bW5cIiBjbGFzcz1cInNyay1kaXJ0LWhlYWRlciBzcmstLXRleHQtcmlnaHQgc3JrLS1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgICB7eyByZXNvbHZlQ29sdW1uVGl0bGUoJ2RpcnQnLCAnRGlydCcpIH19XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDx0aCAqbmdJZj1cInNob3dTRUNvbHVtblwiIGNsYXNzPVwic3JrLXNlLWhlYWRlciBzcmstLXRleHQtcmlnaHQgc3JrLS1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgICB7eyByZXNvbHZlQ29sdW1uVGl0bGUoJ3NlJywgJ1NFJykgfX1cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IHJvdyBvZiBkYXRhLnJvd3M7IGxldCByb3dJbmRleCA9IGluZGV4XCI+XG4gICAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCByYW5rVmFsdWUgb2YgZ2V0UmFua1ZhbHVlcyhyb3cpOyBsZXQgc2VyaWVzSW5kZXggPSBpbmRleFwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstLXRleHQtcmlnaHQgc3JrLS1ub3dyYXBcIlxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImdldFNlcmllc1NlZ21lbnRDbGFzcyhyYW5rVmFsdWUsIGRhdGEuc2VyaWVzW3Nlcmllc0luZGV4XSlcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5zcmstc2VyaWVzLXNlZ21lbnRlZC1jb2x1bW5dPVwiaXNTZXJpZXNTZWdtZW50ZWRDb2x1bW4oZGF0YS5zZXJpZXNbc2VyaWVzSW5kZXhdKVwiXG4gICAgICAgICAgICAgICAgW25nU3R5bGVdPVwiZ2V0U2VyaWVzU2VnbWVudFN0eWxlKHJhbmtWYWx1ZSwgZGF0YS5zZXJpZXNbc2VyaWVzSW5kZXhdKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyBnZXRSYW5rVGV4dChyYW5rVmFsdWUsIHJvdykgfX1cbiAgICAgICAgICAgICAgPC90ZD5cblxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNwbGl0T3JnYW5pemF0aW9uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1vcmdhbml6YXRpb24tY2VsbCBzcmstLXRleHQtbGVmdCBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLnNyay1vcmdhbml6YXRpb24tY2VsbC1hdmF0YXJdPVwic2hvd0F2YXRhckluT3JnYW5pemF0aW9uKCkgJiYgISFyb3cudXNlci5hdmF0YXJcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNyay1vcmdhbml6YXRpb24tY2VsbC1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwic2hvd0F2YXRhckluT3JnYW5pemF0aW9uKCkgJiYgcm93LnVzZXIuYXZhdGFyXCIgY2xhc3M9XCJzcmstdXNlci1hdmF0YXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiZm9ybWF0QXNzZXRVcmwocm93LnVzZXIuYXZhdGFyLCAndXNlci5hdmF0YXInKVwiXG4gICAgICAgICAgICAgICAgICAgICAgYWx0PVwiVXNlciBBdmF0YXJcIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1vcmdhbml6YXRpb24tbmFtZS10ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cInJvdy51c2VyLm9yZ2FuaXphdGlvbiA/IHJlc29sdmVEaXNwbGF5VGV4dChyb3cudXNlci5vcmdhbml6YXRpb24pIDogJydcIlxuICAgICAgICAgICAgICAgICAgICBbdGV4dENvbnRlbnRdPVwicm93LnVzZXIub3JnYW5pemF0aW9uID8gcmVzb2x2ZURpc3BsYXlUZXh0KHJvdy51c2VyLm9yZ2FuaXphdGlvbikgOiAnJ1wiXG4gICAgICAgICAgICAgICAgICA+PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L3RkPlxuXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ1c2VyQ2VsbFRlbXBsYXRlOyBlbHNlIGRlZmF1bHRVc2VyQ2VsbFwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInVzZXJDZWxsVGVtcGxhdGUudGVtcGxhdGVSZWZcIlxuICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cImJ1aWxkVXNlckNlbGxDb250ZXh0KHJvdywgcm93SW5kZXgpXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0VXNlckNlbGw+XG4gICAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay0tdGV4dC1sZWZ0IHNyay0tbm93cmFwIHNyay11c2VyLWNlbGwgc3JrLS1jdXJzb3ItcG9pbnRlclwiXG4gICAgICAgICAgICAgICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZW1pdFVzZXJDbGljaygkZXZlbnQsIHJvdywgcm93SW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cImFjdGl2YXRlVXNlckNlbGxGcm9tS2V5Ym9hcmQoJGV2ZW50LCByb3csIHJvd0luZGV4KVwiXG4gICAgICAgICAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCJhY3RpdmF0ZVVzZXJDZWxsRnJvbUtleWJvYXJkKCRldmVudCwgcm93LCByb3dJbmRleClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcmstdXNlci1jZWxsLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInJvdy51c2VyLmF2YXRhciAmJiAhc2hvd0F2YXRhckluT3JnYW5pemF0aW9uKClcIiBjbGFzcz1cInNyay11c2VyLWF2YXRhclwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiZm9ybWF0QXNzZXRVcmwocm93LnVzZXIuYXZhdGFyLCAndXNlci5hdmF0YXInKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJVc2VyIEF2YXRhclwiXG4gICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcmstdXNlci1ib2R5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNyay11c2VyLW5hbWUtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay11c2VyLW5hbWUtdGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCJyZXNvbHZlRGlzcGxheVRleHQocm93LnVzZXIubmFtZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB7eyByZXNvbHZlRGlzcGxheVRleHQocm93LnVzZXIubmFtZSkgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JrLW1hcmtlci1kb3QtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgbWFya2VyIG9mIHJlc29sdmVkVXNlck1hcmtlcnMocm93LnVzZXIpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1tYXJrZXIgc3JrLW1hcmtlci1kb3Qgc3JrLS1jLXRvb2x0aXBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1hcmtlci5wcmVzZW50YXRpb24uY2xhc3NOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJtYXJrZXIucHJlc2VudGF0aW9uLnN0eWxlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5kYXRhLXRvb2x0aXBdPVwicmVzb2x2ZURpc3BsYXlUZXh0KG1hcmtlci5tYXJrZXIubGFiZWwpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8cFxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJyb3cudXNlci5vcmdhbml6YXRpb24gJiYgIXNwbGl0T3JnYW5pemF0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLXVzZXItc2Vjb25kYXJ5LXRleHQgc3JrLS10ZXh0LWVsbGlwc2lzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyByZXNvbHZlRGlzcGxheVRleHQocm93LnVzZXIub3JnYW5pemF0aW9uKSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInNyay0tdGV4dC1yaWdodCBzcmstLW5vd3JhcFwiPnt7IHJvdy5zY29yZS52YWx1ZSB9fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZCAqbmdJZj1cInNob3dUaW1lQ29sdW1uKClcIiBjbGFzcz1cInNyay0tdGV4dC1yaWdodCBzcmstLW5vd3JhcFwiPlxuICAgICAgICAgICAgICAgIHt7IHJvdy5zY29yZS50aW1lID8gZm9ybWF0VGltZShyb3cuc2NvcmUudGltZSkgOiAnLScgfX1cbiAgICAgICAgICAgICAgPC90ZD5cblxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdGF0dXMgb2Ygcm93LnN0YXR1c2VzOyBsZXQgcHJvYmxlbUluZGV4ID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3RhdHVzQ2VsbFRlbXBsYXRlOyBlbHNlIGRlZmF1bHRTdGF0dXNDZWxsXCI+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInN0YXR1c0NlbGxUZW1wbGF0ZS50ZW1wbGF0ZVJlZlwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJidWlsZFN0YXR1c0NlbGxDb250ZXh0KHJvdywgcm93SW5kZXgsIHN0YXR1cywgcHJvYmxlbUluZGV4KVwiXG4gICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFN0YXR1c0NlbGw+XG4gICAgICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJzdGF0dXMucmVzdWx0ID09PSAnRkInIHx8IHN0YXR1cy5yZXN1bHQgPT09ICdBQyc7IGVsc2UgZmFpbGVkT3JGcm96ZW5TdGF0dXNcIlxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJzdGF0dXNDZWxsQ2xhc3Moc3RhdHVzKVwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLnJvbGVdPVwic3RhdHVzQ2VsbFJvbGUoc3RhdHVzKVwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLnRhYmluZGV4XT1cInN0YXR1c0NlbGxUYWJJbmRleChzdGF0dXMpXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImVtaXRTb2x1dGlvbkNsaWNrKCRldmVudCwgcm93LCByb3dJbmRleCwgc3RhdHVzLCBwcm9ibGVtSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiYWN0aXZhdGVTdGF0dXNDZWxsRnJvbUtleWJvYXJkKCRldmVudCwgcm93LCByb3dJbmRleCwgc3RhdHVzLCBwcm9ibGVtSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgKGtleWRvd24uc3BhY2UpPVwiYWN0aXZhdGVTdGF0dXNDZWxsRnJvbUtleWJvYXJkKCRldmVudCwgcm93LCByb3dJbmRleCwgc3RhdHVzLCBwcm9ibGVtSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInN0YXR1c0NvbG9yQXNUZXh0ICYmIHN0YXR1cy5yZXN1bHQgPT09ICdGQidcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLXByZXN0LXN0YXR1cy1ibG9jay1mYi1zdGFyXCJcbiAgICAgICAgICAgICAgICAgICAgICBbdGV4dENvbnRlbnRdPVwiZmlyc3RCbG9vZFN0YXJcIlxuICAgICAgICAgICAgICAgICAgICA+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3RhdHVzUHJlc2VudGF0aW9uKHN0YXR1cykgYXMgcHJlc2VudGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzTnVtYmVyKHByZXNlbnRhdGlvbi5zY29yZSk7IGVsc2Ugc3RhdHVzVGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJlc3Qtc3RhdHVzLWJsb2NrLXNjb3JlXCI+e3sgcHJlc2VudGF0aW9uLnNjb3JlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJlc3Qtc3RhdHVzLWJsb2NrLXNjb3JlLWRldGFpbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAge3sgcHJlc2VudGF0aW9uLnNjb3JlRGV0YWlscyB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc3RhdHVzVGV4dD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJwcmVzZW50YXRpb24uc2Vjb25kYXJ5ICE9PSB1bmRlZmluZWQ7IGVsc2Ugc2luZ2xlU3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JrLXByZXN0LXN0YXR1cy1ibG9jay1wcmltYXJ5XCI+e3sgcHJlc2VudGF0aW9uLnByaW1hcnkgfHwgJycgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFt0ZXh0Q29udGVudF09XCJzdGF0dXNTZXBhcmF0b3JcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JrLXByZXN0LXN0YXR1cy1ibG9jay1zZWNvbmRhcnlcIj57eyBwcmVzZW50YXRpb24uc2Vjb25kYXJ5IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI3NpbmdsZVN0YXR1cz57eyBwcmVzZW50YXRpb24ucHJpbWFyeSB9fTwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNmYWlsZWRPckZyb3plblN0YXR1cz5cbiAgICAgICAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJzdGF0dXMucmVzdWx0ID09PSAnPycgfHwgc3RhdHVzLnJlc3VsdCA9PT0gJ1JKJzsgZWxzZSBlbXB0eVN0YXR1c1wiXG4gICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwic3RhdHVzQ2VsbENsYXNzKHN0YXR1cylcIlxuICAgICAgICAgICAgICAgICAgICAgIFthdHRyLnJvbGVdPVwic3RhdHVzQ2VsbFJvbGUoc3RhdHVzKVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2F0dHIudGFiaW5kZXhdPVwic3RhdHVzQ2VsbFRhYkluZGV4KHN0YXR1cylcIlxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJlbWl0U29sdXRpb25DbGljaygkZXZlbnQsIHJvdywgcm93SW5kZXgsIHN0YXR1cywgcHJvYmxlbUluZGV4KVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiYWN0aXZhdGVTdGF0dXNDZWxsRnJvbUtleWJvYXJkKCRldmVudCwgcm93LCByb3dJbmRleCwgc3RhdHVzLCBwcm9ibGVtSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCJhY3RpdmF0ZVN0YXR1c0NlbGxGcm9tS2V5Ym9hcmQoJGV2ZW50LCByb3csIHJvd0luZGV4LCBzdGF0dXMsIHByb2JsZW1JbmRleClcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInN0YXR1c1ByZXNlbnRhdGlvbihzdGF0dXMpIGFzIHByZXNlbnRhdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInByZXNlbnRhdGlvbi5zZWNvbmRhcnkgIT09IHVuZGVmaW5lZDsgZWxzZSBzaW5nbGVTdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJlc3Qtc3RhdHVzLWJsb2NrLXByaW1hcnlcIj57eyBwcmVzZW50YXRpb24ucHJpbWFyeSB8fCAnJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW3RleHRDb250ZW50XT1cInN0YXR1c1NlcGFyYXRvclwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJlc3Qtc3RhdHVzLWJsb2NrLXNlY29uZGFyeVwiPnt7IHByZXNlbnRhdGlvbi5zZWNvbmRhcnkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlU3RhdHVzPnt7IHByZXNlbnRhdGlvbi5wcmltYXJ5IH19PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2VtcHR5U3RhdHVzPlxuICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJzcmstc3RhdHVzLXBsYWNlaG9sZGVyLWNlbGwgc3JrLS10ZXh0LWNlbnRlciBzcmstLW5vd3JhcFwiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IGVtcHR5U3RhdHVzUGxhY2Vob2xkZXIgfX1cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgPHRkICpuZ0lmPVwic2hvd0RpcnRDb2x1bW5cIiBjbGFzcz1cInNyay1kaXJ0LWNlbGwgc3JrLS10ZXh0LXJpZ2h0IHNyay0tbm93cmFwXCI+XG4gICAgICAgICAgICAgICAge3sgY2FsY3VsYXRlRGlydFBlcmNlbnRhZ2Uocm93KSB9fVxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGQgKm5nSWY9XCJzaG93U0VDb2x1bW5cIiBjbGFzcz1cInNyay1zZS1jZWxsIHNyay0tdGV4dC1yaWdodCBzcmstLW5vd3JhcFwiPlxuICAgICAgICAgICAgICAgIHt7IGNhbGN1bGF0ZVNFVmFsdWUocm93LCBwcm9ibGVtU3RhdGlzdGljcykgfX1cbiAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICA8dGZvb3QgKm5nSWY9XCJzaG93UHJvYmxlbVN0YXRpc3RpY3NGb290ZXJcIj5cbiAgICAgICAgICAgIDx0clxuICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgZm9vdGVyUm93IG9mIHByb2JsZW1TdGF0aXN0aWNzRm9vdGVyUm93c1wiXG4gICAgICAgICAgICAgIGNsYXNzPVwic3JrLXByb2JsZW0tc3RhdGlzdGljcy1mb290ZXItcm93XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1sYWJlbHMgc3JrLS10ZXh0LXJpZ2h0IHNyay0tbm93cmFwXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5jb2xzcGFuXT1cImxlZnRGb290ZXJDb2x1bW5Db3VudCgpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLWxhYmVsIHNyay0tYy10b29sdGlwXCJcbiAgICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtdG9vbHRpcF09XCJmb290ZXJSb3cudG9vbHRpcFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAge3sgZm9vdGVyUm93LmxhYmVsIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgc3RhdCBvZiBwcm9ibGVtU3RhdGlzdGljc1wiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1jZWxsIHNyay0tdGV4dC1jZW50ZXIgc3JrLS1ub3dyYXBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1wcmltYXJ5XCI+XG4gICAgICAgICAgICAgICAgICB7eyBnZXRQcm9ibGVtU3RhdGlzdGljc0Zvb3RlckNlbGxQcmltYXJ5KGZvb3RlclJvdy5rZXksIHN0YXQpIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRQcm9ibGVtU3RhdGlzdGljc0Zvb3RlckNlbGxTZWNvbmRhcnkoZm9vdGVyUm93LmtleSwgc3RhdCkgIT09IHVuZGVmaW5lZFwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+IDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JrLXByb2JsZW0tc3RhdGlzdGljcy1mb290ZXItc2Vjb25kYXJ5XCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGdldFByb2JsZW1TdGF0aXN0aWNzRm9vdGVyQ2VsbFNlY29uZGFyeShmb290ZXJSb3cua2V5LCBzdGF0KSB9fVxuICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dEaXJ0Q29sdW1uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLWNlbGwgc3JrLWV4dHJhLXN0YXRpc3RpY3MtZm9vdGVyLWNlbGwgc3JrLWRpcnQtZm9vdGVyLWNlbGwgc3JrLS1ub3dyYXBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1wcmltYXJ5XCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dTRUNvbHVtblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1jZWxsIHNyay1leHRyYS1zdGF0aXN0aWNzLWZvb3Rlci1jZWxsIHNyay1zZS1mb290ZXItY2VsbCBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLXByaW1hcnlcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPHRyIGNsYXNzPVwic3JrLXByb2JsZW0tc3RhdGlzdGljcy1mb290ZXItcm93IHNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLXByb2JsZW0tbGFiZWwtcm93XCI+XG4gICAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLXByb2JsZW0tc3RhdGlzdGljcy1mb290ZXItbGFiZWxzIHNyay0tdGV4dC1yaWdodCBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgICAgW2F0dHIuY29sc3Bhbl09XCJsZWZ0Rm9vdGVyQ29sdW1uQ291bnQoKVwiXG4gICAgICAgICAgICAgID48L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgcHJvYmxlbSBvZiBkYXRhLnByb2JsZW1zOyBsZXQgcHJvYmxlbUluZGV4ID0gaW5kZXhcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLXByb2JsZW0tc3RhdGlzdGljcy1mb290ZXItY2VsbCBzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1wcm9ibGVtLWhlYWRlciBzcmstcHJvYmxlbS1oZWFkZXIgc3JrLS10ZXh0LWNlbnRlciBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmQtaW1hZ2VdPVwicHJvYmxlbUhlYWRlckJhY2tncm91bmRJbWFnZShwcm9ibGVtLCAwKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyay0tZGlzcGxheS1ibG9ja1wiPnt7IHByb2JsZW1BbGlhcyhwcm9ibGVtLCBwcm9ibGVtSW5kZXgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dEaXJ0Q29sdW1uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLWNlbGwgc3JrLWV4dHJhLXN0YXRpc3RpY3MtZm9vdGVyLWNlbGwgc3JrLWRpcnQtZm9vdGVyLWNlbGwgc3JrLS1ub3dyYXBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1wcmltYXJ5XCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dTRUNvbHVtblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1jZWxsIHNyay1leHRyYS1zdGF0aXN0aWNzLWZvb3Rlci1jZWxsIHNyay1zZS1mb290ZXItY2VsbCBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLXByaW1hcnlcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGZvb3Q+XG4gICAgICAgIDwvdGFibGU+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBSYW5rbGlzdENvbXBvbmVudCB7XG4gIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pIGRhdGEhOiBTdGF0aWNSYW5rbGlzdDtcbiAgQElucHV0KCkgdGhlbWU6IEVudW1UaGVtZSA9IEVudW1UaGVtZS5saWdodDtcbiAgQElucHV0KCkgcm93Qm9yZGVyZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgY29sdW1uQm9yZGVyZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgcm93U3RyaXBlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBmb3JtYXRTcmtBc3NldFVybD86ICh1cmw6IHN0cmluZywgZmllbGQ6IHN0cmluZykgPT4gc3RyaW5nO1xuICBASW5wdXQoKSBzcGxpdE9yZ2FuaXphdGlvbiA9IGZhbHNlO1xuICBASW5wdXQoKSBjb2x1bW5UaXRsZXM/OiBSYW5rbGlzdENvbHVtblRpdGxlcztcbiAgQElucHV0KCkgc3RhdHVzQ2VsbFByZXNldDogUmFua2xpc3RTdGF0dXNDZWxsUHJlc2V0ID0gJ2NsYXNzaWMnO1xuICBASW5wdXQoKSBzdGF0dXNDb2xvckFzVGV4dCA9IGZhbHNlO1xuICBASW5wdXQoKSBzaG93UHJvYmxlbVN0YXRpc3RpY3NGb290ZXIgPSBmYWxzZTtcbiAgQElucHV0KCkgc2hvd0RpcnRDb2x1bW4gPSBmYWxzZTtcbiAgQElucHV0KCkgc2hvd1NFQ29sdW1uID0gZmFsc2U7XG4gIEBJbnB1dCgpIGVtcHR5U3RhdHVzUGxhY2Vob2xkZXI6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSB1c2VyQXZhdGFyUGxhY2VtZW50OiBSYW5rbGlzdFVzZXJBdmF0YXJQbGFjZW1lbnQgPSAndXNlcic7XG5cbiAgQE91dHB1dCgpIHVzZXJDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8VXNlckNsaWNrUGF5bG9hZD4oKTtcbiAgQE91dHB1dCgpIHNvbHV0aW9uQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPFNvbHV0aW9uQ2xpY2tQYXlsb2FkPigpO1xuXG4gIEBDb250ZW50Q2hpbGQoU3JrU3RhdHVzQ2VsbFRlbXBsYXRlRGlyZWN0aXZlKVxuICBzdGF0dXNDZWxsVGVtcGxhdGU/OiBTcmtTdGF0dXNDZWxsVGVtcGxhdGVEaXJlY3RpdmU7XG5cbiAgQENvbnRlbnRDaGlsZChTcmtVc2VyQ2VsbFRlbXBsYXRlRGlyZWN0aXZlKVxuICB1c2VyQ2VsbFRlbXBsYXRlPzogU3JrVXNlckNlbGxUZW1wbGF0ZURpcmVjdGl2ZTtcblxuICByZWFkb25seSBzdXBwb3J0ZWRWZXJzaW9ucyA9IHNya1N1cHBvcnRlZFZlcnNpb25zO1xuICByZWFkb25seSBmaXJzdEJsb29kU3RhciA9ICdcXHUyNjA1JztcbiAgcmVhZG9ubHkgc3RhdHVzU2VwYXJhdG9yID0gJyAnO1xuICByZWFkb25seSBwcm9ibGVtU3RhdGlzdGljc0Zvb3RlclJvd3MgPSBbXG4gICAge1xuICAgICAga2V5OiAnYWNjZXB0ZWQnLFxuICAgICAgbGFiZWw6ICdBY2NlcHRlZCcsXG4gICAgICB0b29sdGlwOiAnTnVtYmVyIG9mIHBhcnRpY2lwYW50cyB3aG8gc29sdmVkIHRoaXMgcHJvYmxlbScsXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6ICd0cmllZCcsXG4gICAgICBsYWJlbDogJ1RyaWVkJyxcbiAgICAgIHRvb2x0aXA6ICdOdW1iZXIgb2YgcGFydGljaXBhbnRzIHdobyBhdHRlbXB0ZWQgdGhpcyBwcm9ibGVtJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGtleTogJ3N1Ym1pdHRlZCcsXG4gICAgICBsYWJlbDogJ1N1Ym1pdHRlZCcsXG4gICAgICB0b29sdGlwOiAnVG90YWwgbnVtYmVyIG9mIHZhbGlkIHN1Ym1pc3Npb25zIGZvciB0aGlzIHByb2JsZW0nLFxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnZGlydCcsXG4gICAgICBsYWJlbDogJ0RpcnQnLFxuICAgICAgdG9vbHRpcDogJ1dyb25nIHN1Ym1pc3Npb25zIGFtb25nIHBhcnRpY2lwYW50cyB3aG8gc29sdmVkIHRoaXMgcHJvYmxlbScsXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6ICdzZScsXG4gICAgICBsYWJlbDogJ1NFJyxcbiAgICAgIHRvb2x0aXA6ICdBdmVyYWdlIGhhcmRuZXNzLCBjYWxjdWxhdGVkIGFzIChwYXJ0aWNpcGFudHMgLSBhY2NlcHRlZCkgLyBwYXJ0aWNpcGFudHMnLFxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnZmlyc3RBY2NlcHRlZCcsXG4gICAgICBsYWJlbDogJ0ZCIGF0JyxcbiAgICAgIHRvb2x0aXA6ICdGaXJzdCBCbG9vZCBhdCwgYWxzbyBrbm93biBhcyBmaXJzdCBzb2x2ZSB0aW1lLCBpbiBtaW51dGVzJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGtleTogJ2xhc3RBY2NlcHRlZCcsXG4gICAgICBsYWJlbDogJ0xCIGF0JyxcbiAgICAgIHRvb2x0aXA6ICdMYXN0IEJsb29kIGF0LCBhbHNvIGtub3duIGFzIGxhc3Qgc29sdmUgdGltZSwgaW4gbWludXRlcycsXG4gICAgfSxcbiAgXTtcbiAgcHJpdmF0ZSBwcm9ibGVtU3RhdGlzdGljc1NvdXJjZT86IFN0YXRpY1JhbmtsaXN0O1xuICBwcml2YXRlIHByb2JsZW1TdGF0aXN0aWNzQ2FjaGU/OiBQcm9ibGVtU3RhdGlzdGljc0Zvb3RlcltdO1xuXG4gIGdldCBwcm9ibGVtU3RhdGlzdGljcygpIHtcbiAgICBpZiAoIXRoaXMuc2hvd1Byb2JsZW1TdGF0aXN0aWNzRm9vdGVyICYmICF0aGlzLnNob3dTRUNvbHVtbikge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcm9ibGVtU3RhdGlzdGljc1NvdXJjZSAhPT0gdGhpcy5kYXRhIHx8ICF0aGlzLnByb2JsZW1TdGF0aXN0aWNzQ2FjaGUpIHtcbiAgICAgIHRoaXMucHJvYmxlbVN0YXRpc3RpY3NTb3VyY2UgPSB0aGlzLmRhdGE7XG4gICAgICB0aGlzLnByb2JsZW1TdGF0aXN0aWNzQ2FjaGUgPSBjYWxjdWxhdGVQcm9ibGVtU3RhdGlzdGljc0Zvb3Rlcih0aGlzLmRhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wcm9ibGVtU3RhdGlzdGljc0NhY2hlO1xuICB9XG5cbiAgaXNTdXBwb3J0ZWRWZXJzaW9uKCkge1xuICAgIHJldHVybiBjYW5pdXNlKHRoaXMuZGF0YS52ZXJzaW9uKTtcbiAgfVxuXG4gIHNob3dUaW1lQ29sdW1uKCkge1xuICAgIHJldHVybiBzaG91bGRTaG93VGltZUNvbHVtbih0aGlzLmRhdGEucm93cyk7XG4gIH1cblxuICBzaG93QXZhdGFySW5Pcmdhbml6YXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuc3BsaXRPcmdhbml6YXRpb24gJiYgdGhpcy51c2VyQXZhdGFyUGxhY2VtZW50ID09PSAnb3JnYW5pemF0aW9uJztcbiAgfVxuXG4gIGxlZnRGb290ZXJDb2x1bW5Db3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhLnNlcmllcy5sZW5ndGggKyAxICsgMSArICh0aGlzLnNob3dUaW1lQ29sdW1uKCkgPyAxIDogMCkgKyAodGhpcy5zcGxpdE9yZ2FuaXphdGlvbiA/IDEgOiAwKTtcbiAgfVxuXG4gIGdldFJhbmtWYWx1ZXMocm93OiBTdGF0aWNSYW5rbGlzdFJvdyk6IFJhbmtWYWx1ZVtdIHtcbiAgICByZXR1cm4gcm93LnJhbmtWYWx1ZXMgfHwgdGhpcy5kYXRhLnNlcmllcy5tYXAoKCkgPT4gKHsgcmFuazogbnVsbCwgc2VnbWVudEluZGV4OiBudWxsIH0pKTtcbiAgfVxuXG4gIGdldFJhbmtUZXh0KHJhbmtWYWx1ZTogUmFua1ZhbHVlLCByb3c6IFN0YXRpY1JhbmtsaXN0Um93KSB7XG4gICAgcmV0dXJuIHJhbmtWYWx1ZS5yYW5rID8gcmFua1ZhbHVlLnJhbmsgOiByb3cudXNlci5vZmZpY2lhbCA9PT0gZmFsc2UgPyAn77yKJyA6ICcnO1xuICB9XG5cbiAgcmVzb2x2ZURpc3BsYXlUZXh0KHRleHQ6IFBhcmFtZXRlcnM8dHlwZW9mIHJlc29sdmVUZXh0PlswXSkge1xuICAgIHJldHVybiByZXNvbHZlVGV4dCh0ZXh0KTtcbiAgfVxuXG4gIHJlc29sdmVTZXJpZXNDb2x1bW5UaXRsZShzZXJpZXM6IHNyay5SYW5rU2VyaWVzLCBpbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3Qgc2VyaWVzVGl0bGVzID0gdGhpcy5jb2x1bW5UaXRsZXM/LnNlcmllcztcbiAgICBpZiAodHlwZW9mIHNlcmllc1RpdGxlcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIHNlcmllc1RpdGxlcyhzZXJpZXMsIGluZGV4KSA/PyBzZXJpZXMudGl0bGU7XG4gICAgfVxuICAgIGlmIChBcnJheS5pc0FycmF5KHNlcmllc1RpdGxlcykpIHtcbiAgICAgIHJldHVybiBzZXJpZXNUaXRsZXNbaW5kZXhdID8/IHNlcmllcy50aXRsZTtcbiAgICB9XG4gICAgcmV0dXJuIHNlcmllcy50aXRsZTtcbiAgfVxuXG4gIHJlc29sdmVDb2x1bW5UaXRsZShrZXk6IEV4Y2x1ZGU8a2V5b2YgUmFua2xpc3RDb2x1bW5UaXRsZXMsICdzZXJpZXMnPiwgZmFsbGJhY2s6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmNvbHVtblRpdGxlcz8uW2tleV0gPz8gZmFsbGJhY2s7XG4gIH1cblxuICBwcm9ibGVtQWxpYXMocHJvYmxlbTogc3JrLlByb2JsZW0sIHByb2JsZW1JbmRleDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIHByb2JsZW0uYWxpYXMgfHwgbnVtYmVyVG9BbHBoYWJldChwcm9ibGVtSW5kZXgpO1xuICB9XG5cbiAgcHJvYmxlbVN0YXRzVGl0bGUoc3RhdGlzdGljczogc3JrLlByb2JsZW1TdGF0aXN0aWNzKSB7XG4gICAgY29uc3QgcmF0aW8gPSBzdGF0aXN0aWNzLnN1Ym1pdHRlZCA/ICgoc3RhdGlzdGljcy5hY2NlcHRlZCAvIHN0YXRpc3RpY3Muc3VibWl0dGVkKSAqIDEwMCkudG9GaXhlZCgxKSA6IDA7XG4gICAgcmV0dXJuIGAke3N0YXRpc3RpY3MuYWNjZXB0ZWR9IC8gJHtzdGF0aXN0aWNzLnN1Ym1pdHRlZH0gKCR7cmF0aW99JSlgO1xuICB9XG5cbiAgcHJvYmxlbUhlYWRlckJhY2tncm91bmRJbWFnZShwcm9ibGVtOiBzcmsuUHJvYmxlbSwgZ3JhZGllbnREaXJlY3Rpb24gPSAxODApIHtcbiAgICByZXR1cm4gZ2V0UHJvYmxlbUhlYWRlckJhY2tncm91bmRJbWFnZShwcm9ibGVtLnN0eWxlLCB0aGlzLnRoZW1lLCBncmFkaWVudERpcmVjdGlvbik7XG4gIH1cblxuICByZXNvbHZlZFVzZXJNYXJrZXJzKHVzZXI6IHNyay5Vc2VyKSB7XG4gICAgcmV0dXJuIHJlc29sdmVVc2VyTWFya2Vycyh1c2VyLCB0aGlzLmRhdGEubWFya2VycykubWFwKChtYXJrZXIpID0+ICh7XG4gICAgICBtYXJrZXIsXG4gICAgICBwcmVzZW50YXRpb246IGdldE1hcmtlclByZXNlbnRhdGlvbihtYXJrZXIsIHRoaXMudGhlbWUpLFxuICAgIH0pKTtcbiAgfVxuXG4gIGZvcm1hdEFzc2V0VXJsKHVybDogc3RyaW5nLCBmaWVsZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHJlc29sdmVTcmtBc3NldFVybCh1cmwsIGZpZWxkLCB0aGlzLmZvcm1hdFNya0Fzc2V0VXJsKTtcbiAgfVxuXG4gIGZvcm1hdFRpbWUodGltZTogUGFyYW1ldGVyczx0eXBlb2YgZm9ybWF0VGltZUR1cmF0aW9uPlswXSkge1xuICAgIHJldHVybiBmb3JtYXRUaW1lRHVyYXRpb24odGltZSwgJ21pbicsIE1hdGguZmxvb3IpO1xuICB9XG5cbiAgY2FsY3VsYXRlRGlydFBlcmNlbnRhZ2Uocm93OiBTdGF0aWNSYW5rbGlzdFJvdykge1xuICAgIHJldHVybiBjYWxjdWxhdGVEaXJ0UGVyY2VudGFnZShyb3cpO1xuICB9XG5cbiAgY2FsY3VsYXRlU0VWYWx1ZShyb3c6IFN0YXRpY1JhbmtsaXN0Um93LCBwcm9ibGVtU3RhdGlzdGljczogUHJvYmxlbVN0YXRpc3RpY3NGb290ZXJbXSkge1xuICAgIHJldHVybiBjYWxjdWxhdGVTRVZhbHVlKHJvdywgcHJvYmxlbVN0YXRpc3RpY3MpO1xuICB9XG5cbiAgc3RhdHVzUHJlc2VudGF0aW9uKHN0YXR1czogc3JrLlJhbmtQcm9ibGVtU3RhdHVzKSB7XG4gICAgcmV0dXJuIGdldFJhbmtQcm9ibGVtU3RhdHVzQ2VsbFByZXNlbnRhdGlvbihzdGF0dXMsIHRoaXMuZGF0YSwgdGhpcy5zdGF0dXNDZWxsUHJlc2V0KTtcbiAgfVxuXG4gIGlzTnVtYmVyKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgbnVtYmVyIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJztcbiAgfVxuXG4gIGdldFN0YXR1c1NvbHV0aW9ucyhzdGF0dXM6IHNyay5SYW5rUHJvYmxlbVN0YXR1cykge1xuICAgIHJldHVybiBbLi4uKHN0YXR1cy5zb2x1dGlvbnMgfHwgW10pXS5yZXZlcnNlKCk7XG4gIH1cblxuICBzdGF0dXNDZWxsQ2xhc3Moc3RhdHVzOiBzcmsuUmFua1Byb2JsZW1TdGF0dXMpIHtcbiAgICBjb25zdCBjbGFzc05hbWVzID0gWydzcmstcHJlc3Qtc3RhdHVzLWJsb2NrJywgJ3Nyay0tdGV4dC1jZW50ZXInLCAnc3JrLS1ub3dyYXAnXTtcbiAgICBpZiAodGhpcy5pc1N0YXR1c0NsaWNrYWJsZShzdGF0dXMpKSB7XG4gICAgICBjbGFzc05hbWVzLnB1c2goJ3Nyay0tY3Vyc29yLXBvaW50ZXInKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc3RhdHVzQ29sb3JBc1RleHQpIHtcbiAgICAgIGNsYXNzTmFtZXMucHVzaCgnc3JrLXByZXN0LXN0YXR1cy1ibG9jay1jb2xvci10ZXh0Jyk7XG4gICAgfVxuICAgIGlmIChzdGF0dXMucmVzdWx0ID09PSAnRkInKSB7XG4gICAgICBjbGFzc05hbWVzLnB1c2goJ3Nyay1wcmVzdC1zdGF0dXMtYmxvY2stZmInKTtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cy5yZXN1bHQgPT09ICdBQycpIHtcbiAgICAgIGNsYXNzTmFtZXMucHVzaCgnc3JrLXByZXN0LXN0YXR1cy1ibG9jay1hY2NlcHRlZCcpO1xuICAgIH0gZWxzZSBpZiAoc3RhdHVzLnJlc3VsdCA9PT0gJz8nKSB7XG4gICAgICBjbGFzc05hbWVzLnB1c2goJ3Nyay1wcmVzdC1zdGF0dXMtYmxvY2stZnJvemVuJyk7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMucmVzdWx0ID09PSAnUkonKSB7XG4gICAgICBjbGFzc05hbWVzLnB1c2goJ3Nyay1wcmVzdC1zdGF0dXMtYmxvY2stZmFpbGVkJyk7XG4gICAgfVxuICAgIHJldHVybiBjbGFzc05hbWVzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIGlzU3RhdHVzQ2xpY2thYmxlKHN0YXR1czogc3JrLlJhbmtQcm9ibGVtU3RhdHVzKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0U3RhdHVzU29sdXRpb25zKHN0YXR1cykubGVuZ3RoID4gMDtcbiAgfVxuXG4gIHN0YXR1c0NlbGxSb2xlKHN0YXR1czogc3JrLlJhbmtQcm9ibGVtU3RhdHVzKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNTdGF0dXNDbGlja2FibGUoc3RhdHVzKSA/ICdidXR0b24nIDogbnVsbDtcbiAgfVxuXG4gIHN0YXR1c0NlbGxUYWJJbmRleChzdGF0dXM6IHNyay5SYW5rUHJvYmxlbVN0YXR1cykge1xuICAgIHJldHVybiB0aGlzLmlzU3RhdHVzQ2xpY2thYmxlKHN0YXR1cykgPyAwIDogbnVsbDtcbiAgfVxuXG4gIGJ1aWxkVXNlckNlbGxDb250ZXh0KHJvdzogU3RhdGljUmFua2xpc3RSb3csIHJvd0luZGV4OiBudW1iZXIpOiBVc2VyQ2VsbFRlbXBsYXRlQ29udGV4dCB7XG4gICAgcmV0dXJuIHtcbiAgICAgICRpbXBsaWNpdDogcm93LnVzZXIsXG4gICAgICB1c2VyOiByb3cudXNlcixcbiAgICAgIHJvdyxcbiAgICAgIHJvd0luZGV4LFxuICAgICAgcmFua2xpc3Q6IHRoaXMuZGF0YSxcbiAgICAgIG1hcmtlcnM6IHRoaXMuZGF0YS5tYXJrZXJzLFxuICAgICAgaGlkZU9yZ2FuaXphdGlvbjogdGhpcy5zcGxpdE9yZ2FuaXphdGlvbixcbiAgICAgIGhpZGVBdmF0YXI6IHRoaXMuc2hvd0F2YXRhckluT3JnYW5pemF0aW9uKCksXG4gICAgICBvbkNsaWNrOiAoZXZlbnQ/OiBNb3VzZUV2ZW50KSA9PiB0aGlzLmVtaXRVc2VyQ2xpY2soZXZlbnQsIHJvdywgcm93SW5kZXgpLFxuICAgIH07XG4gIH1cblxuICBidWlsZFN0YXR1c0NlbGxDb250ZXh0KFxuICAgIHJvdzogU3RhdGljUmFua2xpc3RSb3csXG4gICAgcm93SW5kZXg6IG51bWJlcixcbiAgICBzdGF0dXM6IHNyay5SYW5rUHJvYmxlbVN0YXR1cyxcbiAgICBwcm9ibGVtSW5kZXg6IG51bWJlcixcbiAgKTogU3RhdHVzQ2VsbFRlbXBsYXRlQ29udGV4dCB7XG4gICAgcmV0dXJuIHtcbiAgICAgICRpbXBsaWNpdDogc3RhdHVzLFxuICAgICAgc3RhdHVzLFxuICAgICAgcHJvYmxlbTogdGhpcy5kYXRhLnByb2JsZW1zW3Byb2JsZW1JbmRleF0sXG4gICAgICBwcm9ibGVtSW5kZXgsXG4gICAgICB1c2VyOiByb3cudXNlcixcbiAgICAgIHJvdyxcbiAgICAgIHJvd0luZGV4LFxuICAgICAgcmFua2xpc3Q6IHRoaXMuZGF0YSxcbiAgICAgIHNvbHV0aW9uczogdGhpcy5nZXRTdGF0dXNTb2x1dGlvbnMoc3RhdHVzKSxcbiAgICAgIHN0YXR1c0NlbGxQcmVzZXQ6IHRoaXMuc3RhdHVzQ2VsbFByZXNldCxcbiAgICAgIHN0YXR1c0NvbG9yQXNUZXh0OiB0aGlzLnN0YXR1c0NvbG9yQXNUZXh0LFxuICAgICAgZW1wdHlTdGF0dXNQbGFjZWhvbGRlcjogdGhpcy5lbXB0eVN0YXR1c1BsYWNlaG9sZGVyLFxuICAgICAgb25DbGljazogKGV2ZW50PzogTW91c2VFdmVudCkgPT4gdGhpcy5lbWl0U29sdXRpb25DbGljayhldmVudCwgcm93LCByb3dJbmRleCwgc3RhdHVzLCBwcm9ibGVtSW5kZXgpLFxuICAgIH07XG4gIH1cblxuICBhY3RpdmF0ZVVzZXJDZWxsRnJvbUtleWJvYXJkKGV2ZW50OiBFdmVudCwgcm93OiBTdGF0aWNSYW5rbGlzdFJvdywgcm93SW5kZXg6IG51bWJlcikge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5lbWl0VXNlckNsaWNrKHVuZGVmaW5lZCwgcm93LCByb3dJbmRleCk7XG4gIH1cblxuICBhY3RpdmF0ZVN0YXR1c0NlbGxGcm9tS2V5Ym9hcmQoXG4gICAgZXZlbnQ6IEV2ZW50LFxuICAgIHJvdzogU3RhdGljUmFua2xpc3RSb3csXG4gICAgcm93SW5kZXg6IG51bWJlcixcbiAgICBzdGF0dXM6IHNyay5SYW5rUHJvYmxlbVN0YXR1cyxcbiAgICBwcm9ibGVtSW5kZXg6IG51bWJlcixcbiAgKSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLmVtaXRTb2x1dGlvbkNsaWNrKHVuZGVmaW5lZCwgcm93LCByb3dJbmRleCwgc3RhdHVzLCBwcm9ibGVtSW5kZXgpO1xuICB9XG5cbiAgZW1pdFVzZXJDbGljayhldmVudDogTW91c2VFdmVudCB8IHVuZGVmaW5lZCwgcm93OiBTdGF0aWNSYW5rbGlzdFJvdywgcm93SW5kZXg6IG51bWJlcikge1xuICAgIGlmIChldmVudCkge1xuICAgICAgY2FwdHVyZU1vZGFsVHJpZ2dlclBvaW50RnJvbU1vdXNlRXZlbnQoZXZlbnQsIHtcbiAgICAgICAgc291cmNlOiAndXNlci1jZWxsJyxcbiAgICAgICAgY29udGV4dDoge1xuICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgIHVzZXJJZDogcm93LnVzZXIuaWQgfHwgbnVsbCxcbiAgICAgICAgICB1c2VyTmFtZTogdGhpcy5yZXNvbHZlRGlzcGxheVRleHQocm93LnVzZXIubmFtZSksXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy51c2VyQ2xpY2suZW1pdCh7XG4gICAgICB1c2VyOiByb3cudXNlcixcbiAgICAgIHJvdyxcbiAgICAgIHJvd0luZGV4LFxuICAgICAgcmFua2xpc3Q6IHRoaXMuZGF0YSxcbiAgICB9KTtcbiAgfVxuXG4gIGVtaXRTb2x1dGlvbkNsaWNrKFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgdW5kZWZpbmVkLFxuICAgIHJvdzogU3RhdGljUmFua2xpc3RSb3csXG4gICAgcm93SW5kZXg6IG51bWJlcixcbiAgICBzdGF0dXM6IHNyay5SYW5rUHJvYmxlbVN0YXR1cyxcbiAgICBwcm9ibGVtSW5kZXg6IG51bWJlcixcbiAgKSB7XG4gICAgY29uc3Qgc29sdXRpb25zID0gdGhpcy5nZXRTdGF0dXNTb2x1dGlvbnMoc3RhdHVzKTtcbiAgICBpZiAoIXNvbHV0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGV2ZW50KSB7XG4gICAgICBjYXB0dXJlTW9kYWxUcmlnZ2VyUG9pbnRGcm9tTW91c2VFdmVudChldmVudCwge1xuICAgICAgICBzb3VyY2U6ICdzdGF0dXMtY2VsbCcsXG4gICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICByb3dJbmRleCxcbiAgICAgICAgICBwcm9ibGVtSW5kZXgsXG4gICAgICAgICAgcHJvYmxlbUFsaWFzOiB0aGlzLmRhdGEucHJvYmxlbXNbcHJvYmxlbUluZGV4XT8uYWxpYXMgfHwgbnVsbCxcbiAgICAgICAgICBwcm9ibGVtVGl0bGU6IHRoaXMuZGF0YS5wcm9ibGVtc1twcm9ibGVtSW5kZXhdID8gdGhpcy5yZXNvbHZlRGlzcGxheVRleHQodGhpcy5kYXRhLnByb2JsZW1zW3Byb2JsZW1JbmRleF0udGl0bGUpIDogbnVsbCxcbiAgICAgICAgICB1c2VySWQ6IHJvdy51c2VyLmlkIHx8IG51bGwsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5zb2x1dGlvbkNsaWNrLmVtaXQoe1xuICAgICAgdXNlcjogcm93LnVzZXIsXG4gICAgICByb3csXG4gICAgICByb3dJbmRleCxcbiAgICAgIHByb2JsZW1JbmRleCxcbiAgICAgIHByb2JsZW06IHRoaXMuZGF0YS5wcm9ibGVtc1twcm9ibGVtSW5kZXhdLFxuICAgICAgc3RhdHVzLFxuICAgICAgc29sdXRpb25zLFxuICAgICAgcmFua2xpc3Q6IHRoaXMuZGF0YSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZVNlcmllc1NlZ21lbnQocmFua1ZhbHVlOiBSYW5rVmFsdWUsIHNlcmllczogc3JrLlJhbmtTZXJpZXMgfCB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBpbmRleCA9IHJhbmtWYWx1ZS5zZWdtZW50SW5kZXggfHwgcmFua1ZhbHVlLnNlZ21lbnRJbmRleCA9PT0gMCA/IHJhbmtWYWx1ZS5zZWdtZW50SW5kZXggOiAtMTtcbiAgICByZXR1cm4gKHNlcmllcz8uc2VnbWVudHMgfHwgW10pW2luZGV4XSB8fCB7fTtcbiAgfVxuXG4gIGlzU2VyaWVzU2VnbWVudGVkQ29sdW1uKHNlcmllczogc3JrLlJhbmtTZXJpZXMgfCB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gKHNlcmllcz8uc2VnbWVudHMgfHwgW10pLnNvbWUoKHNlZ21lbnQpID0+IHR5cGVvZiBzZWdtZW50LnN0eWxlID09PSAnc3RyaW5nJyk7XG4gIH1cblxuICBnZXRTZXJpZXNTZWdtZW50Q2xhc3MocmFua1ZhbHVlOiBSYW5rVmFsdWUsIHNlcmllczogc3JrLlJhbmtTZXJpZXMgfCB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBzZWdtZW50U3R5bGUgPSB0aGlzLnJlc29sdmVTZXJpZXNTZWdtZW50KHJhbmtWYWx1ZSwgc2VyaWVzKS5zdHlsZTtcbiAgICByZXR1cm4gdHlwZW9mIHNlZ21lbnRTdHlsZSA9PT0gJ3N0cmluZycgPyBgc3JrLXByZXNldC1zZXJpZXMtc2VnbWVudC0ke3NlZ21lbnRTdHlsZX1gIDogJyc7XG4gIH1cblxuICBnZXRTZXJpZXNTZWdtZW50U3R5bGUocmFua1ZhbHVlOiBSYW5rVmFsdWUsIHNlcmllczogc3JrLlJhbmtTZXJpZXMgfCB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBlbXB0eUNvbG9yOiBUaGVtZUNvbG9yID0ge1xuICAgICAgW0VudW1UaGVtZS5saWdodF06IHVuZGVmaW5lZCxcbiAgICAgIFtFbnVtVGhlbWUuZGFya106IHVuZGVmaW5lZCxcbiAgICB9O1xuICAgIGNvbnN0IHNlZ21lbnRTdHlsZSA9IHRoaXMucmVzb2x2ZVNlcmllc1NlZ21lbnQocmFua1ZhbHVlLCBzZXJpZXMpLnN0eWxlO1xuICAgIGlmICghc2VnbWVudFN0eWxlIHx8IHR5cGVvZiBzZWdtZW50U3R5bGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNvbnN0IHN0eWxlID0gcmVzb2x2ZVN0eWxlKHNlZ21lbnRTdHlsZSk7XG4gICAgY29uc3QgdGV4dENvbG9yID0gc3R5bGUudGV4dENvbG9yIHx8IGVtcHR5Q29sb3I7XG4gICAgY29uc3QgYmFja2dyb3VuZENvbG9yID0gc3R5bGUuYmFja2dyb3VuZENvbG9yIHx8IGVtcHR5Q29sb3I7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbG9yOiB0ZXh0Q29sb3JbdGhpcy50aGVtZV0sXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IGJhY2tncm91bmRDb2xvclt0aGlzLnRoZW1lXSxcbiAgICB9O1xuICB9XG5cbiAgZ2V0UHJvYmxlbVN0YXRpc3RpY3NGb290ZXJDZWxsUHJpbWFyeShrZXk6IHN0cmluZywgc3RhdDogUHJvYmxlbVN0YXRpc3RpY3NGb290ZXIpIHtcbiAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgY2FzZSAnYWNjZXB0ZWQnOlxuICAgICAgICByZXR1cm4gc3RhdC5hY2NlcHRlZDtcbiAgICAgIGNhc2UgJ3RyaWVkJzpcbiAgICAgICAgcmV0dXJuIHN0YXQudHJpZWQ7XG4gICAgICBjYXNlICdzdWJtaXR0ZWQnOlxuICAgICAgICByZXR1cm4gc3RhdC5zdWJtaXR0ZWQ7XG4gICAgICBjYXNlICdkaXJ0JzpcbiAgICAgICAgcmV0dXJuIHN0YXQuZGlydDtcbiAgICAgIGNhc2UgJ3NlJzpcbiAgICAgICAgcmV0dXJuIGZvcm1hdFByb2JsZW1TdGF0aXN0aWNzQXZlcmFnZUhhcmRuZXNzKHN0YXQpO1xuICAgICAgY2FzZSAnZmlyc3RBY2NlcHRlZCc6XG4gICAgICAgIHJldHVybiBmb3JtYXRQcm9ibGVtU3RhdGlzdGljc0FjY2VwdGVkTWludXRlKHN0YXQuZmlyc3RBY2NlcHRlZFRpbWUpO1xuICAgICAgY2FzZSAnbGFzdEFjY2VwdGVkJzpcbiAgICAgICAgcmV0dXJuIGZvcm1hdFByb2JsZW1TdGF0aXN0aWNzQWNjZXB0ZWRNaW51dGUoc3RhdC5sYXN0QWNjZXB0ZWRUaW1lKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1cblxuICBnZXRQcm9ibGVtU3RhdGlzdGljc0Zvb3RlckNlbGxTZWNvbmRhcnkoa2V5OiBzdHJpbmcsIHN0YXQ6IFByb2JsZW1TdGF0aXN0aWNzRm9vdGVyKSB7XG4gICAgc3dpdGNoIChrZXkpIHtcbiAgICAgIGNhc2UgJ2FjY2VwdGVkJzpcbiAgICAgICAgcmV0dXJuIGZvcm1hdFByb2JsZW1TdGF0aXN0aWNzUGVyY2VudChzdGF0LmFjY2VwdGVkLCBzdGF0LnBhcnRpY2lwYW50Q291bnQpO1xuICAgICAgY2FzZSAndHJpZWQnOlxuICAgICAgICByZXR1cm4gZm9ybWF0UHJvYmxlbVN0YXRpc3RpY3NQZXJjZW50KHN0YXQudHJpZWQsIHN0YXQucGFydGljaXBhbnRDb3VudCk7XG4gICAgICBjYXNlICdkaXJ0JzpcbiAgICAgICAgcmV0dXJuIGZvcm1hdFByb2JsZW1TdGF0aXN0aWNzUGVyY2VudChzdGF0LmRpcnQsIHN0YXQuZGlydFN1Ym1pdHRlZCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufVxuIl19
|