@visuno/angular 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +24 -0
- package/README.md +56 -2
- package/account-table/account-table.component.d.ts +72 -0
- package/action-log/action-log.component.d.ts +41 -0
- package/activity-heatmap/activity-heatmap.component.d.ts +67 -0
- package/agent-inbox/agent-inbox.component.d.ts +75 -0
- package/agent-lanes/agent-lanes.component.d.ts +152 -0
- package/agent-phases/agent-phases.component.d.ts +62 -0
- package/agent-run-timeline/agent-run-timeline.component.d.ts +113 -0
- package/agent-tree/agent-tree.component.d.ts +80 -0
- package/answer-action-bar/answer-action-bar.component.d.ts +110 -0
- package/artifact-card/artifact-card.component.d.ts +145 -0
- package/attachment-tray/attachment-tray.component.d.ts +84 -0
- package/badge/badge.component.d.ts +25 -0
- package/bar-chart/bar-chart.component.d.ts +87 -0
- package/browser-session/browser-session.component.d.ts +70 -0
- package/buttons/buttons.component.d.ts +63 -0
- package/card/card.component.d.ts +21 -0
- package/change-review/change-review.component.d.ts +97 -0
- package/citation-hover-card/citation-hover-card.component.d.ts +95 -0
- package/code-viewer/code-viewer.component.d.ts +86 -0
- package/composer/composer.component.d.ts +114 -0
- package/context-meter/context-meter.component.d.ts +60 -0
- package/core/icon.component.d.ts +10 -0
- package/core/reduced-motion.service.d.ts +15 -0
- package/decision-prompt/decision-prompt.component.d.ts +56 -0
- package/design-review/design-review.component.d.ts +108 -0
- package/design-tuner/design-tuner.component.d.ts +75 -0
- package/details-panel/details-panel.component.d.ts +150 -0
- package/donut-chart/donut-chart.component.d.ts +63 -0
- package/draft-review/draft-review.component.d.ts +128 -0
- package/error-recovery/error-recovery.component.d.ts +59 -0
- package/esm2022/account-table/account-table.component.mjs +399 -0
- package/esm2022/action-log/action-log.component.mjs +177 -0
- package/esm2022/activity-heatmap/activity-heatmap.component.mjs +285 -0
- package/esm2022/agent-inbox/agent-inbox.component.mjs +284 -0
- package/esm2022/agent-lanes/agent-lanes.component.mjs +600 -0
- package/esm2022/agent-phases/agent-phases.component.mjs +300 -0
- package/esm2022/agent-run-timeline/agent-run-timeline.component.mjs +412 -0
- package/esm2022/agent-tree/agent-tree.component.mjs +393 -0
- package/esm2022/answer-action-bar/answer-action-bar.component.mjs +636 -0
- package/esm2022/artifact-card/artifact-card.component.mjs +916 -0
- package/esm2022/attachment-tray/attachment-tray.component.mjs +402 -0
- package/esm2022/badge/badge.component.mjs +97 -0
- package/esm2022/bar-chart/bar-chart.component.mjs +300 -0
- package/esm2022/browser-session/browser-session.component.mjs +352 -0
- package/esm2022/buttons/buttons.component.mjs +215 -0
- package/esm2022/card/card.component.mjs +107 -0
- package/esm2022/change-review/change-review.component.mjs +398 -0
- package/esm2022/citation-hover-card/citation-hover-card.component.mjs +360 -0
- package/esm2022/code-viewer/code-viewer.component.mjs +291 -0
- package/esm2022/composer/composer.component.mjs +743 -0
- package/esm2022/context-meter/context-meter.component.mjs +275 -0
- package/esm2022/core/icon.component.mjs +111 -0
- package/esm2022/core/reduced-motion.service.mjs +34 -0
- package/esm2022/decision-prompt/decision-prompt.component.mjs +259 -0
- package/esm2022/design-review/design-review.component.mjs +428 -0
- package/esm2022/design-tuner/design-tuner.component.mjs +341 -0
- package/esm2022/details-panel/details-panel.component.mjs +537 -0
- package/esm2022/donut-chart/donut-chart.component.mjs +240 -0
- package/esm2022/draft-review/draft-review.component.mjs +549 -0
- package/esm2022/error-recovery/error-recovery.component.mjs +231 -0
- package/esm2022/eval-results/eval-results.component.mjs +368 -0
- package/esm2022/feedback-sheet/feedback-sheet.component.mjs +411 -0
- package/esm2022/field-extraction/field-extraction.component.mjs +368 -0
- package/esm2022/funnel-chart/funnel-chart.component.mjs +258 -0
- package/esm2022/grid/grid.component.mjs +66 -0
- package/esm2022/health-score/health-score.component.mjs +420 -0
- package/esm2022/human-handoff/human-handoff.component.mjs +676 -0
- package/esm2022/image-generation/image-generation.component.mjs +1028 -0
- package/esm2022/inline-text-diff/inline-text-diff.component.mjs +390 -0
- package/esm2022/launch-checklist/launch-checklist.component.mjs +229 -0
- package/esm2022/line-chart/line-chart.component.mjs +417 -0
- package/esm2022/live-answer/live-answer.component.mjs +411 -0
- package/esm2022/metric-insight/metric-insight.component.mjs +511 -0
- package/esm2022/modal/modal.component.mjs +202 -0
- package/esm2022/model-picker/model-picker.component.mjs +491 -0
- package/esm2022/permission-gate/permission-gate.component.mjs +498 -0
- package/esm2022/plan-review/plan-review.component.mjs +432 -0
- package/esm2022/progress/progress.component.mjs +503 -0
- package/esm2022/prompt-library/prompt-library.component.mjs +453 -0
- package/esm2022/prompt-starters/prompt-starters.component.mjs +272 -0
- package/esm2022/proposal-card/proposal-card.component.mjs +402 -0
- package/esm2022/public-api.mjs +88 -0
- package/esm2022/radar-chart/radar-chart.component.mjs +500 -0
- package/esm2022/radial-goals/radial-goals.component.mjs +418 -0
- package/esm2022/reasoning-trail/reasoning-trail.component.mjs +284 -0
- package/esm2022/response-versions/response-versions.component.mjs +288 -0
- package/esm2022/rewrite-toolbar/rewrite-toolbar.component.mjs +397 -0
- package/esm2022/rich-text-editor/rich-text-editor.component.mjs +1755 -0
- package/esm2022/run-cost/run-cost.component.mjs +215 -0
- package/esm2022/run-queue/run-queue.component.mjs +481 -0
- package/esm2022/run-summary/run-summary.component.mjs +331 -0
- package/esm2022/scatter-chart/scatter-chart.component.mjs +705 -0
- package/esm2022/score-breakdown/score-breakdown.component.mjs +460 -0
- package/esm2022/segmented-control/segmented-control.component.mjs +180 -0
- package/esm2022/source-stack/source-stack.component.mjs +245 -0
- package/esm2022/stat-cards/stat-cards.component.mjs +258 -0
- package/esm2022/status-pill/status-pill.component.mjs +305 -0
- package/esm2022/steering/steering.component.mjs +343 -0
- package/esm2022/step-loader/step-loader.component.mjs +209 -0
- package/esm2022/task-table/task-table.component.mjs +534 -0
- package/esm2022/terminal-stream/terminal-stream.component.mjs +583 -0
- package/esm2022/thinking/thinking.component.mjs +276 -0
- package/esm2022/thinking-states/thinking-states.component.mjs +333 -0
- package/esm2022/thread-panel/thread-panel.component.mjs +271 -0
- package/esm2022/toast/toast.component.mjs +195 -0
- package/esm2022/toast-stack/toast-stack.component.mjs +301 -0
- package/esm2022/tool-call/tool-call.component.mjs +273 -0
- package/esm2022/tooltip/tooltip.component.mjs +417 -0
- package/esm2022/top-pages/top-pages.component.mjs +240 -0
- package/esm2022/trace-view/trace-view.component.mjs +440 -0
- package/esm2022/visuno-angular.mjs +5 -0
- package/esm2022/voice-capture/voice-capture.component.mjs +650 -0
- package/esm2022/voice-orb/voice-orb.component.mjs +538 -0
- package/esm2022/web-search/web-search.component.mjs +374 -0
- package/eval-results/eval-results.component.d.ts +67 -0
- package/feedback-sheet/feedback-sheet.component.d.ts +74 -0
- package/fesm2022/visuno-angular.mjs +31992 -0
- package/fesm2022/visuno-angular.mjs.map +1 -0
- package/field-extraction/field-extraction.component.d.ts +82 -0
- package/funnel-chart/funnel-chart.component.d.ts +70 -0
- package/grid/grid.component.d.ts +22 -0
- package/health-score/health-score.component.d.ts +87 -0
- package/human-handoff/human-handoff.component.d.ts +125 -0
- package/image-generation/image-generation.component.d.ts +253 -0
- package/index.d.ts +5 -0
- package/inline-text-diff/inline-text-diff.component.d.ts +76 -0
- package/launch-checklist/launch-checklist.component.d.ts +46 -0
- package/line-chart/line-chart.component.d.ts +89 -0
- package/live-answer/live-answer.component.d.ts +110 -0
- package/metric-insight/metric-insight.component.d.ts +110 -0
- package/modal/modal.component.d.ts +37 -0
- package/model-picker/model-picker.component.d.ts +97 -0
- package/package.json +51 -4
- package/permission-gate/permission-gate.component.d.ts +100 -0
- package/plan-review/plan-review.component.d.ts +86 -0
- package/progress/progress.component.d.ts +91 -0
- package/prompt-library/prompt-library.component.d.ts +121 -0
- package/prompt-starters/prompt-starters.component.d.ts +65 -0
- package/proposal-card/proposal-card.component.d.ts +101 -0
- package/public-api.d.ts +82 -0
- package/radar-chart/radar-chart.component.d.ts +110 -0
- package/radial-goals/radial-goals.component.d.ts +90 -0
- package/reasoning-trail/reasoning-trail.component.d.ts +73 -0
- package/response-versions/response-versions.component.d.ts +54 -0
- package/rewrite-toolbar/rewrite-toolbar.component.d.ts +92 -0
- package/rich-text-editor/rich-text-editor.component.d.ts +180 -0
- package/run-cost/run-cost.component.d.ts +43 -0
- package/run-queue/run-queue.component.d.ts +93 -0
- package/run-summary/run-summary.component.d.ts +81 -0
- package/scatter-chart/scatter-chart.component.d.ts +139 -0
- package/score-breakdown/score-breakdown.component.d.ts +107 -0
- package/segmented-control/segmented-control.component.d.ts +44 -0
- package/source-stack/source-stack.component.d.ts +60 -0
- package/stat-cards/stat-cards.component.d.ts +86 -0
- package/status-pill/status-pill.component.d.ts +64 -0
- package/steering/steering.component.d.ts +75 -0
- package/step-loader/step-loader.component.d.ts +40 -0
- package/styles.css +424 -0
- package/task-table/task-table.component.d.ts +114 -0
- package/terminal-stream/terminal-stream.component.d.ts +110 -0
- package/thinking/thinking.component.d.ts +63 -0
- package/thinking-states/thinking-states.component.d.ts +51 -0
- package/thread-panel/thread-panel.component.d.ts +75 -0
- package/toast/toast.component.d.ts +56 -0
- package/toast-stack/toast-stack.component.d.ts +72 -0
- package/tokens.css +424 -0
- package/tool-call/tool-call.component.d.ts +61 -0
- package/tooltip/tooltip.component.d.ts +89 -0
- package/top-pages/top-pages.component.d.ts +75 -0
- package/trace-view/trace-view.component.d.ts +95 -0
- package/voice-capture/voice-capture.component.d.ts +103 -0
- package/voice-orb/voice-orb.component.d.ts +78 -0
- package/web-search/web-search.component.d.ts +77 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
// framework/angular/run-queue/run-queue.component.ts
|
|
2
|
+
//
|
|
3
|
+
// Native Angular port of framework/react/run-queue/RunQueue.tsx.
|
|
4
|
+
// A queue of agent jobs in three parts: the one running (raised, with its steps,
|
|
5
|
+
// progress and time left), the ones up next, and the ones done. A compact switch
|
|
6
|
+
// folds the running job's steps away; a failed step turns its job red and offers
|
|
7
|
+
// Retry; when every job is done a summary takes the running job's place. Inputs
|
|
8
|
+
// mirror the React props; callbacks become @Output() EventEmitters.
|
|
9
|
+
//
|
|
10
|
+
// The segmented density switch is reproduced inline (a sliding knob placed over
|
|
11
|
+
// the pressed button), as stat-cards.component.ts does for its period switch.
|
|
12
|
+
import { Component, EventEmitter, Input, Output, ViewEncapsulation, } from '@angular/core';
|
|
13
|
+
import { VoIconComponent } from '../core/icon.component';
|
|
14
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
15
|
+
import * as i0 from "@angular/core";
|
|
16
|
+
const liveState = (s) => s === 'running' || s === 'failed';
|
|
17
|
+
const shareOf = (j) => j.progress ??
|
|
18
|
+
(j.steps?.length
|
|
19
|
+
? j.steps.filter((s) => s.state === 'done').length / j.steps.length
|
|
20
|
+
: j.state === 'done'
|
|
21
|
+
? 1
|
|
22
|
+
: 0);
|
|
23
|
+
const clamp01 = (n) => Math.max(0, Math.min(1, n));
|
|
24
|
+
/** A queue of agent jobs: running, up next, and done, with per-row progress and a compact toggle. */
|
|
25
|
+
export class RunQueueComponent {
|
|
26
|
+
/** detailed lists the running job's steps, compact folds them away. */
|
|
27
|
+
set density(value) {
|
|
28
|
+
this.controlled = value !== undefined;
|
|
29
|
+
if (value !== undefined && value !== this.dens) {
|
|
30
|
+
this.dens = value;
|
|
31
|
+
if (this.ready)
|
|
32
|
+
this.placeKnob();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
constructor(cdr, host) {
|
|
36
|
+
this.cdr = cdr;
|
|
37
|
+
this.host = host;
|
|
38
|
+
this.jobs = [];
|
|
39
|
+
/** The queue's name over its status line. */
|
|
40
|
+
this.title = 'Run queue';
|
|
41
|
+
this.defaultDensity = 'detailed';
|
|
42
|
+
/** Whether the Retry button shows on a failed step (React: onRetry wired). */
|
|
43
|
+
this.retryWired = true;
|
|
44
|
+
/** Sits flat in a chat thread, with no card. */
|
|
45
|
+
this.bare = false;
|
|
46
|
+
this.densityChange = new EventEmitter();
|
|
47
|
+
this.retry = new EventEmitter();
|
|
48
|
+
this.densityOptions = [
|
|
49
|
+
{ value: 'detailed', label: 'Detailed' },
|
|
50
|
+
{ value: 'compact', label: 'Compact' },
|
|
51
|
+
];
|
|
52
|
+
this.dens = 'detailed';
|
|
53
|
+
this.knobLeft = 0;
|
|
54
|
+
this.knobWidth = 0;
|
|
55
|
+
this.controlled = false;
|
|
56
|
+
this.ready = false;
|
|
57
|
+
}
|
|
58
|
+
keyOf(j) {
|
|
59
|
+
return j.id ?? j.title;
|
|
60
|
+
}
|
|
61
|
+
partOf(s) {
|
|
62
|
+
return liveState(s) ? 'run' : s === 'done' ? 'done' : 'next';
|
|
63
|
+
}
|
|
64
|
+
get views() {
|
|
65
|
+
return this.jobs.map((job, index) => {
|
|
66
|
+
const dataS = job.state === 'running'
|
|
67
|
+
? 'run'
|
|
68
|
+
: job.state === 'failed'
|
|
69
|
+
? 'fail'
|
|
70
|
+
: job.state === 'done'
|
|
71
|
+
? 'done'
|
|
72
|
+
: 'wait';
|
|
73
|
+
const at = job.steps?.find((x) => x.state === 'failed') ?? job.steps?.find((x) => x.state === 'running');
|
|
74
|
+
const note = liveState(job.state) ? (job.note ?? at?.label) : undefined;
|
|
75
|
+
return {
|
|
76
|
+
job,
|
|
77
|
+
index,
|
|
78
|
+
key: this.keyOf(job),
|
|
79
|
+
part: this.partOf(job.state),
|
|
80
|
+
dataS,
|
|
81
|
+
progress: clamp01(shareOf(job)),
|
|
82
|
+
note,
|
|
83
|
+
showSteps: this.dens === 'detailed' && liveState(job.state) && !!job.steps?.length,
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
get runViews() {
|
|
88
|
+
return this.views.filter((v) => v.part === 'run');
|
|
89
|
+
}
|
|
90
|
+
get nextViews() {
|
|
91
|
+
return this.views.filter((v) => v.part === 'next');
|
|
92
|
+
}
|
|
93
|
+
get doneViews() {
|
|
94
|
+
return this.views.filter((v) => v.part === 'done');
|
|
95
|
+
}
|
|
96
|
+
get doneCount() {
|
|
97
|
+
return this.jobs.filter((j) => j.state === 'done').length;
|
|
98
|
+
}
|
|
99
|
+
get fin() {
|
|
100
|
+
return this.jobs.length > 0 && this.doneCount === this.jobs.length;
|
|
101
|
+
}
|
|
102
|
+
get line() {
|
|
103
|
+
if (this.status !== undefined)
|
|
104
|
+
return this.status;
|
|
105
|
+
if (this.fin)
|
|
106
|
+
return `All ${this.jobs.length} done`;
|
|
107
|
+
if (this.jobs.some((j) => j.state === 'failed'))
|
|
108
|
+
return '1 step failed, waiting for Retry';
|
|
109
|
+
return `${this.doneCount} of ${this.jobs.length} done`;
|
|
110
|
+
}
|
|
111
|
+
subLine(v) {
|
|
112
|
+
return [v.job.agent, v.note].filter(Boolean).join(' · ');
|
|
113
|
+
}
|
|
114
|
+
pctText(v) {
|
|
115
|
+
return Math.round(v.progress * 100);
|
|
116
|
+
}
|
|
117
|
+
stepClass(st) {
|
|
118
|
+
return st.state === 'queued'
|
|
119
|
+
? 'vo-wait'
|
|
120
|
+
: st.state === 'running'
|
|
121
|
+
? 'vo-run'
|
|
122
|
+
: st.state === 'failed'
|
|
123
|
+
? 'vo-fail'
|
|
124
|
+
: 'vo-done';
|
|
125
|
+
}
|
|
126
|
+
setDensity(value) {
|
|
127
|
+
if (!this.controlled) {
|
|
128
|
+
this.dens = value;
|
|
129
|
+
this.placeKnob();
|
|
130
|
+
}
|
|
131
|
+
this.densityChange.emit(value);
|
|
132
|
+
}
|
|
133
|
+
ngAfterViewInit() {
|
|
134
|
+
if (!this.controlled)
|
|
135
|
+
this.dens = this.defaultDensity;
|
|
136
|
+
this.ready = true;
|
|
137
|
+
this.cdr.detectChanges();
|
|
138
|
+
this.placeKnob();
|
|
139
|
+
}
|
|
140
|
+
ngOnChanges() {
|
|
141
|
+
if (this.ready) {
|
|
142
|
+
// the knob may need to move if the pressed button's width changed
|
|
143
|
+
queueMicrotask(() => this.placeKnob());
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
placeKnob() {
|
|
147
|
+
const btns = this.host.nativeElement.querySelectorAll('.vo-rq-sg button');
|
|
148
|
+
const i = this.densityOptions.findIndex((o) => o.value === this.dens);
|
|
149
|
+
const b = btns[i];
|
|
150
|
+
if (b) {
|
|
151
|
+
this.knobLeft = b.offsetLeft;
|
|
152
|
+
this.knobWidth = b.offsetWidth;
|
|
153
|
+
this.cdr.markForCheck();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RunQueueComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
157
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: RunQueueComponent, isStandalone: true, selector: "vo-run-queue", inputs: { jobs: "jobs", title: "title", status: "status", summary: "summary", density: "density", defaultDensity: "defaultDensity", retryWired: "retryWired", bare: "bare" }, outputs: { densityChange: "densityChange", retry: "retry" }, usesOnChanges: true, ngImport: i0, template: `
|
|
158
|
+
<div
|
|
159
|
+
data-vo=""
|
|
160
|
+
class="vo-rq"
|
|
161
|
+
[class.vo-panel]="!bare"
|
|
162
|
+
[class.vo-keep]="!bare"
|
|
163
|
+
[class.vo-fin]="fin"
|
|
164
|
+
[style.paddingInline]="bare ? '0' : null"
|
|
165
|
+
>
|
|
166
|
+
<div class="vo-rq-h">
|
|
167
|
+
<div class="vo-rq-ht">
|
|
168
|
+
<b>{{ title }}</b>
|
|
169
|
+
<span class="vo-rq-st vo-num vo-sw">{{ line }}</span>
|
|
170
|
+
</div>
|
|
171
|
+
<div class="vo-seg2 vo-rq-sg" role="group" aria-label="Density">
|
|
172
|
+
<span class="vo-knob" [style.left.px]="knobLeft" [style.width.px]="knobWidth"></span>
|
|
173
|
+
@for (o of densityOptions; track o.value) {
|
|
174
|
+
<button
|
|
175
|
+
type="button"
|
|
176
|
+
[attr.aria-pressed]="dens === o.value"
|
|
177
|
+
(click)="setDensity(o.value)"
|
|
178
|
+
>{{ o.label }}</button>
|
|
179
|
+
}
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<div class="vo-rq-tot" aria-hidden="true">
|
|
184
|
+
@for (v of views; track v.key) {
|
|
185
|
+
<i [class.vo-fail]="v.job.state === 'failed'"><b [style.--vo-p]="v.progress"></b></i>
|
|
186
|
+
}
|
|
187
|
+
</div>
|
|
188
|
+
|
|
189
|
+
<div class="vo-rq-b">
|
|
190
|
+
<div class="vo-fold vo-rq-ff" [class.vo-shut]="!fin" [attr.inert]="fin ? null : ''">
|
|
191
|
+
<div>
|
|
192
|
+
<div class="vo-rq-sec">
|
|
193
|
+
<div class="vo-rq-fin" [class.vo-enter]="fin">
|
|
194
|
+
<span class="vo-rq-av" aria-hidden="true"><vo-icon name="ok"></vo-icon></span>
|
|
195
|
+
<span class="vo-rq-jt">
|
|
196
|
+
<b class="vo-rq-ft">All {{ jobs.length }} jobs done</b>
|
|
197
|
+
@if (summary) {
|
|
198
|
+
<span class="vo-rq-js">{{ summary }}</span>
|
|
199
|
+
}
|
|
200
|
+
</span>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
|
|
206
|
+
<div class="vo-fold vo-rq-rf" [class.vo-shut]="fin" [attr.inert]="fin ? '' : null">
|
|
207
|
+
<div>
|
|
208
|
+
<div class="vo-rq-sec">
|
|
209
|
+
<span class="vo-rq-l">Running</span>
|
|
210
|
+
<ul class="vo-rq-run" aria-label="Running">
|
|
211
|
+
@for (v of runViews; track v.key) {
|
|
212
|
+
<ng-container [ngTemplateOutlet]="jobRow" [ngTemplateOutletContext]="{ $implicit: v }"></ng-container>
|
|
213
|
+
}
|
|
214
|
+
</ul>
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
|
|
219
|
+
<div class="vo-fold vo-rq-nf" [class.vo-shut]="fin" [attr.inert]="fin ? '' : null">
|
|
220
|
+
<div>
|
|
221
|
+
<div class="vo-rq-sec">
|
|
222
|
+
<span class="vo-rq-l">Up next</span>
|
|
223
|
+
<ol class="vo-rq-next" aria-label="Up next">
|
|
224
|
+
@for (v of nextViews; track v.key) {
|
|
225
|
+
<ng-container [ngTemplateOutlet]="jobRow" [ngTemplateOutletContext]="{ $implicit: v }"></ng-container>
|
|
226
|
+
}
|
|
227
|
+
</ol>
|
|
228
|
+
<p class="vo-rq-none">Nothing waiting</p>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<div class="vo-fold vo-rq-df">
|
|
234
|
+
<div>
|
|
235
|
+
<div class="vo-rq-sec">
|
|
236
|
+
<span class="vo-rq-l">Done <span class="vo-num">{{ doneCount }}</span></span>
|
|
237
|
+
<ul class="vo-rq-done" aria-label="Done">
|
|
238
|
+
@for (v of doneViews; track v.key) {
|
|
239
|
+
<ng-container [ngTemplateOutlet]="jobRow" [ngTemplateOutletContext]="{ $implicit: v }"></ng-container>
|
|
240
|
+
}
|
|
241
|
+
</ul>
|
|
242
|
+
<p class="vo-rq-none">Nothing done yet</p>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
</div>
|
|
248
|
+
|
|
249
|
+
<ng-template #jobRow let-v>
|
|
250
|
+
<li class="vo-rq-j" [attr.data-s]="v.dataS" [attr.data-k]="v.key" [attr.data-p]="v.part">
|
|
251
|
+
<div class="vo-rq-jh">
|
|
252
|
+
<span class="vo-rq-av" aria-hidden="true"><vo-icon [name]="v.job.icon ?? 'spark'"></vo-icon></span>
|
|
253
|
+
<span class="vo-rq-jt">
|
|
254
|
+
<b>{{ v.job.title }}</b>
|
|
255
|
+
<span class="vo-rq-js vo-sw">{{ subLine(v) }}</span>
|
|
256
|
+
</span>
|
|
257
|
+
<span class="vo-rq-jm vo-num">
|
|
258
|
+
@if (v.job.time) {
|
|
259
|
+
<span>{{ v.job.time }}</span>
|
|
260
|
+
}
|
|
261
|
+
@if (v.job.state === 'done') {
|
|
262
|
+
<span class="vo-ok"><vo-icon name="check" size="xs"></vo-icon></span>
|
|
263
|
+
}
|
|
264
|
+
</span>
|
|
265
|
+
</div>
|
|
266
|
+
<div class="vo-rq-jb" aria-hidden="true">
|
|
267
|
+
<div class="vo-rq-bar"><i [style.--vo-p]="v.progress"></i></div>
|
|
268
|
+
<span class="vo-rq-pc vo-num">{{ pctText(v) }}%</span>
|
|
269
|
+
</div>
|
|
270
|
+
<div class="vo-fold vo-rq-sf" [class.vo-shut]="!v.showSteps" [attr.inert]="v.showSteps ? null : ''">
|
|
271
|
+
<div>
|
|
272
|
+
<ul class="vo-rq-steps">
|
|
273
|
+
@for (st of v.job.steps ?? []; track $index; let si = $index) {
|
|
274
|
+
<li class="vo-rq-sp" [class]="stepClass(st)">
|
|
275
|
+
<span class="vo-g">
|
|
276
|
+
@switch (st.state) {
|
|
277
|
+
@case ('running') {
|
|
278
|
+
<span class="vo-spin" aria-hidden="true"></span>
|
|
279
|
+
}
|
|
280
|
+
@case ('failed') {
|
|
281
|
+
<vo-icon name="x" size="xs"></vo-icon>
|
|
282
|
+
}
|
|
283
|
+
@case ('done') {
|
|
284
|
+
<vo-icon name="check" size="xs"></vo-icon>
|
|
285
|
+
}
|
|
286
|
+
@default {
|
|
287
|
+
<span class="vo-dot" aria-hidden="true"></span>
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
</span>
|
|
291
|
+
<span>{{ st.label }}</span>
|
|
292
|
+
<span class="vo-m">
|
|
293
|
+
@if (st.state === 'failed' && retryWired) {
|
|
294
|
+
<button type="button" class="vo-rq-retry vo-enter" (click)="retry.emit({ job: v.index, step: si })">Retry</button>
|
|
295
|
+
} @else if (st.state === 'done' && st.meta) {
|
|
296
|
+
<span class="vo-sw">{{ st.meta }}</span>
|
|
297
|
+
}
|
|
298
|
+
</span>
|
|
299
|
+
</li>
|
|
300
|
+
}
|
|
301
|
+
</ul>
|
|
302
|
+
</div>
|
|
303
|
+
</div>
|
|
304
|
+
</li>
|
|
305
|
+
</ng-template>
|
|
306
|
+
`, isInline: true, styles: [".vo-rq{display:flex;flex-direction:column;padding:var(--vo-s-3);text-align:left}.vo-rq-h{display:flex;align-items:center;justify-content:space-between;gap:var(--vo-s-3)}.vo-rq-ht{display:flex;flex-direction:column;min-width:0}.vo-rq-ht b{font-weight:500}.vo-rq-st{font-size:12.5px;color:var(--vo-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.vo-rq-tot{display:flex;gap:3px;margin-top:var(--vo-s-3)}.vo-rq-tot i{flex:1;height:4px;border-radius:2px;background:var(--vo-line);overflow:hidden}.vo-rq-tot b{display:block;height:100%;border-radius:inherit;background:var(--vo-accent-mark,var(--vo-accent));transform-origin:left;transform:scaleX(var(--vo-p,0));transition:transform .3s linear,background .3s}.vo-rq-tot i.vo-fail b{background:var(--vo-bad)}.vo-rq-b{flex:1;display:flex;flex-direction:column}.vo-rq-sec{display:flex;flex-direction:column;gap:6px;padding-top:var(--vo-s-3)}.vo-rq-l{display:flex;align-items:baseline;gap:6px;font-size:12px;color:var(--vo-muted)}.vo-rq-l .vo-num{color:var(--vo-fg2)}.vo-rq-none{display:none;align-items:center;min-height:40px;margin:0;font-size:12.5px;color:var(--vo-muted)}.vo-rq-next:empty+.vo-rq-none,.vo-rq-done:empty+.vo-rq-none{display:flex}.vo-rq-run,.vo-rq-next,.vo-rq-done{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}.vo-rq-j{display:flex;flex-direction:column;border-radius:var(--vo-r-in);font-size:13px}.vo-rq-jh{display:flex;align-items:center;gap:10px;min-height:40px}.vo-rq-av{position:relative;width:28px;height:28px;border-radius:calc(9px * var(--vo-rk));display:grid;place-items:center;flex:none;background:var(--vo-chip);color:var(--vo-fg2);transition:background .3s,color .3s}.vo-rq-av .vo-i{width:13px;height:13px;stroke-width:1.9}.vo-rq-jt{flex:1;min-width:0;display:flex;flex-direction:column}.vo-rq-jt b{font-weight:400;color:var(--vo-fg2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .3s}.vo-rq-js{font-size:12px;color:var(--vo-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.vo-rq-jm{display:flex;align-items:center;gap:6px;flex:none;font-size:12px;color:var(--vo-muted);white-space:nowrap}.vo-rq-jm .vo-ok{display:grid;color:var(--vo-ok)}.vo-rq-jb{display:none;align-items:center;gap:10px;padding:0 0 2px 38px}.vo-rq-bar{flex:1;height:4px;border-radius:2px;background:var(--vo-line);overflow:hidden}.vo-rq-bar i{display:block;height:100%;border-radius:inherit;background:var(--vo-accent-mark,var(--vo-accent));transform-origin:left;transform:scaleX(var(--vo-p,0));transition:transform .2s linear}.vo-rq-pc{width:32px;flex:none;font-size:12px;color:var(--vo-muted);text-align:right}.vo-rq-j:is([data-s=run],[data-s=fail]){padding:var(--vo-s-1) 10px 10px;background:var(--vo-surface);box-shadow:var(--vo-shadow);gap:6px}.vo-rq-j:is([data-s=run],[data-s=fail]) .vo-rq-jb{display:flex}.vo-rq-j:is([data-s=run],[data-s=fail]) .vo-rq-jt b{font-weight:500;color:var(--vo-fg)}.vo-rq-j[data-s=run] .vo-rq-av{background:var(--vo-accent-bg);color:var(--vo-accent-fg,var(--vo-accent))}.vo-rq-j[data-s=done] .vo-rq-jt b{color:var(--vo-fg2)}.vo-rq-j[data-s=fail]{background:var(--vo-bad-bg);box-shadow:none}.vo-rq-j[data-s=fail] .vo-rq-av{background:var(--vo-surface);color:var(--vo-bad)}.vo-rq-j[data-s=fail] :is(.vo-rq-jt b,.vo-rq-jm,.vo-rq-pc){color:var(--vo-bad)}.vo-rq-j[data-s=fail] .vo-rq-js{color:var(--vo-fg2)}.vo-rq-j[data-s=fail] .vo-rq-bar{background:color-mix(in srgb,var(--vo-bad) 18%,transparent)}.vo-rq-j[data-s=fail] .vo-rq-bar i{background:var(--vo-bad)}.vo-rq-steps{list-style:none;margin:0;padding:var(--vo-s-1) 0 0 38px;display:flex;flex-direction:column}.vo-rq-sp{display:flex;align-items:center;gap:var(--vo-s-2);min-height:26px;font-size:12.5px;color:var(--vo-fg2)}.vo-rq-sp .vo-g{width:14px;display:grid;place-items:center;flex:none}.vo-rq-sp .vo-g .vo-spin{width:10px;height:10px}.vo-rq-sp .vo-g .vo-dot{width:5px;height:5px;color:var(--vo-faint)}.vo-rq-sp .vo-m{margin-left:auto;font-size:12px;color:var(--vo-muted)}.vo-rq-sp.vo-wait{color:var(--vo-muted)}.vo-rq-sp.vo-done .vo-g{color:var(--vo-ok)}.vo-rq-sp.vo-fail,.vo-rq-sp.vo-fail .vo-g{color:var(--vo-bad)}.vo-rq-retry{height:24px;padding:0 10px;border-radius:var(--vo-r-pill);background:var(--vo-surface);box-shadow:var(--vo-shadow);font-size:12px;font-weight:500;color:var(--vo-fg);transition:box-shadow .2s,transform .15s}.vo-rq-retry.vo-on{box-shadow:var(--vo-shadow-pop)}@media (hover:hover) and (pointer:fine){.vo-rq-retry:hover{box-shadow:var(--vo-shadow-pop)}}.vo-rq-retry:active{transform:scale(.96)}.vo-rq-fin{display:flex;align-items:center;gap:10px;padding:10px;border-radius:var(--vo-r-in);background:var(--vo-ok-bg)}.vo-rq-fin .vo-rq-av{background:var(--vo-surface);color:var(--vo-ok)}.vo-rq-fin b{font-weight:500;color:var(--vo-ok)}.vo-rq-fin .vo-rq-js{color:var(--vo-fg2)}.vo-rq-say{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@container (max-width:340px){.vo-rq-h{flex-wrap:wrap}.vo-rq-jb,.vo-rq-steps{padding-left:0}}:root:not([data-style=soft]) .vo-rq-j:is([data-s=run],[data-s=fail]):not(:where([data-style=soft],[data-style=soft] *)){box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--vo-line) 70%,transparent)}:root:not([data-style=soft]) .vo-rq-j[data-s=run]:not(:where([data-style=soft],[data-style=soft] *)){box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--vo-accent-mark,var(--vo-accent)) 45%,transparent)}:root:not([data-style=soft]) .vo-rq-j[data-s=fail]:not(:where([data-style=soft],[data-style=soft] *)){background:repeating-linear-gradient(135deg,transparent 0 5px,color-mix(in srgb,var(--vo-bad) 10%,transparent) 5px 6px),var(--vo-bad-bg);box-shadow:none}:root:not([data-style=soft]) .vo-rq-bar i:not(:where([data-style=soft],[data-style=soft] *)),:root:not([data-style=soft]) .vo-rq-tot b:not(:where([data-style=soft],[data-style=soft] *)){transition:transform .2s steps(2,end)}:root:not([data-style=soft]) .vo-rq-retry:not(:where([data-style=soft],[data-style=soft] *)){box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--vo-line) 70%,transparent)}.vo-panel{background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow);position:relative}.vo-spin{width:12px;height:12px;border-radius:50%;border:1.5px solid currentColor;border-right-color:transparent;animation:vo-rot .8s linear infinite;flex:none;display:inline-block}@keyframes vo-rot{to{transform:rotate(360deg)}}.vo-dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none;display:inline-block}.vo-sw{display:inline-block;transition:opacity .2s var(--vo-ease),filter .2s var(--vo-ease),transform .25s var(--vo-ease)}.vo-sw.vo-out{opacity:0;filter:blur(3px);transform:translateY(3px)}.vo-enter{animation:vo-enter var(--vo-t-slow) var(--vo-ease) backwards}@keyframes vo-enter{0%{opacity:0;transform:translateY(6px);filter:blur(4px)}to{opacity:1;transform:none;filter:blur(0)}}.vo-fold{display:grid;grid-template-rows:1fr;grid-template-columns:minmax(0,1fr);transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease)}.vo-fold>*{overflow:clip;overflow-clip-margin:12px;min-height:0;min-width:0}.vo-fold.vo-shut{grid-template-rows:0fr;opacity:0;visibility:hidden;transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease),visibility 0s var(--vo-t)}.vo-seg2{display:inline-flex;padding:2px;background:var(--vo-chip);border-radius:var(--vo-r-pill);position:relative}.vo-seg2 button{position:relative;z-index:1;height:26px;padding:0 11px;border-radius:var(--vo-r-pill);font-size:12.5px;color:var(--vo-fg2);transition:color var(--vo-t-fast)}.vo-seg2 button[aria-pressed=true]{color:var(--vo-fg)}.vo-seg2 .vo-knob{position:absolute;top:2px;bottom:2px;border-radius:var(--vo-r-pill);background:var(--vo-surface);box-shadow:0 1px 2px #00000014;transition:left var(--vo-t) var(--vo-ease),width var(--vo-t) var(--vo-ease)}.vo-seg2 button:focus-visible{outline-offset:-2px;border-radius:var(--vo-r-pill)}:root:not([data-style=soft]) .vo-seg2 .vo-knob:not(:where([data-style=soft],[data-style=soft] *)){box-shadow:0 0 0 1px color-mix(in srgb,var(--vo-rail) 50%,transparent)}\n"], dependencies: [{ kind: "component", type: VoIconComponent, selector: "vo-icon", inputs: ["name", "size"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
307
|
+
}
|
|
308
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RunQueueComponent, decorators: [{
|
|
309
|
+
type: Component,
|
|
310
|
+
args: [{ selector: 'vo-run-queue', standalone: true, encapsulation: ViewEncapsulation.None, imports: [VoIconComponent, NgTemplateOutlet], template: `
|
|
311
|
+
<div
|
|
312
|
+
data-vo=""
|
|
313
|
+
class="vo-rq"
|
|
314
|
+
[class.vo-panel]="!bare"
|
|
315
|
+
[class.vo-keep]="!bare"
|
|
316
|
+
[class.vo-fin]="fin"
|
|
317
|
+
[style.paddingInline]="bare ? '0' : null"
|
|
318
|
+
>
|
|
319
|
+
<div class="vo-rq-h">
|
|
320
|
+
<div class="vo-rq-ht">
|
|
321
|
+
<b>{{ title }}</b>
|
|
322
|
+
<span class="vo-rq-st vo-num vo-sw">{{ line }}</span>
|
|
323
|
+
</div>
|
|
324
|
+
<div class="vo-seg2 vo-rq-sg" role="group" aria-label="Density">
|
|
325
|
+
<span class="vo-knob" [style.left.px]="knobLeft" [style.width.px]="knobWidth"></span>
|
|
326
|
+
@for (o of densityOptions; track o.value) {
|
|
327
|
+
<button
|
|
328
|
+
type="button"
|
|
329
|
+
[attr.aria-pressed]="dens === o.value"
|
|
330
|
+
(click)="setDensity(o.value)"
|
|
331
|
+
>{{ o.label }}</button>
|
|
332
|
+
}
|
|
333
|
+
</div>
|
|
334
|
+
</div>
|
|
335
|
+
|
|
336
|
+
<div class="vo-rq-tot" aria-hidden="true">
|
|
337
|
+
@for (v of views; track v.key) {
|
|
338
|
+
<i [class.vo-fail]="v.job.state === 'failed'"><b [style.--vo-p]="v.progress"></b></i>
|
|
339
|
+
}
|
|
340
|
+
</div>
|
|
341
|
+
|
|
342
|
+
<div class="vo-rq-b">
|
|
343
|
+
<div class="vo-fold vo-rq-ff" [class.vo-shut]="!fin" [attr.inert]="fin ? null : ''">
|
|
344
|
+
<div>
|
|
345
|
+
<div class="vo-rq-sec">
|
|
346
|
+
<div class="vo-rq-fin" [class.vo-enter]="fin">
|
|
347
|
+
<span class="vo-rq-av" aria-hidden="true"><vo-icon name="ok"></vo-icon></span>
|
|
348
|
+
<span class="vo-rq-jt">
|
|
349
|
+
<b class="vo-rq-ft">All {{ jobs.length }} jobs done</b>
|
|
350
|
+
@if (summary) {
|
|
351
|
+
<span class="vo-rq-js">{{ summary }}</span>
|
|
352
|
+
}
|
|
353
|
+
</span>
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
</div>
|
|
357
|
+
</div>
|
|
358
|
+
|
|
359
|
+
<div class="vo-fold vo-rq-rf" [class.vo-shut]="fin" [attr.inert]="fin ? '' : null">
|
|
360
|
+
<div>
|
|
361
|
+
<div class="vo-rq-sec">
|
|
362
|
+
<span class="vo-rq-l">Running</span>
|
|
363
|
+
<ul class="vo-rq-run" aria-label="Running">
|
|
364
|
+
@for (v of runViews; track v.key) {
|
|
365
|
+
<ng-container [ngTemplateOutlet]="jobRow" [ngTemplateOutletContext]="{ $implicit: v }"></ng-container>
|
|
366
|
+
}
|
|
367
|
+
</ul>
|
|
368
|
+
</div>
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
|
|
372
|
+
<div class="vo-fold vo-rq-nf" [class.vo-shut]="fin" [attr.inert]="fin ? '' : null">
|
|
373
|
+
<div>
|
|
374
|
+
<div class="vo-rq-sec">
|
|
375
|
+
<span class="vo-rq-l">Up next</span>
|
|
376
|
+
<ol class="vo-rq-next" aria-label="Up next">
|
|
377
|
+
@for (v of nextViews; track v.key) {
|
|
378
|
+
<ng-container [ngTemplateOutlet]="jobRow" [ngTemplateOutletContext]="{ $implicit: v }"></ng-container>
|
|
379
|
+
}
|
|
380
|
+
</ol>
|
|
381
|
+
<p class="vo-rq-none">Nothing waiting</p>
|
|
382
|
+
</div>
|
|
383
|
+
</div>
|
|
384
|
+
</div>
|
|
385
|
+
|
|
386
|
+
<div class="vo-fold vo-rq-df">
|
|
387
|
+
<div>
|
|
388
|
+
<div class="vo-rq-sec">
|
|
389
|
+
<span class="vo-rq-l">Done <span class="vo-num">{{ doneCount }}</span></span>
|
|
390
|
+
<ul class="vo-rq-done" aria-label="Done">
|
|
391
|
+
@for (v of doneViews; track v.key) {
|
|
392
|
+
<ng-container [ngTemplateOutlet]="jobRow" [ngTemplateOutletContext]="{ $implicit: v }"></ng-container>
|
|
393
|
+
}
|
|
394
|
+
</ul>
|
|
395
|
+
<p class="vo-rq-none">Nothing done yet</p>
|
|
396
|
+
</div>
|
|
397
|
+
</div>
|
|
398
|
+
</div>
|
|
399
|
+
</div>
|
|
400
|
+
</div>
|
|
401
|
+
|
|
402
|
+
<ng-template #jobRow let-v>
|
|
403
|
+
<li class="vo-rq-j" [attr.data-s]="v.dataS" [attr.data-k]="v.key" [attr.data-p]="v.part">
|
|
404
|
+
<div class="vo-rq-jh">
|
|
405
|
+
<span class="vo-rq-av" aria-hidden="true"><vo-icon [name]="v.job.icon ?? 'spark'"></vo-icon></span>
|
|
406
|
+
<span class="vo-rq-jt">
|
|
407
|
+
<b>{{ v.job.title }}</b>
|
|
408
|
+
<span class="vo-rq-js vo-sw">{{ subLine(v) }}</span>
|
|
409
|
+
</span>
|
|
410
|
+
<span class="vo-rq-jm vo-num">
|
|
411
|
+
@if (v.job.time) {
|
|
412
|
+
<span>{{ v.job.time }}</span>
|
|
413
|
+
}
|
|
414
|
+
@if (v.job.state === 'done') {
|
|
415
|
+
<span class="vo-ok"><vo-icon name="check" size="xs"></vo-icon></span>
|
|
416
|
+
}
|
|
417
|
+
</span>
|
|
418
|
+
</div>
|
|
419
|
+
<div class="vo-rq-jb" aria-hidden="true">
|
|
420
|
+
<div class="vo-rq-bar"><i [style.--vo-p]="v.progress"></i></div>
|
|
421
|
+
<span class="vo-rq-pc vo-num">{{ pctText(v) }}%</span>
|
|
422
|
+
</div>
|
|
423
|
+
<div class="vo-fold vo-rq-sf" [class.vo-shut]="!v.showSteps" [attr.inert]="v.showSteps ? null : ''">
|
|
424
|
+
<div>
|
|
425
|
+
<ul class="vo-rq-steps">
|
|
426
|
+
@for (st of v.job.steps ?? []; track $index; let si = $index) {
|
|
427
|
+
<li class="vo-rq-sp" [class]="stepClass(st)">
|
|
428
|
+
<span class="vo-g">
|
|
429
|
+
@switch (st.state) {
|
|
430
|
+
@case ('running') {
|
|
431
|
+
<span class="vo-spin" aria-hidden="true"></span>
|
|
432
|
+
}
|
|
433
|
+
@case ('failed') {
|
|
434
|
+
<vo-icon name="x" size="xs"></vo-icon>
|
|
435
|
+
}
|
|
436
|
+
@case ('done') {
|
|
437
|
+
<vo-icon name="check" size="xs"></vo-icon>
|
|
438
|
+
}
|
|
439
|
+
@default {
|
|
440
|
+
<span class="vo-dot" aria-hidden="true"></span>
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
</span>
|
|
444
|
+
<span>{{ st.label }}</span>
|
|
445
|
+
<span class="vo-m">
|
|
446
|
+
@if (st.state === 'failed' && retryWired) {
|
|
447
|
+
<button type="button" class="vo-rq-retry vo-enter" (click)="retry.emit({ job: v.index, step: si })">Retry</button>
|
|
448
|
+
} @else if (st.state === 'done' && st.meta) {
|
|
449
|
+
<span class="vo-sw">{{ st.meta }}</span>
|
|
450
|
+
}
|
|
451
|
+
</span>
|
|
452
|
+
</li>
|
|
453
|
+
}
|
|
454
|
+
</ul>
|
|
455
|
+
</div>
|
|
456
|
+
</div>
|
|
457
|
+
</li>
|
|
458
|
+
</ng-template>
|
|
459
|
+
`, styles: [".vo-rq{display:flex;flex-direction:column;padding:var(--vo-s-3);text-align:left}.vo-rq-h{display:flex;align-items:center;justify-content:space-between;gap:var(--vo-s-3)}.vo-rq-ht{display:flex;flex-direction:column;min-width:0}.vo-rq-ht b{font-weight:500}.vo-rq-st{font-size:12.5px;color:var(--vo-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.vo-rq-tot{display:flex;gap:3px;margin-top:var(--vo-s-3)}.vo-rq-tot i{flex:1;height:4px;border-radius:2px;background:var(--vo-line);overflow:hidden}.vo-rq-tot b{display:block;height:100%;border-radius:inherit;background:var(--vo-accent-mark,var(--vo-accent));transform-origin:left;transform:scaleX(var(--vo-p,0));transition:transform .3s linear,background .3s}.vo-rq-tot i.vo-fail b{background:var(--vo-bad)}.vo-rq-b{flex:1;display:flex;flex-direction:column}.vo-rq-sec{display:flex;flex-direction:column;gap:6px;padding-top:var(--vo-s-3)}.vo-rq-l{display:flex;align-items:baseline;gap:6px;font-size:12px;color:var(--vo-muted)}.vo-rq-l .vo-num{color:var(--vo-fg2)}.vo-rq-none{display:none;align-items:center;min-height:40px;margin:0;font-size:12.5px;color:var(--vo-muted)}.vo-rq-next:empty+.vo-rq-none,.vo-rq-done:empty+.vo-rq-none{display:flex}.vo-rq-run,.vo-rq-next,.vo-rq-done{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}.vo-rq-j{display:flex;flex-direction:column;border-radius:var(--vo-r-in);font-size:13px}.vo-rq-jh{display:flex;align-items:center;gap:10px;min-height:40px}.vo-rq-av{position:relative;width:28px;height:28px;border-radius:calc(9px * var(--vo-rk));display:grid;place-items:center;flex:none;background:var(--vo-chip);color:var(--vo-fg2);transition:background .3s,color .3s}.vo-rq-av .vo-i{width:13px;height:13px;stroke-width:1.9}.vo-rq-jt{flex:1;min-width:0;display:flex;flex-direction:column}.vo-rq-jt b{font-weight:400;color:var(--vo-fg2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .3s}.vo-rq-js{font-size:12px;color:var(--vo-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.vo-rq-jm{display:flex;align-items:center;gap:6px;flex:none;font-size:12px;color:var(--vo-muted);white-space:nowrap}.vo-rq-jm .vo-ok{display:grid;color:var(--vo-ok)}.vo-rq-jb{display:none;align-items:center;gap:10px;padding:0 0 2px 38px}.vo-rq-bar{flex:1;height:4px;border-radius:2px;background:var(--vo-line);overflow:hidden}.vo-rq-bar i{display:block;height:100%;border-radius:inherit;background:var(--vo-accent-mark,var(--vo-accent));transform-origin:left;transform:scaleX(var(--vo-p,0));transition:transform .2s linear}.vo-rq-pc{width:32px;flex:none;font-size:12px;color:var(--vo-muted);text-align:right}.vo-rq-j:is([data-s=run],[data-s=fail]){padding:var(--vo-s-1) 10px 10px;background:var(--vo-surface);box-shadow:var(--vo-shadow);gap:6px}.vo-rq-j:is([data-s=run],[data-s=fail]) .vo-rq-jb{display:flex}.vo-rq-j:is([data-s=run],[data-s=fail]) .vo-rq-jt b{font-weight:500;color:var(--vo-fg)}.vo-rq-j[data-s=run] .vo-rq-av{background:var(--vo-accent-bg);color:var(--vo-accent-fg,var(--vo-accent))}.vo-rq-j[data-s=done] .vo-rq-jt b{color:var(--vo-fg2)}.vo-rq-j[data-s=fail]{background:var(--vo-bad-bg);box-shadow:none}.vo-rq-j[data-s=fail] .vo-rq-av{background:var(--vo-surface);color:var(--vo-bad)}.vo-rq-j[data-s=fail] :is(.vo-rq-jt b,.vo-rq-jm,.vo-rq-pc){color:var(--vo-bad)}.vo-rq-j[data-s=fail] .vo-rq-js{color:var(--vo-fg2)}.vo-rq-j[data-s=fail] .vo-rq-bar{background:color-mix(in srgb,var(--vo-bad) 18%,transparent)}.vo-rq-j[data-s=fail] .vo-rq-bar i{background:var(--vo-bad)}.vo-rq-steps{list-style:none;margin:0;padding:var(--vo-s-1) 0 0 38px;display:flex;flex-direction:column}.vo-rq-sp{display:flex;align-items:center;gap:var(--vo-s-2);min-height:26px;font-size:12.5px;color:var(--vo-fg2)}.vo-rq-sp .vo-g{width:14px;display:grid;place-items:center;flex:none}.vo-rq-sp .vo-g .vo-spin{width:10px;height:10px}.vo-rq-sp .vo-g .vo-dot{width:5px;height:5px;color:var(--vo-faint)}.vo-rq-sp .vo-m{margin-left:auto;font-size:12px;color:var(--vo-muted)}.vo-rq-sp.vo-wait{color:var(--vo-muted)}.vo-rq-sp.vo-done .vo-g{color:var(--vo-ok)}.vo-rq-sp.vo-fail,.vo-rq-sp.vo-fail .vo-g{color:var(--vo-bad)}.vo-rq-retry{height:24px;padding:0 10px;border-radius:var(--vo-r-pill);background:var(--vo-surface);box-shadow:var(--vo-shadow);font-size:12px;font-weight:500;color:var(--vo-fg);transition:box-shadow .2s,transform .15s}.vo-rq-retry.vo-on{box-shadow:var(--vo-shadow-pop)}@media (hover:hover) and (pointer:fine){.vo-rq-retry:hover{box-shadow:var(--vo-shadow-pop)}}.vo-rq-retry:active{transform:scale(.96)}.vo-rq-fin{display:flex;align-items:center;gap:10px;padding:10px;border-radius:var(--vo-r-in);background:var(--vo-ok-bg)}.vo-rq-fin .vo-rq-av{background:var(--vo-surface);color:var(--vo-ok)}.vo-rq-fin b{font-weight:500;color:var(--vo-ok)}.vo-rq-fin .vo-rq-js{color:var(--vo-fg2)}.vo-rq-say{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@container (max-width:340px){.vo-rq-h{flex-wrap:wrap}.vo-rq-jb,.vo-rq-steps{padding-left:0}}:root:not([data-style=soft]) .vo-rq-j:is([data-s=run],[data-s=fail]):not(:where([data-style=soft],[data-style=soft] *)){box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--vo-line) 70%,transparent)}:root:not([data-style=soft]) .vo-rq-j[data-s=run]:not(:where([data-style=soft],[data-style=soft] *)){box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--vo-accent-mark,var(--vo-accent)) 45%,transparent)}:root:not([data-style=soft]) .vo-rq-j[data-s=fail]:not(:where([data-style=soft],[data-style=soft] *)){background:repeating-linear-gradient(135deg,transparent 0 5px,color-mix(in srgb,var(--vo-bad) 10%,transparent) 5px 6px),var(--vo-bad-bg);box-shadow:none}:root:not([data-style=soft]) .vo-rq-bar i:not(:where([data-style=soft],[data-style=soft] *)),:root:not([data-style=soft]) .vo-rq-tot b:not(:where([data-style=soft],[data-style=soft] *)){transition:transform .2s steps(2,end)}:root:not([data-style=soft]) .vo-rq-retry:not(:where([data-style=soft],[data-style=soft] *)){box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--vo-line) 70%,transparent)}.vo-panel{background:var(--vo-surface);border-radius:var(--vo-r-card);box-shadow:var(--vo-shadow);position:relative}.vo-spin{width:12px;height:12px;border-radius:50%;border:1.5px solid currentColor;border-right-color:transparent;animation:vo-rot .8s linear infinite;flex:none;display:inline-block}@keyframes vo-rot{to{transform:rotate(360deg)}}.vo-dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none;display:inline-block}.vo-sw{display:inline-block;transition:opacity .2s var(--vo-ease),filter .2s var(--vo-ease),transform .25s var(--vo-ease)}.vo-sw.vo-out{opacity:0;filter:blur(3px);transform:translateY(3px)}.vo-enter{animation:vo-enter var(--vo-t-slow) var(--vo-ease) backwards}@keyframes vo-enter{0%{opacity:0;transform:translateY(6px);filter:blur(4px)}to{opacity:1;transform:none;filter:blur(0)}}.vo-fold{display:grid;grid-template-rows:1fr;grid-template-columns:minmax(0,1fr);transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease)}.vo-fold>*{overflow:clip;overflow-clip-margin:12px;min-height:0;min-width:0}.vo-fold.vo-shut{grid-template-rows:0fr;opacity:0;visibility:hidden;transition:grid-template-rows var(--vo-t) var(--vo-ease),opacity var(--vo-t) var(--vo-ease),visibility 0s var(--vo-t)}.vo-seg2{display:inline-flex;padding:2px;background:var(--vo-chip);border-radius:var(--vo-r-pill);position:relative}.vo-seg2 button{position:relative;z-index:1;height:26px;padding:0 11px;border-radius:var(--vo-r-pill);font-size:12.5px;color:var(--vo-fg2);transition:color var(--vo-t-fast)}.vo-seg2 button[aria-pressed=true]{color:var(--vo-fg)}.vo-seg2 .vo-knob{position:absolute;top:2px;bottom:2px;border-radius:var(--vo-r-pill);background:var(--vo-surface);box-shadow:0 1px 2px #00000014;transition:left var(--vo-t) var(--vo-ease),width var(--vo-t) var(--vo-ease)}.vo-seg2 button:focus-visible{outline-offset:-2px;border-radius:var(--vo-r-pill)}:root:not([data-style=soft]) .vo-seg2 .vo-knob:not(:where([data-style=soft],[data-style=soft] *)){box-shadow:0 0 0 1px color-mix(in srgb,var(--vo-rail) 50%,transparent)}\n"] }]
|
|
460
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { jobs: [{
|
|
461
|
+
type: Input
|
|
462
|
+
}], title: [{
|
|
463
|
+
type: Input
|
|
464
|
+
}], status: [{
|
|
465
|
+
type: Input
|
|
466
|
+
}], summary: [{
|
|
467
|
+
type: Input
|
|
468
|
+
}], density: [{
|
|
469
|
+
type: Input
|
|
470
|
+
}], defaultDensity: [{
|
|
471
|
+
type: Input
|
|
472
|
+
}], retryWired: [{
|
|
473
|
+
type: Input
|
|
474
|
+
}], bare: [{
|
|
475
|
+
type: Input
|
|
476
|
+
}], densityChange: [{
|
|
477
|
+
type: Output
|
|
478
|
+
}], retry: [{
|
|
479
|
+
type: Output
|
|
480
|
+
}] } });
|
|
481
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLXF1ZXVlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3J1bi1xdWV1ZS9ydW4tcXVldWUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHFEQUFxRDtBQUNyRCxFQUFFO0FBQ0YsaUVBQWlFO0FBQ2pFLGlGQUFpRjtBQUNqRixpRkFBaUY7QUFDakYsaUZBQWlGO0FBQ2pGLGdGQUFnRjtBQUNoRixvRUFBb0U7QUFDcEUsRUFBRTtBQUNGLGdGQUFnRjtBQUNoRiw4RUFBOEU7QUFFOUUsT0FBTyxFQUdMLFNBQVMsRUFFVCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFDTixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGVBQWUsRUFBbUIsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7QUFnQ25ELE1BQU0sU0FBUyxHQUFHLENBQUMsQ0FBVyxFQUFXLEVBQUUsQ0FBQyxDQUFDLEtBQUssU0FBUyxJQUFJLENBQUMsS0FBSyxRQUFRLENBQUM7QUFDOUUsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFTLEVBQVUsRUFBRSxDQUNwQyxDQUFDLENBQUMsUUFBUTtJQUNWLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNO1FBQ2QsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLE1BQU0sQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU07UUFDbkUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssTUFBTTtZQUNsQixDQUFDLENBQUMsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNYLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBUyxFQUFV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O3NCQUFkLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvLyBmcmFtZXdvcmsvYW5ndWxhci9ydW4tcXVldWUvcnVuLXF1ZXVlLmNvbXBvbmVudC50c1xuLy9cbi8vIE5hdGl2ZSBBbmd1bGFyIHBvcnQgb2YgZnJhbWV3b3JrL3JlYWN0L3J1bi1xdWV1ZS9SdW5RdWV1ZS50c3guXG4vLyBBIHF1ZXVlIG9mIGFnZW50IGpvYnMgaW4gdGhyZWUgcGFydHM6IHRoZSBvbmUgcnVubmluZyAocmFpc2VkLCB3aXRoIGl0cyBzdGVwcyxcbi8vIHByb2dyZXNzIGFuZCB0aW1lIGxlZnQpLCB0aGUgb25lcyB1cCBuZXh0LCBhbmQgdGhlIG9uZXMgZG9uZS4gQSBjb21wYWN0IHN3aXRjaFxuLy8gZm9sZHMgdGhlIHJ1bm5pbmcgam9iJ3Mgc3RlcHMgYXdheTsgYSBmYWlsZWQgc3RlcCB0dXJucyBpdHMgam9iIHJlZCBhbmQgb2ZmZXJzXG4vLyBSZXRyeTsgd2hlbiBldmVyeSBqb2IgaXMgZG9uZSBhIHN1bW1hcnkgdGFrZXMgdGhlIHJ1bm5pbmcgam9iJ3MgcGxhY2UuIElucHV0c1xuLy8gbWlycm9yIHRoZSBSZWFjdCBwcm9wczsgY2FsbGJhY2tzIGJlY29tZSBAT3V0cHV0KCkgRXZlbnRFbWl0dGVycy5cbi8vXG4vLyBUaGUgc2VnbWVudGVkIGRlbnNpdHkgc3dpdGNoIGlzIHJlcHJvZHVjZWQgaW5saW5lIChhIHNsaWRpbmcga25vYiBwbGFjZWQgb3ZlclxuLy8gdGhlIHByZXNzZWQgYnV0dG9uKSwgYXMgc3RhdC1jYXJkcy5jb21wb25lbnQudHMgZG9lcyBmb3IgaXRzIHBlcmlvZCBzd2l0Y2guXG5cbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT3V0cHV0LFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBWb0ljb25Db21wb25lbnQsIHR5cGUgVm9JY29uTmFtZSB9IGZyb20gJy4uL2NvcmUvaWNvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgTmdUZW1wbGF0ZU91dGxldCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbmV4cG9ydCB0eXBlIFJ1blN0YXRlID0gJ3F1ZXVlZCcgfCAncnVubmluZycgfCAnZmFpbGVkJyB8ICdkb25lJztcblxuZXhwb3J0IGludGVyZmFjZSBSdW5TdGVwIHtcbiAgbGFiZWw6IHN0cmluZztcbiAgc3RhdGU6IFJ1blN0YXRlO1xuICAvKiogV2hhdCB0aGUgc3RlcCBjYW1lIHRvLCBzaG93biBvbmNlIGl0IGlzIGRvbmUsIGxpa2UgXCIzIG9mIDNcIiBvciBcIjQgYXJ0aWNsZXNcIi4gKi9cbiAgbWV0YT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSdW5Kb2Ige1xuICAvKiogS2VlcHMgdGhlIGpvYidzIHJvdyB3aGVuIHRoZSBsaXN0IGNoYW5nZXMgb3JkZXIuIERlZmF1bHRzIHRvIHRoZSB0aXRsZS4gKi9cbiAgaWQ/OiBzdHJpbmc7XG4gIC8qKiBXaGF0IHRoZSBqb2IgaXMsIGxpa2UgXCJEcmFmdCB0aGUgbGF1bmNoIGVtYWlsXCIuICovXG4gIHRpdGxlOiBzdHJpbmc7XG4gIC8qKiBXaG8gZG9lcyBpdCwgbGlrZSBcIkNvcHkgYWdlbnRcIiwgdW5kZXIgdGhlIHRpdGxlLiAqL1xuICBhZ2VudD86IHN0cmluZztcbiAgLyoqIFRoZSBpY29uIG9uIHRoZSBqb2IncyBiYWRnZS4gRGVmYXVsdHMgdG8gYSBzcGFyay4gKi9cbiAgaWNvbj86IFZvSWNvbk5hbWU7XG4gIHN0YXRlOiBSdW5TdGF0ZTtcbiAgLyoqIEhvdyBmYXIgdGhlIGpvYiBpcywgMCB0byAxLiBEZWZhdWx0cyB0byB0aGUgc2hhcmUgb2YgaXRzIHN0ZXBzIHRoYXQgYXJlIGRvbmUuICovXG4gIHByb2dyZXNzPzogbnVtYmVyO1xuICAvKiogVGhlIHRpbWUgYXQgdGhlIGVuZCBvZiB0aGUgcm93LCBsaWtlIFwiaW4gfjRzXCIsIFwiMTJzIGxlZnRcIiBvciBcIjQuMnNcIi4gKi9cbiAgdGltZT86IHN0cmluZztcbiAgLyoqIFRoZSBsaW5lIGFmdGVyIHRoZSBhZ2VudCB3aGlsZSBpdCBydW5zLiBEZWZhdWx0cyB0byB0aGUgc3RlcCBydW5uaW5nIG9yIGZhaWxlZC4gKi9cbiAgbm90ZT86IHN0cmluZztcbiAgc3RlcHM/OiBSdW5TdGVwW107XG59XG5cbmV4cG9ydCB0eXBlIFJ1blF1ZXVlRGVuc2l0eSA9ICdkZXRhaWxlZCcgfCAnY29tcGFjdCc7XG5cbmNvbnN0IGxpdmVTdGF0ZSA9IChzOiBSdW5TdGF0ZSk6IGJvb2xlYW4gPT4gcyA9PT0gJ3J1bm5pbmcnIHx8IHMgPT09ICdmYWlsZWQnO1xuY29uc3Qgc2hhcmVPZiA9IChqOiBSdW5Kb2IpOiBudW1iZXIgPT5cbiAgai5wcm9ncmVzcyA/P1xuICAoai5zdGVwcz8ubGVuZ3RoXG4gICAgPyBqLnN0ZXBzLmZpbHRlcigocykgPT4gcy5zdGF0ZSA9PT0gJ2RvbmUnKS5sZW5ndGggLyBqLnN0ZXBzLmxlbmd0aFxuICAgIDogai5zdGF0ZSA9PT0gJ2RvbmUnXG4gICAgICA/IDFcbiAgICAgIDogMCk7XG5jb25zdCBjbGFtcDAxID0gKG46IG51bWJlcik6IG51bWJlciA9PiBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBuKSk7XG5cbi8qKiBJbnRlcm5hbCBwZXItam9iIHJlbmRlciBzdGF0ZS4gKi9cbmludGVyZmFjZSBKb2JWaWV3IHtcbiAgam9iOiBSdW5Kb2I7XG4gIGluZGV4OiBudW1iZXI7XG4gIGtleTogc3RyaW5nO1xuICBwYXJ0OiAncnVuJyB8ICduZXh0JyB8ICdkb25lJztcbiAgZGF0YVM6ICdydW4nIHwgJ2ZhaWwnIHwgJ2RvbmUnIHwgJ3dhaXQnO1xuICBwcm9ncmVzczogbnVtYmVyO1xuICBub3RlPzogc3RyaW5nO1xuICBzaG93U3RlcHM6IGJvb2xlYW47XG59XG5cbi8qKiBBIHF1ZXVlIG9mIGFnZW50IGpvYnM6IHJ1bm5pbmcsIHVwIG5leHQsIGFuZCBkb25lLCB3aXRoIHBlci1yb3cgcHJvZ3Jlc3MgYW5kIGEgY29tcGFjdCB0b2dnbGUuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2by1ydW4tcXVldWUnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBpbXBvcnRzOiBbVm9JY29uQ29tcG9uZW50LCBOZ1RlbXBsYXRlT3V0bGV0XSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2XG4gICAgICBkYXRhLXZvPVwiXCJcbiAgICAgIGNsYXNzPVwidm8tcnFcIlxuICAgICAgW2NsYXNzLnZvLXBhbmVsXT1cIiFiYXJlXCJcbiAgICAgIFtjbGFzcy52by1rZWVwXT1cIiFiYXJlXCJcbiAgICAgIFtjbGFzcy52by1maW5dPVwiZmluXCJcbiAgICAgIFtzdHlsZS5wYWRkaW5nSW5saW5lXT1cImJhcmUgPyAnMCcgOiBudWxsXCJcbiAgICA+XG4gICAgICA8ZGl2IGNsYXNzPVwidm8tcnEtaFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidm8tcnEtaHRcIj5cbiAgICAgICAgICA8Yj57eyB0aXRsZSB9fTwvYj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLXJxLXN0IHZvLW51bSB2by1zd1wiPnt7IGxpbmUgfX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidm8tc2VnMiB2by1ycS1zZ1wiIHJvbGU9XCJncm91cFwiIGFyaWEtbGFiZWw9XCJEZW5zaXR5XCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1rbm9iXCIgW3N0eWxlLmxlZnQucHhdPVwia25vYkxlZnRcIiBbc3R5bGUud2lkdGgucHhdPVwia25vYldpZHRoXCI+PC9zcGFuPlxuICAgICAgICAgIEBmb3IgKG8gb2YgZGVuc2l0eU9wdGlvbnM7IHRyYWNrIG8udmFsdWUpIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCJkZW5zID09PSBvLnZhbHVlXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNldERlbnNpdHkoby52YWx1ZSlcIlxuICAgICAgICAgICAgPnt7IG8ubGFiZWwgfX08L2J1dHRvbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJ2by1ycS10b3RcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgQGZvciAodiBvZiB2aWV3czsgdHJhY2sgdi5rZXkpIHtcbiAgICAgICAgICA8aSBbY2xhc3Mudm8tZmFpbF09XCJ2LmpvYi5zdGF0ZSA9PT0gJ2ZhaWxlZCdcIj48YiBbc3R5bGUuLS12by1wXT1cInYucHJvZ3Jlc3NcIj48L2I+PC9pPlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cInZvLXJxLWJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInZvLWZvbGQgdm8tcnEtZmZcIiBbY2xhc3Mudm8tc2h1dF09XCIhZmluXCIgW2F0dHIuaW5lcnRdPVwiZmluID8gbnVsbCA6ICcnXCI+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ2by1ycS1zZWNcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZvLXJxLWZpblwiIFtjbGFzcy52by1lbnRlcl09XCJmaW5cIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLXJxLWF2XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PHZvLWljb24gbmFtZT1cIm9rXCI+PC92by1pY29uPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLXJxLWp0XCI+XG4gICAgICAgICAgICAgICAgICA8YiBjbGFzcz1cInZvLXJxLWZ0XCI+QWxsIHt7IGpvYnMubGVuZ3RoIH19IGpvYnMgZG9uZTwvYj5cbiAgICAgICAgICAgICAgICAgIEBpZiAoc3VtbWFyeSkge1xuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLXJxLWpzXCI+e3sgc3VtbWFyeSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ2by1mb2xkIHZvLXJxLXJmXCIgW2NsYXNzLnZvLXNodXRdPVwiZmluXCIgW2F0dHIuaW5lcnRdPVwiZmluID8gJycgOiBudWxsXCI+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ2by1ycS1zZWNcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1ycS1sXCI+UnVubmluZzwvc3Bhbj5cbiAgICAgICAgICAgICAgPHVsIGNsYXNzPVwidm8tcnEtcnVuXCIgYXJpYS1sYWJlbD1cIlJ1bm5pbmdcIj5cbiAgICAgICAgICAgICAgICBAZm9yICh2IG9mIHJ1blZpZXdzOyB0cmFjayB2LmtleSkge1xuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJqb2JSb3dcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IHYgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwidm8tZm9sZCB2by1ycS1uZlwiIFtjbGFzcy52by1zaHV0XT1cImZpblwiIFthdHRyLmluZXJ0XT1cImZpbiA/ICcnIDogbnVsbFwiPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidm8tcnEtc2VjXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tcnEtbFwiPlVwIG5leHQ8L3NwYW4+XG4gICAgICAgICAgICAgIDxvbCBjbGFzcz1cInZvLXJxLW5leHRcIiBhcmlhLWxhYmVsPVwiVXAgbmV4dFwiPlxuICAgICAgICAgICAgICAgIEBmb3IgKHYgb2YgbmV4dFZpZXdzOyB0cmFjayB2LmtleSkge1xuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJqb2JSb3dcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IHYgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9vbD5cbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ2by1ycS1ub25lXCI+Tm90aGluZyB3YWl0aW5nPC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ2by1mb2xkIHZvLXJxLWRmXCI+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ2by1ycS1zZWNcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1ycS1sXCI+RG9uZSA8c3BhbiBjbGFzcz1cInZvLW51bVwiPnt7IGRvbmVDb3VudCB9fTwvc3Bhbj48L3NwYW4+XG4gICAgICAgICAgICAgIDx1bCBjbGFzcz1cInZvLXJxLWRvbmVcIiBhcmlhLWxhYmVsPVwiRG9uZVwiPlxuICAgICAgICAgICAgICAgIEBmb3IgKHYgb2YgZG9uZVZpZXdzOyB0cmFjayB2LmtleSkge1xuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJqb2JSb3dcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IHYgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ2by1ycS1ub25lXCI+Tm90aGluZyBkb25lIHlldDwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPG5nLXRlbXBsYXRlICNqb2JSb3cgbGV0LXY+XG4gICAgICA8bGkgY2xhc3M9XCJ2by1ycS1qXCIgW2F0dHIuZGF0YS1zXT1cInYuZGF0YVNcIiBbYXR0ci5kYXRhLWtdPVwidi5rZXlcIiBbYXR0ci5kYXRhLXBdPVwidi5wYXJ0XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ2by1ycS1qaFwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tcnEtYXZcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48dm8taWNvbiBbbmFtZV09XCJ2LmpvYi5pY29uID8/ICdzcGFyaydcIj48L3ZvLWljb24+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tcnEtanRcIj5cbiAgICAgICAgICAgIDxiPnt7IHYuam9iLnRpdGxlIH19PC9iPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1ycS1qcyB2by1zd1wiPnt7IHN1YkxpbmUodikgfX08L3NwYW4+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tcnEtam0gdm8tbnVtXCI+XG4gICAgICAgICAgICBAaWYgKHYuam9iLnRpbWUpIHtcbiAgICAgICAgICAgICAgPHNwYW4+e3sgdi5qb2IudGltZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBpZiAodi5qb2Iuc3RhdGUgPT09ICdkb25lJykge1xuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLW9rXCI+PHZvLWljb24gbmFtZT1cImNoZWNrXCIgc2l6ZT1cInhzXCI+PC92by1pY29uPjwvc3Bhbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidm8tcnEtamJcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidm8tcnEtYmFyXCI+PGkgW3N0eWxlLi0tdm8tcF09XCJ2LnByb2dyZXNzXCI+PC9pPjwvZGl2PlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tcnEtcGMgdm8tbnVtXCI+e3sgcGN0VGV4dCh2KSB9fSU8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidm8tZm9sZCB2by1ycS1zZlwiIFtjbGFzcy52by1zaHV0XT1cIiF2LnNob3dTdGVwc1wiIFthdHRyLmluZXJ0XT1cInYuc2hvd1N0ZXBzID8gbnVsbCA6ICcnXCI+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDx1bCBjbGFzcz1cInZvLXJxLXN0ZXBzXCI+XG4gICAgICAgICAgICAgIEBmb3IgKHN0IG9mIHYuam9iLnN0ZXBzID8/IFtdOyB0cmFjayAkaW5kZXg7IGxldCBzaSA9ICRpbmRleCkge1xuICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInZvLXJxLXNwXCIgW2NsYXNzXT1cInN0ZXBDbGFzcyhzdClcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tZ1wiPlxuICAgICAgICAgICAgICAgICAgICBAc3dpdGNoIChzdC5zdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgIEBjYXNlICgncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tc3BpblwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdmYWlsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8dm8taWNvbiBuYW1lPVwieFwiIHNpemU9XCJ4c1wiPjwvdm8taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdkb25lJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHZvLWljb24gbmFtZT1cImNoZWNrXCIgc2l6ZT1cInhzXCI+PC92by1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICBAZGVmYXVsdCB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLWRvdFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IHN0LmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1tXCI+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoc3Quc3RhdGUgPT09ICdmYWlsZWQnICYmIHJldHJ5V2lyZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInZvLXJxLXJldHJ5IHZvLWVudGVyXCIgKGNsaWNrKT1cInJldHJ5LmVtaXQoeyBqb2I6IHYuaW5kZXgsIHN0ZXA6IHNpIH0pXCI+UmV0cnk8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoc3Quc3RhdGUgPT09ICdkb25lJyAmJiBzdC5tZXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2by1zd1wiPnt7IHN0Lm1ldGEgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L3VsPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbGk+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgYCxcbiAgc3R5bGVVcmw6ICcuL3J1bi1xdWV1ZS5jc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBSdW5RdWV1ZUNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIGpvYnM6IFJ1bkpvYltdID0gW107XG4gIC8qKiBUaGUgcXVldWUncyBuYW1lIG92ZXIgaXRzIHN0YXR1cyBsaW5lLiAqL1xuICBASW5wdXQoKSB0aXRsZSA9ICdSdW4gcXVldWUnO1xuICAvKiogT3ZlcnJpZGVzIHRoZSBzdGF0dXMgbGluZS4gKi9cbiAgQElucHV0KCkgc3RhdHVzPzogc3RyaW5nO1xuICAvKiogVGhlIGxpbmUgdW5kZXIgXCJBbGwgTiBqb2JzIGRvbmVcIiBvbmNlIGV2ZXJ5IGpvYiBpcyBkb25lLiAqL1xuICBASW5wdXQoKSBzdW1tYXJ5Pzogc3RyaW5nO1xuICAvKiogZGV0YWlsZWQgbGlzdHMgdGhlIHJ1bm5pbmcgam9iJ3Mgc3RlcHMsIGNvbXBhY3QgZm9sZHMgdGhlbSBhd2F5LiAqL1xuICBASW5wdXQoKSBzZXQgZGVuc2l0eSh2YWx1ZTogUnVuUXVldWVEZW5zaXR5IHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5jb250cm9sbGVkID0gdmFsdWUgIT09IHVuZGVmaW5lZDtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gdGhpcy5kZW5zKSB7XG4gICAgICB0aGlzLmRlbnMgPSB2YWx1ZTtcbiAgICAgIGlmICh0aGlzLnJlYWR5KSB0aGlzLnBsYWNlS25vYigpO1xuICAgIH1cbiAgfVxuICBASW5wdXQoKSBkZWZhdWx0RGVuc2l0eTogUnVuUXVldWVEZW5zaXR5ID0gJ2RldGFpbGVkJztcbiAgLyoqIFdoZXRoZXIgdGhlIFJldHJ5IGJ1dHRvbiBzaG93cyBvbiBhIGZhaWxlZCBzdGVwIChSZWFjdDogb25SZXRyeSB3aXJlZCkuICovXG4gIEBJbnB1dCgpIHJldHJ5V2lyZWQgPSB0cnVlO1xuICAvKiogU2l0cyBmbGF0IGluIGEgY2hhdCB0aHJlYWQsIHdpdGggbm8gY2FyZC4gKi9cbiAgQElucHV0KCkgYmFyZSA9IGZhbHNlO1xuXG4gIEBPdXRwdXQoKSBkZW5zaXR5Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxSdW5RdWV1ZURlbnNpdHk+KCk7XG4gIEBPdXRwdXQoKSByZXRyeSA9IG5ldyBFdmVudEVtaXR0ZXI8eyBqb2I6IG51bWJlcjsgc3RlcDogbnVtYmVyIH0+KCk7XG5cbiAgcmVhZG9ubHkgZGVuc2l0eU9wdGlvbnM6IHsgdmFsdWU6IFJ1blF1ZXVlRGVuc2l0eTsgbGFiZWw6IHN0cmluZyB9W10gPSBbXG4gICAgeyB2YWx1ZTogJ2RldGFpbGVkJywgbGFiZWw6ICdEZXRhaWxlZCcgfSxcbiAgICB7IHZhbHVlOiAnY29tcGFjdCcsIGxhYmVsOiAnQ29tcGFjdCcgfSxcbiAgXTtcblxuICBkZW5zOiBSdW5RdWV1ZURlbnNpdHkgPSAnZGV0YWlsZWQnO1xuICBrbm9iTGVmdCA9IDA7XG4gIGtub2JXaWR0aCA9IDA7XG5cbiAgcHJpdmF0ZSBjb250cm9sbGVkID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZHkgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgKSB7fVxuXG4gIHByaXZhdGUga2V5T2YoajogUnVuSm9iKTogc3RyaW5nIHtcbiAgICByZXR1cm4gai5pZCA/PyBqLnRpdGxlO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJ0T2YoczogUnVuU3RhdGUpOiAncnVuJyB8ICduZXh0JyB8ICdkb25lJyB7XG4gICAgcmV0dXJuIGxpdmVTdGF0ZShzKSA/ICdydW4nIDogcyA9PT0gJ2RvbmUnID8gJ2RvbmUnIDogJ25leHQnO1xuICB9XG5cbiAgZ2V0IHZpZXdzKCk6IEpvYlZpZXdbXSB7XG4gICAgcmV0dXJuIHRoaXMuam9icy5tYXAoKGpvYiwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGRhdGFTOiBKb2JWaWV3WydkYXRhUyddID1cbiAgICAgICAgam9iLnN0YXRlID09PSAncnVubmluZydcbiAgICAgICAgICA/ICdydW4nXG4gICAgICAgICAgOiBqb2Iuc3RhdGUgPT09ICdmYWlsZWQnXG4gICAgICAgICAgICA/ICdmYWlsJ1xuICAgICAgICAgICAgOiBqb2Iuc3RhdGUgPT09ICdkb25lJ1xuICAgICAgICAgICAgICA/ICdkb25lJ1xuICAgICAgICAgICAgICA6ICd3YWl0JztcbiAgICAgIGNvbnN0IGF0ID0gam9iLnN0ZXBzPy5maW5kKCh4KSA9PiB4LnN0YXRlID09PSAnZmFpbGVkJykgPz8gam9iLnN0ZXBzPy5maW5kKCh4KSA9PiB4LnN0YXRlID09PSAncnVubmluZycpO1xuICAgICAgY29uc3Qgbm90ZSA9IGxpdmVTdGF0ZShqb2Iuc3RhdGUpID8gKGpvYi5ub3RlID8/IGF0Py5sYWJlbCkgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBqb2IsXG4gICAgICAgIGluZGV4LFxuICAgICAgICBrZXk6IHRoaXMua2V5T2Yoam9iKSxcbiAgICAgICAgcGFydDogdGhpcy5wYXJ0T2Yoam9iLnN0YXRlKSxcbiAgICAgICAgZGF0YVMsXG4gICAgICAgIHByb2dyZXNzOiBjbGFtcDAxKHNoYXJlT2Yoam9iKSksXG4gICAgICAgIG5vdGUsXG4gICAgICAgIHNob3dTdGVwczogdGhpcy5kZW5zID09PSAnZGV0YWlsZWQnICYmIGxpdmVTdGF0ZShqb2Iuc3RhdGUpICYmICEham9iLnN0ZXBzPy5sZW5ndGgsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0IHJ1blZpZXdzKCk6IEpvYlZpZXdbXSB7XG4gICAgcmV0dXJuIHRoaXMudmlld3MuZmlsdGVyKCh2KSA9PiB2LnBhcnQgPT09ICdydW4nKTtcbiAgfVxuICBnZXQgbmV4dFZpZXdzKCk6IEpvYlZpZXdbXSB7XG4gICAgcmV0dXJuIHRoaXMudmlld3MuZmlsdGVyKCh2KSA9PiB2LnBhcnQgPT09ICduZXh0Jyk7XG4gIH1cbiAgZ2V0IGRvbmVWaWV3cygpOiBKb2JWaWV3W10ge1xuICAgIHJldHVybiB0aGlzLnZpZXdzLmZpbHRlcigodikgPT4gdi5wYXJ0ID09PSAnZG9uZScpO1xuICB9XG5cbiAgZ2V0IGRvbmVDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmpvYnMuZmlsdGVyKChqKSA9PiBqLnN0YXRlID09PSAnZG9uZScpLmxlbmd0aDtcbiAgfVxuXG4gIGdldCBmaW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuam9icy5sZW5ndGggPiAwICYmIHRoaXMuZG9uZUNvdW50ID09PSB0aGlzLmpvYnMubGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGxpbmUoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5zdGF0dXMgIT09IHVuZGVmaW5lZCkgcmV0dXJuIHRoaXMuc3RhdHVzO1xuICAgIGlmICh0aGlzLmZpbikgcmV0dXJuIGBBbGwgJHt0aGlzLmpvYnMubGVuZ3RofSBkb25lYDtcbiAgICBpZiAodGhpcy5qb2JzLnNvbWUoKGopID0+IGouc3RhdGUgPT09ICdmYWlsZWQnKSkgcmV0dXJuICcxIHN0ZXAgZmFpbGVkLCB3YWl0aW5nIGZvciBSZXRyeSc7XG4gICAgcmV0dXJuIGAke3RoaXMuZG9uZUNvdW50fSBvZiAke3RoaXMuam9icy5sZW5ndGh9IGRvbmVgO1xuICB9XG5cbiAgc3ViTGluZSh2OiBKb2JWaWV3KTogc3RyaW5nIHtcbiAgICByZXR1cm4gW3Yuam9iLmFnZW50LCB2Lm5vdGVdLmZpbHRlcihCb29sZWFuKS5qb2luKCcgwrcgJyk7XG4gIH1cblxuICBwY3RUZXh0KHY6IEpvYlZpZXcpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKHYucHJvZ3Jlc3MgKiAxMDApO1xuICB9XG5cbiAgc3RlcENsYXNzKHN0OiBSdW5TdGVwKTogc3RyaW5nIHtcbiAgICByZXR1cm4gc3Quc3RhdGUgPT09ICdxdWV1ZWQnXG4gICAgICA/ICd2by13YWl0J1xuICAgICAgOiBzdC5zdGF0ZSA9PT0gJ3J1bm5pbmcnXG4gICAgICAgID8gJ3ZvLXJ1bidcbiAgICAgICAgOiBzdC5zdGF0ZSA9PT0gJ2ZhaWxlZCdcbiAgICAgICAgICA/ICd2by1mYWlsJ1xuICAgICAgICAgIDogJ3ZvLWRvbmUnO1xuICB9XG5cbiAgc2V0RGVuc2l0eSh2YWx1ZTogUnVuUXVldWVEZW5zaXR5KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xsZWQpIHtcbiAgICAgIHRoaXMuZGVucyA9IHZhbHVlO1xuICAgICAgdGhpcy5wbGFjZUtub2IoKTtcbiAgICB9XG4gICAgdGhpcy5kZW5zaXR5Q2hhbmdlLmVtaXQodmFsdWUpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb250cm9sbGVkKSB0aGlzLmRlbnMgPSB0aGlzLmRlZmF1bHREZW5zaXR5O1xuICAgIHRoaXMucmVhZHkgPSB0cnVlO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB0aGlzLnBsYWNlS25vYigpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVhZHkpIHtcbiAgICAgIC8vIHRoZSBrbm9iIG1heSBuZWVkIHRvIG1vdmUgaWYgdGhlIHByZXNzZWQgYnV0dG9uJ3Mgd2lkdGggY2hhbmdlZFxuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5wbGFjZUtub2IoKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwbGFjZUtub2IoKTogdm9pZCB7XG4gICAgY29uc3QgYnRucyA9IHRoaXMuaG9zdC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTEVsZW1lbnQ+KCcudm8tcnEtc2cgYnV0dG9uJyk7XG4gICAgY29uc3QgaSA9IHRoaXMuZGVuc2l0eU9wdGlvbnMuZmluZEluZGV4KChvKSA9PiBvLnZhbHVlID09PSB0aGlzLmRlbnMpO1xuICAgIGNvbnN0IGIgPSBidG5zW2ldO1xuICAgIGlmIChiKSB7XG4gICAgICB0aGlzLmtub2JMZWZ0ID0gYi5vZmZzZXRMZWZ0O1xuICAgICAgdGhpcy5rbm9iV2lkdGggPSBiLm9mZnNldFdpZHRoO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG59XG4iXX0=
|