@myrmidon/cadmus-refs-asserted-ids 2.0.0 → 2.1.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 +96 -96
- package/esm2022/lib/asserted-composite-id/asserted-composite-id.component.mjs +142 -0
- package/esm2022/lib/asserted-composite-ids/asserted-composite-ids.component.mjs +154 -0
- package/esm2022/lib/asserted-id/asserted-id.component.mjs +3 -3
- package/esm2022/lib/cadmus-refs-asserted-ids.module.mjs +31 -1
- package/esm2022/lib/pin-target-lookup/pin-target-lookup.component.mjs +405 -0
- package/esm2022/lib/scoped-pin-lookup/scoped-pin-lookup.component.mjs +3 -3
- package/esm2022/lib/services/item-ref-lookup.service.mjs +29 -0
- package/esm2022/lib/services/pin-ref-lookup.service.mjs +17 -5
- package/esm2022/public-api.mjs +5 -1
- package/fesm2022/myrmidon-cadmus-refs-asserted-ids.mjs +737 -19
- package/fesm2022/myrmidon-cadmus-refs-asserted-ids.mjs.map +1 -1
- package/lib/asserted-composite-id/asserted-composite-id.component.d.ts +83 -0
- package/lib/asserted-composite-ids/asserted-composite-ids.component.d.ts +67 -0
- package/lib/cadmus-refs-asserted-ids.module.d.ts +21 -15
- package/lib/pin-target-lookup/pin-target-lookup.component.d.ts +139 -0
- package/lib/services/item-ref-lookup.service.d.ts +13 -0
- package/lib/services/pin-ref-lookup.service.d.ts +10 -1
- package/package.json +1 -1
- package/public-api.d.ts +4 -0
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { Component, EventEmitter, Inject, Input, Output, } from '@angular/core';
|
|
2
|
+
import { Validators, } from '@angular/forms';
|
|
3
|
+
import { debounceTime, distinctUntilChanged, forkJoin, take, } from 'rxjs';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "../services/item-ref-lookup.service";
|
|
6
|
+
import * as i2 from "../services/pin-ref-lookup.service";
|
|
7
|
+
import * as i3 from "@myrmidon/cadmus-api";
|
|
8
|
+
import * as i4 from "@angular/material/snack-bar";
|
|
9
|
+
import * as i5 from "@angular/forms";
|
|
10
|
+
import * as i6 from "@angular/common";
|
|
11
|
+
import * as i7 from "@angular/cdk/clipboard";
|
|
12
|
+
import * as i8 from "@angular/material/button";
|
|
13
|
+
import * as i9 from "@angular/material/checkbox";
|
|
14
|
+
import * as i10 from "@angular/material/expansion";
|
|
15
|
+
import * as i11 from "@angular/material/form-field";
|
|
16
|
+
import * as i12 from "@angular/material/icon";
|
|
17
|
+
import * as i13 from "@angular/material/input";
|
|
18
|
+
import * as i14 from "@angular/material/select";
|
|
19
|
+
import * as i15 from "@angular/material/core";
|
|
20
|
+
import * as i16 from "@myrmidon/cadmus-refs-lookup";
|
|
21
|
+
import * as i17 from "@myrmidon/ng-tools";
|
|
22
|
+
// from Cadmus general parts
|
|
23
|
+
const METADATA_PART_ID = 'it.vedph.metadata';
|
|
24
|
+
/*
|
|
25
|
+
* Scoped pin-based lookup component. This component provides a list
|
|
26
|
+
* of pin-based searches, with a lookup control. Whenever the user
|
|
27
|
+
* picks a pin value, he gets the details about its item and part, and
|
|
28
|
+
* item's metadata part, if any. He can then use these data to build
|
|
29
|
+
* some EID by variously assembling these components.
|
|
30
|
+
*/
|
|
31
|
+
class PinTargetLookupComponent {
|
|
32
|
+
/**
|
|
33
|
+
* True when the by-type pin lookup mode is active.
|
|
34
|
+
* User can change mode unless modeSwitching is false.
|
|
35
|
+
*/
|
|
36
|
+
get pinByTypeMode() {
|
|
37
|
+
return this.byTypeMode?.value;
|
|
38
|
+
}
|
|
39
|
+
set pinByTypeMode(value) {
|
|
40
|
+
if (!this.byTypeMode) {
|
|
41
|
+
this._startWithByTypeMode = value;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.byTypeMode.setValue(value || false);
|
|
45
|
+
this.byTypeMode.updateValueAndValidity();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The target to be edited.
|
|
50
|
+
*/
|
|
51
|
+
get target() {
|
|
52
|
+
return this._target;
|
|
53
|
+
}
|
|
54
|
+
set target(value) {
|
|
55
|
+
if (this._target === value) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this._target = value || undefined;
|
|
59
|
+
this.updateForm(this._target);
|
|
60
|
+
}
|
|
61
|
+
constructor(_presetLookupDefs, itemLookupService, pinLookupService, _itemService, _thesService, _snackbar, formBuilder) {
|
|
62
|
+
this._presetLookupDefs = _presetLookupDefs;
|
|
63
|
+
this.itemLookupService = itemLookupService;
|
|
64
|
+
this.pinLookupService = pinLookupService;
|
|
65
|
+
this._itemService = _itemService;
|
|
66
|
+
this._thesService = _thesService;
|
|
67
|
+
this._snackbar = _snackbar;
|
|
68
|
+
this.partTypeKeys = [];
|
|
69
|
+
this.itemParts = [];
|
|
70
|
+
this._subs = [];
|
|
71
|
+
this.modelEntries = [];
|
|
72
|
+
// this is the default filter for the pin lookup, which will
|
|
73
|
+
// be merged with values provided by user here
|
|
74
|
+
this.filter = {
|
|
75
|
+
text: '',
|
|
76
|
+
limit: 10,
|
|
77
|
+
};
|
|
78
|
+
// form
|
|
79
|
+
this.item = formBuilder.control(null);
|
|
80
|
+
this.itemPart = formBuilder.control(null);
|
|
81
|
+
this.partTypeKey = formBuilder.control(null);
|
|
82
|
+
this.gid = formBuilder.control(null, [
|
|
83
|
+
Validators.required,
|
|
84
|
+
Validators.maxLength(300),
|
|
85
|
+
]);
|
|
86
|
+
this.label = formBuilder.control(null, [
|
|
87
|
+
Validators.required,
|
|
88
|
+
Validators.maxLength(300),
|
|
89
|
+
]);
|
|
90
|
+
this.byTypeMode = formBuilder.control(false, { nonNullable: true });
|
|
91
|
+
this.external = formBuilder.control(false, { nonNullable: true });
|
|
92
|
+
this.form = formBuilder.group({
|
|
93
|
+
item: this.item,
|
|
94
|
+
itemPart: this.itemPart,
|
|
95
|
+
partTypeKey: this.partTypeKey,
|
|
96
|
+
gid: this.gid,
|
|
97
|
+
label: this.label,
|
|
98
|
+
byTypeMode: this.byTypeMode,
|
|
99
|
+
external: this.external,
|
|
100
|
+
});
|
|
101
|
+
// events
|
|
102
|
+
this.targetChange = new EventEmitter();
|
|
103
|
+
this.editorClose = new EventEmitter();
|
|
104
|
+
}
|
|
105
|
+
forceByItem() {
|
|
106
|
+
this.pinByTypeMode = false;
|
|
107
|
+
this.canSwitchMode = false;
|
|
108
|
+
}
|
|
109
|
+
setupKeys() {
|
|
110
|
+
// use DI presets if no lookup definitions
|
|
111
|
+
if (!this.lookupDefinitions) {
|
|
112
|
+
this.lookupDefinitions = this._presetLookupDefs;
|
|
113
|
+
}
|
|
114
|
+
// keys are all the defined lookup searches
|
|
115
|
+
this.partTypeKeys = Object.keys(this.lookupDefinitions);
|
|
116
|
+
// if no keys, get them from thesaurus model-types;
|
|
117
|
+
// if this is not available, just force by item mode.
|
|
118
|
+
if (!this.partTypeKeys.length) {
|
|
119
|
+
if (this.modelEntries?.length) {
|
|
120
|
+
// set lookupDefinitions from thesaurus entries
|
|
121
|
+
this.lookupDefinitions = {};
|
|
122
|
+
this.modelEntries.forEach((e) => {
|
|
123
|
+
this.lookupDefinitions[e.value] = {
|
|
124
|
+
name: e.value,
|
|
125
|
+
typeId: e.id,
|
|
126
|
+
};
|
|
127
|
+
});
|
|
128
|
+
// set type keys from thesaurus entries
|
|
129
|
+
this.partTypeKeys = this.modelEntries.map((e) => e.value);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// if still no keys, force by item mode
|
|
133
|
+
if (!this.partTypeKeys.length) {
|
|
134
|
+
this.forceByItem();
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// if there is only one key, set it as the default
|
|
138
|
+
if (this.partTypeKeys.length === 1) {
|
|
139
|
+
this.partTypeKey.setValue(this.partTypeKeys[0]);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
canBuildGid() {
|
|
144
|
+
return (!this.external.value && !this.gid.value) || this.gid.pristine;
|
|
145
|
+
}
|
|
146
|
+
canBuildLabel() {
|
|
147
|
+
return (!this.external.value && !this.label.value) || this.label.pristine;
|
|
148
|
+
}
|
|
149
|
+
ngOnInit() {
|
|
150
|
+
// set start mode if required
|
|
151
|
+
if (this._startWithByTypeMode) {
|
|
152
|
+
this.byTypeMode.setValue(true);
|
|
153
|
+
}
|
|
154
|
+
// whenever item changes, update item's parts and filter
|
|
155
|
+
this._subs.push(this.item.valueChanges
|
|
156
|
+
.pipe(distinctUntilChanged(), debounceTime(300))
|
|
157
|
+
.subscribe((item) => {
|
|
158
|
+
this.itemPart.setValue(null);
|
|
159
|
+
this.itemParts = item?.parts || [];
|
|
160
|
+
this.filter = {
|
|
161
|
+
...this.filter,
|
|
162
|
+
itemId: item?.id,
|
|
163
|
+
};
|
|
164
|
+
}));
|
|
165
|
+
// whenever itemPart changes, update target and eventually gid
|
|
166
|
+
this._subs.push(this.itemPart.valueChanges
|
|
167
|
+
.pipe(distinctUntilChanged(), debounceTime(300))
|
|
168
|
+
.subscribe((part) => {
|
|
169
|
+
if (!this.gid.value || this.gid.pristine) {
|
|
170
|
+
this.gid.setValue(this.buildGid());
|
|
171
|
+
}
|
|
172
|
+
this.filter = {
|
|
173
|
+
...this.filter,
|
|
174
|
+
partId: part?.id,
|
|
175
|
+
};
|
|
176
|
+
this.updateTarget();
|
|
177
|
+
}));
|
|
178
|
+
// whenever partTypeKey changes, update filter's options
|
|
179
|
+
this._subs.push(this.partTypeKey.valueChanges
|
|
180
|
+
.pipe(distinctUntilChanged(), debounceTime(300))
|
|
181
|
+
.subscribe((key) => {
|
|
182
|
+
this.pinFilterOptions = key
|
|
183
|
+
? this.lookupDefinitions[key]
|
|
184
|
+
: undefined;
|
|
185
|
+
}));
|
|
186
|
+
// load model-types thesaurus entries
|
|
187
|
+
this._thesService.getThesaurus('model-types', true).subscribe({
|
|
188
|
+
next: (t) => {
|
|
189
|
+
this.modelEntries = t.entries || [];
|
|
190
|
+
if (this.modelEntries?.length) {
|
|
191
|
+
this.setupKeys();
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
this.forceByItem();
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
error: () => {
|
|
198
|
+
this.forceByItem();
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
ngOnDestroy() {
|
|
203
|
+
for (let i = 0; i < this._subs.length; i++) {
|
|
204
|
+
this._subs[i].unsubscribe();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
buildGid() {
|
|
208
|
+
// the GID is the part ID if any, or the item ID, followed by
|
|
209
|
+
// the pin's value (=EID)
|
|
210
|
+
const pin = this.lookupData?.pin;
|
|
211
|
+
if (!pin) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
return pin.partId
|
|
215
|
+
? `P${pin.partId}/${pin.value}`
|
|
216
|
+
: `I${pin.itemId}/${pin.value}`;
|
|
217
|
+
}
|
|
218
|
+
buildLabel() {
|
|
219
|
+
if (!this.lookupData?.pin) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
const sb = [];
|
|
223
|
+
// pin value
|
|
224
|
+
sb.push(this.lookupData.pin.value);
|
|
225
|
+
// item title
|
|
226
|
+
sb.push(' | ');
|
|
227
|
+
sb.push(this.lookupData.item.title || this.lookupData.item.id);
|
|
228
|
+
// part type and role
|
|
229
|
+
const e = this.modelEntries?.find((e) => e.id === this.lookupData.pin.partTypeId);
|
|
230
|
+
sb.push(' (');
|
|
231
|
+
sb.push(e?.value || this.lookupData.pin.partTypeId);
|
|
232
|
+
if (this.lookupData.pin.roleId) {
|
|
233
|
+
sb.push(`, ${this.lookupData.pin.roleId}`);
|
|
234
|
+
}
|
|
235
|
+
sb.push(')');
|
|
236
|
+
return sb.join('');
|
|
237
|
+
}
|
|
238
|
+
getTarget() {
|
|
239
|
+
if (this.external.value) {
|
|
240
|
+
return {
|
|
241
|
+
gid: this.gid.value || '',
|
|
242
|
+
label: this.label.value || '',
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
const pin = this.lookupData?.pin;
|
|
247
|
+
return {
|
|
248
|
+
gid: this.gid.value || '',
|
|
249
|
+
label: this.label.value || '',
|
|
250
|
+
itemId: pin?.itemId || '',
|
|
251
|
+
partId: pin?.partId || '',
|
|
252
|
+
partTypeId: pin?.partTypeId || '',
|
|
253
|
+
roleId: pin?.roleId || '',
|
|
254
|
+
name: pin?.name || '',
|
|
255
|
+
value: pin?.value || '',
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
updateTarget() {
|
|
260
|
+
this._noFormUpdate = true;
|
|
261
|
+
if (this.canBuildGid()) {
|
|
262
|
+
this.gid.setValue(this.buildGid());
|
|
263
|
+
this.gid.markAsDirty();
|
|
264
|
+
}
|
|
265
|
+
if (this.canBuildLabel()) {
|
|
266
|
+
this.label.setValue(this.buildLabel());
|
|
267
|
+
this.label.markAsDirty();
|
|
268
|
+
}
|
|
269
|
+
this.target = this.getTarget();
|
|
270
|
+
this._noFormUpdate = false;
|
|
271
|
+
}
|
|
272
|
+
updateForm(target) {
|
|
273
|
+
if (this._noFormUpdate) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
// build pin info from target
|
|
277
|
+
if (!target) {
|
|
278
|
+
this.lookupData = undefined;
|
|
279
|
+
this.form.reset();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
this.external.setValue(!target.name);
|
|
283
|
+
this.lookupData = {
|
|
284
|
+
pin: {
|
|
285
|
+
itemId: target.itemId || '',
|
|
286
|
+
partId: target.partId || '',
|
|
287
|
+
partTypeId: target.partTypeId || '',
|
|
288
|
+
roleId: target.roleId || '',
|
|
289
|
+
name: target.name || '',
|
|
290
|
+
value: target.value || '',
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
// get item
|
|
294
|
+
if (target.itemId) {
|
|
295
|
+
this._itemService.getItem(target.itemId, true).subscribe({
|
|
296
|
+
next: (item) => {
|
|
297
|
+
this.item.setValue(item);
|
|
298
|
+
this.form.markAsPristine();
|
|
299
|
+
},
|
|
300
|
+
error: (error) => {
|
|
301
|
+
if (error) {
|
|
302
|
+
console.error(JSON.stringify(error));
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Called when the item lookup changes (item is looked up
|
|
310
|
+
* by its title).
|
|
311
|
+
*
|
|
312
|
+
* @param item The item got from lookup.
|
|
313
|
+
*/
|
|
314
|
+
onItemLookupChange(item) {
|
|
315
|
+
// load item's parts
|
|
316
|
+
this._itemService.getItem(item.id, true).subscribe({
|
|
317
|
+
next: (i) => {
|
|
318
|
+
// setting the item will trigger its parts update
|
|
319
|
+
this.item.setValue(i);
|
|
320
|
+
this.updateTarget();
|
|
321
|
+
},
|
|
322
|
+
error: (error) => {
|
|
323
|
+
if (error) {
|
|
324
|
+
console.error(JSON.stringify(error));
|
|
325
|
+
}
|
|
326
|
+
this.itemPart.setValue(null);
|
|
327
|
+
this.itemParts = [];
|
|
328
|
+
this.updateTarget();
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
loadItemInfo(pin) {
|
|
333
|
+
forkJoin({
|
|
334
|
+
item: this._itemService.getItem(pin.itemId, false),
|
|
335
|
+
part: this._itemService.getPartFromTypeAndRole(pin.itemId, METADATA_PART_ID),
|
|
336
|
+
})
|
|
337
|
+
.pipe(take(1))
|
|
338
|
+
.subscribe({
|
|
339
|
+
next: (result) => {
|
|
340
|
+
this.lookupData = {
|
|
341
|
+
pin: pin,
|
|
342
|
+
item: result.item,
|
|
343
|
+
metaPart: result.part,
|
|
344
|
+
};
|
|
345
|
+
this.updateTarget();
|
|
346
|
+
},
|
|
347
|
+
error: (error) => {
|
|
348
|
+
this.lookupData = undefined;
|
|
349
|
+
console.error(error ? JSON.stringify(error) : 'Error loading item/metadata');
|
|
350
|
+
},
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Called when the pin lookup change. A pin is looked up by its
|
|
355
|
+
* name and value (=the filter's text), and optionally by:
|
|
356
|
+
* - its index lookup definition (selected by partTypeKey).
|
|
357
|
+
* - its item (defined by item, in filter).
|
|
358
|
+
* - its part (defined by itemPart, in filter).
|
|
359
|
+
*
|
|
360
|
+
* @param info The pin info from pin lookup.
|
|
361
|
+
*/
|
|
362
|
+
onPinLookupChange(info) {
|
|
363
|
+
this.loadItemInfo(info);
|
|
364
|
+
}
|
|
365
|
+
onCopied() {
|
|
366
|
+
this._snackbar.open('Copied to clipboard', 'OK', {
|
|
367
|
+
duration: 1500,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
close() {
|
|
371
|
+
this.editorClose.emit();
|
|
372
|
+
}
|
|
373
|
+
save() {
|
|
374
|
+
if (this.form.invalid) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
this._target = this.getTarget();
|
|
378
|
+
this.targetChange.emit(this._target);
|
|
379
|
+
}
|
|
380
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: PinTargetLookupComponent, deps: [{ token: 'indexLookupDefinitions' }, { token: i1.ItemRefLookupService }, { token: i2.PinRefLookupService }, { token: i3.ItemService }, { token: i3.ThesaurusService }, { token: i4.MatSnackBar }, { token: i5.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
381
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: PinTargetLookupComponent, selector: "cadmus-pin-target-lookup", inputs: { pinByTypeMode: "pinByTypeMode", canSwitchMode: "canSwitchMode", canEditTarget: "canEditTarget", lookupDefinitions: "lookupDefinitions", target: "target" }, outputs: { editorClose: "editorClose", targetChange: "targetChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <!-- external -->\r\n <mat-checkbox [formControl]=\"external\">external</mat-checkbox>\r\n\r\n <div class=\"form-row\">\r\n <!-- label -->\r\n <div>\r\n <mat-form-field *ngIf=\"external.value || canEditTarget\">\r\n <mat-label>label</mat-label>\r\n <input matInput [formControl]=\"label\" />\r\n <mat-error\r\n *ngIf=\"$any(label).errors?.required && (label.dirty || label.touched)\"\r\n >label required</mat-error\r\n >\r\n <mat-error\r\n *ngIf=\"\r\n $any(label).errors?.maxLength && (label.dirty || label.touched)\r\n \"\r\n >label too long</mat-error\r\n >\r\n </mat-form-field>\r\n <div\r\n *ngIf=\"!external.value && !canEditTarget && label.value\"\r\n class=\"info\"\r\n >\r\n <span class=\"label\">label</span>{{ label.value }}\r\n </div>\r\n </div>\r\n\r\n <!-- gid -->\r\n <div>\r\n <mat-form-field *ngIf=\"external.value || canEditTarget\">\r\n <mat-label>GID</mat-label>\r\n <input matInput [formControl]=\"gid\" />\r\n <mat-error\r\n *ngIf=\"$any(gid).errors?.required && (gid.dirty || gid.touched)\"\r\n >GID required</mat-error\r\n >\r\n <mat-error\r\n *ngIf=\"$any(gid).errors?.maxLength && (gid.dirty || gid.touched)\"\r\n >GID too long</mat-error\r\n >\r\n </mat-form-field>\r\n <div *ngIf=\"!external.value && !canEditTarget && gid.value\" class=\"info\">\r\n <span class=\"label\">GID</span> <span class=\"gid\">{{ gid.value }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- BY ITEM -->\r\n <div *ngIf=\"!external.value\">\r\n <fieldset *ngIf=\"!byTypeMode.value\" class=\"form-row\">\r\n <legend>pin filters</legend>\r\n <!-- item filter -->\r\n <cadmus-ref-lookup\r\n [service]=\"itemLookupService\"\r\n label=\"item\"\r\n (itemChange)=\"onItemLookupChange($event)\"\r\n ></cadmus-ref-lookup>\r\n\r\n <!-- part filter -->\r\n <mat-form-field *ngIf=\"itemParts.length\">\r\n <mat-label>part</mat-label>\r\n <mat-select [formControl]=\"itemPart\">\r\n <mat-option [value]=\"null\">(any)</mat-option>\r\n <mat-option *ngFor=\"let p of itemParts\" [value]=\"p\">{{\r\n p.typeId | flatLookup : modelEntries : \"id\" : \"value\"\r\n }}</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </fieldset>\r\n\r\n <!-- BY TYPE -->\r\n <div *ngIf=\"byTypeMode.value\">\r\n <!-- par type filter -->\r\n <mat-form-field *ngIf=\"partTypeKeys?.length\">\r\n <mat-label>part type</mat-label>\r\n <mat-select [formControl]=\"partTypeKey\">\r\n <mat-option *ngFor=\"let k of partTypeKeys\" [value]=\"k\">{{\r\n k\r\n }}</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- PIN -->\r\n <div class=\"form-row\">\r\n <!-- pin lookup -->\r\n <cadmus-ref-lookup\r\n [service]=\"pinLookupService\"\r\n [baseFilter]=\"filter\"\r\n [options]=\"pinFilterOptions\"\r\n label=\"pin\"\r\n (itemChange)=\"onPinLookupChange($event)\"\r\n ></cadmus-ref-lookup>\r\n <!-- mode switcher -->\r\n <div>\r\n <mat-checkbox [formControl]=\"byTypeMode\" *ngIf=\"canSwitchMode\">\r\n by type</mat-checkbox\r\n >\r\n </div>\r\n </div>\r\n\r\n <!-- data -->\r\n <mat-expansion-panel id=\"data\" *ngIf=\"lookupData?.pin?.name\">\r\n <mat-expansion-panel-header>pin data</mat-expansion-panel-header>\r\n <!-- table -->\r\n <table>\r\n <thead>\r\n <th></th>\r\n <th>source</th>\r\n <th>value</th>\r\n </thead>\r\n <tbody>\r\n <!-- pin -->\r\n <tr *ngIf=\"lookupData?.pin?.value\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>pin</td>\r\n <td>{{ lookupData!.pin.value }}</td>\r\n </tr>\r\n <!-- item ID -->\r\n <tr *ngIf=\"lookupData?.pin?.itemId\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.itemId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item ID</td>\r\n <td>{{ lookupData!.pin.itemId }}</td>\r\n </tr>\r\n <!-- item title -->\r\n <tr *ngIf=\"lookupData?.item?.title\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.item!.title\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item title</td>\r\n <td>{{ lookupData!.item!.title }}</td>\r\n </tr>\r\n <!-- part ID -->\r\n <tr *ngIf=\"lookupData?.pin?.partId\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part ID</td>\r\n <td>{{ lookupData!.pin.partId }}</td>\r\n </tr>\r\n <!-- part type ID -->\r\n <tr *ngIf=\"lookupData?.pin?.partTypeId\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partTypeId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part type ID</td>\r\n <td>{{ lookupData!.pin!.partTypeId }}</td>\r\n </tr>\r\n <!-- part role ID -->\r\n <tr *ngIf=\"lookupData?.pin?.roleId\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.roleId!\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part role ID</td>\r\n <td>{{ lookupData!.pin!.roleId }}</td>\r\n </tr>\r\n\r\n <!-- part's metadata -->\r\n <tr\r\n *ngFor=\"\r\n let m of lookupData?.metaPart?.metadata || [];\r\n let i = index\r\n \"\r\n >\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"m.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td class=\"metadata\">{{ m.name }}</td>\r\n <td class=\"metadata\">{{ m.value }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </mat-expansion-panel>\r\n </div>\r\n\r\n <!-- buttons -->\r\n <div>\r\n <button mat-flat-button type=\"button\" (click)=\"close()\">\r\n <mat-icon color=\"warn\">close</mat-icon>\r\n </button>\r\n <button mat-flat-button type=\"submit\" [disabled]=\"form.invalid\">\r\n <mat-icon color=\"primary\">check_circle</mat-icon> target\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".metadata{color:#4a3001}.info{border:1px solid silver;border-radius:6px;background-color:silver;color:#fff;padding:4px;margin:8px 0}.info .label{background-color:#fff;color:silver;margin:0 6px}#data{margin:8px 0}table{border:1px solid silver;border-radius:6px;padding:4px;margin-top:8px}tr:nth-child(odd){background-color:#f0f0f0}th{font-weight:400;text-align:left;color:silver}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.label{border:1px solid silver;border-radius:6px;padding:4px}fieldset{border:1px solid silver;border-radius:6px;padding:4px 8px;margin-bottom:8px}legend{color:silver}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i7.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "component", type: i8.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i10.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i10.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["tabIndex", "expandedHeight", "collapsedHeight"] }, { kind: "component", type: i11.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i11.MatLabel, selector: "mat-label" }, { kind: "directive", type: i11.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i12.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i13.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: "component", type: i14.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i15.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i16.RefLookupComponent, selector: "cadmus-ref-lookup", inputs: ["label", "limit", "baseFilter", "service", "item", "required", "hasMore", "linkTemplate", "optDialog", "options"], outputs: ["itemChange", "moreRequest"] }, { kind: "pipe", type: i17.FlatLookupPipe, name: "flatLookup" }] }); }
|
|
382
|
+
}
|
|
383
|
+
export { PinTargetLookupComponent };
|
|
384
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: PinTargetLookupComponent, decorators: [{
|
|
385
|
+
type: Component,
|
|
386
|
+
args: [{ selector: 'cadmus-pin-target-lookup', template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <!-- external -->\r\n <mat-checkbox [formControl]=\"external\">external</mat-checkbox>\r\n\r\n <div class=\"form-row\">\r\n <!-- label -->\r\n <div>\r\n <mat-form-field *ngIf=\"external.value || canEditTarget\">\r\n <mat-label>label</mat-label>\r\n <input matInput [formControl]=\"label\" />\r\n <mat-error\r\n *ngIf=\"$any(label).errors?.required && (label.dirty || label.touched)\"\r\n >label required</mat-error\r\n >\r\n <mat-error\r\n *ngIf=\"\r\n $any(label).errors?.maxLength && (label.dirty || label.touched)\r\n \"\r\n >label too long</mat-error\r\n >\r\n </mat-form-field>\r\n <div\r\n *ngIf=\"!external.value && !canEditTarget && label.value\"\r\n class=\"info\"\r\n >\r\n <span class=\"label\">label</span>{{ label.value }}\r\n </div>\r\n </div>\r\n\r\n <!-- gid -->\r\n <div>\r\n <mat-form-field *ngIf=\"external.value || canEditTarget\">\r\n <mat-label>GID</mat-label>\r\n <input matInput [formControl]=\"gid\" />\r\n <mat-error\r\n *ngIf=\"$any(gid).errors?.required && (gid.dirty || gid.touched)\"\r\n >GID required</mat-error\r\n >\r\n <mat-error\r\n *ngIf=\"$any(gid).errors?.maxLength && (gid.dirty || gid.touched)\"\r\n >GID too long</mat-error\r\n >\r\n </mat-form-field>\r\n <div *ngIf=\"!external.value && !canEditTarget && gid.value\" class=\"info\">\r\n <span class=\"label\">GID</span> <span class=\"gid\">{{ gid.value }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- BY ITEM -->\r\n <div *ngIf=\"!external.value\">\r\n <fieldset *ngIf=\"!byTypeMode.value\" class=\"form-row\">\r\n <legend>pin filters</legend>\r\n <!-- item filter -->\r\n <cadmus-ref-lookup\r\n [service]=\"itemLookupService\"\r\n label=\"item\"\r\n (itemChange)=\"onItemLookupChange($event)\"\r\n ></cadmus-ref-lookup>\r\n\r\n <!-- part filter -->\r\n <mat-form-field *ngIf=\"itemParts.length\">\r\n <mat-label>part</mat-label>\r\n <mat-select [formControl]=\"itemPart\">\r\n <mat-option [value]=\"null\">(any)</mat-option>\r\n <mat-option *ngFor=\"let p of itemParts\" [value]=\"p\">{{\r\n p.typeId | flatLookup : modelEntries : \"id\" : \"value\"\r\n }}</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </fieldset>\r\n\r\n <!-- BY TYPE -->\r\n <div *ngIf=\"byTypeMode.value\">\r\n <!-- par type filter -->\r\n <mat-form-field *ngIf=\"partTypeKeys?.length\">\r\n <mat-label>part type</mat-label>\r\n <mat-select [formControl]=\"partTypeKey\">\r\n <mat-option *ngFor=\"let k of partTypeKeys\" [value]=\"k\">{{\r\n k\r\n }}</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- PIN -->\r\n <div class=\"form-row\">\r\n <!-- pin lookup -->\r\n <cadmus-ref-lookup\r\n [service]=\"pinLookupService\"\r\n [baseFilter]=\"filter\"\r\n [options]=\"pinFilterOptions\"\r\n label=\"pin\"\r\n (itemChange)=\"onPinLookupChange($event)\"\r\n ></cadmus-ref-lookup>\r\n <!-- mode switcher -->\r\n <div>\r\n <mat-checkbox [formControl]=\"byTypeMode\" *ngIf=\"canSwitchMode\">\r\n by type</mat-checkbox\r\n >\r\n </div>\r\n </div>\r\n\r\n <!-- data -->\r\n <mat-expansion-panel id=\"data\" *ngIf=\"lookupData?.pin?.name\">\r\n <mat-expansion-panel-header>pin data</mat-expansion-panel-header>\r\n <!-- table -->\r\n <table>\r\n <thead>\r\n <th></th>\r\n <th>source</th>\r\n <th>value</th>\r\n </thead>\r\n <tbody>\r\n <!-- pin -->\r\n <tr *ngIf=\"lookupData?.pin?.value\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>pin</td>\r\n <td>{{ lookupData!.pin.value }}</td>\r\n </tr>\r\n <!-- item ID -->\r\n <tr *ngIf=\"lookupData?.pin?.itemId\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.itemId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item ID</td>\r\n <td>{{ lookupData!.pin.itemId }}</td>\r\n </tr>\r\n <!-- item title -->\r\n <tr *ngIf=\"lookupData?.item?.title\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.item!.title\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item title</td>\r\n <td>{{ lookupData!.item!.title }}</td>\r\n </tr>\r\n <!-- part ID -->\r\n <tr *ngIf=\"lookupData?.pin?.partId\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part ID</td>\r\n <td>{{ lookupData!.pin.partId }}</td>\r\n </tr>\r\n <!-- part type ID -->\r\n <tr *ngIf=\"lookupData?.pin?.partTypeId\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partTypeId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part type ID</td>\r\n <td>{{ lookupData!.pin!.partTypeId }}</td>\r\n </tr>\r\n <!-- part role ID -->\r\n <tr *ngIf=\"lookupData?.pin?.roleId\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.roleId!\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part role ID</td>\r\n <td>{{ lookupData!.pin!.roleId }}</td>\r\n </tr>\r\n\r\n <!-- part's metadata -->\r\n <tr\r\n *ngFor=\"\r\n let m of lookupData?.metaPart?.metadata || [];\r\n let i = index\r\n \"\r\n >\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n [cdkCopyToClipboard]=\"m.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td class=\"metadata\">{{ m.name }}</td>\r\n <td class=\"metadata\">{{ m.value }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </mat-expansion-panel>\r\n </div>\r\n\r\n <!-- buttons -->\r\n <div>\r\n <button mat-flat-button type=\"button\" (click)=\"close()\">\r\n <mat-icon color=\"warn\">close</mat-icon>\r\n </button>\r\n <button mat-flat-button type=\"submit\" [disabled]=\"form.invalid\">\r\n <mat-icon color=\"primary\">check_circle</mat-icon> target\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".metadata{color:#4a3001}.info{border:1px solid silver;border-radius:6px;background-color:silver;color:#fff;padding:4px;margin:8px 0}.info .label{background-color:#fff;color:silver;margin:0 6px}#data{margin:8px 0}table{border:1px solid silver;border-radius:6px;padding:4px;margin-top:8px}tr:nth-child(odd){background-color:#f0f0f0}th{font-weight:400;text-align:left;color:silver}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.label{border:1px solid silver;border-radius:6px;padding:4px}fieldset{border:1px solid silver;border-radius:6px;padding:4px 8px;margin-bottom:8px}legend{color:silver}\n"] }]
|
|
387
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
388
|
+
type: Inject,
|
|
389
|
+
args: ['indexLookupDefinitions']
|
|
390
|
+
}] }, { type: i1.ItemRefLookupService }, { type: i2.PinRefLookupService }, { type: i3.ItemService }, { type: i3.ThesaurusService }, { type: i4.MatSnackBar }, { type: i5.FormBuilder }]; }, propDecorators: { pinByTypeMode: [{
|
|
391
|
+
type: Input
|
|
392
|
+
}], canSwitchMode: [{
|
|
393
|
+
type: Input
|
|
394
|
+
}], canEditTarget: [{
|
|
395
|
+
type: Input
|
|
396
|
+
}], lookupDefinitions: [{
|
|
397
|
+
type: Input
|
|
398
|
+
}], target: [{
|
|
399
|
+
type: Input
|
|
400
|
+
}], editorClose: [{
|
|
401
|
+
type: Output
|
|
402
|
+
}], targetChange: [{
|
|
403
|
+
type: Output
|
|
404
|
+
}] } });
|
|
405
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGluLXRhcmdldC1sb29rdXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbXlybWlkb24vY2FkbXVzLXJlZnMtYXNzZXJ0ZWQtaWRzL3NyYy9saWIvcGluLXRhcmdldC1sb29rdXAvcGluLXRhcmdldC1sb29rdXAuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbXlybWlkb24vY2FkbXVzLXJlZnMtYXNzZXJ0ZWQtaWRzL3NyYy9saWIvcGluLXRhcmdldC1sb29rdXAvcGluLXRhcmdldC1sb29rdXAuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUlMLFVBQVUsR0FDWCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFFTCxZQUFZLEVBQ1osb0JBQW9CLEVBQ3BCLFFBQVEsRUFDUixJQUFJLEdBQ0wsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQmQsNEJBQTRCO0FBQzVCLE1BQU0sZ0JBQWdCLEdBQUcsbUJBQW1CLENBQUM7QUFtQzdDOzs7Ozs7R0FNRztBQUNILE1BS2Esd0JBQXdCO0lBTW5DOzs7T0FHRztJQUNILElBQ1csYUFBYTtRQUN0QixPQUFPLElBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDO0lBQ2hDLENBQUM7SUFDRCxJQUFXLGFBQWEsQ0FBQyxLQUEwQjtRQUNqRCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNwQixJQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSyxDQUFDO1NBQ25DO2FBQU07WUFDTCxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLENBQUM7WUFDekMs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aEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7OEdBamNVLHdCQUF3QixrQkE4RnpCLHdCQUF3QjtrR0E5RnZCLHdCQUF3Qiw2U0N4RnJDLCs3UUF1UEE7O1NEL0phLHdCQUF3QjsyRkFBeEIsd0JBQXdCO2tCQUxwQyxTQUFTOytCQUNFLDBCQUEwQjs7MEJBa0dqQyxNQUFNOzJCQUFDLHdCQUF3Qjs4TkFuRnZCLGFBQWE7c0JBRHZCLEtBQUs7Z0JBaUJDLGFBQWE7c0JBRG5CLEtBQUs7Z0JBT0MsYUFBYTtzQkFEbkIsS0FBSztnQkFXQyxpQkFBaUI7c0JBRHZCLEtBQUs7Z0JBT0ssTUFBTTtzQkFEaEIsS0FBSztnQkFnQkMsV0FBVztzQkFEakIsTUFBTTtnQkFPQSxZQUFZO3NCQURsQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgRm9ybUJ1aWxkZXIsXG4gIEZvcm1Db250cm9sLFxuICBGb3JtR3JvdXAsXG4gIFZhbGlkYXRvcnMsXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIFN1YnNjcmlwdGlvbixcbiAgZGVib3VuY2VUaW1lLFxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgZm9ya0pvaW4sXG4gIHRha2UsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgTWF0U25hY2tCYXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zbmFjay1iYXInO1xuXG5pbXBvcnQgeyBJdGVtU2VydmljZSwgVGhlc2F1cnVzU2VydmljZSB9IGZyb20gJ0BteXJtaWRvbi9jYWRtdXMtYXBpJztcbmltcG9ydCB7XG4gIERhdGFQaW5JbmZvLFxuICBJbmRleExvb2t1cERlZmluaXRpb24sXG4gIEluZGV4TG9va3VwRGVmaW5pdGlvbnMsXG4gIEl0ZW0sXG4gIFBhcnQsXG4gIFRoZXNhdXJ1c0VudHJ5LFxufSBmcm9tICdAbXlybWlkb24vY2FkbXVzLWNvcmUnO1xuXG5pbXBvcnQge1xuICBQaW5SZWZMb29rdXBGaWx0ZXIsXG4gIFBpblJlZkxvb2t1cFNlcnZpY2UsXG59IGZyb20gJy4uL3NlcnZpY2VzL3Bpbi1yZWYtbG9va3VwLnNlcnZpY2UnO1xuaW1wb3J0IHsgSXRlbVJlZkxvb2t1cFNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9pdGVtLXJlZi1sb29rdXAuc2VydmljZSc7XG5cbi8vIGZyb20gQ2FkbXVzIGdlbmVyYWwgcGFydHNcbmNvbnN0IE1FVEFEQVRBX1BBUlRfSUQgPSAnaXQudmVkcGgubWV0YWRhdGEnO1xuaW50ZXJmYWNlIE1ldGFkYXRhUGFydCBleHRlbmRzIFBhcnQge1xuICBtZXRhZGF0YToge1xuICAgIHR5cGU/OiBzdHJpbmc7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHZhbHVlOiBzdHJpbmc7XG4gIH1bXTtcbn1cblxuLyoqXG4gKiBQaW4gbG9va3VwIGRhdGEgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSBjb21wb25lbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGluTG9va3VwRGF0YSB7XG4gIHBpbjogRGF0YVBpbkluZm87XG4gIGl0ZW0/OiBJdGVtO1xuICBtZXRhUGFydD86IE1ldGFkYXRhUGFydDtcbn1cblxuLyoqXG4gKiBBIHBpbi1iYXNlZCB0YXJnZXQuIFRoaXMgaW5jbHVkZXMgcGluJ3MgbmFtZSBhbmQgdmFsdWUsIGFuZFxuICogdGhlIGl0ZW0ncyBJRCBhbmQgb3B0aW9uYWwgcGFydCBJRHMuIFRoZSBsYWJlbCBpcyBhIHVzZXIgZnJpZW5kbHlcbiAqIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGFyZ2V0LCB3aGlsZSB0aGUgZ2lkIGlzIGEgZ2xvYmFsbHlcbiAqIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgdGFyZ2V0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBpblRhcmdldCB7XG4gIGdpZDogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xuICBpdGVtSWQ/OiBzdHJpbmc7XG4gIHBhcnRJZD86IHN0cmluZztcbiAgcGFydFR5cGVJZD86IHN0cmluZztcbiAgcm9sZUlkPzogc3RyaW5nO1xuICBuYW1lPzogc3RyaW5nO1xuICB2YWx1ZT86IHN0cmluZztcbn1cblxuLypcbiAqIFNjb3BlZCBwaW4tYmFzZWQgbG9va3VwIGNvbXBvbmVudC4gVGhpcyBjb21wb25lbnQgcHJvdmlkZXMgYSBsaXN0XG4gKiBvZiBwaW4tYmFzZWQgc2VhcmNoZXMsIHdpdGggYSBsb29rdXAgY29udHJvbC4gV2hlbmV2ZXIgdGhlIHVzZXJcbiAqIHBpY2tzIGEgcGluIHZhbHVlLCBoZSBnZXRzIHRoZSBkZXRhaWxzIGFib3V0IGl0cyBpdGVtIGFuZCBwYXJ0LCBhbmRcbiAqIGl0ZW0ncyBtZXRhZGF0YSBwYXJ0LCBpZiBhbnkuIEhlIGNhbiB0aGVuIHVzZSB0aGVzZSBkYXRhIHRvIGJ1aWxkXG4gKiBzb21lIEVJRCBieSB2YXJpb3VzbHkgYXNzZW1ibGluZyB0aGVzZSBjb21wb25lbnRzLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjYWRtdXMtcGluLXRhcmdldC1sb29rdXAnLFxuICB0ZW1wbGF0ZVVybDogJy4vcGluLXRhcmdldC1sb29rdXAuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9waW4tdGFyZ2V0LWxvb2t1cC5jb21wb25lbnQuY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFBpblRhcmdldExvb2t1cENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBfc3ViczogU3Vic2NyaXB0aW9uW107XG4gIHByaXZhdGUgX3RhcmdldDogUGluVGFyZ2V0IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIF9ub0Zvcm1VcGRhdGU/OiBib29sZWFuO1xuICBwcml2YXRlIF9zdGFydFdpdGhCeVR5cGVNb2RlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVHJ1ZSB3aGVuIHRoZSBieS10eXBlIHBpbiBsb29rdXAgbW9kZSBpcyBhY3RpdmUuXG4gICAqIFVzZXIgY2FuIGNoYW5nZSBtb2RlIHVubGVzcyBtb2RlU3dpdGNoaW5nIGlzIGZhbHNlLlxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIGdldCBwaW5CeVR5cGVNb2RlKCk6IGJvb2xlYW4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmJ5VHlwZU1vZGU/LnZhbHVlO1xuICB9XG4gIHB1YmxpYyBzZXQgcGluQnlUeXBlTW9kZSh2YWx1ZTogYm9vbGVhbiB8IHVuZGVmaW5lZCkge1xuICAgIGlmICghdGhpcy5ieVR5cGVNb2RlKSB7XG4gICAgICB0aGlzLl9zdGFydFdpdGhCeVR5cGVNb2RlID0gdmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYnlUeXBlTW9kZS5zZXRWYWx1ZSh2YWx1ZSB8fCBmYWxzZSk7XG4gICAgICB0aGlzLmJ5VHlwZU1vZGUudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcnVlIHdoZW4gdGhlIHVzZXIgY2FuIHN3aXRjaCBiZXR3ZWVuIGJ5LXR5cGUgYW5kIGJ5LWl0ZW0gbW9kZS5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjYW5Td2l0Y2hNb2RlPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFRydWUgd2hlbiB0aGUgdXNlciBjYW4gZWRpdCB0aGUgdGFyZ2V0J3MgZ2lkL2xhYmVsIGZvciBpbnRlcm5hbFxuICAgKiB0YXJnZXRzLlxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIGNhbkVkaXRUYXJnZXQ/OiBib29sZWFuO1xuICAvKipcbiAgICogVGhlIGxvb2t1cCBkZWZpbml0aW9ucyB0byBiZSB1c2VkIGZvciB0aGUgYnktdHlwZSBsb29rdXAuIElmXG4gICAqIG5vdCBzcGVjaWZpZWQsIHRoZSBsb29rdXAgZGVmaW5pdGlvbnMgd2lsbCBiZSBnb3QgdmlhIGluamVjdGlvblxuICAgKiB3aGVuIGF2YWlsYWJsZTsgaWYgdGhlIGluamVjdGVkIGRlZmluaXRpb25zIGFyZSBlbXB0eSwgdGhlXG4gICAqIGxvb2t1cCBkZWZpbml0aW9ucyB3aWxsIGJlIGJ1aWx0IGZyb20gdGhlIG1vZGVsLXR5cGVzIHRoZXNhdXJ1cztcbiAgICogaWYgdGhpcyBpcyBub3QgYXZhaWxhYmxlIGVpdGhlciwgdGhlIGJ5LXR5cGUgbG9va3VwIHdpbGwgYmVcbiAgICogZGlzYWJsZWQuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgbG9va3VwRGVmaW5pdGlvbnM/OiBJbmRleExvb2t1cERlZmluaXRpb25zO1xuXG4gIC8qKlxuICAgKiBUaGUgdGFyZ2V0IHRvIGJlIGVkaXRlZC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBnZXQgdGFyZ2V0KCk6IFBpblRhcmdldCB8IHVuZGVmaW5lZCB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl90YXJnZXQ7XG4gIH1cbiAgcHVibGljIHNldCB0YXJnZXQodmFsdWU6IFBpblRhcmdldCB8IHVuZGVmaW5lZCB8IG51bGwpIHtcbiAgICBpZiAodGhpcy5fdGFyZ2V0ID09PSB2YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl90YXJnZXQgPSB2YWx1ZSB8fCB1bmRlZmluZWQ7XG4gICAgdGhpcy51cGRhdGVGb3JtKHRoaXMuX3RhcmdldCk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHRlZCB3aGVuIHVzZXIgY2xvc2VzIHRoZSBlZGl0b3IuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgcHVibGljIGVkaXRvckNsb3NlOiBFdmVudEVtaXR0ZXI8YW55PjtcbiAgLyoqXG4gICAqIEVtaXR0ZWQgd2hlbmV2ZXIgdGhlIHRhcmdldCBjaGFuZ2VzLlxuICAgKiBUaGUgZXZlbnQncyB2YWx1ZSBpcyB0aGUgbmV3IHRhcmdldC5cbiAgICovXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgdGFyZ2V0Q2hhbmdlOiBFdmVudEVtaXR0ZXI8UGluVGFyZ2V0PjtcblxuICAvLyBieSB0eXBlXG4gIHB1YmxpYyBtb2RlbEVudHJpZXM6IFRoZXNhdXJ1c0VudHJ5W107XG4gIHB1YmxpYyBwYXJ0VHlwZUtleXM6IHN0cmluZ1tdO1xuICAvLyBieSBpdGVtXG4gIHB1YmxpYyBpdGVtUGFydHM6IFBhcnRbXTtcbiAgLy8gZm9ybSAtIGJ5IGl0ZW1cbiAgcHVibGljIGl0ZW06IEZvcm1Db250cm9sPEl0ZW0gfCBudWxsPjtcbiAgcHVibGljIGl0ZW1QYXJ0OiBGb3JtQ29udHJvbDxQYXJ0IHwgbnVsbD47XG4gIC8vIGZvcm0gLSBieSB0eXBlXG4gIHB1YmxpYyBwYXJ0VHlwZUtleTogRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD47XG4gIC8vIGZvcm0gLSBib3RoXG4gIHB1YmxpYyBnaWQ6IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+O1xuICBwdWJsaWMgbGFiZWw6IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+O1xuICBwdWJsaWMgYnlUeXBlTW9kZTogRm9ybUNvbnRyb2w8Ym9vbGVhbj47XG4gIHB1YmxpYyBleHRlcm5hbDogRm9ybUNvbnRyb2w8Ym9vbGVhbj47XG4gIHB1YmxpYyBmb3JtOiBGb3JtR3JvdXA7XG5cbiAgcHVibGljIGZpbHRlcjogUGluUmVmTG9va3VwRmlsdGVyO1xuICBwdWJsaWMgcGluRmlsdGVyT3B0aW9ucz86IEluZGV4TG9va3VwRGVmaW5pdGlvbjtcbiAgcHVibGljIGxvb2t1cERhdGE/OiBQaW5Mb29rdXBEYXRhO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoJ2luZGV4TG9va3VwRGVmaW5pdGlvbnMnKVxuICAgIHByaXZhdGUgX3ByZXNldExvb2t1cERlZnM6IEluZGV4TG9va3VwRGVmaW5pdGlvbnMsXG4gICAgcHVibGljIGl0ZW1Mb29rdXBTZXJ2aWNlOiBJdGVtUmVmTG9va3VwU2VydmljZSxcbiAgICBwdWJsaWMgcGluTG9va3VwU2VydmljZTogUGluUmVmTG9va3VwU2VydmljZSxcbiAgICBwcml2YXRlIF9pdGVtU2VydmljZTogSXRlbVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBfdGhlc1NlcnZpY2U6IFRoZXNhdXJ1c1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBfc25hY2tiYXI6IE1hdFNuYWNrQmFyLFxuICAgIGZvcm1CdWlsZGVyOiBGb3JtQnVpbGRlclxuICApIHtcbiAgICB0aGlzLnBhcnRUeXBlS2V5cyA9IFtdO1xuICAgIHRoaXMuaXRlbVBhcnRzID0gW107XG4gICAgdGhpcy5fc3VicyA9IFtdO1xuICAgIHRoaXMubW9kZWxFbnRyaWVzID0gW107XG4gICAgLy8gdGhpcyBpcyB0aGUgZGVmYXVsdCBmaWx0ZXIgZm9yIHRoZSBwaW4gbG9va3VwLCB3aGljaCB3aWxsXG4gICAgLy8gYmUgbWVyZ2VkIHdpdGggdmFsdWVzIHByb3ZpZGVkIGJ5IHVzZXIgaGVyZVxuICAgIHRoaXMuZmlsdGVyID0ge1xuICAgICAgdGV4dDogJycsXG4gICAgICBsaW1pdDogMTAsXG4gICAgfTtcbiAgICAvLyBmb3JtXG4gICAgdGhpcy5pdGVtID0gZm9ybUJ1aWxkZXIuY29udHJvbChudWxsKTtcbiAgICB0aGlzLml0ZW1QYXJ0ID0gZm9ybUJ1aWxkZXIuY29udHJvbChudWxsKTtcbiAgICB0aGlzLnBhcnRUeXBlS2V5ID0gZm9ybUJ1aWxkZXIuY29udHJvbChudWxsKTtcbiAgICB0aGlzLmdpZCA9IGZvcm1CdWlsZGVyLmNvbnRyb2wobnVsbCwgW1xuICAgICAgVmFsaWRhdG9ycy5yZXF1aXJlZCxcbiAgICAgIFZhbGlkYXRvcnMubWF4TGVuZ3RoKDMwMCksXG4gICAgXSk7XG4gICAgdGhpcy5sYWJlbCA9IGZvcm1CdWlsZGVyLmNvbnRyb2wobnVsbCwgW1xuICAgICAgVmFsaWRhdG9ycy5yZXF1aXJlZCxcbiAgICAgIFZhbGlkYXRvcnMubWF4TGVuZ3RoKDMwMCksXG4gICAgXSk7XG4gICAgdGhpcy5ieVR5cGVNb2RlID0gZm9ybUJ1aWxkZXIuY29udHJvbChmYWxzZSwgeyBub25OdWxsYWJsZTogdHJ1ZSB9KTtcbiAgICB0aGlzLmV4dGVybmFsID0gZm9ybUJ1aWxkZXIuY29udHJvbChmYWxzZSwgeyBub25OdWxsYWJsZTogdHJ1ZSB9KTtcbiAgICB0aGlzLmZvcm0gPSBmb3JtQnVpbGRlci5ncm91cCh7XG4gICAgICBpdGVtOiB0aGlzLml0ZW0sXG4gICAgICBpdGVtUGFydDogdGhpcy5pdGVtUGFydCxcbiAgICAgIHBhcnRUeXBlS2V5OiB0aGlzLnBhcnRUeXBlS2V5LFxuICAgICAgZ2lkOiB0aGlzLmdpZCxcbiAgICAgIGxhYmVsOiB0aGlzLmxhYmVsLFxuICAgICAgYnlUeXBlTW9kZTogdGhpcy5ieVR5cGVNb2RlLFxuICAgICAgZXh0ZXJuYWw6IHRoaXMuZXh0ZXJuYWwsXG4gICAgfSk7XG4gICAgLy8gZXZlbnRzXG4gICAgdGhpcy50YXJnZXRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFBpblRhcmdldD4oKTtcbiAgICB0aGlzLmVkaXRvckNsb3NlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIH1cblxuICBwcml2YXRlIGZvcmNlQnlJdGVtKCk6IHZvaWQge1xuICAgIHRoaXMucGluQnlUeXBlTW9kZSA9IGZhbHNlO1xuICAgIHRoaXMuY2FuU3dpdGNoTW9kZSA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cEtleXMoKTogdm9pZCB7XG4gICAgLy8gdXNlIERJIHByZXNldHMgaWYgbm8gbG9va3VwIGRlZmluaXRpb25zXG4gICAgaWYgKCF0aGlzLmxvb2t1cERlZmluaXRpb25zKSB7XG4gICAgICB0aGlzLmxvb2t1cERlZmluaXRpb25zID0gdGhpcy5fcHJlc2V0TG9va3VwRGVmcztcbiAgICB9XG4gICAgLy8ga2V5cyBhcmUgYWxsIHRoZSBkZWZpbmVkIGxvb2t1cCBzZWFyY2hlc1xuICAgIHRoaXMucGFydFR5cGVLZXlzID0gT2JqZWN0LmtleXModGhpcy5sb29rdXBEZWZpbml0aW9ucyk7XG5cbiAgICAvLyBpZiBubyBrZXlzLCBnZXQgdGhlbSBmcm9tIHRoZXNhdXJ1cyBtb2RlbC10eXBlcztcbiAgICAvLyBpZiB0aGlzIGlzIG5vdCBhdmFpbGFibGUsIGp1c3QgZm9yY2UgYnkgaXRlbSBtb2RlLlxuICAgIGlmICghdGhpcy5wYXJ0VHlwZUtleXMubGVuZ3RoKSB7XG4gICAgICBpZiAodGhpcy5tb2RlbEVudHJpZXM/Lmxlbmd0aCkge1xuICAgICAgICAvLyBzZXQgbG9va3VwRGVmaW5pdGlvbnMgZnJvbSB0aGVzYXVydXMgZW50cmllc1xuICAgICAgICB0aGlzLmxvb2t1cERlZmluaXRpb25zID0ge307XG4gICAgICAgIHRoaXMubW9kZWxFbnRyaWVzLmZvckVhY2goKGUpID0+IHtcbiAgICAgICAgICB0aGlzLmxvb2t1cERlZmluaXRpb25zIVtlLnZhbHVlXSA9IHtcbiAgICAgICAgICAgIG5hbWU6IGUudmFsdWUsXG4gICAgICAgICAgICB0eXBlSWQ6IGUuaWQsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHNldCB0eXBlIGtleXMgZnJvbSB0aGVzYXVydXMgZW50cmllc1xuICAgICAgICB0aGlzLnBhcnRUeXBlS2V5cyA9IHRoaXMubW9kZWxFbnRyaWVzLm1hcCgoZSkgPT4gZS52YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gaWYgc3RpbGwgbm8ga2V5cywgZm9yY2UgYnkgaXRlbSBtb2RlXG4gICAgaWYgKCF0aGlzLnBhcnRUeXBlS2V5cy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuZm9yY2VCeUl0ZW0oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgdGhlcmUgaXMgb25seSBvbmUga2V5LCBzZXQgaXQgYXMgdGhlIGRlZmF1bHRcbiAgICAgIGlmICh0aGlzLnBhcnRUeXBlS2V5cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgdGhpcy5wYXJ0VHlwZUtleS5zZXRWYWx1ZSh0aGlzLnBhcnRUeXBlS2V5c1swXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjYW5CdWlsZEdpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKCF0aGlzLmV4dGVybmFsLnZhbHVlICYmICF0aGlzLmdpZC52YWx1ZSkgfHwgdGhpcy5naWQucHJpc3RpbmU7XG4gIH1cblxuICBwcml2YXRlIGNhbkJ1aWxkTGFiZWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICghdGhpcy5leHRlcm5hbC52YWx1ZSAmJiAhdGhpcy5sYWJlbC52YWx1ZSkgfHwgdGhpcy5sYWJlbC5wcmlzdGluZTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAvLyBzZXQgc3RhcnQgbW9kZSBpZiByZXF1aXJlZFxuICAgIGlmICh0aGlzLl9zdGFydFdpdGhCeVR5cGVNb2RlKSB7XG4gICAgICB0aGlzLmJ5VHlwZU1vZGUuc2V0VmFsdWUodHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gd2hlbmV2ZXIgaXRlbSBjaGFuZ2VzLCB1cGRhdGUgaXRlbSdzIHBhcnRzIGFuZCBmaWx0ZXJcbiAgICB0aGlzLl9zdWJzLnB1c2goXG4gICAgICB0aGlzLml0ZW0udmFsdWVDaGFuZ2VzXG4gICAgICAgIC5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksIGRlYm91bmNlVGltZSgzMDApKVxuICAgICAgICAuc3Vic2NyaWJlKChpdGVtKSA9PiB7XG4gICAgICAgICAgdGhpcy5pdGVtUGFydC5zZXRWYWx1ZShudWxsKTtcbiAgICAgICAgICB0aGlzLml0ZW1QYXJ0cyA9IGl0ZW0/LnBhcnRzIHx8IFtdO1xuICAgICAgICAgIHRoaXMuZmlsdGVyID0ge1xuICAgICAgICAgICAgLi4udGhpcy5maWx0ZXIsXG4gICAgICAgICAgICBpdGVtSWQ6IGl0ZW0/LmlkLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pXG4gICAgKTtcblxuICAgIC8vIHdoZW5ldmVyIGl0ZW1QYXJ0IGNoYW5nZXMsIHVwZGF0ZSB0YXJnZXQgYW5kIGV2ZW50dWFsbHkgZ2lkXG4gICAgdGhpcy5fc3Vicy5wdXNoKFxuICAgICAgdGhpcy5pdGVtUGFydC52YWx1ZUNoYW5nZXNcbiAgICAgICAgLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSwgZGVib3VuY2VUaW1lKDMwMCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKHBhcnQpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuZ2lkLnZhbHVlIHx8IHRoaXMuZ2lkLnByaXN0aW5lKSB7XG4gICAgICAgICAgICB0aGlzLmdpZC5zZXRWYWx1ZSh0aGlzLmJ1aWxkR2lkKCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmZpbHRlciA9IHtcbiAgICAgICAgICAgIC4uLnRoaXMuZmlsdGVyLFxuICAgICAgICAgICAgcGFydElkOiBwYXJ0Py5pZCxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHRoaXMudXBkYXRlVGFyZ2V0KCk7XG4gICAgICAgIH0pXG4gICAgKTtcblxuICAgIC8vIHdoZW5ldmVyIHBhcnRUeXBlS2V5IGNoYW5nZXMsIHVwZGF0ZSBmaWx0ZXIncyBvcHRpb25zXG4gICAgdGhpcy5fc3Vicy5wdXNoKFxuICAgICAgdGhpcy5wYXJ0VHlwZUtleS52YWx1ZUNoYW5nZXNcbiAgICAgICAgLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSwgZGVib3VuY2VUaW1lKDMwMCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKGtleSkgPT4ge1xuICAgICAgICAgIHRoaXMucGluRmlsdGVyT3B0aW9ucyA9IGtleVxuICAgICAgICAgICAgPyB0aGlzLmxvb2t1cERlZmluaXRpb25zIVtrZXldXG4gICAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgICAgfSlcbiAgICApO1xuXG4gICAgLy8gbG9hZCBtb2RlbC10eXBlcyB0aGVzYXVydXMgZW50cmllc1xuICAgIHRoaXMuX3RoZXNTZXJ2aWNlLmdldFRoZXNhdXJ1cygnbW9kZWwtdHlwZXMnLCB0cnVlKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHQpID0+IHtcbiAgICAgICAgdGhpcy5tb2RlbEVudHJpZXMgPSB0LmVudHJpZXMgfHwgW107XG4gICAgICAgIGlmICh0aGlzLm1vZGVsRW50cmllcz8ubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy5zZXR1cEtleXMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmZvcmNlQnlJdGVtKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLmZvcmNlQnlJdGVtKCk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fc3Vicy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5fc3Vic1tpXS51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRHaWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgLy8gdGhlIEdJRCBpcyB0aGUgcGFydCBJRCBpZiBhbnksIG9yIHRoZSBpdGVtIElELCBmb2xsb3dlZCBieVxuICAgIC8vIHRoZSBwaW4ncyB2YWx1ZSAoPUVJRClcbiAgICBjb25zdCBwaW4gPSB0aGlzLmxvb2t1cERhdGE/LnBpbjtcbiAgICBpZiAoIXBpbikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBwaW4ucGFydElkXG4gICAgICA/IGBQJHtwaW4ucGFydElkfS8ke3Bpbi52YWx1ZX1gXG4gICAgICA6IGBJJHtwaW4uaXRlbUlkfS8ke3Bpbi52YWx1ZX1gO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZExhYmVsKCk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICghdGhpcy5sb29rdXBEYXRhPy5waW4pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCBzYjogc3RyaW5nW10gPSBbXTtcbiAgICAvLyBwaW4gdmFsdWVcbiAgICBzYi5wdXNoKHRoaXMubG9va3VwRGF0YS5waW4udmFsdWUhKTtcbiAgICAvLyBpdGVtIHRpdGxlXG4gICAgc2IucHVzaCgnIHwgJyk7XG4gICAgc2IucHVzaCh0aGlzLmxvb2t1cERhdGEuaXRlbSEudGl0bGUgfHwgdGhpcy5sb29rdXBEYXRhLml0ZW0hLmlkKTtcbiAgICAvLyBwYXJ0IHR5cGUgYW5kIHJvbGVcbiAgICBjb25zdCBlID0gdGhpcy5tb2RlbEVudHJpZXM/LmZpbmQoXG4gICAgICAoZSkgPT4gZS5pZCA9PT0gdGhpcy5sb29rdXBEYXRhIS5waW4ucGFydFR5cGVJZFxuICAgICk7XG4gICAgc2IucHVzaCgnICgnKTtcbiAgICBzYi5wdXNoKGU/LnZhbHVlIHx8IHRoaXMubG9va3VwRGF0YS5waW4ucGFydFR5cGVJZCk7XG4gICAgaWYgKHRoaXMubG9va3VwRGF0YS5waW4ucm9sZUlkKSB7XG4gICAgICBzYi5wdXNoKGAsICR7dGhpcy5sb29rdXBEYXRhLnBpbi5yb2xlSWR9YCk7XG4gICAgfVxuICAgIHNiLnB1c2goJyknKTtcbiAgICByZXR1cm4gc2Iuam9pbignJyk7XG4gIH1cblxuICBwcml2YXRlIGdldFRhcmdldCgpOiBQaW5UYXJnZXQge1xuICAgIGlmICh0aGlzLmV4dGVybmFsLnZhbHVlKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBnaWQ6IHRoaXMuZ2lkLnZhbHVlIHx8ICcnLFxuICAgICAgICBsYWJlbDogdGhpcy5sYWJlbC52YWx1ZSB8fCAnJyxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHBpbiA9IHRoaXMubG9va3VwRGF0YT8ucGluO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZ2lkOiB0aGlzLmdpZC52YWx1ZSB8fCAnJyxcbiAgICAgICAgbGFiZWw6IHRoaXMubGFiZWwudmFsdWUgfHwgJycsXG4gICAgICAgIGl0ZW1JZDogcGluPy5pdGVtSWQgfHwgJycsXG4gICAgICAgIHBhcnRJZDogcGluPy5wYXJ0SWQgfHwgJycsXG4gICAgICAgIHBhcnRUeXBlSWQ6IHBpbj8ucGFydFR5cGVJZCB8fCAnJyxcbiAgICAgICAgcm9sZUlkOiBwaW4/LnJvbGVJZCB8fCAnJyxcbiAgICAgICAgbmFtZTogcGluPy5uYW1lIHx8ICcnLFxuICAgICAgICB2YWx1ZTogcGluPy52YWx1ZSB8fCAnJyxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVUYXJnZXQoKTogdm9pZCB7XG4gICAgdGhpcy5fbm9Gb3JtVXBkYXRlID0gdHJ1ZTtcblxuICAgIGlmICh0aGlzLmNhbkJ1aWxkR2lkKCkpIHtcbiAgICAgIHRoaXMuZ2lkLnNldFZhbHVlKHRoaXMuYnVpbGRHaWQoKSk7XG4gICAgICB0aGlzLmdpZC5tYXJrQXNEaXJ0eSgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5jYW5CdWlsZExhYmVsKCkpIHtcbiAgICAgIHRoaXMubGFiZWwuc2V0VmFsdWUodGhpcy5idWlsZExhYmVsKCkpO1xuICAgICAgdGhpcy5sYWJlbC5tYXJrQXNEaXJ0eSgpO1xuICAgIH1cbiAgICB0aGlzLnRhcmdldCA9IHRoaXMuZ2V0VGFyZ2V0KCk7XG5cbiAgICB0aGlzLl9ub0Zvcm1VcGRhdGUgPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlRm9ybSh0YXJnZXQ/OiBQaW5UYXJnZXQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fbm9Gb3JtVXBkYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGJ1aWxkIHBpbiBpbmZvIGZyb20gdGFyZ2V0XG4gICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgIHRoaXMubG9va3VwRGF0YSA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuZm9ybS5yZXNldCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmV4dGVybmFsLnNldFZhbHVlKCF0YXJnZXQubmFtZSk7XG4gICAgdGhpcy5sb29rdXBEYXRhID0ge1xuICAgICAgcGluOiB7XG4gICAgICAgIGl0ZW1JZDogdGFyZ2V0Lml0ZW1JZCB8fCAnJyxcbiAgICAgICAgcGFydElkOiB0YXJnZXQucGFydElkIHx8ICcnLFxuICAgICAgICBwYXJ0VHlwZUlkOiB0YXJnZXQucGFydFR5cGVJZCB8fCAnJyxcbiAgICAgICAgcm9sZUlkOiB0YXJnZXQucm9sZUlkIHx8ICcnLFxuICAgICAgICBuYW1lOiB0YXJnZXQubmFtZSB8fCAnJyxcbiAgICAgICAgdmFsdWU6IHRhcmdldC52YWx1ZSB8fCAnJyxcbiAgICAgIH0sXG4gICAgfTtcbiAgICAvLyBnZXQgaXRlbVxuICAgIGlmICh0YXJnZXQuaXRlbUlkKSB7XG4gICAgICB0aGlzLl9pdGVtU2VydmljZS5nZXRJdGVtKHRhcmdldC5pdGVtSWQsIHRydWUpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChpdGVtKSA9PiB7XG4gICAgICAgICAgdGhpcy5pdGVtLnNldFZhbHVlKGl0ZW0pO1xuICAgICAgICAgIHRoaXMuZm9ybS5tYXJrQXNQcmlzdGluZSgpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBpdGVtIGxvb2t1cCBjaGFuZ2VzIChpdGVtIGlzIGxvb2tlZCB1cFxuICAgKiBieSBpdHMgdGl0bGUpLlxuICAgKlxuICAgKiBAcGFyYW0gaXRlbSBUaGUgaXRlbSBnb3QgZnJvbSBsb29rdXAuXG4gICAqL1xuICBwdWJsaWMgb25JdGVtTG9va3VwQ2hhbmdlKGl0ZW06IEl0ZW0pOiB2b2lkIHtcbiAgICAvLyBsb2FkIGl0ZW0ncyBwYXJ0c1xuICAgIHRoaXMuX2l0ZW1TZXJ2aWNlLmdldEl0ZW0oaXRlbS5pZCwgdHJ1ZSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChpKSA9PiB7XG4gICAgICAgIC8vIHNldHRpbmcgdGhlIGl0ZW0gd2lsbCB0cmlnZ2VyIGl0cyBwYXJ0cyB1cGRhdGVcbiAgICAgICAgdGhpcy5pdGVtLnNldFZhbHVlKGkpO1xuICAgICAgICB0aGlzLnVwZGF0ZVRhcmdldCgpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihKU09OLnN0cmluZ2lmeShlcnJvcikpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaXRlbVBhcnQuc2V0VmFsdWUobnVsbCk7XG4gICAgICAgIHRoaXMuaXRlbVBhcnRzID0gW107XG4gICAgICAgIHRoaXMudXBkYXRlVGFyZ2V0KCk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkSXRlbUluZm8ocGluOiBEYXRhUGluSW5mbyk6IHZvaWQge1xuICAgIGZvcmtKb2luKHtcbiAgICAgIGl0ZW06IHRoaXMuX2l0ZW1TZXJ2aWNlLmdldEl0ZW0ocGluLml0ZW1JZCwgZmFsc2UpLFxuICAgICAgcGFydDogdGhpcy5faXRlbVNlcnZpY2UuZ2V0UGFydEZyb21UeXBlQW5kUm9sZShcbiAgICAgICAgcGluLml0ZW1JZCxcbiAgICAgICAgTUVUQURBVEFfUEFSVF9JRFxuICAgICAgKSxcbiAgICB9KVxuICAgICAgLnBpcGUodGFrZSgxKSlcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgdGhpcy5sb29rdXBEYXRhID0ge1xuICAgICAgICAgICAgcGluOiBwaW4sXG4gICAgICAgICAgICBpdGVtOiByZXN1bHQuaXRlbSxcbiAgICAgICAgICAgIG1ldGFQYXJ0OiByZXN1bHQucGFydCBhcyBNZXRhZGF0YVBhcnQsXG4gICAgICAgICAgfTtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVRhcmdldCgpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgdGhpcy5sb29rdXBEYXRhID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICBlcnJvciA/IEpTT04uc3RyaW5naWZ5KGVycm9yKSA6ICdFcnJvciBsb2FkaW5nIGl0ZW0vbWV0YWRhdGEnXG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBwaW4gbG9va3VwIGNoYW5nZS4gQSBwaW4gaXMgbG9va2VkIHVwIGJ5IGl0c1xuICAgKiBuYW1lIGFuZCB2YWx1ZSAoPXRoZSBmaWx0ZXIncyB0ZXh0KSwgYW5kIG9wdGlvbmFsbHkgYnk6XG4gICAqIC0gaXRzIGluZGV4IGxvb2t1cCBkZWZpbml0aW9uIChzZWxlY3RlZCBieSBwYXJ0VHlwZUtleSkuXG4gICAqIC0gaXRzIGl0ZW0gKGRlZmluZWQgYnkgaXRlbSwgaW4gZmlsdGVyKS5cbiAgICogLSBpdHMgcGFydCAoZGVmaW5lZCBieSBpdGVtUGFydCwgaW4gZmlsdGVyKS5cbiAgICpcbiAgICogQHBhcmFtIGluZm8gVGhlIHBpbiBpbmZvIGZyb20gcGluIGxvb2t1cC5cbiAgICovXG4gIHB1YmxpYyBvblBpbkxvb2t1cENoYW5nZShpbmZvOiBEYXRhUGluSW5mbyk6IHZvaWQge1xuICAgIHRoaXMubG9hZEl0ZW1JbmZvKGluZm8pO1xuICB9XG5cbiAgcHVibGljIG9uQ29waWVkKCk6IHZvaWQge1xuICAgIHRoaXMuX3NuYWNrYmFyLm9wZW4oJ0NvcGllZCB0byBjbGlwYm9hcmQnLCAnT0snLCB7XG4gICAgICBkdXJhdGlvbjogMTUwMCxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBjbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRvckNsb3NlLmVtaXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBzYXZlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmZvcm0uaW52YWxpZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl90YXJnZXQgPSB0aGlzLmdldFRhcmdldCgpO1xuICAgIHRoaXMudGFyZ2V0Q2hhbmdlLmVtaXQodGhpcy5fdGFyZ2V0KTtcbiAgfVxufVxuIiwiPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtXCIgKHN1Ym1pdCk9XCJzYXZlKClcIj5cclxuICA8IS0tIGV4dGVybmFsIC0tPlxyXG4gIDxtYXQtY2hlY2tib3ggW2Zvcm1Db250cm9sXT1cImV4dGVybmFsXCI+ZXh0ZXJuYWw8L21hdC1jaGVja2JveD5cclxuXHJcbiAgPGRpdiBjbGFzcz1cImZvcm0tcm93XCI+XHJcbiAgICA8IS0tIGxhYmVsIC0tPlxyXG4gICAgPGRpdj5cclxuICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ0lmPVwiZXh0ZXJuYWwudmFsdWUgfHwgY2FuRWRpdFRhcmdldFwiPlxyXG4gICAgICAgIDxtYXQtbGFiZWw+bGFiZWw8L21hdC1sYWJlbD5cclxuICAgICAgICA8aW5wdXQgbWF0SW5wdXQgW2Zvcm1Db250cm9sXT1cImxhYmVsXCIgLz5cclxuICAgICAgICA8bWF0LWVycm9yXHJcbiAgICAgICAgICAqbmdJZj1cIiRhbnkobGFiZWwpLmVycm9ycz8ucmVxdWlyZWQgJiYgKGxhYmVsLmRpcnR5IHx8IGxhYmVsLnRvdWNoZWQpXCJcclxuICAgICAgICAgID5sYWJlbCByZXF1aXJlZDwvbWF0LWVycm9yXHJcbiAgICAgICAgPlxyXG4gICAgICAgIDxtYXQtZXJyb3JcclxuICAgICAgICAgICpuZ0lmPVwiXHJcbiAgICAgICAgICAgICRhbnkobGFiZWwpLmVycm9ycz8ubWF4TGVuZ3RoICYmIChsYWJlbC5kaXJ0eSB8fCBsYWJlbC50b3VjaGVkKVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAgID5sYWJlbCB0b28gbG9uZzwvbWF0LWVycm9yXHJcbiAgICAgICAgPlxyXG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICA8ZGl2XHJcbiAgICAgICAgKm5nSWY9XCIhZXh0ZXJuYWwudmFsdWUgJiYgIWNhbkVkaXRUYXJnZXQgJiYgbGFiZWwudmFsdWVcIlxyXG4gICAgICAgIGNsYXNzPVwiaW5mb1wiXHJcbiAgICAgID5cclxuICAgICAgICA8c3BhbiBjbGFzcz1cImxhYmVsXCI+bGFiZWw8L3NwYW4+e3sgbGFiZWwudmFsdWUgfX1cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8IS0tIGdpZCAtLT5cclxuICAgIDxkaXY+XHJcbiAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cImV4dGVybmFsLnZhbHVlIHx8IGNhbkVkaXRUYXJnZXRcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPkdJRDwvbWF0LWxhYmVsPlxyXG4gICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbZm9ybUNvbnRyb2xdPVwiZ2lkXCIgLz5cclxuICAgICAgICA8bWF0LWVycm9yXHJcbiAgICAgICAgICAqbmdJZj1cIiRhbnkoZ2lkKS5lcnJvcnM/LnJlcXVpcmVkICYmIChnaWQuZGlydHkgfHwgZ2lkLnRvdWNoZWQpXCJcclxuICAgICAgICAgID5HSUQgcmVxdWlyZWQ8L21hdC1lcnJvclxyXG4gICAgICAgID5cclxuICAgICAgICA8bWF0LWVycm9yXHJcbiAgICAgICAgICAqbmdJZj1cIiRhbnkoZ2lkKS5lcnJvcnM/Lm1heExlbmd0aCAmJiAoZ2lkLmRpcnR5IHx8IGdpZC50b3VjaGVkKVwiXHJcbiAgICAgICAgICA+R0lEIHRvbyBsb25nPC9tYXQtZXJyb3JcclxuICAgICAgICA+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgIDxkaXYgKm5nSWY9XCIhZXh0ZXJuYWwudmFsdWUgJiYgIWNhbkVkaXRUYXJnZXQgJiYgZ2lkLnZhbHVlXCIgY2xhc3M9XCJpbmZvXCI+XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJsYWJlbFwiPkdJRDwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJnaWRcIj57eyBnaWQudmFsdWUgfX08L3NwYW4+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gQlkgSVRFTSAtLT5cclxuICA8ZGl2ICpuZ0lmPVwiIWV4dGVybmFsLnZhbHVlXCI+XHJcbiAgICA8ZmllbGRzZXQgKm5nSWY9XCIhYnlUeXBlTW9kZS52YWx1ZVwiIGNsYXNzPVwiZm9ybS1yb3dcIj5cclxuICAgICAgPGxlZ2VuZD5waW4gZmlsdGVyczwvbGVnZW5kPlxyXG4gICAgICA8IS0tIGl0ZW0gZmlsdGVyIC0tPlxyXG4gICAgICA8Y2FkbXVzLXJlZi1sb29rdXBcclxuICAgICAgICBbc2VydmljZV09XCJpdGVtTG9va3VwU2VydmljZVwiXHJcbiAgICAgICAgbGFiZWw9XCJpdGVtXCJcclxuICAgICAgICAoaXRlbUNoYW5nZSk9XCJvbkl0ZW1Mb29rdXBDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICAgID48L2NhZG11cy1yZWYtbG9va3VwPlxyXG5cclxuICAgICAgPCEtLSBwYXJ0IGZpbHRlciAtLT5cclxuICAgICAgPG1hdC1mb3JtLWZpZWxkICpuZ0lmPVwiaXRlbVBhcnRzLmxlbmd0aFwiPlxyXG4gICAgICAgIDxtYXQtbGFiZWw+cGFydDwvbWF0LWxhYmVsPlxyXG4gICAgICAgIDxtYXQtc2VsZWN0IFtmb3JtQ29udHJvbF09XCJpdGVtUGFydFwiPlxyXG4gICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIm51bGxcIj4oYW55KTwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBwIG9mIGl0ZW1QYXJ0c1wiIFt2YWx1ZV09XCJwXCI+e3tcclxuICAgICAgICAgICAgcC50eXBlSWQgfCBmbGF0TG9va3VwIDogbW9kZWxFbnRyaWVzIDogXCJpZFwiIDogXCJ2YWx1ZVwiXHJcbiAgICAgICAgICB9fTwvbWF0LW9wdGlvbj5cclxuICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICA8L2ZpZWxkc2V0PlxyXG5cclxuICAgIDwhLS0gQlkgVFlQRSAtLT5cclxuICAgIDxkaXYgKm5nSWY9XCJieVR5cGVNb2RlLnZhbHVlXCI+XHJcbiAgICAgIDwhLS0gcGFyIHR5cGUgZmlsdGVyIC0tPlxyXG4gICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCJwYXJ0VHlwZUtleXM/Lmxlbmd0aFwiPlxyXG4gICAgICAgIDxtYXQtbGFiZWw+cGFydCB0eXBlPC9tYXQtbGFiZWw+XHJcbiAgICAgICAgPG1hdC1zZWxlY3QgW2Zvcm1Db250cm9sXT1cInBhcnRUeXBlS2V5XCI+XHJcbiAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgayBvZiBwYXJ0VHlwZUtleXNcIiBbdmFsdWVdPVwia1wiPnt7XHJcbiAgICAgICAgICAgIGtcclxuICAgICAgICAgIH19PC9tYXQtb3B0aW9uPlxyXG4gICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDwhLS0gUElOIC0tPlxyXG4gICAgPGRpdiBjbGFzcz1cImZvcm0tcm93XCI+XHJcbiAgICAgIDwhLS0gcGluIGxvb2t1cCAtLT5cclxuICAgICAgPGNhZG11cy1yZWYtbG9va3VwXHJcbiAgICAgICAgW3NlcnZpY2VdPVwicGluTG9va3VwU2VydmljZVwiXHJcbiAgICAgICAgW2Jhc2VGaWx0ZXJdPVwiZmlsdGVyXCJcclxuICAgICAgICBbb3B0aW9uc109XCJwaW5GaWx0ZXJPcHRpb25zXCJcclxuICAgICAgICBsYWJlbD1cInBpblwiXHJcbiAgICAgICAgKGl0ZW1DaGFuZ2UpPVwib25QaW5Mb29rdXBDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICAgID48L2NhZG11cy1yZWYtbG9va3VwPlxyXG4gICAgICA8IS0tIG1vZGUgc3dpdGNoZXIgLS0+XHJcbiAgICAgIDxkaXY+XHJcbiAgICAgICAgPG1hdC1jaGVja2JveCBbZm9ybUNvbnRyb2xdPVwiYnlUeXBlTW9kZVwiICpuZ0lmPVwiY2FuU3dpdGNoTW9kZVwiPlxyXG4gICAgICAgICAgYnkgdHlwZTwvbWF0LWNoZWNrYm94XHJcbiAgICAgICAgPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDwhLS0gZGF0YSAtLT5cclxuICAgIDxtYXQtZXhwYW5zaW9uLXBhbmVsIGlkPVwiZGF0YVwiICpuZ0lmPVwibG9va3VwRGF0YT8ucGluPy5uYW1lXCI+XHJcbiAgICAgIDxtYXQtZXhwYW5zaW9uLXBhbmVsLWhlYWRlcj5waW4gZGF0YTwvbWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XHJcbiAgICAgIDwhLS0gdGFibGUgLS0+XHJcbiAgICAgIDx0YWJsZT5cclxuICAgICAgICA8dGhlYWQ+XHJcbiAgICAgICAgICA8dGg+PC90aD5cclxuICAgICAgICAgIDx0aD5zb3VyY2U8L3RoPlxyXG4gICAgICAgICAgPHRoPnZhbHVlPC90aD5cclxuICAgICAgICA8L3RoZWFkPlxyXG4gICAgICAgIDx0Ym9keT5cclxuICAgICAgICAgIDwhLS0gcGluIC0tPlxyXG4gICAgICAgICAgPHRyICpuZ0lmPVwibG9va3VwRGF0YT8ucGluPy52YWx1ZVwiPlxyXG4gICAgICAgICAgICA8dGQ+XHJcbiAgICAgICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAgICAgICBbY2RrQ29weVRvQ2xpcGJvYXJkXT1cImxvb2t1cERhdGEhLnBpbiEudmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgKGNka0NvcHlUb0NsaXBib2FyZENvcGllZCk9XCJvbkNvcGllZCgpXCJcclxuICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICA8bWF0LWljb24+Y29udGVudF9jb3B5PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgPHRkPnBpbjwvdGQ+XHJcbiAgICAgICAgICAgIDx0ZD57eyBsb29rdXBEYXRhIS5waW4udmFsdWUgfX08L3RkPlxyXG4gICAgICAgICAgPC90cj5cclxuICAgICAgICAgIDwhLS0gaXRlbSBJRCAtLT5cclxuICAgICAgICAgIDx0ciAqbmdJZj1cImxvb2t1cERhdGE/LnBpbj8uaXRlbUlkXCI+XHJcbiAgICAgICAgICAgIDx0ZD5cclxuICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcclxuICAgICAgICAgICAgICAgIFtjZGtDb3B5VG9DbGlwYm9hcmRdPVwibG9va3VwRGF0YSEucGluIS5pdGVtSWRcIlxyXG4gICAgICAgICAgICAgICAgKGNka0NvcHlUb0NsaXBib2FyZENvcGllZCk9XCJvbkNvcGllZCgpXCJcclxuICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICA8bWF0LWljb24+Y29udGVudF9jb3B5PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgPHRkPml0ZW0gSUQ8L3RkPlxyXG4gICAgICAgICAgICA8dGQ+e3sgbG9va3VwRGF0YSEucGluLml0ZW1JZCB9fTwvdGQ+XHJcbiAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgPCEtLSBpdGVtIHRpdGxlIC0tPlxyXG4gICAgICAgICAgPHRyICpuZ0lmPVwibG9va3VwRGF0YT8uaXRlbT8udGl0bGVcIj5cclxuICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICAgICAgICAgICAgW2Nka0NvcHlUb0NsaXBib2FyZF09XCJsb29rdXBEYXRhIS5pdGVtIS50aXRsZVwiXHJcbiAgICAgICAgICAgICAgICAoY2RrQ29weVRvQ2xpcGJvYXJkQ29waWVkKT1cIm9uQ29waWVkKClcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jb250ZW50X2NvcHk8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8dGQ+aXRlbSB0aXRsZTwvdGQ+XHJcbiAgICAgICAgICAgIDx0ZD57eyBsb29rdXBEYXRhIS5pdGVtIS50aXRsZSB9fTwvdGQ+XHJcbiAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgPCEtLSBwYXJ0IElEIC0tPlxyXG4gICAgICAgICAgPHRyICpuZ0lmPVwibG9va3VwRGF0YT8ucGluPy5wYXJ0SWRcIj5cclxuICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICAgICAgICAgICAgW2Nka0NvcHlUb0NsaXBib2FyZF09XCJsb29rdXBEYXRhIS5waW4hLnBhcnRJZFwiXHJcbiAgICAgICAgICAgICAgICAoY2RrQ29weVRvQ2xpcGJvYXJkQ29waWVkKT1cIm9uQ29waWVkKClcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jb250ZW50X2NvcHk8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8dGQ+cGFydCBJRDwvdGQ+XHJcbiAgICAgICAgICAgIDx0ZD57eyBsb29rdXBEYXRhIS5waW4ucGFydElkIH19PC90ZD5cclxuICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICA8IS0tIHBhcnQgdHlwZSBJRCAtLT5cclxuICAgICAgICAgIDx0ciAqbmdJZj1cImxvb2t1cERhdGE/LnBpbj8ucGFydFR5cGVJZFwiPlxyXG4gICAgICAgICAgICA8dGQ+XHJcbiAgICAgICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAgICAgICBbY2RrQ29weVRvQ2xpcGJvYXJkXT1cImxvb2t1cERhdGEhLnBpbiEucGFydFR5cGVJZFwiXHJcbiAgICAgICAgICAgICAgICAoY2RrQ29weVRvQ2xpcGJvYXJkQ29waWVkKT1cIm9uQ29waWVkKClcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jb250ZW50X2NvcHk8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8dGQ+cGFydCB0eXBlIElEPC90ZD5cclxuICAgICAgICAgICAgPHRkPnt7IGxvb2t1cERhdGEhLnBpbiEucGFydFR5cGVJZCB9fTwvdGQ+XHJcbiAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgPCEtLSBwYXJ0IHJvbGUgSUQgLS0+XHJcbiAgICAgICAgICA8dHIgKm5nSWY9XCJsb29rdXBEYXRhPy5waW4/LnJvbGVJZFwiPlxyXG4gICAgICAgICAgICA8dGQ+XHJcbiAgICAgICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAgICAgICBbY2RrQ29weVRvQ2xpcGJvYXJkXT1cImxvb2t1cERhdGEhLnBpbiEucm9sZUlkIVwiXHJcbiAgICAgICAgICAgICAgICAoY2RrQ29weVRvQ2xpcGJvYXJkQ29waWVkKT1cIm9uQ29waWVkKClcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jb250ZW50X2NvcHk8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICA8dGQ+cGFydCByb2xlIElEPC90ZD5cclxuICAgICAgICAgICAgPHRkPnt7IGxvb2t1cERhdGEhLnBpbiEucm9sZUlkIH19PC90ZD5cclxuICAgICAgICAgIDwvdHI+XHJcblxyXG4gICAgICAgICAgPCEtLSBwYXJ0J3MgbWV0YWRhdGEgLS0+XHJcbiAgICAgICAgICA8dHJcclxuICAgICAgICAgICAgKm5nRm9yPVwiXHJcbiAgICAgICAgICAgICAgbGV0IG0gb2YgbG9va3VwRGF0YT8ubWV0YVBhcnQ/Lm1ldGFkYXRhIHx8IFtdO1xyXG4gICAgICAgICAgICAgIGxldCBpID0gaW5kZXhcclxuICAgICAgICAgICAgXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgICAgICAgICAgICAgW2Nka0NvcHlUb0NsaXBib2FyZF09XCJtLnZhbHVlXCJcclxuICAgICAgICAgICAgICAgIChjZGtDb3B5VG9DbGlwYm9hcmRDb3BpZWQpPVwib25Db3BpZWQoKVwiXHJcbiAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmNvbnRlbnRfY29weTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cIm1ldGFkYXRhXCI+e3sgbS5uYW1lIH19PC90ZD5cclxuICAgICAgICAgICAgPHRkIGNsYXNzPVwibWV0YWRhdGFcIj57eyBtLnZhbHVlIH19PC90ZD5cclxuICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgPC90Ym9keT5cclxuICAgICAgPC90YWJsZT5cclxuICAgIDwvbWF0LWV4cGFuc2lvbi1wYW5lbD5cclxuICA8L2Rpdj5cclxuXHJcbiAgPCEtLSBidXR0b25zIC0tPlxyXG4gIDxkaXY+XHJcbiAgICA8YnV0dG9uIG1hdC1mbGF0LWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImNsb3NlKClcIj5cclxuICAgICAgPG1hdC1pY29uIGNvbG9yPVwid2FyblwiPmNsb3NlPC9tYXQtaWNvbj5cclxuICAgIDwvYnV0dG9uPlxyXG4gICAgPGJ1dHRvbiBtYXQtZmxhdC1idXR0b24gdHlwZT1cInN1Ym1pdFwiIFtkaXNhYmxlZF09XCJmb3JtLmludmFsaWRcIj5cclxuICAgICAgPG1hdC1pY29uIGNvbG9yPVwicHJpbWFyeVwiPmNoZWNrX2NpcmNsZTwvbWF0LWljb24+IHRhcmdldFxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9kaXY+XHJcbjwvZm9ybT5cclxuIl19
|