angular-debug-recorder 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # DebugRecorder
2
+
3
+ This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.3.0.
4
+
5
+ ## Code scaffolding
6
+
7
+ Run `ng generate component component-name --project debug-recorder` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project debug-recorder`.
8
+ > Note: Don't forget to add `--project debug-recorder` or else it will be added to the default project in your `angular.json` file.
9
+
10
+ ## Build
11
+
12
+ Run `ng build debug-recorder` to build the project. The build artifacts will be stored in the `dist/` directory.
13
+
14
+ ## Publishing
15
+
16
+ After building your library with `ng build debug-recorder`, go to the dist folder `cd dist/debug-recorder` and run `npm publish`.
17
+
18
+ ## Running unit tests
19
+
20
+ Run `ng test debug-recorder` to execute the unit tests via [Karma](https://karma-runner.github.io).
21
+
22
+ ## Further help
23
+
24
+ To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './public-api';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1kZWJ1Zy1yZWNvcmRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2RlYnVnLXJlY29yZGVyL3NyYy9hbmd1bGFyLWRlYnVnLXJlY29yZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG4iXX0=
@@ -0,0 +1,220 @@
1
+ import { Component, Input, Output, EventEmitter, signal } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/forms";
6
+ export class ActionListComponent {
7
+ constructor() {
8
+ this.session = null;
9
+ this.removeAction = new EventEmitter();
10
+ this.addNote = new EventEmitter();
11
+ this.expandedId = signal(null);
12
+ this.noteMap = {};
13
+ }
14
+ toggleExpand(id) {
15
+ this.expandedId.update(v => v === id ? null : id);
16
+ }
17
+ onRemove(id, e) {
18
+ e.stopPropagation();
19
+ this.removeAction.emit(id);
20
+ }
21
+ onAddNote(id) {
22
+ this.addNote.emit({ id, note: this.noteMap[id] ?? '' });
23
+ }
24
+ getActionIcon(type) {
25
+ const icons = {
26
+ click: '👆',
27
+ dblclick: '👆👆',
28
+ input: '⌨️',
29
+ select: '📋',
30
+ submit: '📤',
31
+ navigation: '🔗',
32
+ keypress: '⌨️',
33
+ scroll: '↕️',
34
+ hover: '🖱️',
35
+ assertion: '✅',
36
+ screenshot: '📸',
37
+ };
38
+ return icons[type] ?? '•';
39
+ }
40
+ formatTime(ts) {
41
+ return new Date(ts).toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
42
+ }
43
+ formatDuration(start, end) {
44
+ const s = Math.round((end - start) / 1000);
45
+ return s < 60 ? `${s}s` : `${Math.floor(s / 60)}m ${s % 60}s`;
46
+ }
47
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ActionListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
48
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ActionListComponent, isStandalone: true, selector: "app-action-list", inputs: { session: "session" }, outputs: { removeAction: "removeAction", addNote: "addNote" }, ngImport: i0, template: `
49
+ <div class="action-list" data-debug-panel>
50
+ @if (!session || session.actions.length === 0) {
51
+ <div class="empty-state">
52
+ <div class="empty-icon">🎬</div>
53
+ <p>Noch keine Aktionen aufgezeichnet.</p>
54
+ <p class="hint">Starte die Aufnahme und interagiere mit der App.</p>
55
+ <div class="shortcuts-hint">
56
+ <kbd>Ctrl+Shift+D</kbd> Panel &nbsp;
57
+ <kbd>Ctrl+Shift+R</kbd> Record
58
+ </div>
59
+ </div>
60
+ } @else {
61
+ <div class="list-header">
62
+ <span class="list-count">{{ session.actions.length }} Aktionen</span>
63
+ <span class="list-duration">
64
+ @if (session.endTime) {
65
+ {{ formatDuration(session.startTime, session.endTime) }}
66
+ } @else {
67
+ Live
68
+ }
69
+ </span>
70
+ </div>
71
+
72
+ @for (action of session.actions; track action.id; let i = $index) {
73
+ <div class="action-item" [class.expanded]="expandedId() === action.id">
74
+ <div class="action-row" (click)="toggleExpand(action.id)">
75
+ <span class="action-index">{{ i + 1 }}</span>
76
+ <span class="action-type-badge" [class]="'type-' + action.type">
77
+ {{ getActionIcon(action.type) }}
78
+ </span>
79
+ <div class="action-info">
80
+ <span class="action-desc">{{ action.description }}</span>
81
+ <span class="action-selector">{{ action.selector }}</span>
82
+ </div>
83
+ <span class="action-time">{{ formatTime(action.timestamp) }}</span>
84
+ <button
85
+ class="remove-btn"
86
+ data-debug-panel
87
+ title="Aktion entfernen"
88
+ (click)="onRemove(action.id, $event)"
89
+ >✕</button>
90
+ </div>
91
+
92
+ @if (expandedId() === action.id) {
93
+ <div class="action-detail" data-debug-panel>
94
+ <div class="detail-grid">
95
+ <span class="detail-label">Selector</span>
96
+ <code class="detail-value">{{ action.selector }}</code>
97
+ @if (action.value) {
98
+ <span class="detail-label">Wert</span>
99
+ <code class="detail-value">{{ action.value }}</code>
100
+ }
101
+ @if (action.element?.tagName) {
102
+ <span class="detail-label">Element</span>
103
+ <code class="detail-value">&lt;{{ action.element?.tagName }}&gt;</code>
104
+ }
105
+ <span class="detail-label">Strategie</span>
106
+ <span class="detail-value strategy-badge" [class]="'strat-' + action.selectorStrategy">
107
+ {{ action.selectorStrategy }}
108
+ </span>
109
+ <span class="detail-label">URL</span>
110
+ <code class="detail-value url-val">{{ action.url }}</code>
111
+ </div>
112
+ <div class="note-area">
113
+ <textarea
114
+ data-debug-panel
115
+ class="note-input"
116
+ [(ngModel)]="noteMap[action.id]"
117
+ placeholder="Notiz zu dieser Aktion..."
118
+ rows="2"
119
+ (blur)="onAddNote(action.id)"
120
+ ></textarea>
121
+ </div>
122
+ </div>
123
+ }
124
+ </div>
125
+ }
126
+ }
127
+ </div>
128
+ `, isInline: true, styles: [".action-list{padding:0}.empty-state{text-align:center;padding:32px 20px;color:#64748b}.empty-icon{font-size:40px;margin-bottom:10px}.empty-state p{margin:4px 0;font-size:13px}.hint{font-size:11px;color:#475569}.shortcuts-hint{margin-top:12px;font-size:11px;color:#475569}kbd{background:#1e293b;border:1px solid #334155;color:#94a3b8;padding:2px 6px;border-radius:4px;font-size:10px}.list-header{display:flex;justify-content:space-between;padding:8px 14px;font-size:11px;color:#64748b;background:#0f172a;border-bottom:1px solid #1e293b;position:sticky;top:0}.action-item{border-bottom:1px solid #1e293b;transition:background .1s}.action-item:hover{background:#1e293b80}.action-item.expanded{background:#1e293b}.action-row{display:flex;align-items:center;padding:8px 10px;gap:8px;cursor:pointer}.action-index{color:#475569;font-size:10px;min-width:18px;text-align:right}.action-type-badge{font-size:14px;min-width:20px;text-align:center}.action-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.action-desc{font-size:12px;color:#cbd5e1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.action-selector{font-size:10px;color:#64748b;font-family:Cascadia Code,Consolas,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.action-time{font-size:10px;color:#475569;white-space:nowrap}.remove-btn{background:none;border:none;color:#475569;cursor:pointer;font-size:12px;padding:2px 5px;border-radius:3px;opacity:0;transition:opacity .15s,color .15s}.action-row:hover .remove-btn{opacity:1}.remove-btn:hover{color:#f87171}.action-detail{padding:10px 14px;background:#0f172ab3;border-top:1px solid #1e293b}.detail-grid{display:grid;grid-template-columns:auto 1fr;gap:4px 10px;margin-bottom:8px;align-items:start}.detail-label{font-size:10px;color:#64748b;padding-top:2px;white-space:nowrap}.detail-value{font-size:11px;color:#93c5fd;font-family:Cascadia Code,Consolas,monospace;word-break:break-all}.url-val{color:#6ee7b7}.strategy-badge{font-size:10px;padding:1px 6px;border-radius:3px;font-family:monospace}.strat-data-testid,.strat-data-cy{background:#064e3b;color:#34d399}.strat-id{background:#1e3a8a;color:#93c5fd}.strat-name{background:#44337a;color:#c4b5fd}.strat-class{background:#374151;color:#9ca3af}.strat-combined{background:#292524;color:#d6d3d1}.note-area{margin-top:6px}.note-input{width:100%;box-sizing:border-box;background:#0f172a;border:1px solid #334155;color:#e2e8f0;border-radius:5px;padding:6px 8px;font-size:11px;resize:vertical}.note-input:focus{outline:none;border-color:#3b82f6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
129
+ }
130
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ActionListComponent, decorators: [{
131
+ type: Component,
132
+ args: [{ selector: 'app-action-list', standalone: true, imports: [CommonModule, FormsModule], template: `
133
+ <div class="action-list" data-debug-panel>
134
+ @if (!session || session.actions.length === 0) {
135
+ <div class="empty-state">
136
+ <div class="empty-icon">🎬</div>
137
+ <p>Noch keine Aktionen aufgezeichnet.</p>
138
+ <p class="hint">Starte die Aufnahme und interagiere mit der App.</p>
139
+ <div class="shortcuts-hint">
140
+ <kbd>Ctrl+Shift+D</kbd> Panel &nbsp;
141
+ <kbd>Ctrl+Shift+R</kbd> Record
142
+ </div>
143
+ </div>
144
+ } @else {
145
+ <div class="list-header">
146
+ <span class="list-count">{{ session.actions.length }} Aktionen</span>
147
+ <span class="list-duration">
148
+ @if (session.endTime) {
149
+ {{ formatDuration(session.startTime, session.endTime) }}
150
+ } @else {
151
+ Live
152
+ }
153
+ </span>
154
+ </div>
155
+
156
+ @for (action of session.actions; track action.id; let i = $index) {
157
+ <div class="action-item" [class.expanded]="expandedId() === action.id">
158
+ <div class="action-row" (click)="toggleExpand(action.id)">
159
+ <span class="action-index">{{ i + 1 }}</span>
160
+ <span class="action-type-badge" [class]="'type-' + action.type">
161
+ {{ getActionIcon(action.type) }}
162
+ </span>
163
+ <div class="action-info">
164
+ <span class="action-desc">{{ action.description }}</span>
165
+ <span class="action-selector">{{ action.selector }}</span>
166
+ </div>
167
+ <span class="action-time">{{ formatTime(action.timestamp) }}</span>
168
+ <button
169
+ class="remove-btn"
170
+ data-debug-panel
171
+ title="Aktion entfernen"
172
+ (click)="onRemove(action.id, $event)"
173
+ >✕</button>
174
+ </div>
175
+
176
+ @if (expandedId() === action.id) {
177
+ <div class="action-detail" data-debug-panel>
178
+ <div class="detail-grid">
179
+ <span class="detail-label">Selector</span>
180
+ <code class="detail-value">{{ action.selector }}</code>
181
+ @if (action.value) {
182
+ <span class="detail-label">Wert</span>
183
+ <code class="detail-value">{{ action.value }}</code>
184
+ }
185
+ @if (action.element?.tagName) {
186
+ <span class="detail-label">Element</span>
187
+ <code class="detail-value">&lt;{{ action.element?.tagName }}&gt;</code>
188
+ }
189
+ <span class="detail-label">Strategie</span>
190
+ <span class="detail-value strategy-badge" [class]="'strat-' + action.selectorStrategy">
191
+ {{ action.selectorStrategy }}
192
+ </span>
193
+ <span class="detail-label">URL</span>
194
+ <code class="detail-value url-val">{{ action.url }}</code>
195
+ </div>
196
+ <div class="note-area">
197
+ <textarea
198
+ data-debug-panel
199
+ class="note-input"
200
+ [(ngModel)]="noteMap[action.id]"
201
+ placeholder="Notiz zu dieser Aktion..."
202
+ rows="2"
203
+ (blur)="onAddNote(action.id)"
204
+ ></textarea>
205
+ </div>
206
+ </div>
207
+ }
208
+ </div>
209
+ }
210
+ }
211
+ </div>
212
+ `, styles: [".action-list{padding:0}.empty-state{text-align:center;padding:32px 20px;color:#64748b}.empty-icon{font-size:40px;margin-bottom:10px}.empty-state p{margin:4px 0;font-size:13px}.hint{font-size:11px;color:#475569}.shortcuts-hint{margin-top:12px;font-size:11px;color:#475569}kbd{background:#1e293b;border:1px solid #334155;color:#94a3b8;padding:2px 6px;border-radius:4px;font-size:10px}.list-header{display:flex;justify-content:space-between;padding:8px 14px;font-size:11px;color:#64748b;background:#0f172a;border-bottom:1px solid #1e293b;position:sticky;top:0}.action-item{border-bottom:1px solid #1e293b;transition:background .1s}.action-item:hover{background:#1e293b80}.action-item.expanded{background:#1e293b}.action-row{display:flex;align-items:center;padding:8px 10px;gap:8px;cursor:pointer}.action-index{color:#475569;font-size:10px;min-width:18px;text-align:right}.action-type-badge{font-size:14px;min-width:20px;text-align:center}.action-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.action-desc{font-size:12px;color:#cbd5e1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.action-selector{font-size:10px;color:#64748b;font-family:Cascadia Code,Consolas,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.action-time{font-size:10px;color:#475569;white-space:nowrap}.remove-btn{background:none;border:none;color:#475569;cursor:pointer;font-size:12px;padding:2px 5px;border-radius:3px;opacity:0;transition:opacity .15s,color .15s}.action-row:hover .remove-btn{opacity:1}.remove-btn:hover{color:#f87171}.action-detail{padding:10px 14px;background:#0f172ab3;border-top:1px solid #1e293b}.detail-grid{display:grid;grid-template-columns:auto 1fr;gap:4px 10px;margin-bottom:8px;align-items:start}.detail-label{font-size:10px;color:#64748b;padding-top:2px;white-space:nowrap}.detail-value{font-size:11px;color:#93c5fd;font-family:Cascadia Code,Consolas,monospace;word-break:break-all}.url-val{color:#6ee7b7}.strategy-badge{font-size:10px;padding:1px 6px;border-radius:3px;font-family:monospace}.strat-data-testid,.strat-data-cy{background:#064e3b;color:#34d399}.strat-id{background:#1e3a8a;color:#93c5fd}.strat-name{background:#44337a;color:#c4b5fd}.strat-class{background:#374151;color:#9ca3af}.strat-combined{background:#292524;color:#d6d3d1}.note-area{margin-top:6px}.note-input{width:100%;box-sizing:border-box;background:#0f172a;border:1px solid #334155;color:#e2e8f0;border-radius:5px;padding:6px 8px;font-size:11px;resize:vertical}.note-input:focus{outline:none;border-color:#3b82f6}\n"] }]
213
+ }], propDecorators: { session: [{
214
+ type: Input
215
+ }], removeAction: [{
216
+ type: Output
217
+ }], addNote: [{
218
+ type: Output
219
+ }] } });
220
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVidWctcmVjb3JkZXIvc3JjL2xpYi9hY3Rpb24tbGlzdC9hY3Rpb24tbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0UsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBK083QyxNQUFNLE9BQU8sbUJBQW1CO0lBNU9oQztRQTZPVyxZQUFPLEdBQTRCLElBQUksQ0FBQztRQUN2QyxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDMUMsWUFBTyxHQUFHLElBQUksWUFBWSxFQUFnQyxDQUFDO1FBRXJFLGVBQVUsR0FBRyxNQUFNLENBQWdCLElBQUksQ0FBQyxDQUFDO1FBQ3pDLFlBQU8sR0FBMkIsRUFBRSxDQUFDO0tBd0N0QztJQXRDQyxZQUFZLENBQUMsRUFBVTtRQUNyQixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELFFBQVEsQ0FBQyxFQUFVLEVBQUUsQ0FBUTtRQUMzQixDQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVELFNBQVMsQ0FBQyxFQUFVO1FBQ2xCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELGFBQWEsQ0FBQyxJQUFZO1FBQ3hCLE1BQU0sS0FBSyxHQUEyQjtZQUNwQyxLQUFLLEVBQVEsSUFBSTtZQUNqQixRQUFRLEVBQUssTUFBTTtZQUNuQixLQUFLLEVBQVEsSUFBSTtZQUNqQixNQUFNLEVBQU8sSUFBSTtZQUNqQixNQUFNLEVBQU8sSUFBSTtZQUNqQixVQUFVLEVBQUcsSUFBSTtZQUNqQixRQUFRLEVBQUssSUFBSTtZQUNqQixNQUFNLEVBQU8sSUFBSTtZQUNqQixLQUFLLEVBQVEsS0FBSztZQUNsQixTQUFTLEVBQUksR0FBRztZQUNoQixVQUFVLEVBQUcsSUFBSTtTQUNsQixDQUFDO1FBQ0YsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDO0lBQzVCLENBQUM7SUFFRCxVQUFVLENBQUMsRUFBVTtRQUNuQixPQUFPLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztJQUM3RyxDQUFDO0lBRUQsY0FBYyxDQUFDLEtBQWEsRUFBRSxHQUFXO1FBQ3ZDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDM0MsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBQyxFQUFFLEdBQUcsQ0FBQztJQUM1RCxDQUFDOytHQTdDVSxtQkFBbUI7bUdBQW5CLG1CQUFtQiwwS0F4T3BCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdGVCxvakZBakZTLFlBQVksOEJBQUUsV0FBVzs7NEZBeU94QixtQkFBbUI7a0JBNU8vQixTQUFTOytCQUNFLGlCQUFpQixjQUNmLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxXQUFXLENBQUMsWUFDMUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0ZUOzhCQXlKUSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0ksWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxPQUFPO3NCQUFoQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUmVjb3JkZWRBY3Rpb24sIFJlY29yZGluZ1Nlc3Npb24gfSBmcm9tICcuLi9tb2RlbHMvcmVjb3JkZWQtYWN0aW9uLm1vZGVsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWFjdGlvbi1saXN0JyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tbGlzdFwiIGRhdGEtZGVidWctcGFuZWw+XG4gICAgICBAaWYgKCFzZXNzaW9uIHx8IHNlc3Npb24uYWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LXN0YXRlXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LWljb25cIj7wn46sPC9kaXY+XG4gICAgICAgICAgPHA+Tm9jaCBrZWluZSBBa3Rpb25lbiBhdWZnZXplaWNobmV0LjwvcD5cbiAgICAgICAgICA8cCBjbGFzcz1cImhpbnRcIj5TdGFydGUgZGllIEF1Zm5haG1lIHVuZCBpbnRlcmFnaWVyZSBtaXQgZGVyIEFwcC48L3A+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNob3J0Y3V0cy1oaW50XCI+XG4gICAgICAgICAgICA8a2JkPkN0cmwrU2hpZnQrRDwva2JkPiBQYW5lbCAmbmJzcDtcbiAgICAgICAgICAgIDxrYmQ+Q3RybCtTaGlmdCtSPC9rYmQ+IFJlY29yZFxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8ZGl2IGNsYXNzPVwibGlzdC1oZWFkZXJcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImxpc3QtY291bnRcIj57eyBzZXNzaW9uLmFjdGlvbnMubGVuZ3RoIH19IEFrdGlvbmVuPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGlzdC1kdXJhdGlvblwiPlxuICAgICAgICAgICAgQGlmIChzZXNzaW9uLmVuZFRpbWUpIHtcbiAgICAgICAgICAgICAge3sgZm9ybWF0RHVyYXRpb24oc2Vzc2lvbi5zdGFydFRpbWUsIHNlc3Npb24uZW5kVGltZSkgfX1cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICBMaXZlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICBAZm9yIChhY3Rpb24gb2Ygc2Vzc2lvbi5hY3Rpb25zOyB0cmFjayBhY3Rpb24uaWQ7IGxldCBpID0gJGluZGV4KSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1pdGVtXCIgW2NsYXNzLmV4cGFuZGVkXT1cImV4cGFuZGVkSWQoKSA9PT0gYWN0aW9uLmlkXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLXJvd1wiIChjbGljayk9XCJ0b2dnbGVFeHBhbmQoYWN0aW9uLmlkKVwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFjdGlvbi1pbmRleFwiPnt7IGkgKyAxIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFjdGlvbi10eXBlLWJhZGdlXCIgW2NsYXNzXT1cIid0eXBlLScgKyBhY3Rpb24udHlwZVwiPlxuICAgICAgICAgICAgICAgIHt7IGdldEFjdGlvbkljb24oYWN0aW9uLnR5cGUpIH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1pbmZvXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhY3Rpb24tZGVzY1wiPnt7IGFjdGlvbi5kZXNjcmlwdGlvbiB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFjdGlvbi1zZWxlY3RvclwiPnt7IGFjdGlvbi5zZWxlY3RvciB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWN0aW9uLXRpbWVcIj57eyBmb3JtYXRUaW1lKGFjdGlvbi50aW1lc3RhbXApIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJyZW1vdmUtYnRuXCJcbiAgICAgICAgICAgICAgICBkYXRhLWRlYnVnLXBhbmVsXG4gICAgICAgICAgICAgICAgdGl0bGU9XCJBa3Rpb24gZW50ZmVybmVuXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwib25SZW1vdmUoYWN0aW9uLmlkLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgPuKclTwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIEBpZiAoZXhwYW5kZWRJZCgpID09PSBhY3Rpb24uaWQpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1kZXRhaWxcIiBkYXRhLWRlYnVnLXBhbmVsPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtZ3JpZFwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5TZWxlY3Rvcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgYWN0aW9uLnNlbGVjdG9yIH19PC9jb2RlPlxuICAgICAgICAgICAgICAgICAgQGlmIChhY3Rpb24udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5XZXJ0PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IGFjdGlvbi52YWx1ZSB9fTwvY29kZT5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIEBpZiAoYWN0aW9uLmVsZW1lbnQ/LnRhZ05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5FbGVtZW50PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImRldGFpbC12YWx1ZVwiPiZsdDt7eyBhY3Rpb24uZWxlbWVudD8udGFnTmFtZSB9fSZndDs8L2NvZGU+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPlN0cmF0ZWdpZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlIHN0cmF0ZWd5LWJhZGdlXCIgW2NsYXNzXT1cIidzdHJhdC0nICsgYWN0aW9uLnNlbGVjdG9yU3RyYXRlZ3lcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgYWN0aW9uLnNlbGVjdG9yU3RyYXRlZ3kgfX1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+VVJMPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJkZXRhaWwtdmFsdWUgdXJsLXZhbFwiPnt7IGFjdGlvbi51cmwgfX08L2NvZGU+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5vdGUtYXJlYVwiPlxuICAgICAgICAgICAgICAgICAgPHRleHRhcmVhXG4gICAgICAgICAgICAgICAgICAgIGRhdGEtZGVidWctcGFuZWxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJub3RlLWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJub3RlTWFwW2FjdGlvbi5pZF1cIlxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIk5vdGl6IHp1IGRpZXNlciBBa3Rpb24uLi5cIlxuICAgICAgICAgICAgICAgICAgICByb3dzPVwiMlwiXG4gICAgICAgICAgICAgICAgICAgIChibHVyKT1cIm9uQWRkTm90ZShhY3Rpb24uaWQpXCJcbiAgICAgICAgICAgICAgICAgID48L3RleHRhcmVhPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgLmFjdGlvbi1saXN0IHsgcGFkZGluZzogMDsgfVxuXG4gICAgLmVtcHR5LXN0YXRlIHtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICAgIHBhZGRpbmc6IDMycHggMjBweDtcbiAgICAgIGNvbG9yOiAjNjQ3NDhiO1xuICAgIH1cbiAgICAuZW1wdHktaWNvbiB7IGZvbnQtc2l6ZTogNDBweDsgbWFyZ2luLWJvdHRvbTogMTBweDsgfVxuICAgIC5lbXB0eS1zdGF0ZSBwIHsgbWFyZ2luOiA0cHggMDsgZm9udC1zaXplOiAxM3B4OyB9XG4gICAgLmhpbnQgeyBmb250LXNpemU6IDExcHg7IGNvbG9yOiAjNDc1NTY5OyB9XG4gICAgLnNob3J0Y3V0cy1oaW50IHtcbiAgICAgIG1hcmdpbi10b3A6IDEycHg7XG4gICAgICBmb250LXNpemU6IDExcHg7XG4gICAgICBjb2xvcjogIzQ3NTU2OTtcbiAgICB9XG4gICAga2JkIHtcbiAgICAgIGJhY2tncm91bmQ6ICMxZTI5M2I7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAjMzM0MTU1O1xuICAgICAgY29sb3I6ICM5NGEzYjg7XG4gICAgICBwYWRkaW5nOiAycHggNnB4O1xuICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgZm9udC1zaXplOiAxMHB4O1xuICAgIH1cblxuICAgIC5saXN0LWhlYWRlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgcGFkZGluZzogOHB4IDE0cHg7XG4gICAgICBmb250LXNpemU6IDExcHg7XG4gICAgICBjb2xvcjogIzY0NzQ4YjtcbiAgICAgIGJhY2tncm91bmQ6ICMwZjE3MmE7XG4gICAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgIzFlMjkzYjtcbiAgICAgIHBvc2l0aW9uOiBzdGlja3k7XG4gICAgICB0b3A6IDA7XG4gICAgfVxuXG4gICAgLmFjdGlvbi1pdGVtIHtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjMWUyOTNiO1xuICAgICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAwLjFzO1xuICAgIH1cbiAgICAuYWN0aW9uLWl0ZW06aG92ZXIgeyBiYWNrZ3JvdW5kOiByZ2JhKDMwLDQxLDU5LDAuNSk7IH1cbiAgICAuYWN0aW9uLWl0ZW0uZXhwYW5kZWQgeyBiYWNrZ3JvdW5kOiAjMWUyOTNiOyB9XG5cbiAgICAuYWN0aW9uLXJvdyB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIHBhZGRpbmc6IDhweCAxMHB4O1xuICAgICAgZ2FwOiA4cHg7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgfVxuICAgIC5hY3Rpb24taW5kZXgge1xuICAgICAgY29sb3I6ICM0NzU1Njk7XG4gICAgICBmb250LXNpemU6IDEwcHg7XG4gICAgICBtaW4td2lkdGg6IDE4cHg7XG4gICAgICB0ZXh0LWFsaWduOiByaWdodDtcbiAgICB9XG4gICAgLmFjdGlvbi10eXBlLWJhZGdlIHtcbiAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgIG1pbi13aWR0aDogMjBweDtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB9XG4gICAgLmFjdGlvbi1pbmZvIHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBtaW4td2lkdGg6IDA7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGdhcDogMXB4O1xuICAgIH1cbiAgICAuYWN0aW9uLWRlc2Mge1xuICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgY29sb3I6ICNjYmQ1ZTE7XG4gICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIH1cbiAgICAuYWN0aW9uLXNlbGVjdG9yIHtcbiAgICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICAgIGNvbG9yOiAjNjQ3NDhiO1xuICAgICAgZm9udC1mYW1pbHk6ICdDYXNjYWRpYSBDb2RlJywgJ0NvbnNvbGFzJywgbW9ub3NwYWNlO1xuICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgICB9XG4gICAgLmFjdGlvbi10aW1lIHtcbiAgICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICAgIGNvbG9yOiAjNDc1NTY5O1xuICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICB9XG4gICAgLnJlbW92ZS1idG4ge1xuICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgIGNvbG9yOiAjNDc1NTY5O1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgcGFkZGluZzogMnB4IDVweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgICAgIG9wYWNpdHk6IDA7XG4gICAgICB0cmFuc2l0aW9uOiBvcGFjaXR5IDAuMTVzLCBjb2xvciAwLjE1cztcbiAgICB9XG4gICAgLmFjdGlvbi1yb3c6aG92ZXIgLnJlbW92ZS1idG4geyBvcGFjaXR5OiAxOyB9XG4gICAgLnJlbW92ZS1idG46aG92ZXIgeyBjb2xvcjogI2Y4NzE3MTsgfVxuXG4gICAgLmFjdGlvbi1kZXRhaWwge1xuICAgICAgcGFkZGluZzogMTBweCAxNHB4O1xuICAgICAgYmFja2dyb3VuZDogcmdiYSgxNSwyMyw0MiwwLjcpO1xuICAgICAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICMxZTI5M2I7XG4gICAgfVxuICAgIC5kZXRhaWwtZ3JpZCB7XG4gICAgICBkaXNwbGF5OiBncmlkO1xuICAgICAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiBhdXRvIDFmcjtcbiAgICAgIGdhcDogNHB4IDEwcHg7XG4gICAgICBtYXJnaW4tYm90dG9tOiA4cHg7XG4gICAgICBhbGlnbi1pdGVtczogc3RhcnQ7XG4gICAgfVxuICAgIC5kZXRhaWwtbGFiZWwgeyBmb250LXNpemU6IDEwcHg7IGNvbG9yOiAjNjQ3NDhiOyBwYWRkaW5nLXRvcDogMnB4OyB3aGl0ZS1zcGFjZTogbm93cmFwOyB9XG4gICAgLmRldGFpbC12YWx1ZSB7XG4gICAgICBmb250LXNpemU6IDExcHg7XG4gICAgICBjb2xvcjogIzkzYzVmZDtcbiAgICAgIGZvbnQtZmFtaWx5OiAnQ2FzY2FkaWEgQ29kZScsICdDb25zb2xhcycsIG1vbm9zcGFjZTtcbiAgICAgIHdvcmQtYnJlYWs6IGJyZWFrLWFsbDtcbiAgICB9XG4gICAgLnVybC12YWwgeyBjb2xvcjogIzZlZTdiNzsgfVxuICAgIC5zdHJhdGVneS1iYWRnZSB7XG4gICAgICBmb250LXNpemU6IDEwcHg7XG4gICAgICBwYWRkaW5nOiAxcHggNnB4O1xuICAgICAgYm9yZGVyLXJhZGl1czogM3B4O1xuICAgICAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTtcbiAgICB9XG4gICAgLnN0cmF0LWRhdGEtdGVzdGlkIHsgYmFja2dyb3VuZDogIzA2NGUzYjsgY29sb3I6ICMzNGQzOTk7IH1cbiAgICAuc3RyYXQtZGF0YS1jeSAgICAgeyBiYWNrZ3JvdW5kOiAjMDY0ZTNiOyBjb2xvcjogIzM0ZDM5OTsgfVxuICAgIC5zdHJhdC1pZCAgICAgICAgICB7IGJhY2tncm91bmQ6ICMxZTNhOGE7IGNvbG9yOiAjOTNjNWZkOyB9XG4gICAgLnN0cmF0LW5hbWUgICAgICAgIHsgYmFja2dyb3VuZDogIzQ0MzM3YTsgY29sb3I6ICNjNGI1ZmQ7IH1cbiAgICAuc3RyYXQtY2xhc3MgICAgICAgeyBiYWNrZ3JvdW5kOiAjMzc0MTUxOyBjb2xvcjogIzljYTNhZjsgfVxuICAgIC5zdHJhdC1jb21iaW5lZCAgICB7IGJhY2tncm91bmQ6ICMyOTI1MjQ7IGNvbG9yOiAjZDZkM2QxOyB9XG5cbiAgICAubm90ZS1hcmVhIHsgbWFyZ2luLXRvcDogNnB4OyB9XG4gICAgLm5vdGUtaW5wdXQge1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgYmFja2dyb3VuZDogIzBmMTcyYTtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICMzMzQxNTU7XG4gICAgICBjb2xvcjogI2UyZThmMDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDVweDtcbiAgICAgIHBhZGRpbmc6IDZweCA4cHg7XG4gICAgICBmb250LXNpemU6IDExcHg7XG4gICAgICByZXNpemU6IHZlcnRpY2FsO1xuICAgIH1cbiAgICAubm90ZS1pbnB1dDpmb2N1cyB7IG91dGxpbmU6IG5vbmU7IGJvcmRlci1jb2xvcjogIzNiODJmNjsgfVxuICBgXSxcbn0pXG5leHBvcnQgY2xhc3MgQWN0aW9uTGlzdENvbXBvbmVudCB7XG4gIEBJbnB1dCgpIHNlc3Npb246IFJlY29yZGluZ1Nlc3Npb24gfCBudWxsID0gbnVsbDtcbiAgQE91dHB1dCgpIHJlbW92ZUFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICBAT3V0cHV0KCkgYWRkTm90ZSA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpZDogc3RyaW5nOyBub3RlOiBzdHJpbmcgfT4oKTtcblxuICBleHBhbmRlZElkID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICBub3RlTWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgdG9nZ2xlRXhwYW5kKGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmV4cGFuZGVkSWQudXBkYXRlKHYgPT4gdiA9PT0gaWQgPyBudWxsIDogaWQpO1xuICB9XG5cbiAgb25SZW1vdmUoaWQ6IHN0cmluZywgZTogRXZlbnQpOiB2b2lkIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMucmVtb3ZlQWN0aW9uLmVtaXQoaWQpO1xuICB9XG5cbiAgb25BZGROb3RlKGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmFkZE5vdGUuZW1pdCh7IGlkLCBub3RlOiB0aGlzLm5vdGVNYXBbaWRdID8/ICcnIH0pO1xuICB9XG5cbiAgZ2V0QWN0aW9uSWNvbih0eXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGljb25zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgY2xpY2s6ICAgICAgICfwn5GGJyxcbiAgICAgIGRibGNsaWNrOiAgICAn8J+RhvCfkYYnLFxuICAgICAgaW5wdXQ6ICAgICAgICfijKjvuI8nLFxuICAgICAgc2VsZWN0OiAgICAgICfwn5OLJyxcbiAgICAgIHN1Ym1pdDogICAgICAn8J+TpCcsXG4gICAgICBuYXZpZ2F0aW9uOiAgJ/CflJcnLFxuICAgICAga2V5cHJlc3M6ICAgICfijKjvuI8nLFxuICAgICAgc2Nyb2xsOiAgICAgICfihpXvuI8nLFxuICAgICAgaG92ZXI6ICAgICAgICfwn5ax77iPJyxcbiAgICAgIGFzc2VydGlvbjogICAn4pyFJyxcbiAgICAgIHNjcmVlbnNob3Q6ICAn8J+TuCcsXG4gICAgfTtcbiAgICByZXR1cm4gaWNvbnNbdHlwZV0gPz8gJ+KAoic7XG4gIH1cblxuICBmb3JtYXRUaW1lKHRzOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBuZXcgRGF0ZSh0cykudG9Mb2NhbGVUaW1lU3RyaW5nKCdkZS1ERScsIHsgaG91cjogJzItZGlnaXQnLCBtaW51dGU6ICcyLWRpZ2l0Jywgc2Vjb25kOiAnMi1kaWdpdCcgfSk7XG4gIH1cblxuICBmb3JtYXREdXJhdGlvbihzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgcyA9IE1hdGgucm91bmQoKGVuZCAtIHN0YXJ0KSAvIDEwMDApO1xuICAgIHJldHVybiBzIDwgNjAgPyBgJHtzfXNgIDogYCR7TWF0aC5mbG9vcihzLzYwKX1tICR7cyU2MH1zYDtcbiAgfVxufVxuIl19