@myrmidon/gve-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/esm2022/lib/components/animation-timeline/animation-timeline.component.mjs +176 -0
- package/esm2022/lib/components/animation-tween/animation-tween.component.mjs +161 -0
- package/esm2022/lib/components/animation-vars/animation-vars.component.mjs +141 -0
- package/esm2022/lib/components/base-text-char/base-text-char.component.mjs +37 -0
- package/esm2022/lib/components/base-text-editor/base-text-editor.component.mjs +111 -0
- package/esm2022/lib/components/base-text-view/base-text-view.component.mjs +125 -0
- package/esm2022/lib/components/chain-operation-editor/chain-operation-editor.component.mjs +512 -0
- package/esm2022/lib/components/chain-result-view/chain-result-view.component.mjs +190 -0
- package/esm2022/lib/components/feature-editor/feature-editor.component.mjs +185 -0
- package/esm2022/lib/components/feature-set-editor/feature-set-editor.component.mjs +152 -0
- package/esm2022/lib/components/feature-set-view/feature-set-view.component.mjs +80 -0
- package/esm2022/lib/components/ln-heights-editor/ln-heights-editor.component.mjs +95 -0
- package/esm2022/lib/components/operation-source-editor/operation-source-editor.component.mjs +106 -0
- package/esm2022/lib/components/simple-tree/simple-tree.component.mjs +56 -0
- package/esm2022/lib/components/snapshot-editor/snapshot-editor.component.mjs +510 -0
- package/esm2022/lib/components/steps-map/steps-map.component.mjs +55 -0
- package/esm2022/lib/models.mjs +2 -0
- package/esm2022/lib/services/gve-api.service.mjs +52 -0
- package/esm2022/lib/services/settings.service.mjs +86 -0
- package/esm2022/lib/validators/svg-validators.mjs +28 -0
- package/esm2022/myrmidon-gve-core.mjs +5 -0
- package/esm2022/public-api.mjs +23 -0
- package/fesm2022/myrmidon-gve-core.mjs +2592 -0
- package/fesm2022/myrmidon-gve-core.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/components/animation-timeline/animation-timeline.component.d.ts +42 -0
- package/lib/components/animation-tween/animation-tween.component.d.ts +47 -0
- package/lib/components/animation-vars/animation-vars.component.d.ts +30 -0
- package/lib/components/base-text-char/base-text-char.component.d.ts +29 -0
- package/lib/components/base-text-editor/base-text-editor.component.d.ts +40 -0
- package/lib/components/base-text-view/base-text-view.component.d.ts +29 -0
- package/lib/components/chain-operation-editor/chain-operation-editor.component.d.ts +102 -0
- package/lib/components/chain-result-view/chain-result-view.component.d.ts +44 -0
- package/lib/components/feature-editor/feature-editor.component.d.ts +72 -0
- package/lib/components/feature-set-editor/feature-set-editor.component.d.ts +55 -0
- package/lib/components/feature-set-view/feature-set-view.component.d.ts +36 -0
- package/lib/components/ln-heights-editor/ln-heights-editor.component.d.ts +22 -0
- package/lib/components/operation-source-editor/operation-source-editor.component.d.ts +24 -0
- package/lib/components/simple-tree/simple-tree.component.d.ts +16 -0
- package/lib/components/snapshot-editor/snapshot-editor.component.d.ts +105 -0
- package/lib/components/steps-map/steps-map.component.d.ts +29 -0
- package/lib/models.d.ts +7 -0
- package/lib/services/gve-api.service.d.ts +57 -0
- package/lib/services/settings.service.d.ts +53 -0
- package/lib/validators/svg-validators.d.ts +4 -0
- package/package.json +45 -0
- package/public-api.d.ts +19 -0
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
import { CUSTOM_ELEMENTS_SCHEMA, Component, EventEmitter, Input, Output, } from '@angular/core';
|
|
2
|
+
import { FormControl, FormsModule, ReactiveFormsModule, Validators, } from '@angular/forms';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
5
|
+
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
6
|
+
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
7
|
+
import { MatExpansionModule } from '@angular/material/expansion';
|
|
8
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
9
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
10
|
+
import { MatInputModule } from '@angular/material/input';
|
|
11
|
+
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
12
|
+
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
13
|
+
import { MatTabsModule } from '@angular/material/tabs';
|
|
14
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
15
|
+
import { NgToolsModule, deepCopy } from '@myrmidon/ng-tools';
|
|
16
|
+
import { DEFAULT_SVG_BASE_TEXT_OPTIONS, } from '@myrmidon/gve-snapshot-view';
|
|
17
|
+
import { BaseTextViewComponent, } from '../base-text-view/base-text-view.component';
|
|
18
|
+
import { ChainOperationEditorComponent } from '../chain-operation-editor/chain-operation-editor.component';
|
|
19
|
+
import { ChainResultViewComponent } from '../chain-result-view/chain-result-view.component';
|
|
20
|
+
import { LnHeightsEditorComponent } from '../ln-heights-editor/ln-heights-editor.component';
|
|
21
|
+
import { BaseTextEditorComponent } from '../base-text-editor/base-text-editor.component';
|
|
22
|
+
import * as i0 from "@angular/core";
|
|
23
|
+
import * as i1 from "@angular/forms";
|
|
24
|
+
import * as i2 from "../../services/gve-api.service";
|
|
25
|
+
import * as i3 from "@myrmidon/ng-mat-tools";
|
|
26
|
+
import * as i4 from "@angular/material/snack-bar";
|
|
27
|
+
import * as i5 from "@angular/common";
|
|
28
|
+
import * as i6 from "@angular/material/button";
|
|
29
|
+
import * as i7 from "@angular/material/button-toggle";
|
|
30
|
+
import * as i8 from "@angular/material/expansion";
|
|
31
|
+
import * as i9 from "@angular/material/form-field";
|
|
32
|
+
import * as i10 from "@angular/material/icon";
|
|
33
|
+
import * as i11 from "@angular/material/input";
|
|
34
|
+
import * as i12 from "@angular/material/progress-bar";
|
|
35
|
+
import * as i13 from "@angular/material/tabs";
|
|
36
|
+
import * as i14 from "@angular/material/tooltip";
|
|
37
|
+
import * as i15 from "@myrmidon/ng-tools";
|
|
38
|
+
const VIEW_TITLE = 'preview';
|
|
39
|
+
/**
|
|
40
|
+
* A component to edit a text snapshot.
|
|
41
|
+
*/
|
|
42
|
+
export class SnapshotEditorComponent {
|
|
43
|
+
/**
|
|
44
|
+
* The snapshot to edit.
|
|
45
|
+
*/
|
|
46
|
+
get snapshot() {
|
|
47
|
+
return this._snapshot;
|
|
48
|
+
}
|
|
49
|
+
set snapshot(value) {
|
|
50
|
+
if (this._snapshot === value) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
this._snapshot = value || undefined;
|
|
54
|
+
this.updateForm(this._snapshot);
|
|
55
|
+
this.updateViewData();
|
|
56
|
+
}
|
|
57
|
+
constructor(formBuilder, _api, _dialogService, _snackbar) {
|
|
58
|
+
this._api = _api;
|
|
59
|
+
this._dialogService = _dialogService;
|
|
60
|
+
this._snackbar = _snackbar;
|
|
61
|
+
/**
|
|
62
|
+
* Emitted when the user saves the edited snapshot.
|
|
63
|
+
*/
|
|
64
|
+
this.snapshotChange = new EventEmitter();
|
|
65
|
+
/**
|
|
66
|
+
* Emitted when the user cancels the snapshot editing.
|
|
67
|
+
*/
|
|
68
|
+
this.snapshotCancel = new EventEmitter();
|
|
69
|
+
this.editedOpIndex = -1;
|
|
70
|
+
this.opTypeMap = {
|
|
71
|
+
0: 'replace',
|
|
72
|
+
1: 'delete',
|
|
73
|
+
2: 'addBefore',
|
|
74
|
+
3: 'addAfter',
|
|
75
|
+
4: 'moveBefore',
|
|
76
|
+
5: 'moveAfter',
|
|
77
|
+
6: 'swap',
|
|
78
|
+
7: 'annotate',
|
|
79
|
+
};
|
|
80
|
+
this.lineCount = 0;
|
|
81
|
+
this.viewTitle = VIEW_TITLE;
|
|
82
|
+
this.rulers = true;
|
|
83
|
+
// general
|
|
84
|
+
this.width = new FormControl(800, { nonNullable: true });
|
|
85
|
+
this.height = new FormControl(600, { nonNullable: true });
|
|
86
|
+
this.style = new FormControl(null);
|
|
87
|
+
// base text
|
|
88
|
+
this.baseText = new FormControl([], {
|
|
89
|
+
nonNullable: true,
|
|
90
|
+
validators: [Validators.required],
|
|
91
|
+
});
|
|
92
|
+
this.offsetX = new FormControl(0, { nonNullable: true });
|
|
93
|
+
this.offsetY = new FormControl(0, { nonNullable: true });
|
|
94
|
+
this.lineHeightOffset = new FormControl(DEFAULT_SVG_BASE_TEXT_OPTIONS.lineHeightOffset, { nonNullable: true });
|
|
95
|
+
this.lnHeights = new FormControl(null);
|
|
96
|
+
this.charSpacingOffset = new FormControl(0, { nonNullable: true });
|
|
97
|
+
this.spcWidthOffset = new FormControl(0, { nonNullable: true });
|
|
98
|
+
this.textStyle = new FormControl(null);
|
|
99
|
+
// operations
|
|
100
|
+
this.operations = new FormControl([], {
|
|
101
|
+
nonNullable: true,
|
|
102
|
+
});
|
|
103
|
+
this.inputOps = new FormControl(null);
|
|
104
|
+
this.opStyle = new FormControl(null);
|
|
105
|
+
// image
|
|
106
|
+
this.imageUrl = new FormControl(null);
|
|
107
|
+
this.imageOpacity = new FormControl(1, { nonNullable: true });
|
|
108
|
+
this.imageX = new FormControl(0, { nonNullable: true });
|
|
109
|
+
this.imageY = new FormControl(0, { nonNullable: true });
|
|
110
|
+
this.imageWidth = new FormControl(0, { nonNullable: true });
|
|
111
|
+
this.imageHeight = new FormControl(0, { nonNullable: true });
|
|
112
|
+
this.defs = new FormControl(null);
|
|
113
|
+
this.form = formBuilder.group({
|
|
114
|
+
width: this.width,
|
|
115
|
+
height: this.height,
|
|
116
|
+
style: this.style,
|
|
117
|
+
baseText: this.baseText,
|
|
118
|
+
offsetX: this.offsetX,
|
|
119
|
+
offsetY: this.offsetY,
|
|
120
|
+
lineHeightOffset: this.lineHeightOffset,
|
|
121
|
+
lnHeights: this.lnHeights,
|
|
122
|
+
charSpacingOffset: this.charSpacingOffset,
|
|
123
|
+
spcWidthOffset: this.spcWidthOffset,
|
|
124
|
+
textStyle: this.textStyle,
|
|
125
|
+
operations: this.operations,
|
|
126
|
+
inputOps: this.inputOps,
|
|
127
|
+
opStyle: this.opStyle,
|
|
128
|
+
// image
|
|
129
|
+
imageUrl: this.imageUrl,
|
|
130
|
+
imageOpacity: this.imageOpacity,
|
|
131
|
+
imageX: this.imageX,
|
|
132
|
+
imageY: this.imageY,
|
|
133
|
+
imageWidth: this.imageWidth,
|
|
134
|
+
imageHeight: this.imageHeight,
|
|
135
|
+
defs: this.defs,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
ngOnInit() {
|
|
139
|
+
if (this.batchOps) {
|
|
140
|
+
this.inputOps.setValue(this.batchOps);
|
|
141
|
+
this.parseOperations();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
updateViewData(newOperation, snapshot, title = VIEW_TITLE) {
|
|
145
|
+
if (!snapshot) {
|
|
146
|
+
snapshot = this.getSnapshot();
|
|
147
|
+
}
|
|
148
|
+
// update or add new operation in copy
|
|
149
|
+
if (newOperation) {
|
|
150
|
+
const index = snapshot.operations.findIndex((op) => op.id === newOperation.id);
|
|
151
|
+
if (index > -1) {
|
|
152
|
+
snapshot.operations.splice(index, 1, newOperation);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
snapshot.operations.push(newOperation);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// update view data
|
|
159
|
+
this.viewTitle = title;
|
|
160
|
+
this.visualInfo = undefined;
|
|
161
|
+
this.viewData = {
|
|
162
|
+
snapshot: snapshot,
|
|
163
|
+
options: {
|
|
164
|
+
// debug: true,
|
|
165
|
+
delayedRender: true,
|
|
166
|
+
showRulers: true,
|
|
167
|
+
showGrid: true,
|
|
168
|
+
panZoom: true,
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
updateForm(snapshot) {
|
|
173
|
+
if (!snapshot) {
|
|
174
|
+
this.form.reset();
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
this.width.setValue(snapshot.size.width);
|
|
178
|
+
this.height.setValue(snapshot.size.height);
|
|
179
|
+
this.style.setValue(snapshot.style || null);
|
|
180
|
+
this.imageUrl.setValue(snapshot.image?.url || null);
|
|
181
|
+
this.imageOpacity.setValue(snapshot.image?.opacity || 0);
|
|
182
|
+
this.imageX.setValue(snapshot.image?.canvas?.x || 0);
|
|
183
|
+
this.imageY.setValue(snapshot.image?.canvas?.y || 0);
|
|
184
|
+
this.imageWidth.setValue(snapshot.image?.canvas?.width || 0);
|
|
185
|
+
this.imageHeight.setValue(snapshot.image?.canvas?.height || 0);
|
|
186
|
+
this.defs.setValue(snapshot.defs || null);
|
|
187
|
+
this.baseText.setValue(snapshot.text);
|
|
188
|
+
this.offsetX.setValue(snapshot.textOptions?.offset?.x || 0);
|
|
189
|
+
this.offsetY.setValue(snapshot.textOptions?.offset?.y || 0);
|
|
190
|
+
this.lineHeightOffset.setValue(snapshot.textOptions?.lineHeightOffset);
|
|
191
|
+
this.lnHeights.setValue(snapshot.textOptions?.minLineHeights || null);
|
|
192
|
+
this.charSpacingOffset.setValue(snapshot.textOptions?.charSpacingOffset);
|
|
193
|
+
this.spcWidthOffset.setValue(snapshot.textOptions?.spcWidthOffset);
|
|
194
|
+
this.textStyle.setValue(snapshot.textStyle || null);
|
|
195
|
+
this.operations.setValue(snapshot.operations);
|
|
196
|
+
this.inputOps.reset();
|
|
197
|
+
this.opStyle.setValue(snapshot.opStyle || null);
|
|
198
|
+
}
|
|
199
|
+
this.form.markAsPristine();
|
|
200
|
+
}
|
|
201
|
+
editNewOperation() {
|
|
202
|
+
this.editedOp = {
|
|
203
|
+
id: '',
|
|
204
|
+
type: 0,
|
|
205
|
+
at: this.textRange?.at || 0,
|
|
206
|
+
run: this.textRange?.run || 1,
|
|
207
|
+
};
|
|
208
|
+
this.editedOpIndex = -1;
|
|
209
|
+
}
|
|
210
|
+
editOperation(index) {
|
|
211
|
+
this.editedOp = this.operations.value[index];
|
|
212
|
+
this.editedOpIndex = index;
|
|
213
|
+
}
|
|
214
|
+
closeEditedOp() {
|
|
215
|
+
this.editedOp = undefined;
|
|
216
|
+
this.editedOpIndex = -1;
|
|
217
|
+
}
|
|
218
|
+
onOperationCancel() {
|
|
219
|
+
this.closeEditedOp();
|
|
220
|
+
}
|
|
221
|
+
onOperationChange(op) {
|
|
222
|
+
const operations = [...this.operations.value];
|
|
223
|
+
if (this.editedOpIndex > -1) {
|
|
224
|
+
operations.splice(this.editedOpIndex, 1, op);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
operations.push(op);
|
|
228
|
+
}
|
|
229
|
+
this.operations.setValue(operations);
|
|
230
|
+
this.operations.markAsDirty();
|
|
231
|
+
this.operations.updateValueAndValidity();
|
|
232
|
+
this.closeEditedOp();
|
|
233
|
+
}
|
|
234
|
+
deleteOperation(index) {
|
|
235
|
+
this._dialogService
|
|
236
|
+
.confirm('Confirm Deletion', `Delete operation "${this.operations.value[index].id}"?`)
|
|
237
|
+
.subscribe((yes) => {
|
|
238
|
+
if (yes) {
|
|
239
|
+
if (this.resultOperationId === this.operations.value[index].id) {
|
|
240
|
+
this.resultOperationId = undefined;
|
|
241
|
+
}
|
|
242
|
+
const operations = [...this.operations.value];
|
|
243
|
+
operations.splice(index, 1);
|
|
244
|
+
this.operations.setValue(operations);
|
|
245
|
+
this.operations.markAsDirty();
|
|
246
|
+
this.operations.updateValueAndValidity();
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
onTextChange(text) {
|
|
251
|
+
this.baseText.setValue(text);
|
|
252
|
+
this.baseText.updateValueAndValidity();
|
|
253
|
+
this.baseText.markAsDirty();
|
|
254
|
+
if (!text.length) {
|
|
255
|
+
this.lineCount = 0;
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
this.lineCount = text.filter((c) => c.data === '\n').length + 1;
|
|
259
|
+
}
|
|
260
|
+
this.textRange = undefined;
|
|
261
|
+
this.closeEditedOp();
|
|
262
|
+
this.operations.reset();
|
|
263
|
+
this.updateViewData();
|
|
264
|
+
}
|
|
265
|
+
onRangePick(range) {
|
|
266
|
+
this.textRange = range;
|
|
267
|
+
}
|
|
268
|
+
parseOperations() {
|
|
269
|
+
if (this.busy || !this.inputOps.value) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
this._dialogService
|
|
273
|
+
.confirm('Confirm', 'Parse operations?')
|
|
274
|
+
.subscribe((yes) => {
|
|
275
|
+
if (yes) {
|
|
276
|
+
this.busy = true;
|
|
277
|
+
this.parseError = undefined;
|
|
278
|
+
this._api.parseOperations(this.inputOps.value).subscribe({
|
|
279
|
+
next: (wrapper) => {
|
|
280
|
+
const operations = [...this.operations.value];
|
|
281
|
+
operations.push(...wrapper.result);
|
|
282
|
+
this.operations.setValue(operations);
|
|
283
|
+
this.operations.markAsDirty();
|
|
284
|
+
this.operations.updateValueAndValidity();
|
|
285
|
+
this.updateViewData();
|
|
286
|
+
},
|
|
287
|
+
error: (error) => {
|
|
288
|
+
this.parseError = error.message;
|
|
289
|
+
},
|
|
290
|
+
complete: () => {
|
|
291
|
+
this.busy = false;
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
clearOperations() {
|
|
298
|
+
this._dialogService
|
|
299
|
+
.confirm('Confirm', 'Remove all operations?')
|
|
300
|
+
.subscribe((yes) => {
|
|
301
|
+
if (yes) {
|
|
302
|
+
this.resultOperationId = undefined;
|
|
303
|
+
this.operations.reset();
|
|
304
|
+
this.operations.markAsDirty();
|
|
305
|
+
this.operations.updateValueAndValidity();
|
|
306
|
+
this.updateViewData();
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
onOperationPreview(operation) {
|
|
311
|
+
this.updateViewData(operation);
|
|
312
|
+
}
|
|
313
|
+
runTo(index) {
|
|
314
|
+
const snapshot = this.getSnapshot();
|
|
315
|
+
if (!snapshot.text) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const operations = this.operations.value.slice(0, index + 1);
|
|
319
|
+
this.busy = true;
|
|
320
|
+
this._api.runOperations(snapshot.text, operations).subscribe({
|
|
321
|
+
next: (wrapper) => {
|
|
322
|
+
if (wrapper.error) {
|
|
323
|
+
this._snackbar.open(wrapper.error, 'OK');
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
this.result = wrapper.result;
|
|
327
|
+
// TODO update view
|
|
328
|
+
// this.updateViewData(
|
|
329
|
+
// undefined,
|
|
330
|
+
// snapshot,
|
|
331
|
+
// this.operations.value[index].outputTag
|
|
332
|
+
// );
|
|
333
|
+
},
|
|
334
|
+
error: (error) => {
|
|
335
|
+
console.error(error);
|
|
336
|
+
this._snackbar.open('Error running operations', 'OK');
|
|
337
|
+
},
|
|
338
|
+
complete: () => {
|
|
339
|
+
this.busy = false;
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
onStepPick(step) {
|
|
344
|
+
if (!this.result) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
this.resultOperationId = step.operation.id;
|
|
348
|
+
// get snapshot for preview by updating its text and
|
|
349
|
+
// removing operations past the last executed
|
|
350
|
+
const stepNodes = this.result.taggedNodes[step.outputTag];
|
|
351
|
+
// we always display the original base text, just updating
|
|
352
|
+
// its nodes features to those of the picked step, and adding
|
|
353
|
+
// new nodes if they are not in the original text. It is assumed
|
|
354
|
+
// that these new nodes have a manually set position.
|
|
355
|
+
const snapshot = this.getSnapshot();
|
|
356
|
+
const nodes = deepCopy(snapshot.text);
|
|
357
|
+
for (const sn of stepNodes) {
|
|
358
|
+
const i = nodes.findIndex((n) => n.id === sn.id);
|
|
359
|
+
if (i > -1) {
|
|
360
|
+
nodes[i].features = sn.features;
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
nodes.push(sn);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// find max ID in snapshot.text (=original) nodes,
|
|
367
|
+
// so that any ID greater than it belongs to new nodes
|
|
368
|
+
const maxOriginalId = snapshot.text.reduce((max, n) => Math.max(max, n.id), 0);
|
|
369
|
+
// append nodes introduced before the picked step if any
|
|
370
|
+
// (those introduced by the picked step have already been added)
|
|
371
|
+
const stepIndex = this.result.steps.indexOf(step);
|
|
372
|
+
for (let i = 0; i < stepIndex; i++) {
|
|
373
|
+
const stepNodes = this.result.taggedNodes[this.result.steps[i].outputTag];
|
|
374
|
+
for (const n of stepNodes) {
|
|
375
|
+
if (n.id > maxOriginalId && !nodes.find((x) => x.id === n.id)) {
|
|
376
|
+
nodes.push(n);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
snapshot.text = nodes;
|
|
381
|
+
const i = snapshot.operations.findIndex((o) => o.id === step.operation.id);
|
|
382
|
+
if (i > -1) {
|
|
383
|
+
snapshot.operations = snapshot.operations.slice(0, i + 1);
|
|
384
|
+
}
|
|
385
|
+
this.updateViewData(undefined, snapshot, step.outputTag);
|
|
386
|
+
}
|
|
387
|
+
onVisualEvent(event) {
|
|
388
|
+
const d = event.detail;
|
|
389
|
+
if (d.event.type === 'mouseover') {
|
|
390
|
+
const visual = d.source;
|
|
391
|
+
const sb = [];
|
|
392
|
+
sb.push('#' + visual.id);
|
|
393
|
+
sb.push(` (${visual.type})`);
|
|
394
|
+
if (visual.data?.label) {
|
|
395
|
+
sb.push(': ');
|
|
396
|
+
sb.push(visual.data.label);
|
|
397
|
+
}
|
|
398
|
+
if (visual.data?.features?.length) {
|
|
399
|
+
sb.push(visual.data.features
|
|
400
|
+
.map((f) => `${f.name}=${f.value}`)
|
|
401
|
+
.join('\n'));
|
|
402
|
+
}
|
|
403
|
+
this.visualInfo = sb.join('');
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
onHeightsChange(heights) {
|
|
407
|
+
this.lnHeights.setValue(heights || null);
|
|
408
|
+
this.lnHeights.markAsDirty();
|
|
409
|
+
this.lnHeights.updateValueAndValidity();
|
|
410
|
+
}
|
|
411
|
+
close() {
|
|
412
|
+
this.snapshotCancel.emit();
|
|
413
|
+
}
|
|
414
|
+
onSnapshotRender(event) {
|
|
415
|
+
this._renderer = event.detail.renderer;
|
|
416
|
+
}
|
|
417
|
+
toggleRulers() {
|
|
418
|
+
if (!this._renderer) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
this.rulers = this._renderer.toggleRulers();
|
|
422
|
+
}
|
|
423
|
+
getSnapshot() {
|
|
424
|
+
const snapshot = {
|
|
425
|
+
size: {
|
|
426
|
+
width: this.width.value,
|
|
427
|
+
height: this.height.value,
|
|
428
|
+
},
|
|
429
|
+
style: this.style.value || undefined,
|
|
430
|
+
defs: this.defs.value || undefined,
|
|
431
|
+
text: this.baseText.value,
|
|
432
|
+
textStyle: this.textStyle.value || undefined,
|
|
433
|
+
textOptions: {
|
|
434
|
+
lineHeightOffset: this.lineHeightOffset.value,
|
|
435
|
+
minLineHeights: this.lnHeights.value || undefined,
|
|
436
|
+
charSpacingOffset: this.charSpacingOffset.value,
|
|
437
|
+
spcWidthOffset: this.spcWidthOffset.value,
|
|
438
|
+
offset: {
|
|
439
|
+
x: this.offsetX.value,
|
|
440
|
+
y: this.offsetY.value,
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
operations: this.operations.value,
|
|
444
|
+
opStyle: this.opStyle.value || undefined,
|
|
445
|
+
timelines: {}, // TODO
|
|
446
|
+
};
|
|
447
|
+
// image
|
|
448
|
+
if (this.imageUrl.value) {
|
|
449
|
+
snapshot.image = {
|
|
450
|
+
url: this.imageUrl.value,
|
|
451
|
+
opacity: this.imageOpacity.value || undefined,
|
|
452
|
+
};
|
|
453
|
+
if (this.imageX.value ||
|
|
454
|
+
this.imageY.value ||
|
|
455
|
+
this.imageWidth.value ||
|
|
456
|
+
this.imageHeight.value) {
|
|
457
|
+
snapshot.image.canvas = {
|
|
458
|
+
x: this.imageX.value,
|
|
459
|
+
y: this.imageY.value,
|
|
460
|
+
width: this.imageWidth.value,
|
|
461
|
+
height: this.imageHeight.value,
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return snapshot;
|
|
466
|
+
}
|
|
467
|
+
save() {
|
|
468
|
+
if (this.form.invalid) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
this._snapshot = this.getSnapshot();
|
|
472
|
+
this.snapshotChange.emit(this._snapshot);
|
|
473
|
+
}
|
|
474
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: SnapshotEditorComponent, deps: [{ token: i1.FormBuilder }, { token: i2.GveApiService }, { token: i3.DialogService }, { token: i4.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
475
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.4", type: SnapshotEditorComponent, isStandalone: true, selector: "gve-snapshot-editor", inputs: { snapshot: "snapshot", batchOps: "batchOps" }, outputs: { snapshotChange: "snapshotChange", snapshotCancel: "snapshotCancel" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <mat-tab-group>\r\n <!-- text -->\r\n <mat-tab label=\"text\">\r\n <mat-expansion-panel [expanded]=\"!baseText.value\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title> base text </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <gve-base-text-editor\r\n [text]=\"baseText.value\"\r\n (textChange)=\"onTextChange($event)\"\r\n />\r\n <fieldset>\r\n <div class=\"form-row\">\r\n <!-- offsetX -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>X offset</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"offsetX\"\r\n placeholder=\"X offset\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- offsetY -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>Y offset</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"offsetY\"\r\n placeholder=\"Y offset\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- lineHeightOffset -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>ln h-offset</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"lineHeightOffset\"\r\n placeholder=\"ln h-offset\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- charSpacingOffset -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>char spacing</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"charSpacingOffset\"\r\n placeholder=\"char spacing\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- spcWidthOffset -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>spc w-offset</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"spcWidthOffset\"\r\n placeholder=\"spc w-offset\"\r\n />\r\n </mat-form-field>\r\n <!-- minLineHeights -->\r\n <div>\r\n <gve-ln-heights-editor\r\n [lineCount]=\"lineCount\"\r\n [heights]=\"lnHeights.value\"\r\n (heightsChange)=\"onHeightsChange($event)\"\r\n />\r\n </div>\r\n </div>\r\n <!-- textStyle -->\r\n <div>\r\n <mat-form-field class=\"long-text\" appearance=\"outline\">\r\n <mat-label>text style</mat-label>\r\n <textarea\r\n matInput\r\n [formControl]=\"textStyle\"\r\n placeholder=\"text style\"\r\n ></textarea>\r\n </mat-form-field>\r\n </div>\r\n </fieldset>\r\n </mat-expansion-panel>\r\n </mat-tab>\r\n\r\n <!-- operations -->\r\n <mat-tab label=\"operations\">\r\n <div id=\"snapshot-container\">\r\n <div id=\"general\">\r\n <div class=\"form-row\">\r\n <!-- width -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>width</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n min=\"0\"\r\n [formControl]=\"width\"\r\n placeholder=\"width\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- height -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>height</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n min=\"0\"\r\n [formControl]=\"height\"\r\n placeholder=\"height\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- add op -->\r\n <div>\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n [disabled]=\"!baseText.value\"\r\n (click)=\"editNewOperation()\"\r\n >\r\n <mat-icon>add_circle</mat-icon> operation\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ops -->\r\n <div id=\"ops\">\r\n <!-- operations list -->\r\n @if (operations.value.length) {\r\n <table id=\"list\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>ID</th>\r\n <th>type</th>\r\n <th>at</th>\r\n <th>run</th>\r\n <th>value</th>\r\n <th>itag</th>\r\n <th>otag</th>\r\n <th>gid</th>\r\n <th>feats</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (operation of operations.value; track operation.id; let\r\n index=$index) {\r\n <tr [ngClass]=\"{ selected: operation.id === resultOperationId }\">\r\n <td class=\"fit-width\">\r\n <!-- edit -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n (click)=\"editOperation(index)\"\r\n matTooltip=\"Edit operation\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <!-- delete -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"deleteOperation(index)\"\r\n matTooltip=\"Delete operation\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n <!-- run to -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"accent\"\r\n (click)=\"runTo(index)\"\r\n matTooltip=\"Run to this operation\"\r\n >\r\n <mat-icon class=\"mat-accent\">subscriptions</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ operation.id }}</td>\r\n <td>{{ operation.type | flatLookup : opTypeMap }}</td>\r\n <td>{{ operation.at }}</td>\r\n <td>{{ operation.run }}</td>\r\n <td>{{ operation.value }}</td>\r\n <td>{{ operation.inputTag }}</td>\r\n <td>{{ operation.outputTag }}</td>\r\n <td>{{ operation.groupId }}</td>\r\n <td>{{ operation.features?.length }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <!-- operation editor -->\r\n <mat-expansion-panel [expanded]=\"editedOp\" [disabled]=\"!editedOp\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>operation {{ editedOp?.id }}</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-chain-operation-editor\r\n [operation]=\"editedOp\"\r\n (operationCancel)=\"onOperationCancel()\"\r\n (operationChange)=\"onOperationChange($event)\"\r\n (operationPreview)=\"onOperationPreview($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n\r\n <div>\r\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"busy\" />\r\n </div>\r\n\r\n <!-- opStyle -->\r\n <div id=\"opStyle\">\r\n <mat-form-field class=\"long-text\" appearance=\"outline\">\r\n <mat-label>operations style</mat-label>\r\n <textarea\r\n matInput\r\n [formControl]=\"opStyle\"\r\n placeholder=\"operations style\"\r\n ></textarea>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- batch ops -->\r\n <div>\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>batch operations</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <div id=\"batch-container\">\r\n <div id=\"batch-input\">\r\n <div>\r\n <mat-form-field class=\"full-width\">\r\n <mat-label>operations</mat-label>\r\n <textarea\r\n class=\"code\"\r\n matInput\r\n [formControl]=\"inputOps\"\r\n placeholder=\"operations\"\r\n rows=\"8\"\r\n spellcheck=\"false\"\r\n ></textarea>\r\n </mat-form-field>\r\n </div>\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Remove all the operations\"\r\n [disabled]=\"!operations.value.length || busy\"\r\n (click)=\"clearOperations()\"\r\n >\r\n clear\r\n </button>\r\n <button\r\n type=\"button\"\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Parse text and add results to the operations\"\r\n [disabled]=\"!inputOps.value || busy\"\r\n (click)=\"parseOperations()\"\r\n >\r\n batch add\r\n </button>\r\n @if (parseError) {\r\n <span class=\"error\">{{ parseError }}</span>\r\n }\r\n </div>\r\n </div>\r\n <div id=\"batch-help\">\r\n <ul>\r\n <li>\r\n <strong>replace</strong>:\r\n <code>ATxRUN<strong>=</strong>\"VALUE\"</code>\r\n </li>\r\n <li>\r\n <strong>delete</strong>:\r\n <code>ATxRUN<strong>-</strong></code>\r\n </li>\r\n <li>\r\n <strong>add-before</strong>:\r\n <code>ATxRUN<strong>+[</strong>\"VALUE\"</code>\r\n </li>\r\n <li>\r\n <strong>add-after</strong>:\r\n <code>ATxRUN<strong>+]</strong>\"VALUE\"</code>\r\n </li>\r\n <li>\r\n <strong>move-before</strong>:\r\n <code>ATxRUN<strong>>[</strong>TO</code>\r\n </li>\r\n <li>\r\n <strong>move-after</strong>:\r\n <code>ATxRUN<strong>>]</strong>TO</code>\r\n </li>\r\n <li>\r\n <strong>swap</strong>:\r\n <code>ATxRUN<strong><></strong>TOxRUN</code>\r\n </li>\r\n <li>\r\n <strong>annotate</strong>:\r\n <code>ATxRUN<strong>:</strong></code>\r\n </li>\r\n </ul>\r\n <p>For all the operations:</p>\r\n <ul>\r\n <li>\r\n prefix <code>(ITAG:OTAG)</code> to define input and/or\r\n output tags, separated by colon.\r\n </li>\r\n <li>\r\n prepend <code>@</code> to AT to use character\r\n indexes (0-N) rather than IDs.\r\n </li>\r\n <li>RUN (where applicable) defaults to 1.</li>\r\n <li>\r\n append features like <code>[NAME OPERATOR VALUE]</code>,\r\n separated by space, where:\r\n </li>\r\n <ol>\r\n <li>\r\n NAME is an arbitrary string. Prefixes:\r\n <code>*</code>=global features, <code>!</code>=remove\r\n feature (no value). Suffixes:\r\n <code>^</code>=short-lived (like\r\n <code>*version^=alpha</code>).\r\n </li>\r\n <li>\r\n OPERATOR is <code>=</code> (multiple),\r\n <code>:=</code> (single),\r\n <code>==</code> (first-single).\r\n </li>\r\n <li>\r\n VALUE is a string. If it includes spaces, wrap it in\r\n <code>\"\"</code>.\r\n </li>\r\n </ol>\r\n </ul>\r\n </div>\r\n </div>\r\n </fieldset>\r\n </mat-expansion-panel>\r\n </div>\r\n </div>\r\n\r\n <!-- result -->\r\n @if (result) {\r\n <fieldset id=\"result\">\r\n <legend>result</legend>\r\n <gve-chain-result-view\r\n [result]=\"result\"\r\n (stepPick)=\"onStepPick($event)\"\r\n />\r\n </fieldset>\r\n }\r\n </div>\r\n </mat-tab>\r\n\r\n <!-- image -->\r\n <mat-tab label=\"image\">\r\n <div id=\"image\">\r\n <div id=\"image-ctl\">\r\n <!-- url -->\r\n <mat-form-field class=\"long-text\">\r\n <mat-label>URL</mat-label>\r\n <input matInput [formControl]=\"imageUrl\" />\r\n </mat-form-field>\r\n <div class=\"form-row\">\r\n <!-- x -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>X</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"imageX\"\r\n placeholder=\"X\"\r\n />\r\n </mat-form-field>\r\n <!-- y -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>Y</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"imageY\"\r\n placeholder=\"Y\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n <div class=\"form-row\">\r\n <!-- width -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>width</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n min=\"0\"\r\n [formControl]=\"imageWidth\"\r\n />\r\n </mat-form-field>\r\n <!-- height -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>height</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n min=\"0\"\r\n [formControl]=\"imageHeight\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n <!-- defs -->\r\n <div>\r\n <mat-form-field class=\"long-text\">\r\n <mat-label>defs</mat-label>\r\n <textarea matInput [formControl]=\"defs\" rows=\"3\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n <div id=\"image-view\">\r\n @if (imageUrl.value) {\r\n <img alt=\"background\" [src]=\"imageUrl.value\" width=\"600\" />\r\n }\r\n </div>\r\n </div>\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- preview -->\r\n @if (snapshot) {\r\n <fieldset id=\"preview\">\r\n <legend class=\"button-row\">\r\n <span>{{ viewTitle }}</span>\r\n <button\r\n color=\"primary\"\r\n mat-icon-button\r\n type=\"button\"\r\n matTooltip=\"Refresh preview\"\r\n (click)=\"updateViewData()\"\r\n >\r\n <mat-icon class=\"mat-primary\">refresh</mat-icon>\r\n </button>\r\n </legend>\r\n <gve-snapshot-view\r\n [data]=\"viewData\"\r\n (snapshotRender)=\"onSnapshotRender($any($event))\"\r\n (visualEvent)=\"onVisualEvent($any($event))\"\r\n />\r\n <div>\r\n <mat-button-toggle\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n matTooltip=\"Toggle rulers\"\r\n [checked]=\"rulers\"\r\n (change)=\"toggleRulers()\"\r\n >\r\n <mat-icon class=\"mat-primary\">straighten</mat-icon>\r\n </mat-button-toggle>\r\n </div>\r\n @if (visualInfo) {\r\n <div id=\"visual-info\">{{ visualInfo }}</div>\r\n }\r\n </fieldset>\r\n }\r\n\r\n <!--buttons -->\r\n <div class=\"form-row-center\">\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"close()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n close\r\n </button>\r\n <button\r\n type=\"submit\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save changes\"\r\n [disabled]=\"form.invalid || form.pristine\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.long-text{width:100%;max-width:800px}#text-range{margin:8px;border:1px solid silver;border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:#909090;margin:8px}div#batch-container{display:grid;gap:16px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"batch-input batch-help\"}div#batch-input{grid-area:batch-input}div#batch-help{grid-area:batch-help}div#batch-help strong{color:#ff8c00}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse}th{color:#909090;font-weight:400;text-align:left;background-color:#e1e0e0}th,td{padding:4px;border-bottom:1px solid silver}tbody tr:nth-child(2n){background-color:#e8e8e8}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#c8d9eb}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin:8px 0}legend{color:#909090}.error{color:red}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}div#image{display:grid;gap:8px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"image-ctl image-view\"}div#image-ctl{grid-area:image-ctl}div#image-view{grid-area:image-view}@media only screen and (max-width: 959px){div#batch-container{grid-template-columns:1fr;grid-template-areas:\"batch-input\" \"batch-help\"}div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "component", type: i7.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i8.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i8.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i8.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i12.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i13.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i13.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i14.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: NgToolsModule }, { kind: "pipe", type: i15.FlatLookupPipe, name: "flatLookup" }, { kind: "component", type: BaseTextEditorComponent, selector: "gve-base-text-editor", inputs: ["text"], outputs: ["textChange"] }, { kind: "component", type: ChainOperationEditorComponent, selector: "gve-chain-operation-editor", inputs: ["operation", "snapshot", "hidePreview"], outputs: ["operationChange", "operationPreview", "operationCancel"] }, { kind: "component", type: ChainResultViewComponent, selector: "gve-chain-result-view", inputs: ["result"], outputs: ["stepPick"] }, { kind: "component", type: LnHeightsEditorComponent, selector: "gve-ln-heights-editor", inputs: ["lineCount", "heights"], outputs: ["heightsChange"] }] }); }
|
|
476
|
+
}
|
|
477
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: SnapshotEditorComponent, decorators: [{
|
|
478
|
+
type: Component,
|
|
479
|
+
args: [{ selector: 'gve-snapshot-editor', standalone: true, imports: [
|
|
480
|
+
CommonModule,
|
|
481
|
+
FormsModule,
|
|
482
|
+
ReactiveFormsModule,
|
|
483
|
+
MatButtonModule,
|
|
484
|
+
MatButtonToggleModule,
|
|
485
|
+
MatCheckboxModule,
|
|
486
|
+
MatExpansionModule,
|
|
487
|
+
MatFormFieldModule,
|
|
488
|
+
MatIconModule,
|
|
489
|
+
MatInputModule,
|
|
490
|
+
MatProgressBarModule,
|
|
491
|
+
MatSnackBarModule,
|
|
492
|
+
MatTabsModule,
|
|
493
|
+
MatTooltipModule,
|
|
494
|
+
NgToolsModule,
|
|
495
|
+
BaseTextEditorComponent,
|
|
496
|
+
BaseTextViewComponent,
|
|
497
|
+
ChainOperationEditorComponent,
|
|
498
|
+
ChainResultViewComponent,
|
|
499
|
+
LnHeightsEditorComponent,
|
|
500
|
+
], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <mat-tab-group>\r\n <!-- text -->\r\n <mat-tab label=\"text\">\r\n <mat-expansion-panel [expanded]=\"!baseText.value\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title> base text </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <gve-base-text-editor\r\n [text]=\"baseText.value\"\r\n (textChange)=\"onTextChange($event)\"\r\n />\r\n <fieldset>\r\n <div class=\"form-row\">\r\n <!-- offsetX -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>X offset</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"offsetX\"\r\n placeholder=\"X offset\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- offsetY -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>Y offset</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"offsetY\"\r\n placeholder=\"Y offset\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- lineHeightOffset -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>ln h-offset</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"lineHeightOffset\"\r\n placeholder=\"ln h-offset\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- charSpacingOffset -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>char spacing</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"charSpacingOffset\"\r\n placeholder=\"char spacing\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- spcWidthOffset -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>spc w-offset</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"spcWidthOffset\"\r\n placeholder=\"spc w-offset\"\r\n />\r\n </mat-form-field>\r\n <!-- minLineHeights -->\r\n <div>\r\n <gve-ln-heights-editor\r\n [lineCount]=\"lineCount\"\r\n [heights]=\"lnHeights.value\"\r\n (heightsChange)=\"onHeightsChange($event)\"\r\n />\r\n </div>\r\n </div>\r\n <!-- textStyle -->\r\n <div>\r\n <mat-form-field class=\"long-text\" appearance=\"outline\">\r\n <mat-label>text style</mat-label>\r\n <textarea\r\n matInput\r\n [formControl]=\"textStyle\"\r\n placeholder=\"text style\"\r\n ></textarea>\r\n </mat-form-field>\r\n </div>\r\n </fieldset>\r\n </mat-expansion-panel>\r\n </mat-tab>\r\n\r\n <!-- operations -->\r\n <mat-tab label=\"operations\">\r\n <div id=\"snapshot-container\">\r\n <div id=\"general\">\r\n <div class=\"form-row\">\r\n <!-- width -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>width</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n min=\"0\"\r\n [formControl]=\"width\"\r\n placeholder=\"width\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- height -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>height</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n min=\"0\"\r\n [formControl]=\"height\"\r\n placeholder=\"height\"\r\n />\r\n </mat-form-field>\r\n\r\n <!-- add op -->\r\n <div>\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n [disabled]=\"!baseText.value\"\r\n (click)=\"editNewOperation()\"\r\n >\r\n <mat-icon>add_circle</mat-icon> operation\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ops -->\r\n <div id=\"ops\">\r\n <!-- operations list -->\r\n @if (operations.value.length) {\r\n <table id=\"list\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>ID</th>\r\n <th>type</th>\r\n <th>at</th>\r\n <th>run</th>\r\n <th>value</th>\r\n <th>itag</th>\r\n <th>otag</th>\r\n <th>gid</th>\r\n <th>feats</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (operation of operations.value; track operation.id; let\r\n index=$index) {\r\n <tr [ngClass]=\"{ selected: operation.id === resultOperationId }\">\r\n <td class=\"fit-width\">\r\n <!-- edit -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n (click)=\"editOperation(index)\"\r\n matTooltip=\"Edit operation\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <!-- delete -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"deleteOperation(index)\"\r\n matTooltip=\"Delete operation\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n <!-- run to -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"accent\"\r\n (click)=\"runTo(index)\"\r\n matTooltip=\"Run to this operation\"\r\n >\r\n <mat-icon class=\"mat-accent\">subscriptions</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ operation.id }}</td>\r\n <td>{{ operation.type | flatLookup : opTypeMap }}</td>\r\n <td>{{ operation.at }}</td>\r\n <td>{{ operation.run }}</td>\r\n <td>{{ operation.value }}</td>\r\n <td>{{ operation.inputTag }}</td>\r\n <td>{{ operation.outputTag }}</td>\r\n <td>{{ operation.groupId }}</td>\r\n <td>{{ operation.features?.length }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <!-- operation editor -->\r\n <mat-expansion-panel [expanded]=\"editedOp\" [disabled]=\"!editedOp\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>operation {{ editedOp?.id }}</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-chain-operation-editor\r\n [operation]=\"editedOp\"\r\n (operationCancel)=\"onOperationCancel()\"\r\n (operationChange)=\"onOperationChange($event)\"\r\n (operationPreview)=\"onOperationPreview($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n\r\n <div>\r\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"busy\" />\r\n </div>\r\n\r\n <!-- opStyle -->\r\n <div id=\"opStyle\">\r\n <mat-form-field class=\"long-text\" appearance=\"outline\">\r\n <mat-label>operations style</mat-label>\r\n <textarea\r\n matInput\r\n [formControl]=\"opStyle\"\r\n placeholder=\"operations style\"\r\n ></textarea>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- batch ops -->\r\n <div>\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>batch operations</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <div id=\"batch-container\">\r\n <div id=\"batch-input\">\r\n <div>\r\n <mat-form-field class=\"full-width\">\r\n <mat-label>operations</mat-label>\r\n <textarea\r\n class=\"code\"\r\n matInput\r\n [formControl]=\"inputOps\"\r\n placeholder=\"operations\"\r\n rows=\"8\"\r\n spellcheck=\"false\"\r\n ></textarea>\r\n </mat-form-field>\r\n </div>\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Remove all the operations\"\r\n [disabled]=\"!operations.value.length || busy\"\r\n (click)=\"clearOperations()\"\r\n >\r\n clear\r\n </button>\r\n <button\r\n type=\"button\"\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Parse text and add results to the operations\"\r\n [disabled]=\"!inputOps.value || busy\"\r\n (click)=\"parseOperations()\"\r\n >\r\n batch add\r\n </button>\r\n @if (parseError) {\r\n <span class=\"error\">{{ parseError }}</span>\r\n }\r\n </div>\r\n </div>\r\n <div id=\"batch-help\">\r\n <ul>\r\n <li>\r\n <strong>replace</strong>:\r\n <code>ATxRUN<strong>=</strong>\"VALUE\"</code>\r\n </li>\r\n <li>\r\n <strong>delete</strong>:\r\n <code>ATxRUN<strong>-</strong></code>\r\n </li>\r\n <li>\r\n <strong>add-before</strong>:\r\n <code>ATxRUN<strong>+[</strong>\"VALUE\"</code>\r\n </li>\r\n <li>\r\n <strong>add-after</strong>:\r\n <code>ATxRUN<strong>+]</strong>\"VALUE\"</code>\r\n </li>\r\n <li>\r\n <strong>move-before</strong>:\r\n <code>ATxRUN<strong>>[</strong>TO</code>\r\n </li>\r\n <li>\r\n <strong>move-after</strong>:\r\n <code>ATxRUN<strong>>]</strong>TO</code>\r\n </li>\r\n <li>\r\n <strong>swap</strong>:\r\n <code>ATxRUN<strong><></strong>TOxRUN</code>\r\n </li>\r\n <li>\r\n <strong>annotate</strong>:\r\n <code>ATxRUN<strong>:</strong></code>\r\n </li>\r\n </ul>\r\n <p>For all the operations:</p>\r\n <ul>\r\n <li>\r\n prefix <code>(ITAG:OTAG)</code> to define input and/or\r\n output tags, separated by colon.\r\n </li>\r\n <li>\r\n prepend <code>@</code> to AT to use character\r\n indexes (0-N) rather than IDs.\r\n </li>\r\n <li>RUN (where applicable) defaults to 1.</li>\r\n <li>\r\n append features like <code>[NAME OPERATOR VALUE]</code>,\r\n separated by space, where:\r\n </li>\r\n <ol>\r\n <li>\r\n NAME is an arbitrary string. Prefixes:\r\n <code>*</code>=global features, <code>!</code>=remove\r\n feature (no value). Suffixes:\r\n <code>^</code>=short-lived (like\r\n <code>*version^=alpha</code>).\r\n </li>\r\n <li>\r\n OPERATOR is <code>=</code> (multiple),\r\n <code>:=</code> (single),\r\n <code>==</code> (first-single).\r\n </li>\r\n <li>\r\n VALUE is a string. If it includes spaces, wrap it in\r\n <code>\"\"</code>.\r\n </li>\r\n </ol>\r\n </ul>\r\n </div>\r\n </div>\r\n </fieldset>\r\n </mat-expansion-panel>\r\n </div>\r\n </div>\r\n\r\n <!-- result -->\r\n @if (result) {\r\n <fieldset id=\"result\">\r\n <legend>result</legend>\r\n <gve-chain-result-view\r\n [result]=\"result\"\r\n (stepPick)=\"onStepPick($event)\"\r\n />\r\n </fieldset>\r\n }\r\n </div>\r\n </mat-tab>\r\n\r\n <!-- image -->\r\n <mat-tab label=\"image\">\r\n <div id=\"image\">\r\n <div id=\"image-ctl\">\r\n <!-- url -->\r\n <mat-form-field class=\"long-text\">\r\n <mat-label>URL</mat-label>\r\n <input matInput [formControl]=\"imageUrl\" />\r\n </mat-form-field>\r\n <div class=\"form-row\">\r\n <!-- x -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>X</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"imageX\"\r\n placeholder=\"X\"\r\n />\r\n </mat-form-field>\r\n <!-- y -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>Y</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n [formControl]=\"imageY\"\r\n placeholder=\"Y\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n <div class=\"form-row\">\r\n <!-- width -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>width</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n min=\"0\"\r\n [formControl]=\"imageWidth\"\r\n />\r\n </mat-form-field>\r\n <!-- height -->\r\n <mat-form-field class=\"input-nr\">\r\n <mat-label>height</mat-label>\r\n <input\r\n matInput\r\n type=\"number\"\r\n min=\"0\"\r\n [formControl]=\"imageHeight\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n <!-- defs -->\r\n <div>\r\n <mat-form-field class=\"long-text\">\r\n <mat-label>defs</mat-label>\r\n <textarea matInput [formControl]=\"defs\" rows=\"3\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n <div id=\"image-view\">\r\n @if (imageUrl.value) {\r\n <img alt=\"background\" [src]=\"imageUrl.value\" width=\"600\" />\r\n }\r\n </div>\r\n </div>\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- preview -->\r\n @if (snapshot) {\r\n <fieldset id=\"preview\">\r\n <legend class=\"button-row\">\r\n <span>{{ viewTitle }}</span>\r\n <button\r\n color=\"primary\"\r\n mat-icon-button\r\n type=\"button\"\r\n matTooltip=\"Refresh preview\"\r\n (click)=\"updateViewData()\"\r\n >\r\n <mat-icon class=\"mat-primary\">refresh</mat-icon>\r\n </button>\r\n </legend>\r\n <gve-snapshot-view\r\n [data]=\"viewData\"\r\n (snapshotRender)=\"onSnapshotRender($any($event))\"\r\n (visualEvent)=\"onVisualEvent($any($event))\"\r\n />\r\n <div>\r\n <mat-button-toggle\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n matTooltip=\"Toggle rulers\"\r\n [checked]=\"rulers\"\r\n (change)=\"toggleRulers()\"\r\n >\r\n <mat-icon class=\"mat-primary\">straighten</mat-icon>\r\n </mat-button-toggle>\r\n </div>\r\n @if (visualInfo) {\r\n <div id=\"visual-info\">{{ visualInfo }}</div>\r\n }\r\n </fieldset>\r\n }\r\n\r\n <!--buttons -->\r\n <div class=\"form-row-center\">\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"close()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n close\r\n </button>\r\n <button\r\n type=\"submit\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save changes\"\r\n [disabled]=\"form.invalid || form.pristine\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.long-text{width:100%;max-width:800px}#text-range{margin:8px;border:1px solid silver;border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:#909090;margin:8px}div#batch-container{display:grid;gap:16px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"batch-input batch-help\"}div#batch-input{grid-area:batch-input}div#batch-help{grid-area:batch-help}div#batch-help strong{color:#ff8c00}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse}th{color:#909090;font-weight:400;text-align:left;background-color:#e1e0e0}th,td{padding:4px;border-bottom:1px solid silver}tbody tr:nth-child(2n){background-color:#e8e8e8}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#c8d9eb}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin:8px 0}legend{color:#909090}.error{color:red}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}div#image{display:grid;gap:8px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"image-ctl image-view\"}div#image-ctl{grid-area:image-ctl}div#image-view{grid-area:image-view}@media only screen and (max-width: 959px){div#batch-container{grid-template-columns:1fr;grid-template-areas:\"batch-input\" \"batch-help\"}div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"] }]
|
|
501
|
+
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i2.GveApiService }, { type: i3.DialogService }, { type: i4.MatSnackBar }], propDecorators: { snapshot: [{
|
|
502
|
+
type: Input
|
|
503
|
+
}], batchOps: [{
|
|
504
|
+
type: Input
|
|
505
|
+
}], snapshotChange: [{
|
|
506
|
+
type: Output
|
|
507
|
+
}], snapshotCancel: [{
|
|
508
|
+
type: Output
|
|
509
|
+
}] } });
|
|
510
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic25hcHNob3QtZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2d2ZS1jb3JlL3NyYy9saWIvY29tcG9uZW50cy9zbmFwc2hvdC1lZGl0b3Ivc25hcHNob3QtZWRpdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL2d2ZS1jb3JlL3NyYy9saWIvY29tcG9uZW50cy9zbmFwc2hvdC1lZGl0b3Ivc25hcHNob3QtZWRpdG9yLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFTCxXQUFXLEVBRVgsV0FBVyxFQUNYLG1CQUFtQixFQUNuQixVQUFVLEdBQ1gsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFL0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDdEUsT0FBTyxF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QkFDcEIsaUJBQWlCO3dCQUNqQixhQUFhO3dCQUNiLGdCQUFnQjt3QkFDaEIsYUFBYTt3QkFDYix1QkFBdUI7d0JBQ3ZCLHFCQUFxQjt3QkFDckIsNkJBQTZCO3dCQUM3Qix3QkFBd0I7d0JBQ3hCLHdCQUF3QjtxQkFDekIsV0FDUSxDQUFDLHNCQUFzQixDQUFDO2tLQVl0QixRQUFRO3NCQURsQixLQUFLO2dCQWlCQyxRQUFRO3NCQURkLEtBQUs7Z0JBT1UsY0FBYztzQkFEN0IsTUFBTTtnQkFPUyxjQUFjO3NCQUQ3QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDVVNUT01fRUxFTUVOVFNfU0NIRU1BLFxyXG4gIENvbXBvbmVudCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25Jbml0LFxyXG4gIE91dHB1dCxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtcclxuICBGb3JtQnVpbGRlcixcclxuICBGb3JtQ29udHJvbCxcclxuICBGb3JtR3JvdXAsXHJcbiAgRm9ybXNNb2R1bGUsXHJcbiAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcclxuICBWYWxpZGF0b3JzLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuXHJcbmltcG9ydCB7IE1hdEJ1dHRvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XHJcbmltcG9ydCB7IE1hdEJ1dHRvblRvZ2dsZU1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbi10b2dnbGUnO1xyXG5pbXBvcnQgeyBNYXRDaGVja2JveE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NoZWNrYm94JztcclxuaW1wb3J0IHsgTWF0RXhwYW5zaW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZXhwYW5zaW9uJztcclxuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XHJcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcclxuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XHJcbmltcG9ydCB7IE1hdFByb2dyZXNzQmFyTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvcHJvZ3Jlc3MtYmFyJztcclxuaW1wb3J0IHsgTWF0U25hY2tCYXIsIE1hdFNuYWNrQmFyTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc25hY2stYmFyJztcclxuaW1wb3J0IHsgTWF0VGFic01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYnMnO1xyXG5pbXBvcnQgeyBNYXRUb29sdGlwTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdG9vbHRpcCc7XHJcblxyXG5pbXBvcnQgeyBOZ1Rvb2xzTW9kdWxlLCBkZWVwQ29weSB9IGZyb20gJ0BteXJtaWRvbi9uZy10b29scyc7XHJcbmltcG9ydCB7IERpYWxvZ1NlcnZpY2UgfSBmcm9tICdAbXlybWlkb24vbmctbWF0LXRvb2xzJztcclxuXHJcbmltcG9ydCB7XHJcbiAgQ2hhckNoYWluT3BlcmF0aW9uLFxyXG4gIENoYXJOb2RlLFxyXG4gIERFRkFVTFRfU1ZHX0JBU0VfVEVYVF9PUFRJT05TLFxyXG4gIEZlYXR1cmUsXHJcbiAgR3ZlVmlzdWFsRXZlbnQsXHJcbiAgU25hcHNob3QsXHJcbiAgU25hcHNob3RWaWV3RGF0YSxcclxuICBTbmFwc2hvdFZpZXdSZW5kZXJFdmVudCxcclxuICBTbmFwc2hvdFZpZXdTZXJ2aWNlLFxyXG59IGZyb20gJ0BteXJtaWRvbi9ndmUtc25hcHNob3Qtdmlldyc7XHJcblxyXG5pbXBvcnQge1xyXG4gIEJhc2VUZXh0Vmlld0NvbXBvbmVudCxcclxuICBWYXJCYXNlVGV4dFJhbmdlLFxyXG59IGZyb20gJy4uL2Jhc2UtdGV4dC12aWV3L2Jhc2UtdGV4dC12aWV3LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IENoYWluT3BlcmF0aW9uRWRpdG9yQ29tcG9uZW50IH0gZnJvbSAnLi4vY2hhaW4tb3BlcmF0aW9uLWVkaXRvci9jaGFpbi1vcGVyYXRpb24tZWRpdG9yLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7XHJcbiAgQ2hhaW5PcGVyYXRpb25Db250ZXh0U3RlcCxcclxuICBDaGFyQ2hhaW5SZXN1bHQsXHJcbiAgR3ZlQXBpU2VydmljZSxcclxufSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9ndmUtYXBpLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBDaGFpblJlc3VsdFZpZXdDb21wb25lbnQgfSBmcm9tICcuLi9jaGFpbi1yZXN1bHQtdmlldy9jaGFpbi1yZXN1bHQtdmlldy5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBMbkhlaWdodHNFZGl0b3JDb21wb25lbnQgfSBmcm9tICcuLi9sbi1oZWlnaHRzLWVkaXRvci9sbi1oZWlnaHRzLWVkaXRvci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBCYXNlVGV4dEVkaXRvckNvbXBvbmVudCB9IGZyb20gJy4uL2Jhc2UtdGV4dC1lZGl0b3IvYmFzZS10ZXh0LWVkaXRvci5jb21wb25lbnQnO1xyXG5cclxuY29uc3QgVklFV19USVRMRSA9ICdwcmV2aWV3JztcclxuXHJcbi8qKlxyXG4gKiBBIGNvbXBvbmVudCB0byBlZGl0IGEgdGV4dCBzbmFwc2hvdC5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZ3ZlLXNuYXBzaG90LWVkaXRvcicsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbXHJcbiAgICBDb21tb25Nb2R1bGUsXHJcbiAgICBGb3Jtc01vZHVsZSxcclxuICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXHJcbiAgICBNYXRCdXR0b25Nb2R1bGUsXHJcbiAgICBNYXRCdXR0b25Ub2dnbGVNb2R1bGUsXHJcbiAgICBNYXRDaGVja2JveE1vZHVsZSxcclxuICAgIE1hdEV4cGFuc2lvbk1vZHVsZSxcclxuICAgIE1hdEZvcm1GaWVsZE1vZHVsZSxcclxuICAgIE1hdEljb25Nb2R1bGUsXHJcbiAgICBNYXRJbnB1dE1vZHVsZSxcclxuICAgIE1hdFByb2dyZXNzQmFyTW9kdWxlLFxyXG4gICAgTWF0U25hY2tCYXJNb2R1bGUsXHJcbiAgICBNYXRUYWJzTW9kdWxlLFxyXG4gICAgTWF0VG9vbHRpcE1vZHVsZSxcclxuICAgIE5nVG9vbHNNb2R1bGUsXHJcbiAgICBCYXNlVGV4dEVkaXRvckNvbXBvbmVudCxcclxuICAgIEJhc2VUZXh0Vmlld0NvbXBvbmVudCxcclxuICAgIENoYWluT3BlcmF0aW9uRWRpdG9yQ29tcG9uZW50LFxyXG4gICAgQ2hhaW5SZXN1bHRWaWV3Q29tcG9uZW50LFxyXG4gICAgTG5IZWlnaHRzRWRpdG9yQ29tcG9uZW50LFxyXG4gIF0sXHJcbiAgc2NoZW1hczogW0NVU1RPTV9FTEVNRU5UU19TQ0hFTUFdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9zbmFwc2hvdC1lZGl0b3IuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi9zbmFwc2hvdC1lZGl0b3IuY29tcG9uZW50LmNzcycsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTbmFwc2hvdEVkaXRvckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgcHJpdmF0ZSBfc25hcHNob3Q/OiBTbmFwc2hvdDtcclxuICBwcml2YXRlIF9yZW5kZXJlcj86IFNuYXBzaG90Vmlld1NlcnZpY2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBzbmFwc2hvdCB0byBlZGl0LlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgcHVibGljIGdldCBzbmFwc2hvdCgpOiBTbmFwc2hvdCB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gdGhpcy5fc25hcHNob3Q7XHJcbiAgfVxyXG4gIHB1YmxpYyBzZXQgc25hcHNob3QodmFsdWU6IFNuYXBzaG90IHwgdW5kZWZpbmVkIHwgbnVsbCkge1xyXG4gICAgaWYgKHRoaXMuX3NuYXBzaG90ID09PSB2YWx1ZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLl9zbmFwc2hvdCA9IHZhbHVlIHx8IHVuZGVmaW5lZDtcclxuICAgIHRoaXMudXBkYXRlRm9ybSh0aGlzLl9zbmFwc2hvdCk7XHJcbiAgICB0aGlzLnVwZGF0ZVZpZXdEYXRhKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUaGUgYmF0Y2ggb3BlcmF0aW9ucyB0ZXh0IHRvIHNldCBmb3IgdGhlIGVkaXRvci5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHB1YmxpYyBiYXRjaE9wcz86IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogRW1pdHRlZCB3aGVuIHRoZSB1c2VyIHNhdmVzIHRoZSBlZGl0ZWQgc25hcHNob3QuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpXHJcbiAgcHVibGljIHJlYWRvbmx5IHNuYXBzaG90Q2hhbmdlOiBFdmVudEVtaXR0ZXI8U25hcHNob3Q+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICAvKipcclxuICAgKiBFbWl0dGVkIHdoZW4gdGhlIHVzZXIgY2FuY2VscyB0aGUgc25hcHNob3QgZWRpdGluZy5cclxuICAgKi9cclxuICBAT3V0cHV0KClcclxuICBwdWJsaWMgcmVhZG9ubHkgc25hcHNob3RDYW5jZWwgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gIC8vIGdlbmVyYWxcclxuICBwdWJsaWMgd2lkdGg6IEZvcm1Db250cm9sPG51bWJlcj47XHJcbiAgcHVibGljIGhlaWdodDogRm9ybUNvbnRyb2w8bnVtYmVyPjtcclxuICBwdWJsaWMgc3R5bGU6IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+O1xyXG4gIC8vIGJhc2UgdGV4dFxyXG4gIHB1YmxpYyBiYXNlVGV4dDogRm9ybUNvbnRyb2w8Q2hhck5vZGVbXSB8IHN0cmluZz47XHJcbiAgcHVibGljIG9mZnNldFg6IEZvcm1Db250cm9sPG51bWJlcj47XHJcbiAgcHVibGljIG9mZnNldFk6IEZvcm1Db250cm9sPG51bWJlcj47XHJcbiAgcHVibGljIGxpbmVIZWlnaHRPZmZzZXQ6IEZvcm1Db250cm9sPG51bWJlcj47XHJcbiAgcHVibGljIGxuSGVpZ2h0czogRm9ybUNvbnRyb2w8UmVjb3JkPG51bWJlciwgbnVtYmVyPiB8IG51bGw+O1xyXG4gIHB1YmxpYyBjaGFyU3BhY2luZ09mZnNldDogRm9ybUNvbnRyb2w8bnVtYmVyPjtcclxuICBwdWJsaWMgc3BjV2lkdGhPZmZzZXQ6IEZvcm1Db250cm9sPG51bWJlcj47XHJcbiAgcHVibGljIHRleHRTdHlsZTogRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD47XHJcbiAgLy8gb3BlcmF0aW9uc1xyXG4gIHB1YmxpYyBvcGVyYXRpb25zOiBGb3JtQ29udHJvbDxDaGFyQ2hhaW5PcGVyYXRpb25bXT47XHJcbiAgcHVibGljIGlucHV0T3BzOiBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPjtcclxuICBwdWJsaWMgb3BTdHlsZTogRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD47XHJcbiAgcHVibGljIGZvcm06IEZvcm1Hcm91cDtcclxuICAvLyBpbWFnZSBhbmQgZGVmc1xyXG4gIHB1YmxpYyBpbWFnZVVybDogRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD47XHJcbiAgcHVibGljIGltYWdlT3BhY2l0eTogRm9ybUNvbnRyb2w8bnVtYmVyPjtcclxuICBwdWJsaWMgaW1hZ2VYOiBGb3JtQ29udHJvbDxudW1iZXI+O1xyXG4gIHB1YmxpYyBpbWFnZVk6IEZvcm1Db250cm9sPG51bWJlcj47XHJcbiAgcHVibGljIGltYWdlV2lkdGg6IEZvcm1Db250cm9sPG51bWJlcj47XHJcbiAgcHVibGljIGltYWdlSGVpZ2h0OiBGb3JtQ29udHJvbDxudW1iZXI+O1xyXG4gIHB1YmxpYyBkZWZzOiBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPjtcclxuXHJcbiAgcHVibGljIHRleHRSYW5nZT86IFZhckJhc2VUZXh0UmFuZ2U7XHJcbiAgcHVibGljIGVkaXRlZE9wPzogQ2hhckNoYWluT3BlcmF0aW9uO1xyXG4gIHB1YmxpYyBlZGl0ZWRPcEluZGV4ID0gLTE7XHJcblxyXG4gIHB1YmxpYyBidXN5PzogYm9vbGVhbjtcclxuICBwdWJsaWMgcGFyc2VFcnJvcj86IHN0cmluZztcclxuICBwdWJsaWMgb3BUeXBlTWFwID0ge1xyXG4gICAgMDogJ3JlcGxhY2UnLFxyXG4gICAgMTogJ2RlbGV0ZScsXHJcbiAgICAyOiAnYWRkQmVmb3JlJyxcclxuICAgIDM6ICdhZGRBZnRlcicsXHJcbiAgICA0OiAnbW92ZUJlZm9yZScsXHJcbiAgICA1OiAnbW92ZUFmdGVyJyxcclxuICAgIDY6ICdzd2FwJyxcclxuICAgIDc6ICdhbm5vdGF0ZScsXHJcbiAgfTtcclxuICBwdWJsaWMgbGluZUNvdW50ID0gMDtcclxuXHJcbiAgcHVibGljIHZpZXdUaXRsZSA9IFZJRVdfVElUTEU7XHJcbiAgcHVibGljIHZpZXdEYXRhPzogU25hcHNob3RWaWV3RGF0YTtcclxuICBwdWJsaWMgdmlzdWFsSW5mbz86IHN0cmluZztcclxuICBwdWJsaWMgcnVsZXJzID0gdHJ1ZTtcclxuICAvLyBydW4gcmVzdWx0XHJcbiAgcHVibGljIHJlc3VsdD86IENoYXJDaGFpblJlc3VsdDtcclxuICBwdWJsaWMgcmVzdWx0T3BlcmF0aW9uSWQ/OiBzdHJpbmc7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxyXG4gICAgcHJpdmF0ZSBfYXBpOiBHdmVBcGlTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBfZGlhbG9nU2VydmljZTogRGlhbG9nU2VydmljZSxcclxuICAgIHByaXZhdGUgX3NuYWNrYmFyOiBNYXRTbmFja0JhclxyXG4gICkge1xyXG4gICAgLy8gZ2VuZXJhbFxyXG4gICAgdGhpcy53aWR0aCA9IG5ldyBGb3JtQ29udHJvbDxudW1iZXI+KDgwMCwgeyBub25OdWxsYWJsZTogdHJ1ZSB9KTtcclxuICAgIHRoaXMuaGVpZ2h0ID0gbmV3IEZvcm1Db250cm9sPG51bWJlcj4oNjAwLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xyXG4gICAgdGhpcy5zdHlsZSA9IG5ldyBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPihudWxsKTtcclxuICAgIC8vIGJhc2UgdGV4dFxyXG4gICAgdGhpcy5iYXNlVGV4dCA9IG5ldyBGb3JtQ29udHJvbDxDaGFyTm9kZVtdIHwgc3RyaW5nPihbXSwge1xyXG4gICAgICBub25OdWxsYWJsZTogdHJ1ZSxcclxuICAgICAgdmFsaWRhdG9yczogW1ZhbGlkYXRvcnMucmVxdWlyZWRdLFxyXG4gICAgfSk7XHJcbiAgICB0aGlzLm9mZnNldFggPSBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPigwLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xyXG4gICAgdGhpcy5vZmZzZXRZID0gbmV3IEZvcm1Db250cm9sPG51bWJlcj4oMCwgeyBub25OdWxsYWJsZTogdHJ1ZSB9KTtcclxuICAgIHRoaXMubGluZUhlaWdodE9mZnNldCA9IG5ldyBGb3JtQ29udHJvbDxudW1iZXI+KFxyXG4gICAgICBERUZBVUxUX1NWR19CQVNFX1RFWFRfT1BUSU9OUy5saW5lSGVpZ2h0T2Zmc2V0LFxyXG4gICAgICB7IG5vbk51bGxhYmxlOiB0cnVlIH1cclxuICAgICk7XHJcbiAgICB0aGlzLmxuSGVpZ2h0cyA9IG5ldyBGb3JtQ29udHJvbDxSZWNvcmQ8bnVtYmVyLCBudW1iZXI+IHwgbnVsbD4obnVsbCk7XHJcbiAgICB0aGlzLmNoYXJTcGFjaW5nT2Zmc2V0ID0gbmV3IEZvcm1Db250cm9sPG51bWJlcj4oMCwgeyBub25OdWxsYWJsZTogdHJ1ZSB9KTtcclxuICAgIHRoaXMuc3BjV2lkdGhPZmZzZXQgPSBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPigwLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xyXG4gICAgdGhpcy50ZXh0U3R5bGUgPSBuZXcgRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD4obnVsbCk7XHJcblxyXG4gICAgLy8gb3BlcmF0aW9uc1xyXG4gICAgdGhpcy5vcGVyYXRpb25zID0gbmV3IEZvcm1Db250cm9sPENoYXJDaGFpbk9wZXJhdGlvbltdPihbXSwge1xyXG4gICAgICBub25OdWxsYWJsZTogdHJ1ZSxcclxuICAgIH0pO1xyXG4gICAgdGhpcy5pbnB1dE9wcyA9IG5ldyBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPihudWxsKTtcclxuICAgIHRoaXMub3BTdHlsZSA9IG5ldyBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPihudWxsKTtcclxuICAgIC8vIGltYWdlXHJcbiAgICB0aGlzLmltYWdlVXJsID0gbmV3IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+KG51bGwpO1xyXG4gICAgdGhpcy5pbWFnZU9wYWNpdHkgPSBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPigxLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xyXG4gICAgdGhpcy5pbWFnZVggPSBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPigwLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xyXG4gICAgdGhpcy5pbWFnZVkgPSBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPigwLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xyXG4gICAgdGhpcy5pbWFnZVdpZHRoID0gbmV3IEZvcm1Db250cm9sPG51bWJlcj4oMCwgeyBub25OdWxsYWJsZTogdHJ1ZSB9KTtcclxuICAgIHRoaXMuaW1hZ2VIZWlnaHQgPSBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPigwLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xyXG4gICAgdGhpcy5kZWZzID0gbmV3IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+KG51bGwpO1xyXG5cclxuICAgIHRoaXMuZm9ybSA9IGZvcm1CdWlsZGVyLmdyb3VwKHtcclxuICAgICAgd2lkdGg6IHRoaXMud2lkdGgsXHJcbiAgICAgIGhlaWdodDogdGhpcy5oZWlnaHQsXHJcbiAgICAgIHN0eWxlOiB0aGlzLnN0eWxlLFxyXG4gICAgICBiYXNlVGV4dDogdGhpcy5iYXNlVGV4dCxcclxuICAgICAgb2Zmc2V0WDogdGhpcy5vZmZzZXRYLFxyXG4gICAgICBvZmZzZXRZOiB0aGlzLm9mZnNldFksXHJcbiAgICAgIGxpbmVIZWlnaHRPZmZzZXQ6IHRoaXMubGluZUhlaWdodE9mZnNldCxcclxuICAgICAgbG5IZWlnaHRzOiB0aGlzLmxuSGVpZ2h0cyxcclxuICAgICAgY2hhclNwYWNpbmdPZmZzZXQ6IHRoaXMuY2hhclNwYWNpbmdPZmZzZXQsXHJcbiAgICAgIHNwY1dpZHRoT2Zmc2V0OiB0aGlzLnNwY1dpZHRoT2Zmc2V0LFxyXG4gICAgICB0ZXh0U3R5bGU6IHRoaXMudGV4dFN0eWxlLFxyXG4gICAgICBvcGVyYXRpb25zOiB0aGlzLm9wZXJhdGlvbnMsXHJcbiAgICAgIGlucHV0T3BzOiB0aGlzLmlucHV0T3BzLFxyXG4gICAgICBvcFN0eWxlOiB0aGlzLm9wU3R5bGUsXHJcbiAgICAgIC8vIGltYWdlXHJcbiAgICAgIGltYWdlVXJsOiB0aGlzLmltYWdlVXJsLFxyXG4gICAgICBpbWFnZU9wYWNpdHk6IHRoaXMuaW1hZ2VPcGFjaXR5LFxyXG4gICAgICBpbWFnZVg6IHRoaXMuaW1hZ2VYLFxyXG4gICAgICBpbWFnZVk6IHRoaXMuaW1hZ2VZLFxyXG4gICAgICBpbWFnZVdpZHRoOiB0aGlzLmltYWdlV2lkdGgsXHJcbiAgICAgIGltYWdlSGVpZ2h0OiB0aGlzLmltYWdlSGVpZ2h0LFxyXG4gICAgICBkZWZzOiB0aGlzLmRlZnMsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmJhdGNoT3BzKSB7XHJcbiAgICAgIHRoaXMuaW5wdXRPcHMuc2V0VmFsdWUodGhpcy5iYXRjaE9wcyk7XHJcbiAgICAgIHRoaXMucGFyc2VPcGVyYXRpb25zKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdXBkYXRlVmlld0RhdGEoXHJcbiAgICBuZXdPcGVyYXRpb24/OiBDaGFyQ2hhaW5PcGVyYXRpb24sXHJcbiAgICBzbmFwc2hvdD86IFNuYXBzaG90LFxyXG4gICAgdGl0bGUgPSBWSUVXX1RJVExFXHJcbiAgKTogdm9pZCB7XHJcbiAgICBpZiAoIXNuYXBzaG90KSB7XHJcbiAgICAgIHNuYXBzaG90ID0gdGhpcy5nZXRTbmFwc2hvdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHVwZGF0ZSBvciBhZGQgbmV3IG9wZXJhdGlvbiBpbiBjb3B5XHJcbiAgICBpZiAobmV3T3BlcmF0aW9uKSB7XHJcbiAgICAgIGNvbnN0IGluZGV4ID0gc25hcHNob3Qub3BlcmF0aW9ucy5maW5kSW5kZXgoXHJcbiAgICAgICAgKG9wKSA9PiBvcC5pZCA9PT0gbmV3T3BlcmF0aW9uLmlkXHJcbiAgICAgICk7XHJcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7XHJcbiAgICAgICAgc25hcHNob3Qub3BlcmF0aW9ucy5zcGxpY2UoaW5kZXgsIDEsIG5ld09wZXJhdGlvbik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgc25hcHNob3Qub3BlcmF0aW9ucy5wdXNoKG5ld09wZXJhdGlvbik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyB1cGRhdGUgdmlldyBkYXRhXHJcbiAgICB0aGlzLnZpZXdUaXRsZSA9IHRpdGxlO1xyXG4gICAgdGhpcy52aXN1YWxJbmZvID0gdW5kZWZpbmVkO1xyXG4gICAgdGhpcy52aWV3RGF0YSA9IHtcclxuICAgICAgc25hcHNob3Q6IHNuYXBzaG90LFxyXG4gICAgICBvcHRpb25zOiB7XHJcbiAgICAgICAgLy8gZGVidWc6IHRydWUsXHJcbiAgICAgICAgZGVsYXllZFJlbmRlcjogdHJ1ZSxcclxuICAgICAgICBzaG93UnVsZXJzOiB0cnVlLFxyXG4gICAgICAgIHNob3dHcmlkOiB0cnVlLFxyXG4gICAgICAgIHBhblpvb206IHRydWUsXHJcbiAgICAgIH0sXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVGb3JtKHNuYXBzaG90OiBTbmFwc2hvdCB8IHVuZGVmaW5lZCkge1xyXG4gICAgaWYgKCFzbmFwc2hvdCkge1xyXG4gICAgICB0aGlzLmZvcm0ucmVzZXQoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMud2lkdGguc2V0VmFsdWUoc25hcHNob3Quc2l6ZS53aWR0aCk7XHJcbiAgICAgIHRoaXMuaGVpZ2h0LnNldFZhbHVlKHNuYXBzaG90LnNpemUuaGVpZ2h0KTtcclxuICAgICAgdGhpcy5zdHlsZS5zZXRWYWx1ZShzbmFwc2hvdC5zdHlsZSB8fCBudWxsKTtcclxuICAgICAgdGhpcy5pbWFnZVVybC5zZXRWYWx1ZShzbmFwc2hvdC5pbWFnZT8udXJsIHx8IG51bGwpO1xyXG4gICAgICB0aGlzLmltYWdlT3BhY2l0eS5zZXRWYWx1ZShzbmFwc2hvdC5pbWFnZT8ub3BhY2l0eSB8fCAwKTtcclxuICAgICAgdGhpcy5pbWFnZVguc2V0VmFsdWUoc25hcHNob3QuaW1hZ2U/LmNhbnZhcz8ueCB8fCAwKTtcclxuICAgICAgdGhpcy5pbWFnZVkuc2V0VmFsdWUoc25hcHNob3QuaW1hZ2U/LmNhbnZhcz8ueSB8fCAwKTtcclxuICAgICAgdGhpcy5pbWFnZVdpZHRoLnNldFZhbHVlKHNuYXBzaG90LmltYWdlPy5jYW52YXM/LndpZHRoIHx8IDApO1xyXG4gICAgICB0aGlzLmltYWdlSGVpZ2h0LnNldFZhbHVlKHNuYXBzaG90LmltYWdlPy5jYW52YXM/LmhlaWdodCB8fCAwKTtcclxuICAgICAgdGhpcy5kZWZzLnNldFZhbHVlKHNuYXBzaG90LmRlZnMgfHwgbnVsbCk7XHJcbiAgICAgIHRoaXMuYmFzZVRleHQuc2V0VmFsdWUoc25hcHNob3QudGV4dCk7XHJcbiAgICAgIHRoaXMub2Zmc2V0WC5zZXRWYWx1ZShzbmFwc2hvdC50ZXh0T3B0aW9ucz8ub2Zmc2V0Py54IHx8IDApO1xyXG4gICAgICB0aGlzLm9mZnNldFkuc2V0VmFsdWUoc25hcHNob3QudGV4dE9wdGlvbnM/Lm9mZnNldD8ueSB8fCAwKTtcclxuICAgICAgdGhpcy5saW5lSGVpZ2h0T2Zmc2V0LnNldFZhbHVlKHNuYXBzaG90LnRleHRPcHRpb25zPy5saW5lSGVpZ2h0T2Zmc2V0KTtcclxuICAgICAgdGhpcy5sbkhlaWdodHMuc2V0VmFsdWUoc25hcHNob3QudGV4dE9wdGlvbnM/Lm1pbkxpbmVIZWlnaHRzIHx8IG51bGwpO1xyXG4gICAgICB0aGlzLmNoYXJTcGFjaW5nT2Zmc2V0LnNldFZhbHVlKHNuYXBzaG90LnRleHRPcHRpb25zPy5jaGFyU3BhY2luZ09mZnNldCk7XHJcbiAgICAgIHRoaXMuc3BjV2lkdGhPZmZzZXQuc2V0VmFsdWUoc25hcHNob3QudGV4dE9wdGlvbnM/LnNwY1dpZHRoT2Zmc2V0KTtcclxuICAgICAgdGhpcy50ZXh0U3R5bGUuc2V0VmFsdWUoc25hcHNob3QudGV4dFN0eWxlIHx8IG51bGwpO1xyXG4gICAgICB0aGlzLm9wZXJhdGlvbnMuc2V0VmFsdWUoc25hcHNob3Qub3BlcmF0aW9ucyk7XHJcbiAgICAgIHRoaXMuaW5wdXRPcHMucmVzZXQoKTtcclxuICAgICAgdGhpcy5vcFN0eWxlLnNldFZhbHVlKHNuYXBzaG90Lm9wU3R5bGUgfHwgbnVsbCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmZvcm0ubWFya0FzUHJpc3RpbmUoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBlZGl0TmV3T3BlcmF0aW9uKCkge1xyXG4gICAgdGhpcy5lZGl0ZWRPcCA9IHtcclxuICAgICAgaWQ6ICcnLFxyXG4gICAgICB0eXBlOiAwLFxyXG4gICAgICBhdDogdGhpcy50ZXh0UmFuZ2U/LmF0IHx8IDAsXHJcbiAgICAgIHJ1bjogdGhpcy50ZXh0UmFuZ2U/LnJ1biB8fCAxLFxyXG4gICAgfTtcclxuICAgIHRoaXMuZWRpdGVkT3BJbmRleCA9IC0xO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGVkaXRPcGVyYXRpb24oaW5kZXg6IG51bWJlcikge1xyXG4gICAgdGhpcy5lZGl0ZWRPcCA9IHRoaXMub3BlcmF0aW9ucy52YWx1ZVtpbmRleF07XHJcbiAgICB0aGlzLmVkaXRlZE9wSW5kZXggPSBpbmRleDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2xvc2VFZGl0ZWRPcCgpIHtcclxuICAgIHRoaXMuZWRpdGVkT3AgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmVkaXRlZE9wSW5kZXggPSAtMTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvbk9wZXJhdGlvbkNhbmNlbCgpIHtcclxuICAgIHRoaXMuY2xvc2VFZGl0ZWRPcCgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uT3BlcmF0aW9uQ2hhbmdlKG9wOiBDaGFyQ2hhaW5PcGVyYXRpb24pIHtcclxuICAgIGNvbnN0IG9wZXJhdGlvbnMgPSBbLi4udGhpcy5vcGVyYXRpb25zLnZhbHVlXTtcclxuXHJcbiAgICBpZiAodGhpcy5lZGl0ZWRPcEluZGV4ID4gLTEpIHtcclxuICAgICAgb3BlcmF0aW9ucy5zcGxpY2UodGhpcy5lZGl0ZWRPcEluZGV4LCAxLCBvcCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBvcGVyYXRpb25zLnB1c2gob3ApO1xyXG4gICAgfVxyXG4gICAgdGhpcy5vcGVyYXRpb25zLnNldFZhbHVlKG9wZXJhdGlvbnMpO1xyXG4gICAgdGhpcy5vcGVyYXRpb25zLm1hcmtBc0RpcnR5KCk7XHJcbiAgICB0aGlzLm9wZXJhdGlvbnMudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG5cclxuICAgIHRoaXMuY2xvc2VFZGl0ZWRPcCgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGRlbGV0ZU9wZXJhdGlvbihpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLl9kaWFsb2dTZXJ2aWNlXHJcbiAgICAgIC5jb25maXJtKFxyXG4gICAgICAgICdDb25maXJtIERlbGV0aW9uJyxcclxuICAgICAgICBgRGVsZXRlIG9wZXJhdGlvbiBcIiR7dGhpcy5vcGVyYXRpb25zLnZhbHVlW2luZGV4XS5pZH1cIj9gXHJcbiAgICAgIClcclxuICAgICAgLnN1YnNjcmliZSgoeWVzOiBib29sZWFuKSA9PiB7XHJcbiAgICAgICAgaWYgKHllcykge1xyXG4gICAgICAgICAgaWYgKHRoaXMucmVzdWx0T3BlcmF0aW9uSWQgPT09IHRoaXMub3BlcmF0aW9ucy52YWx1ZVtpbmRleF0uaWQpIHtcclxuICAgICAgICAgICAgdGhpcy5yZXN1bHRPcGVyYXRpb25JZCA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGNvbnN0IG9wZXJhdGlvbnMgPSBbLi4udGhpcy5vcGVyYXRpb25zLnZhbHVlXTtcclxuICAgICAgICAgIG9wZXJhdGlvbnMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgIHRoaXMub3BlcmF0aW9ucy5zZXRWYWx1ZShvcGVyYXRpb25zKTtcclxuICAgICAgICAgIHRoaXMub3BlcmF0aW9ucy5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgICAgICAgdGhpcy5vcGVyYXRpb25zLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uVGV4dENoYW5nZSh0ZXh0OiBDaGFyTm9kZVtdKSB7XHJcbiAgICB0aGlzLmJhc2VUZXh0LnNldFZhbHVlKHRleHQpO1xyXG4gICAgdGhpcy5iYXNlVGV4dC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICB0aGlzLmJhc2VUZXh0Lm1hcmtBc0RpcnR5KCk7XHJcbiAgICBpZiAoIXRleHQubGVuZ3RoKSB7XHJcbiAgICAgIHRoaXMubGluZUNvdW50ID0gMDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMubGluZUNvdW50ID0gdGV4dC5maWx0ZXIoKGMpID0+IGMuZGF0YSA9PT0gJ1xcbicpLmxlbmd0aCArIDE7XHJcbiAgICB9XHJcbiAgICB0aGlzLnRleHRSYW5nZSA9IHVuZGVmaW5lZDtcclxuICAgIHRoaXMuY2xvc2VFZGl0ZWRPcCgpO1xyXG4gICAgdGhpcy5vcGVyYXRpb25zLnJlc2V0KCk7XHJcbiAgICB0aGlzLnVwZGF0ZVZpZXdEYXRhKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25SYW5nZVBpY2socmFuZ2U6IFZhckJhc2VUZXh0UmFuZ2UpIHtcclxuICAgIHRoaXMudGV4dFJhbmdlID0gcmFuZ2U7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgcGFyc2VPcGVyYXRpb25zKCkge1xyXG4gICAgaWYgKHRoaXMuYnVzeSB8fCAhdGhpcy5pbnB1dE9wcy52YWx1ZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLl9kaWFsb2dTZXJ2aWNlXHJcbiAgICAgIC5jb25maXJtKCdDb25maXJtJywgJ1BhcnNlIG9wZXJhdGlvbnM/JylcclxuICAgICAgLnN1YnNjcmliZSgoeWVzOiBib29sZWFuKSA9PiB7XHJcbiAgICAgICAgaWYgKHllcykge1xyXG4gICAgICAgICAgdGhpcy5idXN5ID0gdHJ1ZTtcclxuICAgICAgICAgIHRoaXMucGFyc2VFcnJvciA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICB0aGlzLl9hcGkucGFyc2VPcGVyYXRpb25zKHRoaXMuaW5wdXRPcHMudmFsdWUhKS5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgICBuZXh0OiAod3JhcHBlcikgPT4ge1xyXG4gICAgICAgICAgICAgIGNvbnN0IG9wZXJhdGlvbnMgPSBbLi4udGhpcy5vcGVyYXRpb25zLnZhbHVlXTtcclxuICAgICAgICAgICAgICBvcGVyYXRpb25zLnB1c2goLi4ud3JhcHBlci5yZXN1bHQhKTtcclxuICAgICAgICAgICAgICB0aGlzLm9wZXJhdGlvbnMuc2V0VmFsdWUob3BlcmF0aW9ucyk7XHJcbiAgICAgICAgICAgICAgdGhpcy5vcGVyYXRpb25zLm1hcmtBc0RpcnR5KCk7XHJcbiAgICAgICAgICAgICAgdGhpcy5vcGVyYXRpb25zLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVZpZXdEYXRhKCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICB0aGlzLnBhcnNlRXJyb3IgPSBlcnJvci5tZXNzYWdlO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xyXG4gICAgICAgICAgICAgIHRoaXMuYnVzeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjbGVhck9wZXJhdGlvbnMoKTogdm9pZCB7XHJcbiAgICB0aGlzLl9kaWFsb2dTZXJ2aWNlXHJcbiAgICAgIC5jb25maXJtKCdDb25maXJtJywgJ1JlbW92ZSBhbGwgb3BlcmF0aW9ucz8nKVxyXG4gICAgICAuc3Vic2NyaWJlKCh5ZXM6IGJvb2xlYW4pID0+IHtcclxuICAgICAgICBpZiAoeWVzKSB7XHJcbiAgICAgICAgICB0aGlzLnJlc3VsdE9wZXJhdGlvbklkID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgdGhpcy5vcGVyYXRpb25zLnJlc2V0KCk7XHJcbiAgICAgICAgICB0aGlzLm9wZXJhdGlvbnMubWFya0FzRGlydHkoKTtcclxuICAgICAgICAgIHRoaXMub3BlcmF0aW9ucy51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZVZpZXdEYXRhKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvbk9wZXJhdGlvblByZXZpZXcob3BlcmF0aW9uOiBDaGFyQ2hhaW5PcGVyYXRpb24pOiB2b2lkIHtcclxuICAgIHRoaXMudXBkYXRlVmlld0RhdGEob3BlcmF0aW9uKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBydW5UbyhpbmRleDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBjb25zdCBzbmFwc2hvdCA9IHRoaXMuZ2V0U25hcHNob3QoKTtcclxuICAgIGlmICghc25hcHNob3QudGV4dCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBvcGVyYXRpb25zID0gdGhpcy5vcGVyYXRpb25zLnZhbHVlLnNsaWNlKDAsIGluZGV4ICsgMSk7XHJcbiAgICB0aGlzLmJ1c3kgPSB0cnVlO1xyXG4gICAgdGhpcy5fYXBpLnJ1bk9wZXJhdGlvbnMoc25hcHNob3QudGV4dCBhcyBDaGFyTm9kZVtdLCBvcGVyYXRpb25zKS5zdWJzY3JpYmUoe1xyXG4gICAgICBuZXh0OiAod3JhcHBlcikgPT4ge1xyXG4gICAgICAgIGlmICh3cmFwcGVyLmVycm9yKSB7XHJcbiAgICAgICAgICB0aGlzLl9zbmFja2Jhci5vcGVuKHdyYXBwZXIuZXJyb3IsICdPSycpO1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnJlc3VsdCA9IHdyYXBwZXIucmVzdWx0ITtcclxuICAgICAgICAvLyBUT0RPIHVwZGF0ZSB2aWV3XHJcbiAgICAgICAgLy8gdGhpcy51cGRhdGVWaWV3RGF0YShcclxuICAgICAgICAvLyAgIHVuZGVmaW5lZCxcclxuICAgICAgICAvLyAgIHNuYXBzaG90LFxyXG4gICAgICAgIC8vICAgdGhpcy5vcGVyYXRpb25zLnZhbHVlW2luZGV4XS5vdXRwdXRUYWdcclxuICAgICAgICAvLyApO1xyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogKGVycm9yKSA9PiB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XHJcbiAgICAgICAgdGhpcy5fc25hY2tiYXIub3BlbignRXJyb3IgcnVubmluZyBvcGVyYXRpb25zJywgJ09LJyk7XHJcbiAgICAgIH0sXHJcbiAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5idXN5ID0gZmFsc2U7XHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvblN0ZXBQaWNrKHN0ZXA6IENoYWluT3BlcmF0aW9uQ29udGV4dFN0ZXApOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5yZXN1bHQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5yZXN1bHRPcGVyYXRpb25JZCA9IHN0ZXAub3BlcmF0aW9uLmlkO1xyXG5cclxuICAgIC8vIGdldCBzbmFwc2hvdCBmb3IgcHJldmlldyBieSB1cGRhdGluZyBpdHMgdGV4dCBhbmRcclxuICAgIC8vIHJlbW92aW5nIG9wZXJhdGlvbnMgcGFzdCB0aGUgbGFzdCBleGVjdXRlZFxyXG4gICAgY29uc3Qgc3RlcE5vZGVzID0gdGhpcy5yZXN1bHQudGFnZ2VkTm9kZXNbc3RlcC5vdXRwdXRUYWddO1xyXG5cclxuICAgIC8vIHdlIGFsd2F5cyBkaXNwbGF5IHRoZSBvcmlnaW5hbCBiYXNlIHRleHQsIGp1c3QgdXBkYXRpbmdcclxuICAgIC8vIGl0cyBub2RlcyBmZWF0dXJlcyB0byB0aG9zZSBvZiB0aGUgcGlja2VkIHN0ZXAsIGFuZCBhZGRpbmdcclxuICAgIC8vIG5ldyBub2RlcyBpZiB0aGV5IGFyZSBub3QgaW4gdGhlIG9yaWdpbmFsIHRleHQuIEl0IGlzIGFzc3VtZWRcclxuICAgIC8vIHRoYXQgdGhlc2UgbmV3IG5vZGVzIGhhdmUgYSBtYW51YWxseSBzZXQgcG9zaXRpb24uXHJcbiAgICBjb25zdCBzbmFwc2hvdCA9IHRoaXMuZ2V0U25hcHNob3QoKTtcclxuICAgIGNvbnN0IG5vZGVzOiBDaGFyTm9kZVtdID0gZGVlcENvcHkoc25hcHNob3QudGV4dCBhcyBDaGFyTm9kZVtdKTtcclxuICAgIGZvciAoY29uc3Qgc24gb2Ygc3RlcE5vZGVzKSB7XHJcbiAgICAgIGNvbnN0IGkgPSBub2Rlcy5maW5kSW5kZXgoKG4pID0+IG4uaWQgPT09IHNuLmlkKTtcclxuICAgICAgaWYgKGkgPiAtMSkge1xyXG4gICAgICAgIG5vZGVzW2ldLmZlYXR1cmVzID0gc24uZmVhdHVyZXM7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbm9kZXMucHVzaChzbik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBmaW5kIG1heCBJRCBpbiBzbmFwc2hvdC50ZXh0ICg9b3JpZ2luYWwpIG5vZGVzLFxyXG4gICAgLy8gc28gdGhhdCBhbnkgSUQgZ3JlYXRlciB0aGFuIGl0IGJlbG9uZ3MgdG8gbmV3IG5vZGVzXHJcbiAgICBjb25zdCBtYXhPcmlnaW5hbElkID0gKHNuYXBzaG90LnRleHQgYXMgQ2hhck5vZGVbXSkucmVkdWNlKFxyXG4gICAgICAobWF4LCBuKSA9PiBNYXRoLm1heChtYXgsIG4uaWQpLFxyXG4gICAgICAwXHJcbiAgICApO1xyXG5cclxuICAgIC8vIGFwcGVuZCBub2RlcyBpbnRyb2R1Y2VkIGJlZm9yZSB0aGUgcGlja2VkIHN0ZXAgaWYgYW55XHJcbiAgICAvLyAodGhvc2UgaW50cm9kdWNlZCBieSB0aGUgcGlja2VkIHN0ZXAgaGF2ZSBhbHJlYWR5IGJlZW4gYWRkZWQpXHJcbiAgICBjb25zdCBzdGVwSW5kZXggPSB0aGlzLnJlc3VsdC5zdGVwcy5pbmRleE9mKHN0ZXApO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdGVwSW5kZXg7IGkrKykge1xyXG4gICAgICBjb25zdCBzdGVwTm9kZXMgPSB0aGlzLnJlc3VsdC50YWdnZWROb2Rlc1t0aGlzLnJlc3VsdC5zdGVwc1tpXS5vdXRwdXRUYWddO1xyXG4gICAgICBmb3IgKGNvbnN0IG4gb2Ygc3RlcE5vZGVzKSB7XHJcbiAgICAgICAgaWYgKG4uaWQgPiBtYXhPcmlnaW5hbElkICYmICFub2Rlcy5maW5kKCh4KSA9PiB4LmlkID09PSBuLmlkKSkge1xyXG4gICAgICAgICAgbm9kZXMucHVzaChuKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzbmFwc2hvdC50ZXh0ID0gbm9kZXM7XHJcbiAgICBjb25zdCBpID0gc25hcHNob3Qub3BlcmF0aW9ucy5maW5kSW5kZXgoKG8pID0+IG8uaWQgPT09IHN0ZXAub3BlcmF0aW9uLmlkKTtcclxuICAgIGlmIChpID4gLTEpIHtcclxuICAgICAgc25hcHNob3Qub3BlcmF0aW9ucyA9IHNuYXBzaG90Lm9wZXJhdGlvbnMuc2xpY2UoMCwgaSArIDEpO1xyXG4gICAgfVxyXG4gICAgdGhpcy51cGRhdGVWaWV3RGF0YSh1bmRlZmluZWQsIHNuYXBzaG90LCBzdGVwLm91dHB1dFRhZyk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25WaXN1YWxFdmVudChldmVudDogQ3VzdG9tRXZlbnQ8R3ZlVmlzdWFsRXZlbnQ+KTogdm9pZCB7XHJcbiAgICBjb25zdCBkID0gZXZlbnQuZGV0YWlsO1xyXG4gICAgaWYgKGQuZXZlbnQudHlwZSA9PT0gJ21vdXNlb3ZlcicpIHtcclxuICAgICAgY29uc3QgdmlzdWFsID0gZC5zb3VyY2U7XHJcbiAgICAgIGNvbnN0IHNiOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgICBzYi5wdXNoKCcjJyArIHZpc3VhbC5pZCk7XHJcbiAgICAgIHNiLnB1c2goYCAoJHt2aXN1YWwudHlwZX0pYCk7XHJcbiAgICAgIGlmICh2aXN1YWwuZGF0YT8ubGFiZWwpIHtcclxuICAgICAgICBzYi5wdXNoKCc6ICcpO1xyXG4gICAgICAgIHNiLnB1c2godmlzdWFsLmRhdGEubGFiZWwpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh2aXN1YWwuZGF0YT8uZmVhdHVyZXM/Lmxlbmd0aCkge1xyXG4gICAgICAgIHNiLnB1c2goXHJcbiAgICAgICAgICB2aXN1YWwuZGF0YS5mZWF0dXJlc1xyXG4gICAgICAgICAgICAubWFwKChmOiBGZWF0dXJlKSA9PiBgJHtmLm5hbWV9PSR7Zi52YWx1ZX1gKVxyXG4gICAgICAgICAgICAuam9pbignXFxuJylcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMudmlzdWFsSW5mbyA9IHNiLmpvaW4oJycpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uSGVpZ2h0c0NoYW5nZShoZWlnaHRzOiBSZWNvcmQ8bnVtYmVyLCBudW1iZXI+IHwgdW5kZWZpbmVkKTogdm9pZCB7XHJcbiAgICB0aGlzLmxuSGVpZ2h0cy5zZXRWYWx1ZShoZWlnaHRzIHx8IG51bGwpO1xyXG4gICAgdGhpcy5sbkhlaWdodHMubWFya0FzRGlydHkoKTtcclxuICAgIHRoaXMubG5IZWlnaHRzLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjbG9zZSgpOiB2b2lkIHtcclxuICAgIHRoaXMuc25hcHNob3RDYW5jZWwuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uU25hcHNob3RSZW5kZXIoZXZlbnQ6IEN1c3RvbUV2ZW50PFNuYXBzaG90Vmlld1JlbmRlckV2ZW50Pik6IHZvaWQge1xyXG4gICAgdGhpcy5fcmVuZGVyZXIgPSAoZXZlbnQuZGV0YWlsIGFzIFNuYXBzaG90Vmlld1JlbmRlckV2ZW50KS5yZW5kZXJlcjtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB0b2dnbGVSdWxlcnMoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuX3JlbmRlcmVyKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMucnVsZXJzID0gdGhpcy5fcmVuZGVyZXIudG9nZ2xlUnVsZXJzKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldFNuYXBzaG90KCk6IFNuYXBzaG90IHtcclxuICAgIGNvbnN0IHNuYXBzaG90OiBTbmFwc2hvdCA9IHtcclxuICAgICAgc2l6ZToge1xyXG4gICAgICAgIHdpZHRoOiB0aGlzLndpZHRoLnZhbHVlLFxyXG4gICAgICAgIGhlaWdodDogdGhpcy5oZWlnaHQudmFsdWUsXHJcbiAgICAgIH0sXHJcbiAgICAgIHN0eWxlOiB0aGlzLnN0eWxlLnZhbHVlIHx8IHVuZGVmaW5lZCxcclxuICAgICAgZGVmczogdGhpcy5kZWZzLnZhbHVlIHx8IHVuZGVmaW5lZCxcclxuICAgICAgdGV4dDogdGhpcy5iYXNlVGV4dC52YWx1ZSEsXHJcbiAgICAgIHRleHRTdHlsZTogdGhpcy50ZXh0U3R5bGUudmFsdWUgfHwgdW5kZWZpbmVkLFxyXG4gICAgICB0ZXh0T3B0aW9uczoge1xyXG4gICAgICAgIGxpbmVIZWlnaHRPZmZzZXQ6IHRoaXMubGluZUhlaWdodE9mZnNldC52YWx1ZSxcclxuICAgICAgICBtaW5MaW5lSGVpZ2h0czogdGhpcy5sbkhlaWdodHMudmFsdWUgfHwgdW5kZWZpbmVkLFxyXG4gICAgICAgIGNoYXJTcGFjaW5nT2Zmc2V0OiB0aGlzLmNoYXJTcGFjaW5nT2Zmc2V0LnZhbHVlLFxyXG4gICAgICAgIHNwY1dpZHRoT2Zmc2V0OiB0aGlzLnNwY1dpZHRoT2Zmc2V0LnZhbHVlLFxyXG4gICAgICAgIG9mZnNldDoge1xyXG4gICAgICAgICAgeDogdGhpcy5vZmZzZXRYLnZhbHVlLFxyXG4gICAgICAgICAgeTogdGhpcy5vZmZzZXRZLnZhbHVlLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICAgIG9wZXJhdGlvbnM6IHRoaXMub3BlcmF0aW9ucy52YWx1ZSxcclxuICAgICAgb3BTdHlsZTogdGhpcy5vcFN0eWxlLnZhbHVlIHx8IHVuZGVmaW5lZCxcclxuICAgICAgdGltZWxpbmVzOiB7fSwgLy8gVE9ET1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBpbWFnZVxyXG4gICAgaWYgKHRoaXMuaW1hZ2VVcmwudmFsdWUpIHtcclxuICAgICAgc25hcHNob3QuaW1hZ2UgPSB7XHJcbiAgICAgICAgdXJsOiB0aGlzLmltYWdlVXJsLnZhbHVlLFxyXG4gICAgICAgIG9wYWNpdHk6IHRoaXMuaW1hZ2VPcGFjaXR5LnZhbHVlIHx8IHVuZGVmaW5lZCxcclxuICAgICAgfTtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMuaW1hZ2VYLnZhbHVlIHx8XHJcbiAgICAgICAgdGhpcy5pbWFnZVkudmFsdWUgfHxcclxuICAgICAgICB0aGlzLmltYWdlV2lkdGgudmFsdWUgfHxcclxuICAgICAgICB0aGlzLmltYWdlSGVpZ2h0LnZhbHVlXHJcbiAgICAgICkge1xyXG4gICAgICAgIHNuYXBzaG90LmltYWdlLmNhbnZhcyA9IHtcclxuICAgICAgICAgIHg6IHRoaXMuaW1hZ2VYLnZhbHVlLFxyXG4gICAgICAgICAgeTogdGhpcy5pbWFnZVkudmFsdWUsXHJcbiAgICAgICAgICB3aWR0aDogdGhpcy5pbWFnZVdpZHRoLnZhbHVlLFxyXG4gICAgICAgICAgaGVpZ2h0OiB0aGlzLmltYWdlSGVpZ2h0LnZhbHVlLFxyXG4gICAgICAgIH07XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc25hcHNob3Q7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2F2ZSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmZvcm0uaW52YWxpZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLl9zbmFwc2hvdCA9IHRoaXMuZ2V0U25hcHNob3QoKTtcclxuICAgIHRoaXMuc25hcHNob3RDaGFuZ2UuZW1pdCh0aGlzLl9zbmFwc2hvdCk7XHJcbiAgfVxyXG59XHJcbiIsIjxmb3JtIFtmb3JtR3JvdXBdPVwiZm9ybVwiIChzdWJtaXQpPVwic2F2ZSgpXCI+XHJcbiAgPG1hdC10YWItZ3JvdXA+XHJcbiAgICA8IS0tIHRleHQgLS0+XHJcbiAgICA8bWF0LXRhYiBsYWJlbD1cInRleHRcIj5cclxuICAgICAgPG1hdC1leHBhbnNpb24tcGFuZWwgW2V4cGFuZGVkXT1cIiFiYXNlVGV4dC52YWx1ZVwiPlxyXG4gICAgICAgIDxtYXQtZXhwYW5zaW9uLXBhbmVsLWhlYWRlcj5cclxuICAgICAgICAgIDxtYXQtcGFuZWwtdGl0bGU+IGJhc2UgdGV4dCA8L21hdC1wYW5lbC10aXRsZT5cclxuICAgICAgICA8L21hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxyXG4gICAgICAgIDxndmUtYmFzZS10ZXh0LWVkaXRvclxyXG4gICAgICAgICAgW3RleHRdPVwiYmFzZVRleHQudmFsdWVcIlxyXG4gICAgICAgICAgKHRleHRDaGFuZ2UpPVwib25UZXh0Q2hhbmdlKCRldmVudClcIlxyXG4gICAgICAgIC8+XHJcbiAgICAgICAgPGZpZWxkc2V0PlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tcm93XCI+XHJcbiAgICAgICAgICAgIDwhLS0gb2Zmc2V0WCAtLT5cclxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiaW5wdXQtbnJcIj5cclxuICAgICAgICAgICAgICA8bWF0LWxhYmVsPlggb2Zmc2V0PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXHJcbiAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwib2Zmc2V0WFwiXHJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlggb2Zmc2V0XCJcclxuICAgICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG5cclxuICAgICAgICAgICAgPCEtLSBvZmZzZXRZIC0tPlxyXG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJpbnB1dC1uclwiPlxyXG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+WSBvZmZzZXQ8L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcclxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJvZmZzZXRZXCJcclxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiWSBvZmZzZXRcIlxyXG4gICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcblxyXG4gICAgICAgICAgICA8IS0tIGxpbmVIZWlnaHRPZmZzZXQgLS0+XHJcbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImlucHV0LW5yXCI+XHJcbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5sbiBoLW9mZnNldDwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxyXG4gICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImxpbmVIZWlnaHRPZmZzZXRcIlxyXG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJsbiBoLW9mZnNldFwiXHJcbiAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuXHJcbiAgICAgICAgICAgIDwhLS0gY2hhclNwYWNpbmdPZmZzZXQgLS0+XHJcbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImlucHV0LW5yXCI+XHJcbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5jaGFyIHNwYWNpbmc8L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcclxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJjaGFyU3BhY2luZ09mZnNldFwiXHJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImNoYXIgc3BhY2luZ1wiXHJcbiAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuXHJcbiAgICAgICAgICAgIDwhLS0gc3BjV2lkdGhPZmZzZXQgLS0+XHJcbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImlucHV0LW5yXCI+XHJcbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5zcGMgdy1vZmZzZXQ8L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcclxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJzcGNXaWR0aE9mZnNldFwiXHJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cInNwYyB3LW9mZnNldFwiXHJcbiAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgPCEtLSBtaW5MaW5lSGVpZ2h0cyAtLT5cclxuICAgICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgICA8Z3ZlLWxuLWhlaWdodHMtZWRpdG9yXHJcbiAgICAgICAgICAgICAgICBbbGluZUNvdW50XT1cImxpbmVDb3VudFwiXHJcbiAgICAgICAgICAgICAgICBbaGVpZ2h0c109XCJsbkhlaWdodHMudmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgKGhlaWdodHNDaGFuZ2UpPVwib25IZWlnaHRzQ2hhbmdlKCRldmVudClcIlxyXG4gICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8IS0tIHRleHRTdHlsZSAtLT5cclxuICAgICAgICAgIDxkaXY+XHJcbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImxvbmctdGV4dFwiIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCI+XHJcbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD50ZXh0IHN0eWxlPC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgPHRleHRhcmVhXHJcbiAgICAgICAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cInRleHRTdHlsZVwiXHJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cInRleHQgc3R5bGVcIlxyXG4gICAgICAgICAgICAgID48L3RleHRhcmVhPlxyXG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9maWVsZHNldD5cclxuICAgICAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsPlxyXG4gICAgPC9tYXQtdGFiPlxyXG5cclxuICAgIDwhLS0gb3BlcmF0aW9ucyAtLT5cclxuICAgIDxtYXQtdGFiIGxhYmVsPVwib3BlcmF0aW9uc1wiPlxyXG4gICAgICA8ZGl2IGlkPVwic25hcHNob3QtY29udGFpbmVyXCI+XHJcbiAgICAgICAgPGRpdiBpZD1cImdlbmVyYWxcIj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXJvd1wiPlxyXG4gICAgICAgICAgICA8IS0tIHdpZHRoIC0tPlxyXG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJpbnB1dC1uclwiPlxyXG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+d2lkdGg8L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcclxuICAgICAgICAgICAgICAgIG1pbj1cIjBcIlxyXG4gICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cIndpZHRoXCJcclxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwid2lkdGhcIlxyXG4gICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcblxyXG4gICAgICAgICAgICA8IS0tIGhlaWdodCAtLT5cclxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiaW5wdXQtbnJcIj5cclxuICAgICAgICAgICAgICA8bWF0LWxhYmVsPmhlaWdodDwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxyXG4gICAgICAgICAgICAgICAgbWluPVwiMFwiXHJcbiAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiaGVpZ2h0XCJcclxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiaGVpZ2h0XCJcclxuICAgICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG5cclxuICAgICAgICAgICAgPCEtLSBhZGQgb3AgLS0+XHJcbiAgICAgICAgICAgIDxkaXY+XHJcbiAgICAgICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICBtYXQtZmxhdC1idXR0b25cclxuICAgICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cIm1hdC1wcmltYXJ5XCJcclxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhYmFzZVRleHQudmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImVkaXROZXdPcGVyYXRpb24oKVwiXHJcbiAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmFkZF9jaXJjbGU8L21hdC1pY29uPiBvcGVyYXRpb25cclxuICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPCEtLSBvcHMgLS0+XHJcbiAgICAgICAgPGRpdiBpZD1cIm9wc1wiPlxyXG4gICAgICAgICAgPCEtLSBvcGVyYXRpb25zIGxpc3QgLS0+XHJcbiAgICAgICAgICBAaWYgKG9wZXJhdGlvbnMudmFsdWUubGVuZ3RoKSB7XHJcbiAgICAgICAgICA8dGFibGUgaWQ9XCJsaXN0XCI+XHJcbiAgICAgICAgICAgIDx0aGVhZD5cclxuICAgICAgICAgICAgICA8dHI+XHJcbiAgICAgICAgICAgICAgICA8dGg+PC90aD5cclxuICAgICAgICAgICAgICAgIDx0aD5JRDwvdGg+XHJcbiAgICAgICAgICAgICAgICA8dGg+dHlwZTwvdGg+XHJcbiAgICAgICAgICAgICAgICA8dGg+YXQ8L3RoPlxyXG4gICAgICAgICAgICAgICAgPHRoPnJ1bjwvdGg+XHJcbiAgICAgICAgICAgICAgICA8dGg+dmFsdWU8L3RoPlxyXG4gICAgICAgICAgICAgICAgPHRoPml0YWc8L3RoPlxyXG4gICAgICAgICAgICAgICAgPHRoPm90YWc8L3RoPlxyXG4gICAgICAgICAgICAgICAgPHRoPmdpZDwvdGg+XHJcbiAgICAgICAgICAgICAgICA8dGg+ZmVhdHM8L3RoPlxyXG4gICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgIDwvdGhlYWQ+XHJcbiAgICAgICAgICAgIDx0Ym9keT5cclxuICAgICAgICAgICAgICBAZm9yIChvcGVyYXRpb24gb2Ygb3BlcmF0aW9ucy52YWx1ZTsgdHJhY2sgb3BlcmF0aW9uLmlkOyBsZXRcclxuICAgICAgICAgICAgICBpbmRleD0kaW5kZXgpIHtcclxuICAgICAgICAgICAgICA8dHIgW25nQ2xhc3NdPVwieyBzZWxlY3RlZDogb3BlcmF0aW9uLmlkID09PSByZXN1bHRPcGVyYXRpb25JZCB9XCI+XHJcbiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJmaXQtd2lkdGhcIj5cclxuICAgICAgICAgICAgICAgICAgPCEtLSBlZGl0IC0tPlxyXG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcclxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1hdC1wcmltYXJ5XCJcclxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZWRpdE9wZXJhdGlvbihpbmRleClcIlxyXG4gICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJFZGl0IG9wZXJhdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+ZWRpdDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICA8IS0tIGRlbGV0ZSAtLT5cclxuICAgICAgICAgICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yPVwid2FyblwiXHJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImRlbGV0ZU9wZXJhdGlvbihpbmRleClcIlxyXG4gICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJEZWxldGUgb3BlcmF0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1hdC13YXJuXCI+ZGVsZXRlPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgIDwhLS0gcnVuIHRvIC0tPlxyXG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJhY2NlbnRcIlxyXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJydW5UbyhpbmRleClcIlxyXG4gICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJSdW4gdG8gdGhpcyBvcGVyYXRpb25cIlxyXG4gICAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibWF0LWFjY2VudFwiPnN1YnNjcmlwdGlvbnM8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICA8dGQ+e3sgb3BlcmF0aW9uLmlkIH19PC90ZD5cclxuICAgICAgICAgICAgICAgIDx0ZD57eyBvcGVyYXRpb24udHlwZSB8IGZsYXRMb29rdXAgOiBvcFR5cGVNYXAgfX08L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkPnt7IG9wZXJhdGlvbi5hdCB9fTwvdGQ+XHJcbiAgICAgICAgICAgICAgICA8dGQ+e3sgb3BlcmF0aW9uLnJ1biB9fTwvdGQ+XHJcbiAgICAgICAgICAgICAgICA8dGQ+e3sgb3BlcmF0aW9uLnZhbHVlIH19PC90ZD5cclxuICAgICAgICAgICAgICAgIDx0ZD57eyBvcGVyYXRpb24uaW5wdXRUYWcgfX08L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkPnt7IG9wZXJhdGlvbi5vdXRwdXRUYWcgfX08L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkPnt7IG9wZXJhdGlvbi5ncm91cElkIH19PC90ZD5cclxuICAgICAgICAgICAgICAgIDx0ZD57eyBvcGVyYXRpb24uZmVhdHVyZXM/Lmxlbmd0aCB9fTwvdGQ+XHJcbiAgICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIDwvdGJvZHk+XHJcbiAgICAgICAgICA8L3RhYmxlPlxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIDwhLS0gb3BlcmF0aW9uIGVkaXRvciAtLT5cclxuICAgICAgICAgIDxtYXQtZXhwYW5zaW9uLXBhbmVsIFtleHBhbmRlZF09XCJlZGl0ZWRPcFwiIFtkaXNhYmxlZF09XCIhZWRpdGVkT3BcIj5cclxuICAgICAgICAgICAgPG1hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxyXG4gICAgICAgICAgICAgIDxtYXQtcGFuZWwtdGl0bGU+b3BlcmF0aW9uIHt7IGVkaXRlZE9wPy5pZCB9fTwvbWF0LXBhbmVsLXRpdGxlPlxyXG4gICAgICAgICAgICA8L21hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxyXG4gICAgICAgICAgICA8ZmllbGRzZXQ+XHJcbiAgICAgICAgICAgICAgPGd2ZS1jaGFpbi1vcGVyYXRpb24tZWRpdG9yXHJcbiAgICAgICAgICAgICAgICBbb3BlcmF0aW9uXT1cImVkaXRlZE9wXCJcclxuICAgICAgICAgICAgICAgIChvcGVyYXRpb25DYW5jZWwpPVwib25PcGVyYXRpb25DYW5jZWwoKVwiXHJcbiAgICAgICAgICAgICAgICAob3BlcmF0aW9uQ2hhbmdlKT1cIm9uT3BlcmF0aW9uQ2hhbmdlKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgKG9wZXJhdGlvblByZXZpZXcpPVwib25PcGVyYXRpb25QcmV2aWV3KCRldmVudClcIlxyXG4gICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDwvZmllbGRzZXQ+XHJcbiAgICAgICAgICA8L21hdC1leHBhbnNpb24tcGFuZWw+XHJcblxyXG4gICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgPG1hdC1wcm9ncmVzcy1iYXIgbW9kZT1cImluZGV0ZXJtaW5hdGVcIiAqbmdJZj1cImJ1c3lcIiAvPlxyXG4gICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgPCEtLSBvcFN0eWxlIC0tPlxyXG4gICAgICAgICAgPGRpdiBpZD1cIm9wU3R5bGVcIj5cclxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwibG9uZy10ZXh0XCIgYXBwZWFyYW5jZT1cIm91dGxpbmVcIj5cclxuICAgICAgICAgICAgICA8bWF0LWxhYmVsPm9wZXJhdGlvbnMgc3R5bGU8L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICA8dGV4dGFyZWFcclxuICAgICAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwib3BTdHlsZVwiXHJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIm9wZXJhdGlvbnMgc3R5bGVcIlxyXG4gICAgICAgICAgICAgID48L3RleHRhcmVhPlxyXG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgPCEtLSBiYXRjaCBvcHMgLS0+XHJcbiAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICA8bWF0LWV4cGFuc2lvbi1wYW5lbD5cclxuICAgICAgICAgICAgICA8bWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XHJcbiAgICAgICAgICAgICAgICA8bWF0LXBhbmVsLXRpdGxlPmJhdGNoIG9wZXJhdGlvbnM8L21hdC1wYW5lbC10aXRsZT5cclxuICAgICAgICAgICAgICA8L21hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxyXG4gICAgICAgICAgICAgIDxmaWVsZHNldD5cclxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJiYXRjaC1jb250YWluZXJcIj5cclxuICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cImJhdGNoLWlucHV0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5vcGVyYXRpb25zPC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29kZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiaW5wdXRPcHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwib3BlcmF0aW9uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcm93cz1cIjhcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWxsY2hlY2s9XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID48L3RleHRhcmVhPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1yb3dcIj5cclxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPVwid2FyblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWF0LXdhcm5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXQtZmxhdC1idXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIlJlbW92ZSBhbGwgdGhlIG9wZXJhdGlvbnNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIW9wZXJhdGlvbnMudmFsdWUubGVuZ3RoIHx8IGJ1c3lcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2xlYXJPcGVyYXRpb25zKClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGVhclxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1hdC1wcmltYXJ5XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0LWZsYXQtYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJQYXJzZSB0ZXh0IGFuZCBhZGQgcmVzdWx0cyB0byB0aGUgb3BlcmF0aW9uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhaW5wdXRPcHMudmFsdWUgfHwgYnVzeVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJwYXJzZU9wZXJhdGlvbnMoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoIGFkZFxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICBAaWYgKHBhcnNlRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZXJyb3JcIj57eyBwYXJzZUVycm9yIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cImJhdGNoLWhlbHBcIj5cclxuICAgICAgICAgICAgICAgICAgICA8dWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8bGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+cmVwbGFjZTwvc3Ryb25nPjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+QVR4UlVOPHN0cm9uZz49PC9zdHJvbmc+XCJWQUxVRVwiPC9jb2RlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgIDxsaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz5kZWxldGU8L3N0cm9uZz46XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxjb2RlPkFUeFJVTjxzdHJvbmc+LTwvc3Ryb25nPjwvY29kZT5cclxuICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8bGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+YWRkLWJlZm9yZTwvc3Ryb25nPjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+QVR4UlVOPHN0cm9uZz4rWzwvc3Ryb25nPlwiVkFMVUVcIjwvY29kZT5cclxuICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8bGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+YWRkLWFmdGVyPC9zdHJvbmc+OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5BVHhSVU48c3Ryb25nPitdPC9zdHJvbmc+XCJWQUxVRVwiPC9jb2RlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgIDxsaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz5tb3ZlLWJlZm9yZTwvc3Ryb25nPjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+QVR4UlVOPHN0cm9uZz4mZ3Q7Wzwvc3Ryb25nPlRPPC9jb2RlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgIDxsaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz5tb3ZlLWFmdGVyPC9zdHJvbmc+OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5BVHhSVU48c3Ryb25nPiZndDtdPC9zdHJvbmc+VE88L2NvZGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPGxpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPnN3YXA8L3N0cm9uZz46XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxjb2RlPkFUeFJVTjxzdHJvbmc+Jmx0OyZndDs8L3N0cm9uZz5UT3hSVU48L2NvZGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPGxpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPmFubm90YXRlPC9zdHJvbmc+OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5BVHhSVU48c3Ryb25nPjo8L3N0cm9uZz48L2NvZGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdWw+XHJcbiAgICAgICAgICAgICAgICAgICAgPHA+Rm9yIGFsbCB0aGUgb3BlcmF0aW9uczo8L3A+XHJcbiAgICAgICAgICAgICAgICAgICAgPHVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPGxpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggPGNvZGU+KElUQUc6T1RBRyk8L2NvZGU+IHRvIGRlZmluZSBpbnB1dCBhbmQvb3JcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0IHRhZ3MsIHNlcGFyYXRlZCBieSBjb2xvbi5cclxuICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8bGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXBlbmQgPGNvZGU+JiN4NDA7PC9jb2RlPiB0byBBVCB0byB1c2UgY2hhcmFjdGVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ZXMgKDAtTikgcmF0aGVyIHRoYW4gSURzLlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgIDxsaT5SVU4gKHdoZXJlIGFwcGxpY2FibGUpIGRlZmF1bHRzIHRvIDEuPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgIDxsaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kIGZlYXR1cmVzIGxpa2UgPGNvZGU+W05BTUUgT1BFUkFUT1IgVkFMVUVdPC9jb2RlPixcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VwYXJhdGVkIGJ5IHNwYWNlLCB3aGVyZTpcclxuICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8b2w+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxsaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICBOQU1FIGlzIGFuIGFyYml0cmFyeSBzdHJpbmcuIFByZWZpeGVzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2RlPio8L2NvZGU+PWdsb2JhbCBmZWF0dXJlcywgPGNvZGU+ITwvY29kZT49cmVtb3ZlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZSAobm8gdmFsdWUpLiBTdWZmaXhlczpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5ePC9jb2RlPj1zaG9ydC1saXZlZCAobGlrZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2RlPip2ZXJzaW9uXj1hbHBoYTwvY29kZT4pLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgT1BFUkFUT1IgaXMgPGNvZGU+PTwvY29kZT4gKG11bHRpcGxlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT46PTwvY29kZT4gKHNpbmdsZSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+PT08L2NvZGU+IChmaXJzdC1zaW5nbGUpLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgVkFMVUUgaXMgYSBzdHJpbmcuIElmIGl0IGluY2x1ZGVzIHNwYWNlcywgd3JhcCBpdCBpblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2RlPlwiXCI8L2NvZGU+LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9vbD5cclxuICAgICAgICAgICAgICAgICAgICA8L3VsPlxyXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgIDwvZmllbGRzZXQ+XHJcbiAgICAgICAgICAgIDwvbWF0LWV4cGFuc2lvbi1wYW5lbD5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8IS0tIHJlc3VsdCAtLT5cclxuICAgICAgICBAaWYgKHJlc3VsdCkge1xyXG4gICAgICAgIDxmaWVsZHNldCBpZD1cInJlc3VsdFwiPlxyXG4gICAgICAgICAgPGxlZ2VuZD5yZXN1bHQ8L2xlZ2VuZD5cclxuICAgICAgICAgIDxndmUtY2hhaW4tcmVzdWx0LXZpZXdcclxuICAgICAgICAgICAgW3Jlc3VsdF09XCJyZXN1bHRcIlxyXG4gICAgICAgICAgICAoc3RlcFBpY2spPVwib25TdGVwUGljaygkZXZlbnQpXCJcclxuICAgICAgICAgIC8+XHJcbiAgICAgICAgPC9maWVsZHNldD5cclxuICAgICAgICB9XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9tYXQtdGFiPlxyXG5cclxuICAgIDwhLS0gaW1hZ2UgLS0+XHJcbiAgICA8bWF0LXRhYiBsYWJlbD1cImltYWdlXCI+XHJcbiAgICAgIDxkaXYgaWQ9XCJpbWFnZVwiPlxyXG4gICAgICAgIDxkaXYgaWQ9XCJpbWFnZS1jdGxcIj5cclxuICAgICAgICAgIDwhLS0gdXJsIC0tPlxyXG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwibG9uZy10ZXh0XCI+XHJcbiAgICAgICAgICAgIDxtYXQtbGFiZWw+VVJMPC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbZm9ybUNvbnRyb2xdPVwiaW1hZ2VVcmxcIiAvPlxyXG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXJvd1wiPlxyXG4gICAgICAgICAgICA8IS0tIHggLS0+XHJcbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImlucHV0LW5yXCI+XHJcbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5YPC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXHJcbiAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiaW1hZ2VYXCJcclxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiWFwiXHJcbiAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgPCEtLSB5IC0tPlxyXG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJpbnB1dC1uclwiPlxyXG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+WTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxyXG4gICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImltYWdlWVwiXHJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIllcIlxyXG4gICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXJvd1wiPlxyXG4gICAgICAgICAgICA8IS0tIHdpZHRoIC0tPlxyXG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJpbnB1dC1uclwiPlxyXG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+d2lkdGg8L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcclxuICAgICAgICAgICAgICAgIG1pbj1cIjBcIlxyXG4gICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImltYWdlV2lkdGhcIlxyXG4gICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgIDwhLS0gaGVpZ2h0IC0tPlxyXG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJpbnB1dC1uclwiPlxyXG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+aGVpZ2h0PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgICAgICAgdHlwZT1cIm51bWJlclwiXHJcbiAgICAgICAgICAgICAgICBtaW49XCIwXCJcclxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJpbWFnZUhlaWdodFwiXHJcbiAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPCEtLSBkZWZzIC0tPlxyXG4gICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwibG9uZy10ZXh0XCI+XHJcbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5kZWZzPC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgPHRleHRhcmVhIG1hdElucHV0IFtmb3JtQ29udHJvbF09XCJkZWZzXCIgcm93cz1cIjNcIj48L3RleHRhcmVhPlxyXG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiBpZD1cImltYWdlLXZpZXdcIj5cclxuICAgICAgICAgIEBpZiAoaW1hZ2VVcmwudmFsdWUpIHtcclxuICAgICAgICAgIDxpbWcgYWx0PVwiYmFja2dyb3VuZFwiIFtzcmNdPVwiaW1hZ2VVcmwudmFsdWVcIiB3aWR0aD1cIjYwMFwiIC8+XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9tYXQtdGFiPlxyXG4gIDwvbWF0LXRhYi1ncm91cD5cclxuXHJcbiAgPCEtLSBwcmV2aWV3IC0tPlxyXG4gIEBpZiAoc25hcHNob3QpIHtcclxuICA8ZmllbGRzZXQgaWQ9XCJwcmV2aWV3XCI+XHJcbiAgICA8bGVnZW5kIGNsYXNzPVwiYnV0dG9uLXJvd1wiPlxyXG4gICAgICA8c3Bhbj57eyB2aWV3VGl0bGUgfX08L3NwYW4+XHJcbiAgICAgIDxidXR0b25cclxuICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgIG1hdFRvb2x0aXA9XCJSZWZyZXNoIHByZXZpZXdcIlxyXG4gICAgICAgIChjbGljayk9XCJ1cGRhdGVWaWV3RGF0YSgpXCJcclxuICAgICAgPlxyXG4gICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1hdC1wcmltYXJ5XCI+cmVmcmVzaDwvbWF0LWljb24+XHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgPC9sZWdlbmQ+XHJcbiAgICA8Z3ZlLXNuYXBzaG90LXZpZXdcclxuICAgICAgW2RhdGFdPVwidmlld0RhdGFcIlxyXG4gICAgICAoc25hcHNob3RSZW5kZXIpPVwib25TbmFwc2hvdFJlbmRlcigkYW55KCRldmVudCkpXCJcclxuICAgICAgKHZpc3VhbEV2ZW50KT1cIm9uVmlzdWFsRXZlbnQoJGFueSgkZXZlbnQpKVwiXHJcbiAgICAvPlxyXG4gICAgPGRpdj5cclxuICAgICAgPG1hdC1idXR0b24tdG9nZ2xlXHJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcclxuICAgICAgICBtYXRUb29sdGlwPVwiVG9nZ2xlIHJ1bGVyc1wiXHJcbiAgICAgICAgW2NoZWNrZWRdPVwicnVsZXJzXCJcclxuICAgICAgICAoY2hhbmdlKT1cInRvZ2dsZVJ1bGVycygpXCJcclxuICAgICAgPlxyXG4gICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1hdC1wcmltYXJ5XCI+c3RyYWlnaHRlbjwvbWF0LWljb24+XHJcbiAgICAgIDwvbWF0LWJ1dHRvbi10b2dnbGU+XHJcbiAgICA8L2Rpdj5cclxuICAgIEBpZiAodmlzdWFsSW5mbykge1xyXG4gICAgPGRpdiBpZD1cInZpc3VhbC1pbmZvXCI+e3sgdmlzdWFsSW5mbyB9fTwvZGl2PlxyXG4gICAgfVxyXG4gIDwvZmllbGRzZXQ+XHJcbiAgfVxyXG5cclxuICA8IS0tYnV0dG9ucyAtLT5cclxuICA8ZGl2IGNsYXNzPVwiZm9ybS1yb3ctY2VudGVyXCI+XHJcbiAgICA8YnV0dG9uXHJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICBjbGFzcz1cIm1hdC13YXJuXCJcclxuICAgICAgbWF0LWZsYXQtYnV0dG9uXHJcbiAgICAgIG1hdFRvb2x0aXA9XCJEaXNjYXJkIGNoYW5nZXNcIlxyXG4gICAgICAoY2xpY2spPVwiY2xvc2UoKVwiXHJcbiAgICA+XHJcbiAgICAgIDxtYXQtaWNvbj5jbGVhcjwvbWF0LWljb24+XHJcbiAgICAgIGNsb3NlXHJcbiAgICA8L2J1dHRvbj5cclxuICAgIDxidXR0b25cclxuICAgICAgdHlwZT1cInN1Ym1pdFwiXHJcbiAgICAgIGNsYXNzPVwibWF0LXByaW1hcnlcIlxyXG4gICAgICBtYXQtZmxhdC1idXR0b25cclxuICAgICAgbWF0VG9vbHRpcD1cIlNhdmUgY2hhbmdlc1wiXHJcbiAgICAgIFtkaXNhYmxlZF09XCJmb3JtLmludmFsaWQgfHwgZm9ybS5wcmlzdGluZVwiXHJcbiAgICA+XHJcbiAgICAgIDxtYXQtaWNvbj5jaGVja19jaXJjbGU8L21hdC1pY29uPlxyXG4gICAgICBzYXZlXHJcbiAgICA8L2J1dHRvbj5cclxuICA8L2Rpdj5cclxuPC9mb3JtPlxyXG4iXX0=
|