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