@super-green/query-builder 0.7.2

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.
Files changed (34) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +340 -0
  3. package/dist/query-builder/README.md +24 -0
  4. package/dist/query-builder/esm2022/lib/query-builder/query-arrow-icon.directive.mjs +15 -0
  5. package/dist/query-builder/esm2022/lib/query-builder/query-builder.component.mjs +769 -0
  6. package/dist/query-builder/esm2022/lib/query-builder/query-builder.interfaces.mjs +2 -0
  7. package/dist/query-builder/esm2022/lib/query-builder/query-button-group.directive.mjs +15 -0
  8. package/dist/query-builder/esm2022/lib/query-builder/query-empty-warning.directive.mjs +15 -0
  9. package/dist/query-builder/esm2022/lib/query-builder/query-entity.directive.mjs +15 -0
  10. package/dist/query-builder/esm2022/lib/query-builder/query-field.directive.mjs +15 -0
  11. package/dist/query-builder/esm2022/lib/query-builder/query-input.directive.mjs +28 -0
  12. package/dist/query-builder/esm2022/lib/query-builder/query-operator.directive.mjs +15 -0
  13. package/dist/query-builder/esm2022/lib/query-builder/query-remove-button.directive.mjs +15 -0
  14. package/dist/query-builder/esm2022/lib/query-builder/query-switch-group.directive.mjs +15 -0
  15. package/dist/query-builder/esm2022/lib/query-builder.module.mjs +73 -0
  16. package/dist/query-builder/esm2022/public-api.mjs +16 -0
  17. package/dist/query-builder/esm2022/query-builder.mjs +5 -0
  18. package/dist/query-builder/fesm2022/query-builder.mjs +961 -0
  19. package/dist/query-builder/fesm2022/query-builder.mjs.map +1 -0
  20. package/dist/query-builder/index.d.ts +5 -0
  21. package/dist/query-builder/lib/query-builder/query-arrow-icon.directive.d.ts +8 -0
  22. package/dist/query-builder/lib/query-builder/query-builder.component.d.ts +129 -0
  23. package/dist/query-builder/lib/query-builder/query-builder.interfaces.d.ts +143 -0
  24. package/dist/query-builder/lib/query-builder/query-button-group.directive.d.ts +8 -0
  25. package/dist/query-builder/lib/query-builder/query-empty-warning.directive.d.ts +8 -0
  26. package/dist/query-builder/lib/query-builder/query-entity.directive.d.ts +8 -0
  27. package/dist/query-builder/lib/query-builder/query-field.directive.d.ts +8 -0
  28. package/dist/query-builder/lib/query-builder/query-input.directive.d.ts +12 -0
  29. package/dist/query-builder/lib/query-builder/query-operator.directive.d.ts +8 -0
  30. package/dist/query-builder/lib/query-builder/query-remove-button.directive.d.ts +8 -0
  31. package/dist/query-builder/lib/query-builder/query-switch-group.directive.d.ts +8 -0
  32. package/dist/query-builder/lib/query-builder.module.d.ts +18 -0
  33. package/dist/query-builder/public-api.d.ts +12 -0
  34. package/package.json +56 -0
@@ -0,0 +1,769 @@
1
+ import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
2
+ import { QueryOperatorDirective } from './query-operator.directive';
3
+ import { QueryFieldDirective } from './query-field.directive';
4
+ import { QueryEntityDirective } from './query-entity.directive';
5
+ import { QuerySwitchGroupDirective } from './query-switch-group.directive';
6
+ import { QueryButtonGroupDirective } from './query-button-group.directive';
7
+ import { QueryInputDirective } from './query-input.directive';
8
+ import { QueryRemoveButtonDirective } from './query-remove-button.directive';
9
+ import { QueryEmptyWarningDirective } from './query-empty-warning.directive';
10
+ import { QueryArrowIconDirective } from './query-arrow-icon.directive';
11
+ import { Component, ContentChild, ContentChildren, forwardRef, Input, ViewChild } from '@angular/core';
12
+ import * as i0 from "@angular/core";
13
+ import * as i1 from "@angular/common";
14
+ import * as i2 from "@angular/forms";
15
+ export const CONTROL_VALUE_ACCESSOR = {
16
+ provide: NG_VALUE_ACCESSOR,
17
+ useExisting: forwardRef(() => QueryBuilderComponent),
18
+ multi: true
19
+ };
20
+ export const VALIDATOR = {
21
+ provide: NG_VALIDATORS,
22
+ useExisting: forwardRef(() => QueryBuilderComponent),
23
+ multi: true
24
+ };
25
+ export class QueryBuilderComponent {
26
+ changeDetectorRef;
27
+ fields;
28
+ filterFields;
29
+ entities;
30
+ defaultClassNames = {
31
+ arrowIconButton: 'q-arrow-icon-button',
32
+ arrowIcon: 'q-icon q-arrow-icon',
33
+ removeIcon: 'q-icon q-remove-icon',
34
+ addIcon: 'q-icon q-add-icon',
35
+ button: 'q-button',
36
+ buttonGroup: 'q-button-group',
37
+ removeButton: 'q-remove-button',
38
+ switchGroup: 'q-switch-group',
39
+ switchLabel: 'q-switch-label',
40
+ switchRadio: 'q-switch-radio',
41
+ rightAlign: 'q-right-align',
42
+ transition: 'q-transition',
43
+ collapsed: 'q-collapsed',
44
+ treeContainer: 'q-tree-container',
45
+ tree: 'q-tree',
46
+ row: 'q-row',
47
+ connector: 'q-connector',
48
+ rule: 'q-rule',
49
+ ruleSet: 'q-ruleset',
50
+ invalidRuleSet: 'q-invalid-ruleset',
51
+ emptyWarning: 'q-empty-warning',
52
+ fieldControl: 'q-field-control',
53
+ fieldControlSize: 'q-control-size',
54
+ entityControl: 'q-entity-control',
55
+ entityControlSize: 'q-control-size',
56
+ operatorControl: 'q-operator-control',
57
+ operatorControlSize: 'q-control-size',
58
+ inputControl: 'q-input-control',
59
+ inputControlSize: 'q-control-size'
60
+ };
61
+ defaultOperatorMap = {
62
+ string: ['=', '!=', 'contains', 'like'],
63
+ number: ['=', '!=', '>', '>=', '<', '<='],
64
+ time: ['=', '!=', '>', '>=', '<', '<='],
65
+ date: ['=', '!=', '>', '>=', '<', '<='],
66
+ category: ['=', '!=', 'in', 'not in'],
67
+ boolean: ['=']
68
+ };
69
+ disabled;
70
+ data = { condition: 'and', rules: [] };
71
+ // For ControlValueAccessor interface
72
+ onChangeCallback;
73
+ onTouchedCallback;
74
+ allowRuleset = true;
75
+ allowCollapse = false;
76
+ emptyMessage = 'A ruleset cannot be empty. Please add a rule or remove it all together.';
77
+ classNames;
78
+ operatorMap;
79
+ parentValue;
80
+ config = { fields: {} };
81
+ parentArrowIconTemplate;
82
+ parentInputTemplates;
83
+ parentOperatorTemplate;
84
+ parentFieldTemplate;
85
+ parentEntityTemplate;
86
+ parentSwitchGroupTemplate;
87
+ parentButtonGroupTemplate;
88
+ parentRemoveButtonTemplate;
89
+ parentEmptyWarningTemplate;
90
+ parentChangeCallback;
91
+ parentTouchedCallback;
92
+ persistValueOnFieldChange = false;
93
+ treeContainer;
94
+ buttonGroupTemplate;
95
+ switchGroupTemplate;
96
+ fieldTemplate;
97
+ entityTemplate;
98
+ operatorTemplate;
99
+ removeButtonTemplate;
100
+ emptyWarningTemplate;
101
+ inputTemplates;
102
+ arrowIconTemplate;
103
+ defaultTemplateTypes = [
104
+ 'string', 'number', 'time', 'date', 'category', 'boolean', 'multiselect'
105
+ ];
106
+ defaultPersistValueTypes = [
107
+ 'string', 'number', 'time', 'date', 'boolean'
108
+ ];
109
+ defaultEmptyList = [];
110
+ operatorsCache;
111
+ inputContextCache = new Map();
112
+ operatorContextCache = new Map();
113
+ fieldContextCache = new Map();
114
+ entityContextCache = new Map();
115
+ removeButtonContextCache = new Map();
116
+ buttonGroupContext;
117
+ constructor(changeDetectorRef) {
118
+ this.changeDetectorRef = changeDetectorRef;
119
+ }
120
+ // ----------OnInit Implementation----------
121
+ ngOnInit() { }
122
+ // ----------OnChanges Implementation----------
123
+ ngOnChanges(changes) {
124
+ const config = this.config;
125
+ const type = typeof config;
126
+ if (type === 'object') {
127
+ this.fields = Object.keys(config.fields).map((value) => {
128
+ const field = config.fields[value];
129
+ field.value = field.value || value;
130
+ return field;
131
+ });
132
+ if (config.entities) {
133
+ this.entities = Object.keys(config.entities).map((value) => {
134
+ const entity = config.entities[value];
135
+ entity.value = entity.value || value;
136
+ return entity;
137
+ });
138
+ }
139
+ else {
140
+ this.entities = null;
141
+ }
142
+ this.operatorsCache = {};
143
+ }
144
+ else {
145
+ throw new Error(`Expected 'config' must be a valid object, got ${type} instead.`);
146
+ }
147
+ }
148
+ // ----------Validator Implementation----------
149
+ validate(control) {
150
+ const errors = {};
151
+ const ruleErrorStore = [];
152
+ let hasErrors = false;
153
+ if (!this.config.allowEmptyRulesets && this.checkEmptyRuleInRuleset(this.data)) {
154
+ errors.empty = 'Empty rulesets are not allowed.';
155
+ hasErrors = true;
156
+ }
157
+ this.validateRulesInRuleset(this.data, ruleErrorStore);
158
+ if (ruleErrorStore.length) {
159
+ errors.rules = ruleErrorStore;
160
+ hasErrors = true;
161
+ }
162
+ return hasErrors ? errors : null;
163
+ }
164
+ // ----------ControlValueAccessor Implementation----------
165
+ get value() {
166
+ return this.data;
167
+ }
168
+ set value(value) {
169
+ // When component is initialized without a formControl, null is passed to value
170
+ this.data = value || { condition: 'and', rules: [] };
171
+ this.handleDataChange();
172
+ }
173
+ writeValue(obj) {
174
+ this.value = obj;
175
+ }
176
+ registerOnChange(fn) {
177
+ this.onChangeCallback = () => fn(this.data);
178
+ }
179
+ registerOnTouched(fn) {
180
+ this.onTouchedCallback = () => fn(this.data);
181
+ }
182
+ setDisabledState(isDisabled) {
183
+ this.disabled = isDisabled;
184
+ this.changeDetectorRef.detectChanges();
185
+ }
186
+ // ----------END----------
187
+ getDisabledState = () => {
188
+ return this.disabled;
189
+ };
190
+ findTemplateForRule(rule) {
191
+ const type = this.getInputType(rule.field, rule.operator);
192
+ if (type) {
193
+ const queryInput = this.findQueryInput(type);
194
+ if (queryInput) {
195
+ return queryInput.template;
196
+ }
197
+ else {
198
+ if (this.defaultTemplateTypes.indexOf(type) === -1) {
199
+ console.warn(`Could not find template for field with type: ${type}`);
200
+ }
201
+ }
202
+ }
203
+ return null;
204
+ }
205
+ findQueryInput(type) {
206
+ const templates = this.parentInputTemplates || this.inputTemplates;
207
+ return templates.find((item) => item.queryInputType === type);
208
+ }
209
+ getOperators(field) {
210
+ if (this.operatorsCache[field]) {
211
+ return this.operatorsCache[field];
212
+ }
213
+ let operators = this.defaultEmptyList;
214
+ const fieldObject = this.config.fields[field];
215
+ if (this.config.getOperators) {
216
+ return this.config.getOperators(field, fieldObject);
217
+ }
218
+ const type = fieldObject.type;
219
+ if (fieldObject && fieldObject.operators) {
220
+ operators = fieldObject.operators;
221
+ }
222
+ else if (type) {
223
+ operators = (this.operatorMap && this.operatorMap[type]) || this.defaultOperatorMap[type] || this.defaultEmptyList;
224
+ if (operators.length === 0) {
225
+ console.warn(`No operators found for field '${field}' with type ${fieldObject.type}. ` +
226
+ `Please define an 'operators' property on the field or use the 'operatorMap' binding to fix this.`);
227
+ }
228
+ if (fieldObject.nullable) {
229
+ operators = operators.concat(['is null', 'is not null']);
230
+ }
231
+ }
232
+ else {
233
+ console.warn(`No 'type' property found on field: '${field}'`);
234
+ }
235
+ // Cache reference to array object, so it won't be computed next time and trigger a rerender.
236
+ this.operatorsCache[field] = operators;
237
+ return operators;
238
+ }
239
+ getFields(entity) {
240
+ if (this.entities && entity) {
241
+ return this.fields.filter((field) => {
242
+ return field && field.entity === entity;
243
+ });
244
+ }
245
+ else {
246
+ return this.fields;
247
+ }
248
+ }
249
+ getInputType(field, operator) {
250
+ if (this.config.getInputType) {
251
+ return this.config.getInputType(field, operator);
252
+ }
253
+ if (!this.config.fields[field]) {
254
+ throw new Error(`No configuration for field '${field}' could be found! Please add it to config.fields.`);
255
+ }
256
+ const type = this.config.fields[field].type;
257
+ switch (operator) {
258
+ case 'is null':
259
+ case 'is not null':
260
+ return null; // No displayed component
261
+ case 'in':
262
+ case 'not in':
263
+ return type === 'category' || type === 'boolean' ? 'multiselect' : type;
264
+ default:
265
+ return type;
266
+ }
267
+ }
268
+ getOptions(field) {
269
+ if (this.config.getOptions) {
270
+ return this.config.getOptions(field);
271
+ }
272
+ return this.config.fields[field].options || this.defaultEmptyList;
273
+ }
274
+ getClassNames(...args) {
275
+ const clsLookup = this.classNames ? this.classNames : this.defaultClassNames;
276
+ const classNames = args.map((id) => clsLookup[id] || this.defaultClassNames[id]).filter((c) => !!c);
277
+ return classNames.length ? classNames.join(' ') : null;
278
+ }
279
+ getDefaultField(entity) {
280
+ if (!entity) {
281
+ return null;
282
+ }
283
+ else if (entity.defaultField !== undefined) {
284
+ return this.getDefaultValue(entity.defaultField);
285
+ }
286
+ else {
287
+ const entityFields = this.fields.filter((field) => {
288
+ return field && field.entity === entity.value;
289
+ });
290
+ if (entityFields && entityFields.length) {
291
+ return entityFields[0];
292
+ }
293
+ else {
294
+ console.warn(`No fields found for entity '${entity.name}'. ` +
295
+ `A 'defaultOperator' is also not specified on the field config. Operator value will default to null.`);
296
+ return null;
297
+ }
298
+ }
299
+ }
300
+ getDefaultOperator(field) {
301
+ if (field && field.defaultOperator !== undefined) {
302
+ return this.getDefaultValue(field.defaultOperator);
303
+ }
304
+ else {
305
+ const operators = this.getOperators(field.value);
306
+ if (operators && operators.length) {
307
+ return operators[0];
308
+ }
309
+ else {
310
+ console.warn(`No operators found for field '${field.value}'. ` +
311
+ `A 'defaultOperator' is also not specified on the field config. Operator value will default to null.`);
312
+ return null;
313
+ }
314
+ }
315
+ }
316
+ addRule(parent) {
317
+ if (this.disabled) {
318
+ return;
319
+ }
320
+ parent = parent || this.data;
321
+ if (this.config.addRule) {
322
+ this.config.addRule(parent);
323
+ }
324
+ else {
325
+ const field = this.fields[0];
326
+ parent.rules = parent.rules.concat([{
327
+ field: field.value,
328
+ operator: this.getDefaultOperator(field),
329
+ value: this.getDefaultValue(field.defaultValue),
330
+ entity: field.entity
331
+ }]);
332
+ }
333
+ this.handleTouched();
334
+ this.handleDataChange();
335
+ }
336
+ removeRule(rule, parent) {
337
+ if (this.disabled) {
338
+ return;
339
+ }
340
+ parent = parent || this.data;
341
+ if (this.config.removeRule) {
342
+ this.config.removeRule(rule, parent);
343
+ }
344
+ else {
345
+ parent.rules = parent.rules.filter((r) => r !== rule);
346
+ }
347
+ this.inputContextCache.delete(rule);
348
+ this.operatorContextCache.delete(rule);
349
+ this.fieldContextCache.delete(rule);
350
+ this.entityContextCache.delete(rule);
351
+ this.removeButtonContextCache.delete(rule);
352
+ this.handleTouched();
353
+ this.handleDataChange();
354
+ }
355
+ addRuleSet(parent) {
356
+ if (this.disabled) {
357
+ return;
358
+ }
359
+ parent = parent || this.data;
360
+ if (this.config.addRuleSet) {
361
+ this.config.addRuleSet(parent);
362
+ }
363
+ else {
364
+ parent.rules = parent.rules.concat([{ condition: 'and', rules: [] }]);
365
+ }
366
+ this.handleTouched();
367
+ this.handleDataChange();
368
+ }
369
+ removeRuleSet(ruleset, parent) {
370
+ if (this.disabled) {
371
+ return;
372
+ }
373
+ ruleset = ruleset || this.data;
374
+ parent = parent || this.parentValue;
375
+ if (this.config.removeRuleSet) {
376
+ this.config.removeRuleSet(ruleset, parent);
377
+ }
378
+ else {
379
+ parent.rules = parent.rules.filter((r) => r !== ruleset);
380
+ }
381
+ this.handleTouched();
382
+ this.handleDataChange();
383
+ }
384
+ transitionEnd(e) {
385
+ this.treeContainer.nativeElement.style.maxHeight = null;
386
+ }
387
+ toggleCollapse() {
388
+ this.computedTreeContainerHeight();
389
+ setTimeout(() => {
390
+ this.data.collapsed = !this.data.collapsed;
391
+ }, 100);
392
+ }
393
+ computedTreeContainerHeight() {
394
+ const nativeElement = this.treeContainer.nativeElement;
395
+ if (nativeElement && nativeElement.firstElementChild) {
396
+ nativeElement.style.maxHeight = (nativeElement.firstElementChild.clientHeight + 8) + 'px';
397
+ }
398
+ }
399
+ changeCondition(value) {
400
+ if (this.disabled) {
401
+ return;
402
+ }
403
+ this.data.condition = value;
404
+ this.handleTouched();
405
+ this.handleDataChange();
406
+ }
407
+ changeOperator(rule) {
408
+ if (this.disabled) {
409
+ return;
410
+ }
411
+ if (this.config.coerceValueForOperator) {
412
+ rule.value = this.config.coerceValueForOperator(rule.operator, rule.value, rule);
413
+ }
414
+ else {
415
+ rule.value = this.coerceValueForOperator(rule.operator, rule.value, rule);
416
+ }
417
+ this.handleTouched();
418
+ this.handleDataChange();
419
+ }
420
+ coerceValueForOperator(operator, value, rule) {
421
+ const inputType = this.getInputType(rule.field, operator);
422
+ if (inputType === 'multiselect' && !Array.isArray(value)) {
423
+ return [value];
424
+ }
425
+ return value;
426
+ }
427
+ changeInput() {
428
+ if (this.disabled) {
429
+ return;
430
+ }
431
+ this.handleTouched();
432
+ this.handleDataChange();
433
+ }
434
+ changeField(fieldValue, rule) {
435
+ if (this.disabled) {
436
+ return;
437
+ }
438
+ const inputContext = this.inputContextCache.get(rule);
439
+ const currentField = inputContext && inputContext.field;
440
+ const nextField = this.config.fields[fieldValue];
441
+ const nextValue = this.calculateFieldChangeValue(currentField, nextField, rule.value);
442
+ if (nextValue !== undefined) {
443
+ rule.value = nextValue;
444
+ }
445
+ else {
446
+ delete rule.value;
447
+ }
448
+ rule.operator = this.getDefaultOperator(nextField);
449
+ // Create new context objects so templates will automatically update
450
+ this.inputContextCache.delete(rule);
451
+ this.operatorContextCache.delete(rule);
452
+ this.fieldContextCache.delete(rule);
453
+ this.entityContextCache.delete(rule);
454
+ this.getInputContext(rule);
455
+ this.getFieldContext(rule);
456
+ this.getOperatorContext(rule);
457
+ this.getEntityContext(rule);
458
+ this.handleTouched();
459
+ this.handleDataChange();
460
+ }
461
+ changeEntity(entityValue, rule, index, data) {
462
+ if (this.disabled) {
463
+ return;
464
+ }
465
+ let i = index;
466
+ let rs = data;
467
+ const entity = this.entities.find((e) => e.value === entityValue);
468
+ const defaultField = this.getDefaultField(entity);
469
+ if (!rs) {
470
+ rs = this.data;
471
+ i = rs.rules.findIndex((x) => x === rule);
472
+ }
473
+ rule.field = defaultField.value;
474
+ rs.rules[i] = rule;
475
+ if (defaultField) {
476
+ this.changeField(defaultField.value, rule);
477
+ }
478
+ else {
479
+ this.handleTouched();
480
+ this.handleDataChange();
481
+ }
482
+ }
483
+ getDefaultValue(defaultValue) {
484
+ switch (typeof defaultValue) {
485
+ case 'function':
486
+ return defaultValue();
487
+ default:
488
+ return defaultValue;
489
+ }
490
+ }
491
+ getOperatorTemplate() {
492
+ const t = this.parentOperatorTemplate || this.operatorTemplate;
493
+ return t ? t.template : null;
494
+ }
495
+ getFieldTemplate() {
496
+ const t = this.parentFieldTemplate || this.fieldTemplate;
497
+ return t ? t.template : null;
498
+ }
499
+ getEntityTemplate() {
500
+ const t = this.parentEntityTemplate || this.entityTemplate;
501
+ return t ? t.template : null;
502
+ }
503
+ getArrowIconTemplate() {
504
+ const t = this.parentArrowIconTemplate || this.arrowIconTemplate;
505
+ return t ? t.template : null;
506
+ }
507
+ getButtonGroupTemplate() {
508
+ const t = this.parentButtonGroupTemplate || this.buttonGroupTemplate;
509
+ return t ? t.template : null;
510
+ }
511
+ getSwitchGroupTemplate() {
512
+ const t = this.parentSwitchGroupTemplate || this.switchGroupTemplate;
513
+ return t ? t.template : null;
514
+ }
515
+ getRemoveButtonTemplate() {
516
+ const t = this.parentRemoveButtonTemplate || this.removeButtonTemplate;
517
+ return t ? t.template : null;
518
+ }
519
+ getEmptyWarningTemplate() {
520
+ const t = this.parentEmptyWarningTemplate || this.emptyWarningTemplate;
521
+ return t ? t.template : null;
522
+ }
523
+ getQueryItemClassName(local) {
524
+ let cls = this.getClassNames('row', 'connector', 'transition');
525
+ cls += ' ' + this.getClassNames(local.ruleset ? 'ruleSet' : 'rule');
526
+ if (local.invalid) {
527
+ cls += ' ' + this.getClassNames('invalidRuleSet');
528
+ }
529
+ return cls;
530
+ }
531
+ getButtonGroupContext() {
532
+ if (!this.buttonGroupContext) {
533
+ this.buttonGroupContext = {
534
+ addRule: this.addRule.bind(this),
535
+ addRuleSet: this.allowRuleset && this.addRuleSet.bind(this),
536
+ removeRuleSet: this.allowRuleset && this.parentValue && this.removeRuleSet.bind(this),
537
+ getDisabledState: this.getDisabledState,
538
+ $implicit: this.data
539
+ };
540
+ }
541
+ return this.buttonGroupContext;
542
+ }
543
+ getRemoveButtonContext(rule) {
544
+ if (!this.removeButtonContextCache.has(rule)) {
545
+ this.removeButtonContextCache.set(rule, {
546
+ removeRule: this.removeRule.bind(this),
547
+ getDisabledState: this.getDisabledState,
548
+ $implicit: rule
549
+ });
550
+ }
551
+ return this.removeButtonContextCache.get(rule);
552
+ }
553
+ getFieldContext(rule) {
554
+ if (!this.fieldContextCache.has(rule)) {
555
+ this.fieldContextCache.set(rule, {
556
+ onChange: this.changeField.bind(this),
557
+ getFields: this.getFields.bind(this),
558
+ getDisabledState: this.getDisabledState,
559
+ fields: this.fields,
560
+ $implicit: rule
561
+ });
562
+ }
563
+ return this.fieldContextCache.get(rule);
564
+ }
565
+ getEntityContext(rule) {
566
+ if (!this.entityContextCache.has(rule)) {
567
+ this.entityContextCache.set(rule, {
568
+ onChange: this.changeEntity.bind(this),
569
+ getDisabledState: this.getDisabledState,
570
+ entities: this.entities,
571
+ $implicit: rule
572
+ });
573
+ }
574
+ return this.entityContextCache.get(rule);
575
+ }
576
+ getSwitchGroupContext() {
577
+ return {
578
+ onChange: this.changeCondition.bind(this),
579
+ getDisabledState: this.getDisabledState,
580
+ $implicit: this.data
581
+ };
582
+ }
583
+ getArrowIconContext() {
584
+ return {
585
+ getDisabledState: this.getDisabledState,
586
+ $implicit: this.data
587
+ };
588
+ }
589
+ getEmptyWarningContext() {
590
+ return {
591
+ getDisabledState: this.getDisabledState,
592
+ message: this.emptyMessage,
593
+ $implicit: this.data
594
+ };
595
+ }
596
+ getOperatorContext(rule) {
597
+ if (!this.operatorContextCache.has(rule)) {
598
+ this.operatorContextCache.set(rule, {
599
+ onChange: this.changeOperator.bind(this),
600
+ getDisabledState: this.getDisabledState,
601
+ operators: this.getOperators(rule.field),
602
+ $implicit: rule
603
+ });
604
+ }
605
+ return this.operatorContextCache.get(rule);
606
+ }
607
+ getInputContext(rule) {
608
+ if (!this.inputContextCache.has(rule)) {
609
+ this.inputContextCache.set(rule, {
610
+ onChange: this.changeInput.bind(this),
611
+ getDisabledState: this.getDisabledState,
612
+ options: this.getOptions(rule.field),
613
+ field: this.config.fields[rule.field],
614
+ $implicit: rule
615
+ });
616
+ }
617
+ return this.inputContextCache.get(rule);
618
+ }
619
+ calculateFieldChangeValue(currentField, nextField, currentValue) {
620
+ if (this.config.calculateFieldChangeValue != null) {
621
+ return this.config.calculateFieldChangeValue(currentField, nextField, currentValue);
622
+ }
623
+ const canKeepValue = () => {
624
+ if (currentField == null || nextField == null) {
625
+ return false;
626
+ }
627
+ return currentField.type === nextField.type
628
+ && this.defaultPersistValueTypes.indexOf(currentField.type) !== -1;
629
+ };
630
+ if (this.persistValueOnFieldChange && canKeepValue()) {
631
+ return currentValue;
632
+ }
633
+ if (nextField && nextField.defaultValue !== undefined) {
634
+ return this.getDefaultValue(nextField.defaultValue);
635
+ }
636
+ return undefined;
637
+ }
638
+ checkEmptyRuleInRuleset(ruleset) {
639
+ if (!ruleset || !ruleset.rules || ruleset.rules.length === 0) {
640
+ return true;
641
+ }
642
+ else {
643
+ return ruleset.rules.some((item) => {
644
+ if (item.rules) {
645
+ return this.checkEmptyRuleInRuleset(item);
646
+ }
647
+ else {
648
+ return false;
649
+ }
650
+ });
651
+ }
652
+ }
653
+ validateRulesInRuleset(ruleset, errorStore) {
654
+ if (ruleset && ruleset.rules && ruleset.rules.length > 0) {
655
+ ruleset.rules.forEach((item) => {
656
+ if (item.rules) {
657
+ return this.validateRulesInRuleset(item, errorStore);
658
+ }
659
+ else if (item.field) {
660
+ const field = this.config.fields[item.field];
661
+ if (field && field.validator && field.validator.apply) {
662
+ const error = field.validator(item, ruleset);
663
+ if (error != null) {
664
+ errorStore.push(error);
665
+ }
666
+ }
667
+ }
668
+ });
669
+ }
670
+ }
671
+ handleDataChange() {
672
+ this.changeDetectorRef.markForCheck();
673
+ if (this.onChangeCallback) {
674
+ this.onChangeCallback();
675
+ }
676
+ if (this.parentChangeCallback) {
677
+ this.parentChangeCallback();
678
+ }
679
+ }
680
+ handleTouched() {
681
+ if (this.onTouchedCallback) {
682
+ this.onTouchedCallback();
683
+ }
684
+ if (this.parentTouchedCallback) {
685
+ this.parentTouchedCallback();
686
+ }
687
+ }
688
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: QueryBuilderComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
689
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", type: QueryBuilderComponent, selector: "query-builder", inputs: { disabled: "disabled", data: "data", allowRuleset: "allowRuleset", allowCollapse: "allowCollapse", emptyMessage: "emptyMessage", classNames: "classNames", operatorMap: "operatorMap", parentValue: "parentValue", config: "config", parentArrowIconTemplate: "parentArrowIconTemplate", parentInputTemplates: "parentInputTemplates", parentOperatorTemplate: "parentOperatorTemplate", parentFieldTemplate: "parentFieldTemplate", parentEntityTemplate: "parentEntityTemplate", parentSwitchGroupTemplate: "parentSwitchGroupTemplate", parentButtonGroupTemplate: "parentButtonGroupTemplate", parentRemoveButtonTemplate: "parentRemoveButtonTemplate", parentEmptyWarningTemplate: "parentEmptyWarningTemplate", parentChangeCallback: "parentChangeCallback", parentTouchedCallback: "parentTouchedCallback", persistValueOnFieldChange: "persistValueOnFieldChange", value: "value" }, providers: [CONTROL_VALUE_ACCESSOR, VALIDATOR], queries: [{ propertyName: "buttonGroupTemplate", first: true, predicate: QueryButtonGroupDirective, descendants: true }, { propertyName: "switchGroupTemplate", first: true, predicate: QuerySwitchGroupDirective, descendants: true }, { propertyName: "fieldTemplate", first: true, predicate: QueryFieldDirective, descendants: true }, { propertyName: "entityTemplate", first: true, predicate: QueryEntityDirective, descendants: true }, { propertyName: "operatorTemplate", first: true, predicate: QueryOperatorDirective, descendants: true }, { propertyName: "removeButtonTemplate", first: true, predicate: QueryRemoveButtonDirective, descendants: true }, { propertyName: "emptyWarningTemplate", first: true, predicate: QueryEmptyWarningDirective, descendants: true }, { propertyName: "arrowIconTemplate", first: true, predicate: QueryArrowIconDirective, descendants: true }, { propertyName: "inputTemplates", predicate: QueryInputDirective }], viewQueries: [{ propertyName: "treeContainer", first: true, predicate: ["treeContainer"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div [ngClass]=\"getClassNames('switchRow')\">\r\n <ng-template #defaultArrowIcon>\r\n <i [ngClass]=\"getClassNames('arrowIcon')\"></i>\r\n </ng-template>\r\n\r\n <a *ngIf=\"allowCollapse\" (click)=\"toggleCollapse()\" [ngClass]=\"getClassNames('arrowIconButton', data.collapsed ? 'collapsed' : null)\">\r\n <ng-container *ngIf=\"getArrowIconTemplate() as template; else defaultArrowIcon\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getArrowIconContext()\"></ng-container>\r\n </ng-container>\r\n </a>\r\n\r\n <ng-container *ngIf=\"getButtonGroupTemplate() as template; else defaultButtonGroup\">\r\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getButtonGroupContext()\"></ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #defaultButtonGroup>\r\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\r\n <button type=\"button\" (click)=\"addRule()\" [ngClass]=\"getClassNames('button')\" [disabled]=disabled>\r\n <i [ngClass]=\"getClassNames('addIcon')\"></i> Rule\r\n </button>\r\n <button type=\"button\" (click)=\"addRuleSet()\" [ngClass]=\"getClassNames('button')\" *ngIf=\"allowRuleset\" [disabled]=disabled>\r\n <i [ngClass]=\"getClassNames('addIcon')\"></i> Ruleset\r\n </button>\r\n <ng-container *ngIf=\"!!parentValue && allowRuleset\">\r\n <button type=\"button\" (click)=\"removeRuleSet()\" [ngClass]=\"getClassNames('button', 'removeButton')\" [disabled]=disabled>\r\n <i [ngClass]=\"getClassNames('removeIcon')\"></i>\r\n </button>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-container *ngIf=\"getSwitchGroupTemplate() as template; else defaultSwitchGroup\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getSwitchGroupContext()\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultSwitchGroup>\r\n <div [ngClass]=\"getClassNames('switchGroup', 'transition')\" *ngIf=\"data\">\r\n <div [ngClass]=\"getClassNames('switchControl')\">\r\n <input type=\"radio\" [ngClass]=\"getClassNames('switchRadio')\" [(ngModel)]=\"data.condition\" [disabled]=disabled\r\n value=\"and\" #andOption />\r\n <label (click)=\"changeCondition(andOption.value)\" [ngClass]=\"getClassNames('switchLabel')\">AND</label>\r\n </div>\r\n <div [ngClass]=\"getClassNames('switchControl')\">\r\n <input type=\"radio\" [ngClass]=\"getClassNames('switchRadio')\" [(ngModel)]=\"data.condition\" [disabled]=disabled\r\n value=\"or\" #orOption />\r\n <label (click)=\"changeCondition(orOption.value)\" [ngClass]=\"getClassNames('switchLabel')\">OR</label>\r\n </div>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n<div #treeContainer (transitionend)=\"transitionEnd($event)\" [ngClass]=\"getClassNames('treeContainer', data.collapsed ? 'collapsed' : null)\">\r\n <ul [ngClass]=\"getClassNames('tree')\" *ngIf=\"data && data.rules\">\r\n <ng-container *ngFor=\"let rule of data.rules;let i=index\">\r\n\r\n <ng-container *ngIf=\"{ruleset: !!rule.rules, invalid: !config.allowEmptyRulesets && rule.rules && rule.rules.length === 0} as local\">\r\n <li [ngClass]=\"getQueryItemClassName(local)\">\r\n <ng-container *ngIf=\"!local.ruleset\">\r\n\r\n <ng-container *ngIf=\"getRemoveButtonTemplate() as template; else defaultRemoveButton\">\r\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getRemoveButtonContext(rule)\"></ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #defaultRemoveButton>\r\n <div [ngClass]=\"getClassNames('removeButtonSize', 'rightAlign')\">\r\n <button type=\"button\" [ngClass]=\"getClassNames('button', 'removeButton')\" (click)=\"removeRule(rule, data)\" [disabled]=disabled>\r\n <i [ngClass]=\"getClassNames('removeIcon')\"></i>\r\n </button>\r\n </div>\r\n </ng-template>\r\n\r\n <div *ngIf=\"entities?.length > 0\" class=\"q-inline-block-display\">\r\n <ng-container *ngIf=\"getEntityTemplate() as template; else defaultEntity\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getEntityContext(rule)\"></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #defaultEntity>\r\n <div [ngClass]=\"getClassNames('entityControlSize')\">\r\n <select [ngClass]=\"getClassNames('entityControl')\" [(ngModel)]=\"rule.entity\" (ngModelChange)=\"changeEntity($event, rule,i,data)\"\r\n [disabled]=\"disabled\">\r\n <option *ngFor=\"let entity of entities\" [ngValue]=\"entity.value\">\r\n {{entity.name}}\r\n </option>\r\n </select>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-container *ngIf=\"getFieldTemplate() as template; else defaultField\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getFieldContext(rule)\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultField>\r\n <div [ngClass]=\"getClassNames('fieldControlSize')\">\r\n <select [ngClass]=\"getClassNames('fieldControl')\" [(ngModel)]=\"rule.field\" (ngModelChange)=\"changeField($event, rule)\"\r\n [disabled]=\"disabled\">\r\n <option *ngFor=\"let field of getFields(rule.entity)\" [ngValue]=\"field.value\">\r\n {{field.name}}\r\n </option>\r\n </select>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-container *ngIf=\"getOperatorTemplate() as template; else defaultOperator\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getOperatorContext(rule)\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultOperator>\r\n <div [ngClass]=\"getClassNames('operatorControlSize')\">\r\n <select [ngClass]=\"getClassNames('operatorControl')\" [(ngModel)]=\"rule.operator\" (ngModelChange)=\"changeOperator(rule)\"\r\n [disabled]=\"disabled\">\r\n <option *ngFor=\"let operator of getOperators(rule.field)\" [ngValue]=\"operator\">\r\n {{operator}}\r\n </option>\r\n </select>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-container *ngIf=\"findTemplateForRule(rule) as template; else defaultInput\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getInputContext(rule)\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultInput>\r\n <div [ngClass]=\"getClassNames('inputControlSize')\" [ngSwitch]=\"getInputType(rule.field, rule.operator)\">\r\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'string'\" type=\"text\">\r\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'number'\" type=\"number\">\r\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'date'\" type=\"date\">\r\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'time'\" type=\"time\">\r\n <select [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'category'\">\r\n <option *ngFor=\"let opt of getOptions(rule.field)\" [ngValue]=\"opt.value\">\r\n {{opt.name}}\r\n </option>\r\n </select>\r\n <ng-container *ngSwitchCase=\"'multiselect'\">\r\n <select [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" multiple>\r\n <option *ngFor=\"let opt of getOptions(rule.field)\" [ngValue]=\"opt.value\">\r\n {{opt.name}}\r\n </option>\r\n </select>\r\n </ng-container>\r\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'boolean'\" type=\"checkbox\">\r\n </div>\r\n </ng-template>\r\n\r\n </ng-container>\r\n <query-builder *ngIf=\"local.ruleset\" [data]=\"rule\" [disabled]=\"disabled\" [parentTouchedCallback]=\"parentTouchedCallback || onTouchedCallback\"\r\n [parentChangeCallback]=\"parentChangeCallback || onChangeCallback\" [parentInputTemplates]=\"parentInputTemplates || inputTemplates\"\r\n [parentOperatorTemplate]=\"parentOperatorTemplate || operatorTemplate\" [parentFieldTemplate]=\"parentFieldTemplate || fieldTemplate\"\r\n [parentEntityTemplate]=\"parentEntityTemplate || entityTemplate\" [parentSwitchGroupTemplate]=\"parentSwitchGroupTemplate || switchGroupTemplate\"\r\n [parentButtonGroupTemplate]=\"parentButtonGroupTemplate || buttonGroupTemplate\" [parentRemoveButtonTemplate]=\"parentRemoveButtonTemplate || removeButtonTemplate\"\r\n [parentEmptyWarningTemplate]=\"parentEmptyWarningTemplate || emptyWarningTemplate\" [parentArrowIconTemplate]=\"parentArrowIconTemplate || arrowIconTemplate\"\r\n [parentValue]=\"data\" [classNames]=\"classNames\" [config]=\"config\" [allowRuleset]=\"allowRuleset\"\r\n [allowCollapse]=\"allowCollapse\" [emptyMessage]=\"emptyMessage\" [operatorMap]=\"operatorMap\">\r\n </query-builder>\r\n\r\n <ng-container *ngIf=\"getEmptyWarningTemplate() as template; else defaultEmptyWarning\">\r\n <ng-container *ngIf=\"local.invalid\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getEmptyWarningContext()\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultEmptyWarning>\r\n <p [ngClass]=\"getClassNames('emptyWarning')\" *ngIf=\"local.invalid\">\r\n {{emptyMessage}}\r\n </p>\r\n </ng-template>\r\n </li>\r\n </ng-container>\r\n </ng-container>\r\n </ul>\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}:host .q-icon{font-style:normal;font-size:12px}:host .q-remove-icon:before{content:\"\\274c\"}:host .q-arrow-icon-button{float:left;margin:4px 6px 4px 0;transform:rotate(90deg);transition:linear .25s transform;cursor:pointer}:host .q-arrow-icon-button.q-collapsed{transform:rotate(0)}:host .q-arrow-icon:before{content:\"\\25b6\"}:host .q-add-icon{color:#555}:host .q-add-icon:before{content:\"\\2795\"}:host .q-remove-button{color:#b3415d;width:31px}:host .q-switch-group,:host .q-button-group{font-family:Lucida Grande,Tahoma,Verdana,sans-serif;overflow:hidden}:host .q-right-align{float:right}:host .q-button{margin-left:8px;padding:0 8px;background-color:#fff}:host .q-button:disabled{display:none}:host .q-control-size{display:inline-block;vertical-align:top;padding-right:10px}:host .q-input-control,:host .q-operator-control,:host .q-field-control,:host .q-entity-control{display:inline-block;padding:5px 8px;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;box-sizing:border-box;width:auto}:host .q-input-control:disabled,:host .q-operator-control:disabled,:host .q-field-control:disabled,:host .q-entity-control:disabled{border-color:transparent}:host .q-operator-control,:host .q-field-control,:host .q-entity-control,:host .q-input-control:not([type=checkbox]){min-height:32px;-webkit-appearance:none}:host .q-switch-label,:host .q-button{float:left;margin-bottom:0;font-size:14px;line-height:30px;font-weight:400;text-align:center;text-shadow:none;border:1px solid rgba(0,0,0,.2);box-sizing:border-box}:host .q-switch-label:hover,:host .q-button:hover{cursor:pointer;background-color:#f0f0f0}:host .q-switch-label{background-color:#e4e4e4;padding:0 8px}:host .q-switch-radio{position:absolute;clip:rect(0,0,0,0);height:1px;width:1px;border:0;overflow:hidden}:host .q-switch-radio:checked+.q-switch-label{border:1px solid rgb(97,158,215);background:#fff;color:#3176b3}:host .q-switch-radio:disabled+.q-switch-label{display:none}:host .q-switch-radio:checked:disabled+.q-switch-label{display:initial;color:initial;cursor:default;border-color:transparent}:host .q-invalid-ruleset{border:1px solid rgba(179,65,93,.5)!important;background:#b3415d1a!important}:host .q-empty-warning{color:#8d252e;text-align:center}:host .q-ruleset{border:1px solid #CCC}:host .q-rule{border:1px solid #CCC;background:#fff}:host .q-transition{-webkit-transition:all .1s ease-in-out;-moz-transition:all .1s ease-in-out;-ms-transition:all .1s ease-in-out;-o-transition:all .1s ease-in-out;transition:all .1s ease-in-out}:host .q-tree-container{width:100%;overflow:hidden;transition:ease-in .25s max-height}:host .q-tree-container.q-collapsed{max-height:0!important}:host .q-tree{list-style:none;margin:4px 0 2px}:host .q-row{padding:6px 8px;margin-top:6px}:host .q-connector{position:relative}:host .q-connector:before{top:-5px;border-width:0 0 2px 2px}:host .q-connector:after{border-width:0 0 0 2px;top:50%}:host .q-connector:before,:host .q-connector:after{content:\"\";left:-12px;border-color:#ccc;border-style:solid;width:9px;height:calc(50% + 6px);position:absolute}:host .q-connector:last-child:after{content:none}:host .q-inline-block-display{display:inline-block;vertical-align:top}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.SelectMultipleControlValueAccessor, selector: "select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: QueryBuilderComponent, selector: "query-builder", inputs: ["disabled", "data", "allowRuleset", "allowCollapse", "emptyMessage", "classNames", "operatorMap", "parentValue", "config", "parentArrowIconTemplate", "parentInputTemplates", "parentOperatorTemplate", "parentFieldTemplate", "parentEntityTemplate", "parentSwitchGroupTemplate", "parentButtonGroupTemplate", "parentRemoveButtonTemplate", "parentEmptyWarningTemplate", "parentChangeCallback", "parentTouchedCallback", "persistValueOnFieldChange", "value"] }] });
690
+ }
691
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: QueryBuilderComponent, decorators: [{
692
+ type: Component,
693
+ args: [{ selector: 'query-builder', providers: [CONTROL_VALUE_ACCESSOR, VALIDATOR], template: "<div [ngClass]=\"getClassNames('switchRow')\">\r\n <ng-template #defaultArrowIcon>\r\n <i [ngClass]=\"getClassNames('arrowIcon')\"></i>\r\n </ng-template>\r\n\r\n <a *ngIf=\"allowCollapse\" (click)=\"toggleCollapse()\" [ngClass]=\"getClassNames('arrowIconButton', data.collapsed ? 'collapsed' : null)\">\r\n <ng-container *ngIf=\"getArrowIconTemplate() as template; else defaultArrowIcon\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getArrowIconContext()\"></ng-container>\r\n </ng-container>\r\n </a>\r\n\r\n <ng-container *ngIf=\"getButtonGroupTemplate() as template; else defaultButtonGroup\">\r\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getButtonGroupContext()\"></ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #defaultButtonGroup>\r\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\r\n <button type=\"button\" (click)=\"addRule()\" [ngClass]=\"getClassNames('button')\" [disabled]=disabled>\r\n <i [ngClass]=\"getClassNames('addIcon')\"></i> Rule\r\n </button>\r\n <button type=\"button\" (click)=\"addRuleSet()\" [ngClass]=\"getClassNames('button')\" *ngIf=\"allowRuleset\" [disabled]=disabled>\r\n <i [ngClass]=\"getClassNames('addIcon')\"></i> Ruleset\r\n </button>\r\n <ng-container *ngIf=\"!!parentValue && allowRuleset\">\r\n <button type=\"button\" (click)=\"removeRuleSet()\" [ngClass]=\"getClassNames('button', 'removeButton')\" [disabled]=disabled>\r\n <i [ngClass]=\"getClassNames('removeIcon')\"></i>\r\n </button>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-container *ngIf=\"getSwitchGroupTemplate() as template; else defaultSwitchGroup\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getSwitchGroupContext()\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultSwitchGroup>\r\n <div [ngClass]=\"getClassNames('switchGroup', 'transition')\" *ngIf=\"data\">\r\n <div [ngClass]=\"getClassNames('switchControl')\">\r\n <input type=\"radio\" [ngClass]=\"getClassNames('switchRadio')\" [(ngModel)]=\"data.condition\" [disabled]=disabled\r\n value=\"and\" #andOption />\r\n <label (click)=\"changeCondition(andOption.value)\" [ngClass]=\"getClassNames('switchLabel')\">AND</label>\r\n </div>\r\n <div [ngClass]=\"getClassNames('switchControl')\">\r\n <input type=\"radio\" [ngClass]=\"getClassNames('switchRadio')\" [(ngModel)]=\"data.condition\" [disabled]=disabled\r\n value=\"or\" #orOption />\r\n <label (click)=\"changeCondition(orOption.value)\" [ngClass]=\"getClassNames('switchLabel')\">OR</label>\r\n </div>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n<div #treeContainer (transitionend)=\"transitionEnd($event)\" [ngClass]=\"getClassNames('treeContainer', data.collapsed ? 'collapsed' : null)\">\r\n <ul [ngClass]=\"getClassNames('tree')\" *ngIf=\"data && data.rules\">\r\n <ng-container *ngFor=\"let rule of data.rules;let i=index\">\r\n\r\n <ng-container *ngIf=\"{ruleset: !!rule.rules, invalid: !config.allowEmptyRulesets && rule.rules && rule.rules.length === 0} as local\">\r\n <li [ngClass]=\"getQueryItemClassName(local)\">\r\n <ng-container *ngIf=\"!local.ruleset\">\r\n\r\n <ng-container *ngIf=\"getRemoveButtonTemplate() as template; else defaultRemoveButton\">\r\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getRemoveButtonContext(rule)\"></ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #defaultRemoveButton>\r\n <div [ngClass]=\"getClassNames('removeButtonSize', 'rightAlign')\">\r\n <button type=\"button\" [ngClass]=\"getClassNames('button', 'removeButton')\" (click)=\"removeRule(rule, data)\" [disabled]=disabled>\r\n <i [ngClass]=\"getClassNames('removeIcon')\"></i>\r\n </button>\r\n </div>\r\n </ng-template>\r\n\r\n <div *ngIf=\"entities?.length > 0\" class=\"q-inline-block-display\">\r\n <ng-container *ngIf=\"getEntityTemplate() as template; else defaultEntity\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getEntityContext(rule)\"></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #defaultEntity>\r\n <div [ngClass]=\"getClassNames('entityControlSize')\">\r\n <select [ngClass]=\"getClassNames('entityControl')\" [(ngModel)]=\"rule.entity\" (ngModelChange)=\"changeEntity($event, rule,i,data)\"\r\n [disabled]=\"disabled\">\r\n <option *ngFor=\"let entity of entities\" [ngValue]=\"entity.value\">\r\n {{entity.name}}\r\n </option>\r\n </select>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-container *ngIf=\"getFieldTemplate() as template; else defaultField\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getFieldContext(rule)\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultField>\r\n <div [ngClass]=\"getClassNames('fieldControlSize')\">\r\n <select [ngClass]=\"getClassNames('fieldControl')\" [(ngModel)]=\"rule.field\" (ngModelChange)=\"changeField($event, rule)\"\r\n [disabled]=\"disabled\">\r\n <option *ngFor=\"let field of getFields(rule.entity)\" [ngValue]=\"field.value\">\r\n {{field.name}}\r\n </option>\r\n </select>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-container *ngIf=\"getOperatorTemplate() as template; else defaultOperator\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getOperatorContext(rule)\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultOperator>\r\n <div [ngClass]=\"getClassNames('operatorControlSize')\">\r\n <select [ngClass]=\"getClassNames('operatorControl')\" [(ngModel)]=\"rule.operator\" (ngModelChange)=\"changeOperator(rule)\"\r\n [disabled]=\"disabled\">\r\n <option *ngFor=\"let operator of getOperators(rule.field)\" [ngValue]=\"operator\">\r\n {{operator}}\r\n </option>\r\n </select>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-container *ngIf=\"findTemplateForRule(rule) as template; else defaultInput\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getInputContext(rule)\"></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultInput>\r\n <div [ngClass]=\"getClassNames('inputControlSize')\" [ngSwitch]=\"getInputType(rule.field, rule.operator)\">\r\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'string'\" type=\"text\">\r\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'number'\" type=\"number\">\r\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'date'\" type=\"date\">\r\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'time'\" type=\"time\">\r\n <select [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'category'\">\r\n <option *ngFor=\"let opt of getOptions(rule.field)\" [ngValue]=\"opt.value\">\r\n {{opt.name}}\r\n </option>\r\n </select>\r\n <ng-container *ngSwitchCase=\"'multiselect'\">\r\n <select [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" multiple>\r\n <option *ngFor=\"let opt of getOptions(rule.field)\" [ngValue]=\"opt.value\">\r\n {{opt.name}}\r\n </option>\r\n </select>\r\n </ng-container>\r\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\r\n [disabled]=\"disabled\" *ngSwitchCase=\"'boolean'\" type=\"checkbox\">\r\n </div>\r\n </ng-template>\r\n\r\n </ng-container>\r\n <query-builder *ngIf=\"local.ruleset\" [data]=\"rule\" [disabled]=\"disabled\" [parentTouchedCallback]=\"parentTouchedCallback || onTouchedCallback\"\r\n [parentChangeCallback]=\"parentChangeCallback || onChangeCallback\" [parentInputTemplates]=\"parentInputTemplates || inputTemplates\"\r\n [parentOperatorTemplate]=\"parentOperatorTemplate || operatorTemplate\" [parentFieldTemplate]=\"parentFieldTemplate || fieldTemplate\"\r\n [parentEntityTemplate]=\"parentEntityTemplate || entityTemplate\" [parentSwitchGroupTemplate]=\"parentSwitchGroupTemplate || switchGroupTemplate\"\r\n [parentButtonGroupTemplate]=\"parentButtonGroupTemplate || buttonGroupTemplate\" [parentRemoveButtonTemplate]=\"parentRemoveButtonTemplate || removeButtonTemplate\"\r\n [parentEmptyWarningTemplate]=\"parentEmptyWarningTemplate || emptyWarningTemplate\" [parentArrowIconTemplate]=\"parentArrowIconTemplate || arrowIconTemplate\"\r\n [parentValue]=\"data\" [classNames]=\"classNames\" [config]=\"config\" [allowRuleset]=\"allowRuleset\"\r\n [allowCollapse]=\"allowCollapse\" [emptyMessage]=\"emptyMessage\" [operatorMap]=\"operatorMap\">\r\n </query-builder>\r\n\r\n <ng-container *ngIf=\"getEmptyWarningTemplate() as template; else defaultEmptyWarning\">\r\n <ng-container *ngIf=\"local.invalid\">\r\n <ng-container *ngTemplateOutlet=\"template; context: getEmptyWarningContext()\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #defaultEmptyWarning>\r\n <p [ngClass]=\"getClassNames('emptyWarning')\" *ngIf=\"local.invalid\">\r\n {{emptyMessage}}\r\n </p>\r\n </ng-template>\r\n </li>\r\n </ng-container>\r\n </ng-container>\r\n </ul>\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}:host .q-icon{font-style:normal;font-size:12px}:host .q-remove-icon:before{content:\"\\274c\"}:host .q-arrow-icon-button{float:left;margin:4px 6px 4px 0;transform:rotate(90deg);transition:linear .25s transform;cursor:pointer}:host .q-arrow-icon-button.q-collapsed{transform:rotate(0)}:host .q-arrow-icon:before{content:\"\\25b6\"}:host .q-add-icon{color:#555}:host .q-add-icon:before{content:\"\\2795\"}:host .q-remove-button{color:#b3415d;width:31px}:host .q-switch-group,:host .q-button-group{font-family:Lucida Grande,Tahoma,Verdana,sans-serif;overflow:hidden}:host .q-right-align{float:right}:host .q-button{margin-left:8px;padding:0 8px;background-color:#fff}:host .q-button:disabled{display:none}:host .q-control-size{display:inline-block;vertical-align:top;padding-right:10px}:host .q-input-control,:host .q-operator-control,:host .q-field-control,:host .q-entity-control{display:inline-block;padding:5px 8px;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;box-sizing:border-box;width:auto}:host .q-input-control:disabled,:host .q-operator-control:disabled,:host .q-field-control:disabled,:host .q-entity-control:disabled{border-color:transparent}:host .q-operator-control,:host .q-field-control,:host .q-entity-control,:host .q-input-control:not([type=checkbox]){min-height:32px;-webkit-appearance:none}:host .q-switch-label,:host .q-button{float:left;margin-bottom:0;font-size:14px;line-height:30px;font-weight:400;text-align:center;text-shadow:none;border:1px solid rgba(0,0,0,.2);box-sizing:border-box}:host .q-switch-label:hover,:host .q-button:hover{cursor:pointer;background-color:#f0f0f0}:host .q-switch-label{background-color:#e4e4e4;padding:0 8px}:host .q-switch-radio{position:absolute;clip:rect(0,0,0,0);height:1px;width:1px;border:0;overflow:hidden}:host .q-switch-radio:checked+.q-switch-label{border:1px solid rgb(97,158,215);background:#fff;color:#3176b3}:host .q-switch-radio:disabled+.q-switch-label{display:none}:host .q-switch-radio:checked:disabled+.q-switch-label{display:initial;color:initial;cursor:default;border-color:transparent}:host .q-invalid-ruleset{border:1px solid rgba(179,65,93,.5)!important;background:#b3415d1a!important}:host .q-empty-warning{color:#8d252e;text-align:center}:host .q-ruleset{border:1px solid #CCC}:host .q-rule{border:1px solid #CCC;background:#fff}:host .q-transition{-webkit-transition:all .1s ease-in-out;-moz-transition:all .1s ease-in-out;-ms-transition:all .1s ease-in-out;-o-transition:all .1s ease-in-out;transition:all .1s ease-in-out}:host .q-tree-container{width:100%;overflow:hidden;transition:ease-in .25s max-height}:host .q-tree-container.q-collapsed{max-height:0!important}:host .q-tree{list-style:none;margin:4px 0 2px}:host .q-row{padding:6px 8px;margin-top:6px}:host .q-connector{position:relative}:host .q-connector:before{top:-5px;border-width:0 0 2px 2px}:host .q-connector:after{border-width:0 0 0 2px;top:50%}:host .q-connector:before,:host .q-connector:after{content:\"\";left:-12px;border-color:#ccc;border-style:solid;width:9px;height:calc(50% + 6px);position:absolute}:host .q-connector:last-child:after{content:none}:host .q-inline-block-display{display:inline-block;vertical-align:top}\n"] }]
694
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { disabled: [{
695
+ type: Input
696
+ }], data: [{
697
+ type: Input
698
+ }], allowRuleset: [{
699
+ type: Input
700
+ }], allowCollapse: [{
701
+ type: Input
702
+ }], emptyMessage: [{
703
+ type: Input
704
+ }], classNames: [{
705
+ type: Input
706
+ }], operatorMap: [{
707
+ type: Input
708
+ }], parentValue: [{
709
+ type: Input
710
+ }], config: [{
711
+ type: Input
712
+ }], parentArrowIconTemplate: [{
713
+ type: Input
714
+ }], parentInputTemplates: [{
715
+ type: Input
716
+ }], parentOperatorTemplate: [{
717
+ type: Input
718
+ }], parentFieldTemplate: [{
719
+ type: Input
720
+ }], parentEntityTemplate: [{
721
+ type: Input
722
+ }], parentSwitchGroupTemplate: [{
723
+ type: Input
724
+ }], parentButtonGroupTemplate: [{
725
+ type: Input
726
+ }], parentRemoveButtonTemplate: [{
727
+ type: Input
728
+ }], parentEmptyWarningTemplate: [{
729
+ type: Input
730
+ }], parentChangeCallback: [{
731
+ type: Input
732
+ }], parentTouchedCallback: [{
733
+ type: Input
734
+ }], persistValueOnFieldChange: [{
735
+ type: Input
736
+ }], treeContainer: [{
737
+ type: ViewChild,
738
+ args: ['treeContainer', { static: true }]
739
+ }], buttonGroupTemplate: [{
740
+ type: ContentChild,
741
+ args: [QueryButtonGroupDirective]
742
+ }], switchGroupTemplate: [{
743
+ type: ContentChild,
744
+ args: [QuerySwitchGroupDirective]
745
+ }], fieldTemplate: [{
746
+ type: ContentChild,
747
+ args: [QueryFieldDirective]
748
+ }], entityTemplate: [{
749
+ type: ContentChild,
750
+ args: [QueryEntityDirective]
751
+ }], operatorTemplate: [{
752
+ type: ContentChild,
753
+ args: [QueryOperatorDirective]
754
+ }], removeButtonTemplate: [{
755
+ type: ContentChild,
756
+ args: [QueryRemoveButtonDirective]
757
+ }], emptyWarningTemplate: [{
758
+ type: ContentChild,
759
+ args: [QueryEmptyWarningDirective]
760
+ }], inputTemplates: [{
761
+ type: ContentChildren,
762
+ args: [QueryInputDirective]
763
+ }], arrowIconTemplate: [{
764
+ type: ContentChild,
765
+ args: [QueryArrowIconDirective]
766
+ }], value: [{
767
+ type: Input
768
+ }] } });
769
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktYnVpbGRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9xdWVyeS1idWlsZGVyL3NyYy9saWIvcXVlcnktYnVpbGRlci9xdWVyeS1idWlsZGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3F1ZXJ5LWJ1aWxkZXIvc3JjL2xpYi9xdWVyeS1idWlsZGVyL3F1ZXJ5LWJ1aWxkZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdMLGlCQUFpQixFQUNqQixhQUFhLEVBR2QsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQW9CdkUsT0FBTyxFQUVMLFNBQVMsRUFDVCxZQUFZLEVBQ1osZUFBZSxFQUNmLFVBQVUsRUFDVixLQUFLLEVBTUwsU0FBUyxFQUVWLE1BQU0sZUFBZSxDQUFDOzs7O0FBRXZCLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFRO0lBQ3pDLE9BQU8sRUFBRSxpQkFBaUI7SUFDMUIsV0FB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Uzt1QkFBQyxlQUFlLEVBQUUsRUFBQyxNQUFNLEVBQUUsSUFBSSxFQUFDO2dCQUVELG1CQUFtQjtzQkFBM0QsWUFBWTt1QkFBQyx5QkFBeUI7Z0JBQ0UsbUJBQW1CO3NCQUEzRCxZQUFZO3VCQUFDLHlCQUF5QjtnQkFDSixhQUFhO3NCQUEvQyxZQUFZO3VCQUFDLG1CQUFtQjtnQkFDRyxjQUFjO3NCQUFqRCxZQUFZO3VCQUFDLG9CQUFvQjtnQkFDSSxnQkFBZ0I7c0JBQXJELFlBQVk7dUJBQUMsc0JBQXNCO2dCQUNNLG9CQUFvQjtzQkFBN0QsWUFBWTt1QkFBQywwQkFBMEI7Z0JBQ0Usb0JBQW9CO3NCQUE3RCxZQUFZO3VCQUFDLDBCQUEwQjtnQkFDRixjQUFjO3NCQUFuRCxlQUFlO3VCQUFDLG1CQUFtQjtnQkFDRyxpQkFBaUI7c0JBQXZELFlBQVk7dUJBQUMsdUJBQXVCO2dCQXVFakMsS0FBSztzQkFEUixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBBYnN0cmFjdENvbnRyb2wsXHJcbiAgQ29udHJvbFZhbHVlQWNjZXNzb3IsXHJcbiAgTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgTkdfVkFMSURBVE9SUyxcclxuICBWYWxpZGF0aW9uRXJyb3JzLFxyXG4gIFZhbGlkYXRvclxyXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgUXVlcnlPcGVyYXRvckRpcmVjdGl2ZSB9IGZyb20gJy4vcXVlcnktb3BlcmF0b3IuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgUXVlcnlGaWVsZERpcmVjdGl2ZSB9IGZyb20gJy4vcXVlcnktZmllbGQuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgUXVlcnlFbnRpdHlEaXJlY3RpdmUgfSBmcm9tICcuL3F1ZXJ5LWVudGl0eS5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBRdWVyeVN3aXRjaEdyb3VwRGlyZWN0aXZlIH0gZnJvbSAnLi9xdWVyeS1zd2l0Y2gtZ3JvdXAuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgUXVlcnlCdXR0b25Hcm91cERpcmVjdGl2ZSB9IGZyb20gJy4vcXVlcnktYnV0dG9uLWdyb3VwLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IFF1ZXJ5SW5wdXREaXJlY3RpdmUgfSBmcm9tICcuL3F1ZXJ5LWlucHV0LmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IFF1ZXJ5UmVtb3ZlQnV0dG9uRGlyZWN0aXZlIH0gZnJvbSAnLi9xdWVyeS1yZW1vdmUtYnV0dG9uLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IFF1ZXJ5RW1wdHlXYXJuaW5nRGlyZWN0aXZlIH0gZnJvbSAnLi9xdWVyeS1lbXB0eS13YXJuaW5nLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IFF1ZXJ5QXJyb3dJY29uRGlyZWN0aXZlIH0gZnJvbSAnLi9xdWVyeS1hcnJvdy1pY29uLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7XHJcbiAgQnV0dG9uR3JvdXBDb250ZXh0LFxyXG4gIEVudGl0eSxcclxuICBGaWVsZCxcclxuICBTd2l0Y2hHcm91cENvbnRleHQsXHJcbiAgRW50aXR5Q29udGV4dCxcclxuICBGaWVsZENvbnRleHQsXHJcbiAgSW5wdXRDb250ZXh0LFxyXG4gIExvY2FsUnVsZU1ldGEsXHJcbiAgT3BlcmF0b3JDb250ZXh0LFxyXG4gIE9wdGlvbixcclxuICBRdWVyeUJ1aWxkZXJDbGFzc05hbWVzLFxyXG4gIFF1ZXJ5QnVpbGRlckNvbmZpZyxcclxuICBSZW1vdmVCdXR0b25Db250ZXh0LFxyXG4gIEFycm93SWNvbkNvbnRleHQsXHJcbiAgUnVsZSxcclxuICBSdWxlU2V0LFxyXG4gIEVtcHR5V2FybmluZ0NvbnRleHQsXHJcbn0gZnJvbSAnLi9xdWVyeS1idWlsZGVyLmludGVyZmFjZXMnO1xyXG5pbXBvcnQge1xyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBDb250ZW50Q2hpbGQsXHJcbiAgQ29udGVudENoaWxkcmVuLFxyXG4gIGZvcndhcmRSZWYsXHJcbiAgSW5wdXQsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIE9uSW5pdCxcclxuICBRdWVyeUxpc3QsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxuICBUZW1wbGF0ZVJlZixcclxuICBWaWV3Q2hpbGQsXHJcbiAgRWxlbWVudFJlZlxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuZXhwb3J0IGNvbnN0IENPTlRST0xfVkFMVUVfQUNDRVNTT1I6IGFueSA9IHtcclxuICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBRdWVyeUJ1aWxkZXJDb21wb25lbnQpLFxyXG4gIG11bHRpOiB0cnVlXHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgVkFMSURBVE9SOiBhbnkgPSB7XHJcbiAgcHJvdmlkZTogTkdfVkFMSURBVE9SUyxcclxuICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBRdWVyeUJ1aWxkZXJDb21wb25lbnQpLFxyXG4gIG11bHRpOiB0cnVlXHJcbn07XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3F1ZXJ5LWJ1aWxkZXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9xdWVyeS1idWlsZGVyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9xdWVyeS1idWlsZGVyLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgcHJvdmlkZXJzOiBbQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUiwgVkFMSURBVE9SXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgUXVlcnlCdWlsZGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBWYWxpZGF0b3Ige1xyXG4gIHB1YmxpYyBmaWVsZHM6IEZpZWxkW107XHJcbiAgcHVibGljIGZpbHRlckZpZWxkczogRmllbGRbXTtcclxuICBwdWJsaWMgZW50aXRpZXM6IEVudGl0eVtdO1xyXG4gIHB1YmxpYyBkZWZhdWx0Q2xhc3NOYW1lczogUXVlcnlCdWlsZGVyQ2xhc3NOYW1lcyA9IHtcclxuICAgIGFycm93SWNvbkJ1dHRvbjogJ3EtYXJyb3ctaWNvbi1idXR0b24nLFxyXG4gICAgYXJyb3dJY29uOiAncS1pY29uIHEtYXJyb3ctaWNvbicsXHJcbiAgICByZW1vdmVJY29uOiAncS1pY29uIHEtcmVtb3ZlLWljb24nLFxyXG4gICAgYWRkSWNvbjogJ3EtaWNvbiBxLWFkZC1pY29uJyxcclxuICAgIGJ1dHRvbjogJ3EtYnV0dG9uJyxcclxuICAgIGJ1dHRvbkdyb3VwOiAncS1idXR0b24tZ3JvdXAnLFxyXG4gICAgcmVtb3ZlQnV0dG9uOiAncS1yZW1vdmUtYnV0dG9uJyxcclxuICAgIHN3aXRjaEdyb3VwOiAncS1zd2l0Y2gtZ3JvdXAnLFxyXG4gICAgc3dpdGNoTGFiZWw6ICdxLXN3aXRjaC1sYWJlbCcsXHJcbiAgICBzd2l0Y2hSYWRpbzogJ3Etc3dpdGNoLXJhZGlvJyxcclxuICAgIHJpZ2h0QWxpZ246ICdxLXJpZ2h0LWFsaWduJyxcclxuICAgIHRyYW5zaXRpb246ICdxLXRyYW5zaXRpb24nLFxyXG4gICAgY29sbGFwc2VkOiAncS1jb2xsYXBzZWQnLFxyXG4gICAgdHJlZUNvbnRhaW5lcjogJ3EtdHJlZS1jb250YWluZXInLFxyXG4gICAgdHJlZTogJ3EtdHJlZScsXHJcbiAgICByb3c6ICdxLXJvdycsXHJcbiAgICBjb25uZWN0b3I6ICdxLWNvbm5lY3RvcicsXHJcbiAgICBydWxlOiAncS1ydWxlJyxcclxuICAgIHJ1bGVTZXQ6ICdxLXJ1bGVzZXQnLFxyXG4gICAgaW52YWxpZFJ1bGVTZXQ6ICdxLWludmFsaWQtcnVsZXNldCcsXHJcbiAgICBlbXB0eVdhcm5pbmc6ICdxLWVtcHR5LXdhcm5pbmcnLFxyXG4gICAgZmllbGRDb250cm9sOiAncS1maWVsZC1jb250cm9sJyxcclxuICAgIGZpZWxkQ29udHJvbFNpemU6ICdxLWNvbnRyb2wtc2l6ZScsXHJcbiAgICBlbnRpdHlDb250cm9sOiAncS1lbnRpdHktY29udHJvbCcsXHJcbiAgICBlbnRpdHlDb250cm9sU2l6ZTogJ3EtY29udHJvbC1zaXplJyxcclxuICAgIG9wZXJhdG9yQ29udHJvbDogJ3Etb3BlcmF0b3ItY29udHJvbCcsXHJcbiAgICBvcGVyYXRvckNvbnRyb2xTaXplOiAncS1jb250cm9sLXNpemUnLFxyXG4gICAgaW5wdXRDb250cm9sOiAncS1pbnB1dC1jb250cm9sJyxcclxuICAgIGlucHV0Q29udHJvbFNpemU6ICdxLWNvbnRyb2wtc2l6ZSdcclxuICB9O1xyXG4gIHB1YmxpYyBkZWZhdWx0T3BlcmF0b3JNYXA6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSA9IHtcclxuICAgIHN0cmluZzogWyc9JywgJyE9JywgJ2NvbnRhaW5zJywgJ2xpa2UnXSxcclxuICAgIG51bWJlcjogWyc9JywgJyE9JywgJz4nLCAnPj0nLCAnPCcsICc8PSddLFxyXG4gICAgdGltZTogWyc9JywgJyE9JywgJz4nLCAnPj0nLCAnPCcsICc8PSddLFxyXG4gICAgZGF0ZTogWyc9JywgJyE9JywgJz4nLCAnPj0nLCAnPCcsICc8PSddLFxyXG4gICAgY2F0ZWdvcnk6IFsnPScsICchPScsICdpbicsICdub3QgaW4nXSxcclxuICAgIGJvb2xlYW46IFsnPSddXHJcbiAgfTtcclxuICBASW5wdXQoKSBkaXNhYmxlZDogYm9vbGVhbjtcclxuICBASW5wdXQoKSBkYXRhOiBSdWxlU2V0ID0geyBjb25kaXRpb246ICdhbmQnLCBydWxlczogW10gfTtcclxuXHJcbiAgLy8gRm9yIENvbnRyb2xWYWx1ZUFjY2Vzc29yIGludGVyZmFjZVxyXG4gIHB1YmxpYyBvbkNoYW5nZUNhbGxiYWNrOiAoKSA9PiB2b2lkO1xyXG4gIHB1YmxpYyBvblRvdWNoZWRDYWxsYmFjazogKCkgPT4gYW55O1xyXG5cclxuICBASW5wdXQoKSBhbGxvd1J1bGVzZXQ6IGJvb2xlYW4gPSB0cnVlO1xyXG4gIEBJbnB1dCgpIGFsbG93Q29sbGFwc2U6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBlbXB0eU1lc3NhZ2U6IHN0cmluZyA9ICdBIHJ1bGVzZXQgY2Fubm90IGJlIGVtcHR5LiBQbGVhc2UgYWRkIGEgcnVsZSBvciByZW1vdmUgaXQgYWxsIHRvZ2V0aGVyLic7XHJcbiAgQElucHV0KCkgY2xhc3NOYW1lczogUXVlcnlCdWlsZGVyQ2xhc3NOYW1lcztcclxuICBASW5wdXQoKSBvcGVyYXRvck1hcDogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9O1xyXG4gIEBJbnB1dCgpIHBhcmVudFZhbHVlOiBSdWxlU2V0O1xyXG4gIEBJbnB1dCgpIGNvbmZpZzogUXVlcnlCdWlsZGVyQ29uZmlnID0geyBmaWVsZHM6IHt9IH07XHJcbiAgQElucHV0KCkgcGFyZW50QXJyb3dJY29uVGVtcGxhdGU6IFF1ZXJ5QXJyb3dJY29uRGlyZWN0aXZlO1xyXG4gIEBJbnB1dCgpIHBhcmVudElucHV0VGVtcGxhdGVzOiBRdWVyeUxpc3Q8UXVlcnlJbnB1dERpcmVjdGl2ZT47XHJcbiAgQElucHV0KCkgcGFyZW50T3BlcmF0b3JUZW1wbGF0ZTogUXVlcnlPcGVyYXRvckRpcmVjdGl2ZTtcclxuICBASW5wdXQoKSBwYXJlbnRGaWVsZFRlbXBsYXRlOiBRdWVyeUZpZWxkRGlyZWN0aXZlO1xyXG4gIEBJbnB1dCgpIHBhcmVudEVudGl0eVRlbXBsYXRlOiBRdWVyeUVudGl0eURpcmVjdGl2ZTtcclxuICBASW5wdXQoKSBwYXJlbnRTd2l0Y2hHcm91cFRlbXBsYXRlOiBRdWVyeVN3aXRjaEdyb3VwRGlyZWN0aXZlO1xyXG4gIEBJbnB1dCgpIHBhcmVudEJ1dHRvbkdyb3VwVGVtcGxhdGU6IFF1ZXJ5QnV0dG9uR3JvdXBEaXJlY3RpdmU7XHJcbiAgQElucHV0KCkgcGFyZW50UmVtb3ZlQnV0dG9uVGVtcGxhdGU6IFF1ZXJ5UmVtb3ZlQnV0dG9uRGlyZWN0aXZlO1xyXG4gIEBJbnB1dCgpIHBhcmVudEVtcHR5V2FybmluZ1RlbXBsYXRlOiBRdWVyeUVtcHR5V2FybmluZ0RpcmVjdGl2ZTtcclxuICBASW5wdXQoKSBwYXJlbnRDaGFuZ2VDYWxsYmFjazogKCkgPT4gdm9pZDtcclxuICBASW5wdXQoKSBwYXJlbnRUb3VjaGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQ7XHJcbiAgQElucHV0KCkgcGVyc2lzdFZhbHVlT25GaWVsZENoYW5nZTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBAVmlld0NoaWxkKCd0cmVlQ29udGFpbmVyJywge3N0YXRpYzogdHJ1ZX0pIHRyZWVDb250YWluZXI6IEVsZW1lbnRSZWY7XHJcblxyXG4gIEBDb250ZW50Q2hpbGQoUXVlcnlCdXR0b25Hcm91cERpcmVjdGl2ZSkgYnV0dG9uR3JvdXBUZW1wbGF0ZTogUXVlcnlCdXR0b25Hcm91cERpcmVjdGl2ZTtcclxuICBAQ29udGVudENoaWxkKFF1ZXJ5U3dpdGNoR3JvdXBEaXJlY3RpdmUpIHN3aXRjaEdyb3VwVGVtcGxhdGU6IFF1ZXJ5U3dpdGNoR3JvdXBEaXJlY3RpdmU7XHJcbiAgQENvbnRlbnRDaGlsZChRdWVyeUZpZWxkRGlyZWN0aXZlKSBmaWVsZFRlbXBsYXRlOiBRdWVyeUZpZWxkRGlyZWN0aXZlO1xyXG4gIEBDb250ZW50Q2hpbGQoUXVlcnlFbnRpdHlEaXJlY3RpdmUpIGVudGl0eVRlbXBsYXRlOiBRdWVyeUVudGl0eURpcmVjdGl2ZTtcclxuICBAQ29udGVudENoaWxkKFF1ZXJ5T3BlcmF0b3JEaXJlY3RpdmUpIG9wZXJhdG9yVGVtcGxhdGU6IFF1ZXJ5T3BlcmF0b3JEaXJlY3RpdmU7XHJcbiAgQENvbnRlbnRDaGlsZChRdWVyeVJlbW92ZUJ1dHRvbkRpcmVjdGl2ZSkgcmVtb3ZlQnV0dG9uVGVtcGxhdGU6IFF1ZXJ5UmVtb3ZlQnV0dG9uRGlyZWN0aXZlO1xyXG4gIEBDb250ZW50Q2hpbGQoUXVlcnlFbXB0eVdhcm5pbmdEaXJlY3RpdmUpIGVtcHR5V2FybmluZ1RlbXBsYXRlOiBRdWVyeUVtcHR5V2FybmluZ0RpcmVjdGl2ZTtcclxuICBAQ29udGVudENoaWxkcmVuKFF1ZXJ5SW5wdXREaXJlY3RpdmUpIGlucHV0VGVtcGxhdGVzOiBRdWVyeUxpc3Q8UXVlcnlJbnB1dERpcmVjdGl2ZT47XHJcbiAgQENvbnRlbnRDaGlsZChRdWVyeUFycm93SWNvbkRpcmVjdGl2ZSkgYXJyb3dJY29uVGVtcGxhdGU6IFF1ZXJ5QXJyb3dJY29uRGlyZWN0aXZlO1xyXG5cclxuICBwcml2YXRlIGRlZmF1bHRUZW1wbGF0ZVR5cGVzOiBzdHJpbmdbXSA9IFtcclxuICAgICdzdHJpbmcnLCAnbnVtYmVyJywgJ3RpbWUnLCAnZGF0ZScsICdjYXRlZ29yeScsICdib29sZWFuJywgJ211bHRpc2VsZWN0J107XHJcbiAgcHJpdmF0ZSBkZWZhdWx0UGVyc2lzdFZhbHVlVHlwZXM6IHN0cmluZ1tdID0gW1xyXG4gICAgJ3N0cmluZycsICdudW1iZXInLCAndGltZScsICdkYXRlJywgJ2Jvb2xlYW4nXTtcclxuICBwcml2YXRlIGRlZmF1bHRFbXB0eUxpc3Q6IGFueVtdID0gW107XHJcbiAgcHJpdmF0ZSBvcGVyYXRvcnNDYWNoZTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9O1xyXG4gIHByaXZhdGUgaW5wdXRDb250ZXh0Q2FjaGUgPSBuZXcgTWFwPFJ1bGUsIElucHV0Q29udGV4dD4oKTtcclxuICBwcml2YXRlIG9wZXJhdG9yQ29udGV4dENhY2hlID0gbmV3IE1hcDxSdWxlLCBPcGVyYXRvckNvbnRleHQ+KCk7XHJcbiAgcHJpdmF0ZSBmaWVsZENvbnRleHRDYWNoZSA9IG5ldyBNYXA8UnVsZSwgRmllbGRDb250ZXh0PigpO1xyXG4gIHByaXZhdGUgZW50aXR5Q29udGV4dENhY2hlID0gbmV3IE1hcDxSdWxlLCBFbnRpdHlDb250ZXh0PigpO1xyXG4gIHByaXZhdGUgcmVtb3ZlQnV0dG9uQ29udGV4dENhY2hlID0gbmV3IE1hcDxSdWxlLCBSZW1vdmVCdXR0b25Db250ZXh0PigpO1xyXG4gIHByaXZhdGUgYnV0dG9uR3JvdXBDb250ZXh0OiBCdXR0b25Hcm91cENvbnRleHQ7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7IH1cclxuXHJcbiAgLy8gLS0tLS0tLS0tLU9uSW5pdCBJbXBsZW1lbnRhdGlvbi0tLS0tLS0tLS1cclxuXHJcbiAgbmdPbkluaXQoKSB7IH1cclxuXHJcbiAgLy8gLS0tLS0tLS0tLU9uQ2hhbmdlcyBJbXBsZW1lbnRhdGlvbi0tLS0tLS0tLS1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5jb25maWc7XHJcbiAgICBjb25zdCB0eXBlID0gdHlwZW9mIGNvbmZpZztcclxuICAgIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xyXG4gICAgICB0aGlzLmZpZWxkcyA9IE9iamVjdC5rZXlzKGNvbmZpZy5maWVsZHMpLm1hcCgodmFsdWUpID0+IHtcclxuICAgICAgICBjb25zdCBmaWVsZCA9IGNvbmZpZy5maWVsZHNbdmFsdWVdO1xyXG4gICAgICAgIGZpZWxkLnZhbHVlID0gZmllbGQudmFsdWUgfHwgdmFsdWU7XHJcbiAgICAgICAgcmV0dXJuIGZpZWxkO1xyXG4gICAgICB9KTtcclxuICAgICAgaWYgKGNvbmZpZy5lbnRpdGllcykge1xyXG4gICAgICAgIHRoaXMuZW50aXRpZXMgPSBPYmplY3Qua2V5cyhjb25maWcuZW50aXRpZXMpLm1hcCgodmFsdWUpID0+IHtcclxuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IGNvbmZpZy5lbnRpdGllc1t2YWx1ZV07XHJcbiAgICAgICAgICBlbnRpdHkudmFsdWUgPSBlbnRpdHkudmFsdWUgfHwgdmFsdWU7XHJcbiAgICAgICAgICByZXR1cm4gZW50aXR5O1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuZW50aXRpZXMgPSBudWxsO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMub3BlcmF0b3JzQ2FjaGUgPSB7fTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJ2NvbmZpZycgbXVzdCBiZSBhIHZhbGlkIG9iamVjdCwgZ290ICR7dHlwZX0gaW5zdGVhZC5gKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIC0tLS0tLS0tLS1WYWxpZGF0b3IgSW1wbGVtZW50YXRpb24tLS0tLS0tLS0tXHJcblxyXG4gIHZhbGlkYXRlKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcclxuICAgIGNvbnN0IGVycm9yczogYW55ID0ge307XHJcbiAgICBjb25zdCBydWxlRXJyb3JTdG9yZSA9IFtdO1xyXG4gICAgbGV0IGhhc0Vycm9ycyA9IGZhbHNlO1xyXG5cclxuICAgIGlmICghdGhpcy5jb25maWcuYWxsb3dFbXB0eVJ1bGVzZXRzICYmIHRoaXMuY2hlY2tFbXB0eVJ1bGVJblJ1bGVzZXQodGhpcy5kYXRhKSkge1xyXG4gICAgICBlcnJvcnMuZW1wdHkgPSAnRW1wdHkgcnVsZXNldHMgYXJlIG5vdCBhbGxvd2VkLic7XHJcbiAgICAgIGhhc0Vycm9ycyA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy52YWxpZGF0ZVJ1bGVzSW5SdWxlc2V0KHRoaXMuZGF0YSwgcnVsZUVycm9yU3RvcmUpO1xyXG5cclxuICAgIGlmIChydWxlRXJyb3JTdG9yZS5sZW5ndGgpIHtcclxuICAgICAgZXJyb3JzLnJ1bGVzID0gcnVsZUVycm9yU3RvcmU7XHJcbiAgICAgIGhhc0Vycm9ycyA9IHRydWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gaGFzRXJyb3JzID8gZXJyb3JzIDogbnVsbDtcclxuICB9XHJcblxyXG4gIC8vIC0tLS0tLS0tLS1Db250cm9sVmFsdWVBY2Nlc3NvciBJbXBsZW1lbnRhdGlvbi0tLS0tLS0tLS1cclxuXHJcbiAgQElucHV0KClcclxuICBnZXQgdmFsdWUoKTogUnVsZVNldCB7XHJcbiAgICByZXR1cm4gdGhpcy5kYXRhO1xyXG4gIH1cclxuICBzZXQgdmFsdWUodmFsdWU6IFJ1bGVTZXQpIHtcclxuICAgIC8vIFdoZW4gY29tcG9uZW50IGlzIGluaXRpYWxpemVkIHdpdGhvdXQgYSBmb3JtQ29udHJvbCwgbnVsbCBpcyBwYXNzZWQgdG8gdmFsdWVcclxuICAgIHRoaXMuZGF0YSA9IHZhbHVlIHx8IHsgY29uZGl0aW9uOiAnYW5kJywgcnVsZXM6IFtdIH07XHJcbiAgICB0aGlzLmhhbmRsZURhdGFDaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIHdyaXRlVmFsdWUob2JqOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMudmFsdWUgPSBvYmo7XHJcbiAgfVxyXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5vbkNoYW5nZUNhbGxiYWNrID0gKCkgPT4gZm4odGhpcy5kYXRhKTtcclxuICB9XHJcbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5vblRvdWNoZWRDYWxsYmFjayA9ICgpID0+IGZuKHRoaXMuZGF0YSk7XHJcbiAgfVxyXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XHJcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcclxuICB9XHJcblxyXG4gIC8vIC0tLS0tLS0tLS1FTkQtLS0tLS0tLS0tXHJcblxyXG4gIGdldERpc2FibGVkU3RhdGUgPSAoKTogYm9vbGVhbiA9PiB7XHJcbiAgICByZXR1cm4gdGhpcy5kaXNhYmxlZDtcclxuICB9XHJcblxyXG4gIGZpbmRUZW1wbGF0ZUZvclJ1bGUocnVsZTogUnVsZSk6IFRlbXBsYXRlUmVmPGFueT4ge1xyXG4gICAgY29uc3QgdHlwZSA9IHRoaXMuZ2V0SW5wdXRUeXBlKHJ1bGUuZmllbGQsIHJ1bGUub3BlcmF0b3IpO1xyXG4gICAgaWYgKHR5cGUpIHtcclxuICAgICAgY29uc3QgcXVlcnlJbnB1dCA9IHRoaXMuZmluZFF1ZXJ5SW5wdXQodHlwZSk7XHJcbiAgICAgIGlmIChxdWVyeUlucHV0KSB7XHJcbiAgICAgICAgcmV0dXJuIHF1ZXJ5SW5wdXQudGVtcGxhdGU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZGVmYXVsdFRlbXBsYXRlVHlwZXMuaW5kZXhPZih0eXBlKSA9PT0gLTEpIHtcclxuICAgICAgICAgIGNvbnNvbGUud2FybihgQ291bGQgbm90IGZpbmQgdGVtcGxhdGUgZm9yIGZpZWxkIHdpdGggdHlwZTogJHt0eXBlfWApO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICBmaW5kUXVlcnlJbnB1dCh0eXBlOiBzdHJpbmcpOiBRdWVyeUlucHV0RGlyZWN0aXZlIHtcclxuICAgIGNvbnN0IHRlbXBsYXRlcyA9IHRoaXMucGFyZW50SW5wdXRUZW1wbGF0ZXMgfHwgdGhpcy5pbnB1dFRlbXBsYXRlcztcclxuICAgIHJldHVybiB0ZW1wbGF0ZXMuZmluZCgoaXRlbSkgPT4gaXRlbS5xdWVyeUlucHV0VHlwZSA9PT0gdHlwZSk7XHJcbiAgfVxyXG5cclxuICBnZXRPcGVyYXRvcnMoZmllbGQ6IHN0cmluZyk6IHN0cmluZ1tdIHtcclxuICAgIGlmICh0aGlzLm9wZXJhdG9yc0NhY2hlW2ZpZWxkXSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5vcGVyYXRvcnNDYWNoZVtmaWVsZF07XHJcbiAgICB9XHJcbiAgICBsZXQgb3BlcmF0b3JzID0gdGhpcy5kZWZhdWx0RW1wdHlMaXN0O1xyXG4gICAgY29uc3QgZmllbGRPYmplY3QgPSB0aGlzLmNvbmZpZy5maWVsZHNbZmllbGRdO1xyXG5cclxuICAgIGlmICh0aGlzLmNvbmZpZy5nZXRPcGVyYXRvcnMpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmdldE9wZXJhdG9ycyhmaWVsZCwgZmllbGRPYmplY3QpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHR5cGUgPSBmaWVsZE9iamVjdC50eXBlO1xyXG5cclxuICAgIGlmIChmaWVsZE9iamVjdCAmJiBmaWVsZE9iamVjdC5vcGVyYXRvcnMpIHtcclxuICAgICAgb3BlcmF0b3JzID0gZmllbGRPYmplY3Qub3BlcmF0b3JzO1xyXG4gICAgfSBlbHNlIGlmICh0eXBlKSB7XHJcbiAgICAgIG9wZXJhdG9ycyA9ICh0aGlzLm9wZXJhdG9yTWFwICYmIHRoaXMub3BlcmF0b3JNYXBbdHlwZV0pIHx8IHRoaXMuZGVmYXVsdE9wZXJhdG9yTWFwW3R5cGVdIHx8IHRoaXMuZGVmYXVsdEVtcHR5TGlzdDtcclxuICAgICAgaWYgKG9wZXJhdG9ycy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICBjb25zb2xlLndhcm4oXHJcbiAgICAgICAgICBgTm8gb3BlcmF0b3JzIGZvdW5kIGZvciBmaWVsZCAnJHtmaWVsZH0nIHdpdGggdHlwZSAke2ZpZWxkT2JqZWN0LnR5cGV9LiBgICtcclxuICAgICAgICAgIGBQbGVhc2UgZGVmaW5lIGFuICdvcGVyYXRvcnMnIHByb3BlcnR5IG9uIHRoZSBmaWVsZCBvciB1c2UgdGhlICdvcGVyYXRvck1hcCcgYmluZGluZyB0byBmaXggdGhpcy5gKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoZmllbGRPYmplY3QubnVsbGFibGUpIHtcclxuICAgICAgICBvcGVyYXRvcnMgPSBvcGVyYXRvcnMuY29uY2F0KFsnaXMgbnVsbCcsICdpcyBub3QgbnVsbCddKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc29sZS53YXJuKGBObyAndHlwZScgcHJvcGVydHkgZm91bmQgb24gZmllbGQ6ICcke2ZpZWxkfSdgKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDYWNoZSByZWZlcmVuY2UgdG8gYXJyYXkgb2JqZWN0LCBzbyBpdCB3b24ndCBiZSBjb21wdXRlZCBuZXh0IHRpbWUgYW5kIHRyaWdnZXIgYSByZXJlbmRlci5cclxuICAgIHRoaXMub3BlcmF0b3JzQ2FjaGVbZmllbGRdID0gb3BlcmF0b3JzO1xyXG4gICAgcmV0dXJuIG9wZXJhdG9ycztcclxuICB9XHJcblxyXG4gIGdldEZpZWxkcyhlbnRpdHk6IHN0cmluZyk6IEZpZWxkW10ge1xyXG4gICAgaWYgKHRoaXMuZW50aXRpZXMgJiYgZW50aXR5KSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIGZpZWxkICYmIGZpZWxkLmVudGl0eSA9PT0gZW50aXR5O1xyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmZpZWxkcztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldElucHV0VHlwZShmaWVsZDogc3RyaW5nLCBvcGVyYXRvcjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGlmICh0aGlzLmNvbmZpZy5nZXRJbnB1dFR5cGUpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmdldElucHV0VHlwZShmaWVsZCwgb3BlcmF0b3IpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy5jb25maWcuZmllbGRzW2ZpZWxkXSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGNvbmZpZ3VyYXRpb24gZm9yIGZpZWxkICcke2ZpZWxkfScgY291bGQgYmUgZm91bmQhIFBsZWFzZSBhZGQgaXQgdG8gY29uZmlnLmZpZWxkcy5gKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0eXBlID0gdGhpcy5jb25maWcuZmllbGRzW2ZpZWxkXS50eXBlO1xyXG4gICAgc3dpdGNoIChvcGVyYXRvcikge1xyXG4gICAgICBjYXNlICdpcyBudWxsJzpcclxuICAgICAgY2FzZSAnaXMgbm90IG51bGwnOlxyXG4gICAgICAgIHJldHVybiBudWxsOyAgLy8gTm8gZGlzcGxheWVkIGNvbXBvbmVudFxyXG4gICAgICBjYXNlICdpbic6XHJcbiAgICAgIGNhc2UgJ25vdCBpbic6XHJcbiAgICAgICAgcmV0dXJuIHR5cGUgPT09ICdjYXRlZ29yeScgfHwgdHlwZSA9PT0gJ2Jvb2xlYW4nID8gJ211bHRpc2VsZWN0JyA6IHR5cGU7XHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgcmV0dXJuIHR5cGU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXRPcHRpb25zKGZpZWxkOiBzdHJpbmcpOiBPcHRpb25bXSB7XHJcbiAgICBpZiAodGhpcy5jb25maWcuZ2V0T3B0aW9ucykge1xyXG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuZ2V0T3B0aW9ucyhmaWVsZCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZmllbGRzW2ZpZWxkXS5vcHRpb25zIHx8IHRoaXMuZGVmYXVsdEVtcHR5TGlzdDtcclxuICB9XHJcblxyXG4gIGdldENsYXNzTmFtZXMoLi4uYXJncyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBjbHNMb29rdXAgPSB0aGlzLmNsYXNzTmFtZXMgPyB0aGlzLmNsYXNzTmFtZXMgOiB0aGlzLmRlZmF1bHRDbGFzc05hbWVzO1xyXG4gICAgY29uc3QgY2xhc3NOYW1lcyA9IGFyZ3MubWFwKChpZCkgPT4gY2xzTG9va3VwW2lkXSB8fCB0aGlzLmRlZmF1bHRDbGFzc05hbWVzW2lkXSkuZmlsdGVyKChjKSA9PiAhIWMpO1xyXG4gICAgcmV0dXJuIGNsYXNzTmFtZXMubGVuZ3RoID8gY2xhc3NOYW1lcy5qb2luKCcgJykgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0RGVmYXVsdEZpZWxkKGVudGl0eTogRW50aXR5KTogRmllbGQge1xyXG4gICAgaWYgKCFlbnRpdHkpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9IGVsc2UgaWYgKGVudGl0eS5kZWZhdWx0RmllbGQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5nZXREZWZhdWx0VmFsdWUoZW50aXR5LmRlZmF1bHRGaWVsZCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBlbnRpdHlGaWVsZHMgPSB0aGlzLmZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIGZpZWxkICYmIGZpZWxkLmVudGl0eSA9PT0gZW50aXR5LnZhbHVlO1xyXG4gICAgICB9KTtcclxuICAgICAgaWYgKGVudGl0eUZpZWxkcyAmJiBlbnRpdHlGaWVsZHMubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIGVudGl0eUZpZWxkc1swXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zb2xlLndhcm4oYE5vIGZpZWxkcyBmb3VuZCBmb3IgZW50aXR5ICcke2VudGl0eS5uYW1lfScuIGAgK1xyXG4gICAgICAgICAgYEEgJ2RlZmF1bHRPcGVyYXRvcicgaXMgYWxzbyBub3Qgc3BlY2lmaWVkIG9uIHRoZSBmaWVsZCBjb25maWcuIE9wZXJhdG9yIHZhbHVlIHdpbGwgZGVmYXVsdCB0byBudWxsLmApO1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXREZWZhdWx0T3BlcmF0b3IoZmllbGQ6IEZpZWxkKTogc3RyaW5nIHtcclxuICAgIGlmIChmaWVsZCAmJiBmaWVsZC5kZWZhdWx0T3BlcmF0b3IgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5nZXREZWZhdWx0VmFsdWUoZmllbGQuZGVmYXVsdE9wZXJhdG9yKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IG9wZXJhdG9ycyA9IHRoaXMuZ2V0T3BlcmF0b3JzKGZpZWxkLnZhbHVlKTtcclxuICAgICAgaWYgKG9wZXJhdG9ycyAmJiBvcGVyYXRvcnMubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIG9wZXJhdG9yc1swXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zb2xlLndhcm4oYE5vIG9wZXJhdG9ycyBmb3VuZCBmb3IgZmllbGQgJyR7ZmllbGQudmFsdWV9Jy4gYCArXHJcbiAgICAgICAgICBgQSAnZGVmYXVsdE9wZXJhdG9yJyBpcyBhbHNvIG5vdCBzcGVjaWZpZWQgb24gdGhlIGZpZWxkIGNvbmZpZy4gT3BlcmF0b3IgdmFsdWUgd2lsbCBkZWZhdWx0IHRvIG51bGwuYCk7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGFkZFJ1bGUocGFyZW50PzogUnVsZVNldCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHBhcmVudCA9IHBhcmVudCB8fCB0aGlzLmRhdGE7XHJcbiAgICBpZiAodGhpcy5jb25maWcuYWRkUnVsZSkge1xyXG4gICAgICB0aGlzLmNvbmZpZy5hZGRSdWxlKHBhcmVudCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBmaWVsZCA9IHRoaXMuZmllbGRzWzBdO1xyXG4gICAgICBwYXJlbnQucnVsZXMgPSBwYXJlbnQucnVsZXMuY29uY2F0KFt7XHJcbiAgICAgICAgZmllbGQ6IGZpZWxkLnZhbHVlLFxyXG4gICAgICAgIG9wZXJhdG9yOiB0aGlzLmdldERlZmF1bHRPcGVyYXRvcihmaWVsZCksXHJcbiAgICAgICAgdmFsdWU6IHRoaXMuZ2V0RGVmYXVsdFZhbHVlKGZpZWxkLmRlZmF1bHRWYWx1ZSksXHJcbiAgICAgICAgZW50aXR5OiBmaWVsZC5lbnRpdHlcclxuICAgICAgfV0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaGFuZGxlVG91Y2hlZCgpO1xyXG4gICAgdGhpcy5oYW5kbGVEYXRhQ2hhbmdlKCk7XHJcbiAgfVxyXG5cclxuICByZW1vdmVSdWxlKHJ1bGU6IFJ1bGUsIHBhcmVudD86IFJ1bGVTZXQpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBwYXJlbnQgPSBwYXJlbnQgfHwgdGhpcy5kYXRhO1xyXG4gICAgaWYgKHRoaXMuY29uZmlnLnJlbW92ZVJ1bGUpIHtcclxuICAgICAgdGhpcy5jb25maWcucmVtb3ZlUnVsZShydWxlLCBwYXJlbnQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcGFyZW50LnJ1bGVzID0gcGFyZW50LnJ1bGVzLmZpbHRlcigocikgPT4gciAhPT0gcnVsZSk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmlucHV0Q29udGV4dENhY2hlLmRlbGV0ZShydWxlKTtcclxuICAgIHRoaXMub3BlcmF0b3JDb250ZXh0Q2FjaGUuZGVsZXRlKHJ1bGUpO1xyXG4gICAgdGhpcy5maWVsZENvbnRleHRDYWNoZS5kZWxldGUocnVsZSk7XHJcbiAgICB0aGlzLmVudGl0eUNvbnRleHRDYWNoZS5kZWxldGUocnVsZSk7XHJcbiAgICB0aGlzLnJlbW92ZUJ1dHRvbkNvbnRleHRDYWNoZS5kZWxldGUocnVsZSk7XHJcblxyXG4gICAgdGhpcy5oYW5kbGVUb3VjaGVkKCk7XHJcbiAgICB0aGlzLmhhbmRsZURhdGFDaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIGFkZFJ1bGVTZXQocGFyZW50PzogUnVsZVNldCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHBhcmVudCA9IHBhcmVudCB8fCB0aGlzLmRhdGE7XHJcbiAgICBpZiAodGhpcy5jb25maWcuYWRkUnVsZVNldCkge1xyXG4gICAgICB0aGlzLmNvbmZpZy5hZGRSdWxlU2V0KHBhcmVudCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBwYXJlbnQucnVsZXMgPSBwYXJlbnQucnVsZXMuY29uY2F0KFt7IGNvbmRpdGlvbjogJ2FuZCcsIHJ1bGVzOiBbXSB9XSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5oYW5kbGVUb3VjaGVkKCk7XHJcbiAgICB0aGlzLmhhbmRsZURhdGFDaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIHJlbW92ZVJ1bGVTZXQocnVsZXNldD86IFJ1bGVTZXQsIHBhcmVudD86IFJ1bGVTZXQpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBydWxlc2V0ID0gcnVsZXNldCB8fCB0aGlzLmRhdGE7XHJcbiAgICBwYXJlbnQgPSBwYXJlbnQgfHwgdGhpcy5wYXJlbnRWYWx1ZTtcclxuICAgIGlmICh0aGlzLmNvbmZpZy5yZW1vdmVSdWxlU2V0KSB7XHJcbiAgICAgIHRoaXMuY29uZmlnLnJlbW92ZVJ1bGVTZXQocnVsZXNldCwgcGFyZW50KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHBhcmVudC5ydWxlcyA9IHBhcmVudC5ydWxlcy5maWx0ZXIoKHIpID0+IHIgIT09IHJ1bGVzZXQpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaGFuZGxlVG91Y2hlZCgpO1xyXG4gICAgdGhpcy5oYW5kbGVEYXRhQ2hhbmdlKCk7XHJcbiAgfVxyXG5cclxuICB0cmFuc2l0aW9uRW5kKGU6IEV2ZW50KTogdm9pZCB7XHJcbiAgICB0aGlzLnRyZWVDb250YWluZXIubmF0aXZlRWxlbWVudC5zdHlsZS5tYXhIZWlnaHQgPSBudWxsO1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlQ29sbGFwc2UoKTogdm9pZCB7XHJcbiAgICB0aGlzLmNvbXB1dGVkVHJlZUNvbnRhaW5lckhlaWdodCgpO1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHRoaXMuZGF0YS5jb2xsYXBzZWQgPSAhdGhpcy5kYXRhLmNvbGxhcHNlZDtcclxuICAgIH0sIDEwMCk7XHJcbiAgfVxyXG5cclxuICBjb21wdXRlZFRyZWVDb250YWluZXJIZWlnaHQoKTogdm9pZCB7XHJcbiAgICBjb25zdCBuYXRpdmVFbGVtZW50OiBIVE1MRWxlbWVudCA9IHRoaXMudHJlZUNvbnRhaW5lci5uYXRpdmVFbGVtZW50O1xyXG4gICAgaWYgKG5hdGl2ZUVsZW1lbnQgJiYgbmF0aXZlRWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZCkge1xyXG4gICAgICBuYXRpdmVFbGVtZW50LnN0eWxlLm1heEhlaWdodCA9IChuYXRpdmVFbGVtZW50LmZpcnN0RWxlbWVudENoaWxkLmNsaWVudEhlaWdodCArIDgpICsgJ3B4JztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNoYW5nZUNvbmRpdGlvbih2YWx1ZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5kYXRhLmNvbmRpdGlvbiA9IHZhbHVlO1xyXG4gICAgdGhpcy5oYW5kbGVUb3VjaGVkKCk7XHJcbiAgICB0aGlzLmhhbmRsZURhdGFDaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIGNoYW5nZU9wZXJhdG9yKHJ1bGU6IFJ1bGUpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5jb25maWcuY29lcmNlVmFsdWVGb3JPcGVyYXRvcikge1xyXG4gICAgICBydWxlLnZhbHVlID0gdGhpcy5jb25maWcuY29lcmNlVmFsdWVGb3JPcGVyYXRvcihydWxlLm9wZXJhdG9yLCBydWxlLnZhbHVlLCBydWxlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJ1bGUudmFsdWUgPSB0aGlzLmNvZXJjZVZhbHVlRm9yT3BlcmF0b3IocnVsZS5vcGVyYXRvciwgcnVsZS52YWx1ZSwgcnVsZSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5oYW5kbGVUb3VjaGVkKCk7XHJcbiAgICB0aGlzLmhhbmRsZURhdGFDaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIGNvZXJjZVZhbHVlRm9yT3BlcmF0b3Iob3BlcmF0b3I6IHN0cmluZywgdmFsdWU6IGFueSwgcnVsZTogUnVsZSk6IGFueSB7XHJcbiAgICBjb25zdCBpbnB1dFR5cGU6IHN0cmluZyA9IHRoaXMuZ2V0SW5wdXRUeXBlKHJ1bGUuZmllbGQsIG9wZXJhdG9yKTtcclxuICAgIGlmIChpbnB1dFR5cGUgPT09ICdtdWx0aXNlbGVjdCcgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XHJcbiAgICAgIHJldHVybiBbdmFsdWVdO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgY2hhbmdlSW5wdXQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5oYW5kbGVUb3VjaGVkKCk7XHJcbiAgICB0aGlzLmhhbmRsZURhdGFDaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIGNoYW5nZUZpZWxkKGZpZWxkVmFsdWU6IHN0cmluZywgcnVsZTogUnVsZSk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGlucHV0Q29udGV4dCA9IHRoaXMuaW5wdXRDb250ZXh0Q2FjaGUuZ2V0KHJ1bGUpO1xyXG4gICAgY29uc3QgY3VycmVudEZpZWxkID0gaW5wdXRDb250ZXh0ICYmIGlucHV0Q29udGV4dC5maWVsZDtcclxuXHJcbiAgICBjb25zdCBuZXh0RmllbGQ6IEZpZWxkID0gdGhpcy5jb25maWcuZmllbGRzW2ZpZWxkVmFsdWVdO1xyXG5cclxuICAgIGNvbnN0IG5leHRWYWx1ZSA9IHRoaXMuY2FsY3VsYXRlRmllbGRDaGFuZ2VWYWx1ZShcclxuICAgICAgY3VycmVudEZpZWxkLCBuZXh0RmllbGQsIHJ1bGUudmFsdWUpO1xyXG5cclxuICAgIGlmIChuZXh0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICBydWxlLnZhbHVlID0gbmV4dFZhbHVlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZGVsZXRlIHJ1bGUudmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgcnVsZS5vcGVyYXRvciA9IHRoaXMuZ2V0RGVmYXVsdE9wZXJhdG9yKG5leHRGaWVsZCk7XHJcblxyXG4gICAgLy8gQ3JlYXRlIG5ldyBjb250ZXh0IG9iamVjdHMgc28gdGVtcGxhdGVzIHdpbGwgYXV0b21hdGljYWxseSB1cGRhdGVcclxuICAgIHRoaXMuaW5wdXRDb250ZXh0Q2FjaGUuZGVsZXRlKHJ1bGUpO1xyXG4gICAgdGhpcy5vcGVyYXRvckNvbnRleHRDYWNoZS5kZWxldGUocnVsZSk7XHJcbiAgICB0aGlzLmZpZWxkQ29udGV4dENhY2hlLmRlbGV0ZShydWxlKTtcclxuICAgIHRoaXMuZW50aXR5Q29udGV4dENhY2hlLmRlbGV0ZShydWxlKTtcclxuICAgIHRoaXMuZ2V0SW5wdXRDb250ZXh0KHJ1bGUpO1xyXG4gICAgdGhpcy5nZXRGaWVsZENvbnRleHQocnVsZSk7XHJcbiAgICB0aGlzLmdldE9wZXJhdG9yQ29udGV4dChydWxlKTtcclxuICAgIHRoaXMuZ2V0RW50aXR5Q29udGV4dChydWxlKTtcclxuXHJcbiAgICB0aGlzLmhhbmRsZVRvdWNoZWQoKTtcclxuICAgIHRoaXMuaGFuZGxlRGF0YUNoYW5nZSgpO1xyXG4gIH1cclxuXHJcbiAgY2hhbmdlRW50aXR5KGVudGl0eVZhbHVlOiBzdHJpbmcsIHJ1bGU6IFJ1bGUsIGluZGV4OiBudW1iZXIsIGRhdGE6IFJ1bGVTZXQpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBpID0gaW5kZXg7XHJcbiAgICBsZXQgcnMgPSBkYXRhO1xyXG4gICAgY29uc3QgZW50aXR5OiBFbnRpdHkgPSB0aGlzLmVudGl0aWVzLmZpbmQoKGUpID0+IGUudmFsdWUgPT09IGVudGl0eVZhbHVlKTtcclxuICAgIGNvbnN0IGRlZmF1bHRGaWVsZDogRmllbGQgPSB0aGlzLmdldERlZmF1bHRGaWVsZChlbnRpdHkpO1xyXG4gICAgaWYgKCFycykge1xyXG4gICAgICBycyA9IHRoaXMuZGF0YTtcclxuICAgICAgaSA9IHJzLnJ1bGVzLmZpbmRJbmRleCgoeCkgPT4geCA9PT0gcnVsZSk7XHJcbiAgICB9XHJcbiAgICBydWxlLmZpZWxkID0gZGVmYXVsdEZpZWxkLnZhbHVlO1xyXG4gICAgcnMucnVsZXNbaV0gPSBydWxlO1xyXG4gICAgaWYgKGRlZmF1bHRGaWVsZCkge1xyXG4gICAgICB0aGlzLmNoYW5nZUZpZWxkKGRlZmF1bHRGaWVsZC52YWx1ZSwgcnVsZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmhhbmRsZVRvdWNoZWQoKTtcclxuICAgICAgdGhpcy5oYW5kbGVEYXRhQ2hhbmdlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXREZWZhdWx0VmFsdWUoZGVmYXVsdFZhbHVlOiBhbnkpOiBhbnkge1xyXG4gICAgc3dpdGNoICh0eXBlb2YgZGVmYXVsdFZhbHVlKSB7XHJcbiAgICAgIGNhc2UgJ2Z1bmN0aW9uJzpcclxuICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlKCk7XHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldE9wZXJhdG9yVGVtcGxhdGUoKTogVGVtcGxhdGVSZWY8YW55PiB7XHJcbiAgICBjb25zdCB0ID0gdGhpcy5wYXJlbnRPcGVyYXRvclRlbXBsYXRlIHx8IHRoaXMub3BlcmF0b3JUZW1wbGF0ZTtcclxuICAgIHJldHVybiB0ID8gdC50ZW1wbGF0ZSA6IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXRGaWVsZFRlbXBsYXRlKCk6IFRlbXBsYXRlUmVmPGFueT4ge1xyXG4gICAgY29uc3QgdCA9IHRoaXMucGFyZW50RmllbGRUZW1wbGF0ZSB8fCB0aGlzLmZpZWxkVGVtcGxhdGU7XHJcbiAgICByZXR1cm4gdCA/IHQudGVtcGxhdGUgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0RW50aXR5VGVtcGxhdGUoKTogVGVtcGxhdGVSZWY8YW55PiB7XHJcbiAgICBjb25zdCB0ID0gdGhpcy5wYXJlbnRFbnRpdHlUZW1wbGF0ZSB8fCB0aGlzLmVudGl0eVRlbXBsYXRlO1xyXG4gICAgcmV0dXJuIHQgPyB0LnRlbXBsYXRlIDogbnVsbDtcclxuICB9XHJcblxyXG4gIGdldEFycm93SWNvblRlbXBsYXRlKCk6IFRlbXBsYXRlUmVmPGFueT4ge1xyXG4gICAgY29uc3QgdCA9IHRoaXMucGFyZW50QXJyb3dJY29uVGVtcGxhdGUgfHwgdGhpcy5hcnJvd0ljb25UZW1wbGF0ZTtcclxuICAgIHJldHVybiB0ID8gdC50ZW1wbGF0ZSA6IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXRCdXR0b25Hcm91cFRlbXBsYXRlKCk6IFRlbXBsYXRlUmVmPGFueT4ge1xyXG4gICAgY29uc3QgdCA9IHRoaXMucGFyZW50QnV0dG9uR3JvdXBUZW1wbGF0ZSB8fCB0aGlzLmJ1dHRvbkdyb3VwVGVtcGxhdGU7XHJcbiAgICByZXR1cm4gdCA/IHQudGVtcGxhdGUgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0U3dpdGNoR3JvdXBUZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcclxuICAgIGNvbnN0IHQgPSB0aGlzLnBhcmVudFN3aXRjaEdyb3VwVGVtcGxhdGUgfHwgdGhpcy5zd2l0Y2hHcm91cFRlbXBsYXRlO1xyXG4gICAgcmV0dXJuIHQgPyB0LnRlbXBsYXRlIDogbnVsbDtcclxuICB9XHJcblxyXG4gIGdldFJlbW92ZUJ1dHRvblRlbXBsYXRlKCk6IFRlbXBsYXRlUmVmPGFueT4ge1xyXG4gICAgY29uc3QgdCA9IHRoaXMucGFyZW50UmVtb3ZlQnV0dG9uVGVtcGxhdGUgfHwgdGhpcy5yZW1vdmVCdXR0b25UZW1wbGF0ZTtcclxuICAgIHJldHVybiB0ID8gdC50ZW1wbGF0ZSA6IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXRFbXB0eVdhcm5pbmdUZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcclxuICAgIGNvbnN0IHQgPSB0aGlzLnBhcmVudEVtcHR5V2FybmluZ1RlbXBsYXRlIHx8IHRoaXMuZW1wdHlXYXJuaW5nVGVtcGxhdGU7XHJcbiAgICByZXR1cm4gdCA/IHQudGVtcGxhdGUgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0UXVlcnlJdGVtQ2xhc3NOYW1lKGxvY2FsOiBMb2NhbFJ1bGVNZXRhKTogc3RyaW5nIHtcclxuICAgIGxldCBjbHMgPSB0aGlzLmdldENsYXNzTmFtZXMoJ3JvdycsICdjb25uZWN0b3InLCAndHJhbnNpdGlvbicpO1xyXG4gICAgY2xzICs9ICcgJyArIHRoaXMuZ2V0Q2xhc3NOYW1lcyhsb2NhbC5ydWxlc2V0ID8gJ3J1bGVTZXQnIDogJ3J1bGUnKTtcclxuICAgIGlmIChsb2NhbC5pbnZhbGlkKSB7XHJcbiAgICAgIGNscyArPSAnICcgKyB0aGlzLmdldENsYXNzTmFtZXMoJ2ludmFsaWRSdWxlU2V0Jyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY2xzO1xyXG4gIH1cclxuXHJcbiAgZ2V0QnV0dG9uR3JvdXBDb250ZXh0KCk6IEJ1dHRvbkdyb3VwQ29udGV4dCB7XHJcbiAgICBpZiAoIXRoaXMuYnV0dG9uR3JvdXBDb250ZXh0KSB7XHJcbiAgICAgIHRoaXMuYnV0dG9uR3JvdXBDb250ZXh0ID0ge1xyXG4gICAgICAgIGFkZFJ1bGU6IHRoaXMuYWRkUnVsZS5iaW5kKHRoaXMpLFxyXG4gICAgICAgIGFkZFJ1bGVTZXQ6IHRoaXMuYWxsb3dSdWxlc2V0ICYmIHRoaXMuYWRkUnVsZVNldC5iaW5kKHRoaXMpLFxyXG4gICAgICAgIHJlbW92ZVJ1bGVTZXQ6IHRoaXMuYWxsb3dSdWxlc2V0ICYmIHRoaXMucGFyZW50VmFsdWUgJiYgdGhpcy5yZW1vdmVSdWxlU2V0LmJpbmQodGhpcyksXHJcbiAgICAgICAgZ2V0RGlzYWJsZWRTdGF0ZTogdGhpcy5nZXREaXNhYmxlZFN0YXRlLFxyXG4gICAgICAgICRpbXBsaWNpdDogdGhpcy5kYXRhXHJcbiAgICAgIH07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5idXR0b25Hcm91cENvbnRleHQ7XHJcbiAgfVxyXG5cclxuICBnZXRSZW1vdmVCdXR0b25Db250ZXh0KHJ1bGU6IFJ1bGUpOiBSZW1vdmVCdXR0b25Db250ZXh0IHtcclxuICAgIGlmICghdGhpcy5yZW1vdmVCdXR0b25Db250ZXh0Q2FjaGUuaGFzKHJ1bGUpKSB7XHJcbiAgICAgIHRoaXMucmVtb3ZlQnV0dG9uQ29udGV4dENhY2hlLnNldChydWxlLCB7XHJcbiAgICAgICAgcmVtb3ZlUnVsZTogdGhpcy5yZW1vdmVSdWxlLmJpbmQodGhpcyksXHJcbiAgICAgICAgZ2V0RGlzYWJsZWRTdGF0ZTogdGhpcy5nZXREaXNhYmxlZFN0YXRlLFxyXG4gICAgICAgICRpbXBsaWNpdDogcnVsZVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLnJlbW92ZUJ1dHRvbkNvbnRleHRDYWNoZS5nZXQocnVsZSk7XHJcbiAgfVxyXG5cclxuICBnZXRGaWVsZENvbnRleHQocnVsZTogUnVsZSk6IEZpZWxkQ29udGV4dCB7XHJcbiAgICBpZiAoIXRoaXMuZmllbGRDb250ZXh0Q2FjaGUuaGFzKHJ1bGUpKSB7XHJcbiAgICAgIHRoaXMuZmllbGRDb250ZXh0Q2FjaGUuc2V0KHJ1bGUsIHtcclxuICAgICAgICBvbkNoYW5nZTogdGhpcy5jaGFuZ2VGaWVsZC5iaW5kKHRoaXMpLFxyXG4gICAgICAgIGdldEZpZWxkczogdGhpcy5nZXRGaWVsZHMuYmluZCh0aGlzKSxcclxuICAgICAgICBnZXREaXNhYmxlZFN0YXRlOiB0aGlzLmdldERpc2FibGVkU3RhdGUsXHJcbiAgICAgICAgZmllbGRzOiB0aGlzLmZpZWxkcyxcclxuICAgICAgICAkaW1wbGljaXQ6IHJ1bGVcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5maWVsZENvbnRleHRDYWNoZS5nZXQocnVsZSk7XHJcbiAgfVxyXG5cclxuICBnZXRFbnRpdHlDb250ZXh0KHJ1bGU6IFJ1bGUpOiBFbnRpdHlDb250ZXh0IHtcclxuICAgIGlmICghdGhpcy5lbnRpdHlDb250ZXh0Q2FjaGUuaGFzKHJ1bGUpKSB7XHJcbiAgICAgIHRoaXMuZW50aXR5Q29udGV4dENhY2hlLnNldChydWxlLCB7XHJcbiAgICAgICAgb25DaGFuZ2U6IHRoaXMuY2hhbmdlRW50aXR5LmJpbmQodGhpcyksXHJcbiAgICAgICAgZ2V0RGlzYWJsZWRTdGF0ZTogdGhpcy5nZXREaXNhYmxlZFN0YXRlLFxyXG4gICAgICAgIGVudGl0aWVzOiB0aGlzLmVudGl0aWVzLFxyXG4gICAgICAgICRpbXBsaWNpdDogcnVsZVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmVudGl0eUNvbnRleHRDYWNoZS5nZXQocnVsZSk7XHJcbiAgfVxyXG5cclxuICBnZXRTd2l0Y2hHcm91cENvbnRleHQoKTogU3dpdGNoR3JvdXBDb250ZXh0IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIG9uQ2hhbmdlOiB0aGlzLmNoYW5nZUNvbmRpdGlvbi5iaW5kKHRoaXMpLFxyXG4gICAgICBnZXREaXNhYmxlZFN0YXRlOiB0aGlzLmdldERpc2FibGVkU3RhdGUsXHJcbiAgICAgICRpbXBsaWNpdDogdGhpcy5kYXRhXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgZ2V0QXJyb3dJY29uQ29udGV4dCgpOiBBcnJvd0ljb25Db250ZXh0IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGdldERpc2FibGVkU3RhdGU6IHRoaXMuZ2V0RGlzYWJsZWRTdGF0ZSxcclxuICAgICAgJGltcGxpY2l0OiB0aGlzLmRhdGFcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBnZXRFbXB0eVdhcm5pbmdDb250ZXh0KCk6IEVtcHR5V2FybmluZ0NvbnRleHQge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgZ2V0RGlzYWJsZWRTdGF0ZTogdGhpcy5nZXREaXNhYmxlZFN0YXRlLFxyXG4gICAgICBtZXNzYWdlOiB0aGlzLmVtcHR5TWVzc2FnZSxcclxuICAgICAgJGltcGxpY2l0OiB0aGlzLmRhdGFcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBnZXRPcGVyYXRvckNvbnRleHQocnVsZTogUnVsZSk6IE9wZXJhdG9yQ29udGV4dCB7XHJcbiAgICBpZiAoIXRoaXMub3BlcmF0b3JDb250ZXh0Q2FjaGUuaGFzKHJ1bGUpKSB7XHJcbiAgICAgIHRoaXMub3BlcmF0b3JDb250ZXh0Q2FjaGUuc2V0KHJ1bGUsIHtcclxuICAgICAgICBvbkNoYW5nZTogdGhpcy5jaGFuZ2VPcGVyYXRvci5iaW5kKHRoaXMpLFxyXG4gICAgICAgIGdldERpc2FibGVkU3RhdGU6IHRoaXMuZ2V0RGlzYWJsZWRTdGF0ZSxcclxuICAgICAgICBvcGVyYXRvcnM6IHRoaXMuZ2V0T3BlcmF0b3JzKHJ1bGUuZmllbGQpLFxyXG4gICAgICAgICRpbXBsaWNpdDogcnVsZVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLm9wZXJhdG9yQ29udGV4dENhY2hlLmdldChydWxlKTtcclxuICB9XHJcblxyXG4gIGdldElucHV0Q29udGV4dChydWxlOiBSdWxlKTogSW5wdXRDb250ZXh0IHtcclxuICAgIGlmICghdGhpcy5pbnB1dENvbnRleHRDYWNoZS5oYXMocnVsZSkpIHtcclxuICAgICAgdGhpcy5pbnB1dENvbnRleHRDYWNoZS5zZXQocnVsZSwge1xyXG4gICAgICAgIG9uQ2hhbmdlOiB0aGlzLmNoYW5nZUlucHV0LmJpbmQodGhpcyksXHJcbiAgICAgICAgZ2V0RGlzYWJsZWRTdGF0ZTogdGhpcy5nZXREaXNhYmxlZFN0YXRlLFxyXG4gICAgICAgIG9wdGlvbnM6IHRoaXMuZ2V0T3B0aW9ucyhydWxlLmZpZWxkKSxcclxuICAgICAgICBmaWVsZDogdGhpcy5jb25maWcuZmllbGRzW3J1bGUuZmllbGRdLFxyXG4gICAgICAgICRpbXBsaWNpdDogcnVsZVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmlucHV0Q29udGV4dENhY2hlLmdldChydWxlKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2FsY3VsYXRlRmllbGRDaGFuZ2VWYWx1ZShcclxuICAgIGN1cnJlbnRGaWVsZDogRmllbGQsXHJcbiAgICBuZXh0RmllbGQ6IEZpZWxkLFxyXG4gICAgY3VycmVudFZhbHVlOiBhbnlcclxuICApOiBhbnkge1xyXG5cclxuICAgIGlmICh0aGlzLmNvbmZpZy5jYWxjdWxhdGVGaWVsZENoYW5nZVZhbHVlICE9IG51bGwpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmNhbGN1bGF0ZUZpZWxkQ2hhbmdlVmFsdWUoXHJcbiAgICAgICAgY3VycmVudEZpZWxkLCBuZXh0RmllbGQsIGN1cnJlbnRWYWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY2FuS2VlcFZhbHVlID0gKCkgPT4ge1xyXG4gICAgICBpZiAoY3VycmVudEZpZWxkID09IG51bGwgfHwgbmV4dEZpZWxkID09IG51bGwpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIGN1cnJlbnRGaWVsZC50eXBlID09PSBuZXh0RmllbGQudHlwZVxyXG4gICAgICAgICYmIHRoaXMuZGVmYXVsdFBlcnNpc3RWYWx1ZVR5cGVzLmluZGV4T2YoY3VycmVudEZpZWxkLnR5cGUpICE9PSAtMTtcclxuICAgIH07XHJcblxyXG4gICAgaWYgKHRoaXMucGVyc2lzdFZhbHVlT25GaWVsZENoYW5nZSAmJiBjYW5LZWVwVmFsdWUoKSkge1xyXG4gICAgICByZXR1cm4gY3VycmVudFZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChuZXh0RmllbGQgJiYgbmV4dEZpZWxkLmRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmdldERlZmF1bHRWYWx1ZShuZXh0RmllbGQuZGVmYXVsdFZhbHVlKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGVja0VtcHR5UnVsZUluUnVsZXNldChydWxlc2V0OiBSdWxlU2V0KTogYm9vbGVhbiB7XHJcbiAgICBpZiAoIXJ1bGVzZXQgfHwgIXJ1bGVzZXQucnVsZXMgfHwgcnVsZXNldC5ydWxlcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gcnVsZXNldC5ydWxlcy5zb21lKChpdGVtOiBSdWxlU2V0KSA9PiB7XHJcbiAgICAgICAgaWYgKGl0ZW0ucnVsZXMpIHtcclxuICAgICAgICAgIHJldHVybiB0aGlzLmNoZWNrRW1wdHlSdWxlSW5SdWxlc2V0KGl0ZW0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgdmFsaWRhdGVSdWxlc0luUnVsZXNldChydWxlc2V0OiBSdWxlU2V0LCBlcnJvclN0b3JlOiBhbnlbXSkge1xyXG4gICAgaWYgKHJ1bGVzZXQgJiYgcnVsZXNldC5ydWxlcyAmJiBydWxlc2V0LnJ1bGVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgcnVsZXNldC5ydWxlcy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcbiAgICAgICAgaWYgKChpdGVtIGFzIFJ1bGVTZXQpLnJ1bGVzKSB7XHJcbiAgICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZVJ1bGVzSW5SdWxlc2V0KGl0ZW0gYXMgUnVsZVNldCwgZXJyb3JTdG9yZSk7XHJcbiAgICAgICAgfSBlbHNlIGlmICgoaXRlbSBhcyBSdWxlKS5maWVsZCkge1xyXG4gICAgICAgICAgY29uc3QgZmllbGQgPSB0aGlzLmNvbmZpZy5maWVsZHNbKGl0ZW0gYXMgUnVsZSkuZmllbGRdO1xyXG4gICAgICAgICAgaWYgKGZpZWxkICYmIGZpZWxkLnZhbGlkYXRvciAmJiBmaWVsZC52YWxpZGF0b3IuYXBwbHkpIHtcclxuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBmaWVsZC52YWxpZGF0b3IoaXRlbSBhcyBSdWxlLCBydWxlc2V0KTtcclxuICAgICAgICAgICAgaWYgKGVycm9yICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICBlcnJvclN0b3JlLnB1c2goZXJyb3IpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGFuZGxlRGF0YUNoYW5nZSgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICBpZiAodGhpcy5vbkNoYW5nZUNhbGxiYWNrKSB7XHJcbiAgICAgIHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMucGFyZW50Q2hhbmdlQ2FsbGJhY2spIHtcclxuICAgICAgdGhpcy5wYXJlbnRDaGFuZ2VDYWxsYmFjaygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBoYW5kbGVUb3VjaGVkKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMub25Ub3VjaGVkQ2FsbGJhY2spIHtcclxuICAgICAgdGhpcy5vblRvdWNoZWRDYWxsYmFjaygpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMucGFyZW50VG91Y2hlZENhbGxiYWNrKSB7XHJcbiAgICAgIHRoaXMucGFyZW50VG91Y2hlZENhbGxiYWNrKCk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnc3dpdGNoUm93JylcIj5cclxuICA8bmctdGVtcGxhdGUgI2RlZmF1bHRBcnJvd0ljb24+XHJcbiAgICA8aSBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdhcnJvd0ljb24nKVwiPjwvaT5cclxuICA8L25nLXRlbXBsYXRlPlxyXG5cclxuICA8YSAqbmdJZj1cImFsbG93Q29sbGFwc2VcIiAoY2xpY2spPVwidG9nZ2xlQ29sbGFwc2UoKVwiIFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2Fycm93SWNvbkJ1dHRvbicsIGRhdGEuY29sbGFwc2VkID8gJ2NvbGxhcHNlZCcgOiBudWxsKVwiPlxyXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldEFycm93SWNvblRlbXBsYXRlKCkgYXMgdGVtcGxhdGU7IGVsc2UgZGVmYXVsdEFycm93SWNvblwiPlxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGVtcGxhdGU7IGNvbnRleHQ6IGdldEFycm93SWNvbkNvbnRleHQoKVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcbiAgPC9hPlxyXG5cclxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0QnV0dG9uR3JvdXBUZW1wbGF0ZSgpIGFzIHRlbXBsYXRlOyBlbHNlIGRlZmF1bHRCdXR0b25Hcm91cFwiPlxyXG4gICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdidXR0b25Hcm91cCcsICdyaWdodEFsaWduJylcIj5cclxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRlbXBsYXRlOyBjb250ZXh0OiBnZXRCdXR0b25Hcm91cENvbnRleHQoKVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgPC9kaXY+XHJcbiAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdEJ1dHRvbkdyb3VwPlxyXG4gICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdidXR0b25Hcm91cCcsICdyaWdodEFsaWduJylcIj5cclxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFkZFJ1bGUoKVwiIFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2J1dHRvbicpXCIgW2Rpc2FibGVkXT1kaXNhYmxlZD5cclxuICAgICAgICA8aSBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdhZGRJY29uJylcIj48L2k+IFJ1bGVcclxuICAgICAgPC9idXR0b24+XHJcbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJhZGRSdWxlU2V0KClcIiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdidXR0b24nKVwiICpuZ0lmPVwiYWxsb3dSdWxlc2V0XCIgW2Rpc2FibGVkXT1kaXNhYmxlZD5cclxuICAgICAgICA8aSBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdhZGRJY29uJylcIj48L2k+IFJ1bGVzZXRcclxuICAgICAgPC9idXR0b24+XHJcbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhIXBhcmVudFZhbHVlICYmIGFsbG93UnVsZXNldFwiPlxyXG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJyZW1vdmVSdWxlU2V0KClcIiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdidXR0b24nLCAncmVtb3ZlQnV0dG9uJylcIiBbZGlzYWJsZWRdPWRpc2FibGVkPlxyXG4gICAgICAgICAgPGkgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygncmVtb3ZlSWNvbicpXCI+PC9pPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwvZGl2PlxyXG4gIDwvbmctdGVtcGxhdGU+XHJcblxyXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRTd2l0Y2hHcm91cFRlbXBsYXRlKCkgYXMgdGVtcGxhdGU7IGVsc2UgZGVmYXVsdFN3aXRjaEdyb3VwXCI+XHJcbiAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGVtcGxhdGU7IGNvbnRleHQ6IGdldFN3aXRjaEdyb3VwQ29udGV4dCgpXCI+PC9uZy1jb250YWluZXI+XHJcbiAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFN3aXRjaEdyb3VwPlxyXG4gICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdzd2l0Y2hHcm91cCcsICd0cmFuc2l0aW9uJylcIiAqbmdJZj1cImRhdGFcIj5cclxuICAgICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdzd2l0Y2hDb250cm9sJylcIj5cclxuICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnc3dpdGNoUmFkaW8nKVwiIFsobmdNb2RlbCldPVwiZGF0YS5jb25kaXRpb25cIiBbZGlzYWJsZWRdPWRpc2FibGVkXHJcbiAgICAgICAgICB2YWx1ZT1cImFuZFwiICNhbmRPcHRpb24gLz5cclxuICAgICAgICA8bGFiZWwgKGNsaWNrKT1cImNoYW5nZUNvbmRpdGlvbihhbmRPcHRpb24udmFsdWUpXCIgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnc3dpdGNoTGFiZWwnKVwiPkFORDwvbGFiZWw+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ3N3aXRjaENvbnRyb2wnKVwiPlxyXG4gICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdzd2l0Y2hSYWRpbycpXCIgWyhuZ01vZGVsKV09XCJkYXRhLmNvbmRpdGlvblwiIFtkaXNhYmxlZF09ZGlzYWJsZWRcclxuICAgICAgICAgIHZhbHVlPVwib3JcIiAjb3JPcHRpb24gLz5cclxuICAgICAgICA8bGFiZWwgKGNsaWNrKT1cImNoYW5nZUNvbmRpdGlvbihvck9wdGlvbi52YWx1ZSlcIiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdzd2l0Y2hMYWJlbCcpXCI+T1I8L2xhYmVsPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIDwvbmctdGVtcGxhdGU+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiAjdHJlZUNvbnRhaW5lciAodHJhbnNpdGlvbmVuZCk9XCJ0cmFuc2l0aW9uRW5kKCRldmVudClcIiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCd0cmVlQ29udGFpbmVyJywgZGF0YS5jb2xsYXBzZWQgPyAnY29sbGFwc2VkJyA6IG51bGwpXCI+XHJcbiAgPHVsIFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ3RyZWUnKVwiICpuZ0lmPVwiZGF0YSAmJiBkYXRhLnJ1bGVzXCI+XHJcbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBydWxlIG9mIGRhdGEucnVsZXM7bGV0IGk9aW5kZXhcIj5cclxuXHJcbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ7cnVsZXNldDogISFydWxlLnJ1bGVzLCBpbnZhbGlkOiAhY29uZmlnLmFsbG93RW1wdHlSdWxlc2V0cyAmJiBydWxlLnJ1bGVzICYmIHJ1bGUucnVsZXMubGVuZ3RoID09PSAwfSBhcyBsb2NhbFwiPlxyXG4gICAgICAgIDxsaSBbbmdDbGFzc109XCJnZXRRdWVyeUl0ZW1DbGFzc05hbWUobG9jYWwpXCI+XHJcbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWxvY2FsLnJ1bGVzZXRcIj5cclxuXHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRSZW1vdmVCdXR0b25UZW1wbGF0ZSgpIGFzIHRlbXBsYXRlOyBlbHNlIGRlZmF1bHRSZW1vdmVCdXR0b25cIj5cclxuICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2J1dHRvbkdyb3VwJywgJ3JpZ2h0QWxpZ24nKVwiPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRlbXBsYXRlOyBjb250ZXh0OiBnZXRSZW1vdmVCdXR0b25Db250ZXh0KHJ1bGUpXCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0UmVtb3ZlQnV0dG9uPlxyXG4gICAgICAgICAgICAgIDxkaXYgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygncmVtb3ZlQnV0dG9uU2l6ZScsICdyaWdodEFsaWduJylcIj5cclxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2J1dHRvbicsICdyZW1vdmVCdXR0b24nKVwiIChjbGljayk9XCJyZW1vdmVSdWxlKHJ1bGUsIGRhdGEpXCIgW2Rpc2FibGVkXT1kaXNhYmxlZD5cclxuICAgICAgICAgICAgICAgICAgPGkgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygncmVtb3ZlSWNvbicpXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcblxyXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZW50aXRpZXM/Lmxlbmd0aCA+IDBcIiBjbGFzcz1cInEtaW5saW5lLWJsb2NrLWRpc3BsYXlcIj5cclxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0RW50aXR5VGVtcGxhdGUoKSBhcyB0ZW1wbGF0ZTsgZWxzZSBkZWZhdWx0RW50aXR5XCI+XHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGVtcGxhdGU7IGNvbnRleHQ6IGdldEVudGl0eUNvbnRleHQocnVsZSlcIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRFbnRpdHk+XHJcbiAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdlbnRpdHlDb250cm9sU2l6ZScpXCI+XHJcbiAgICAgICAgICAgICAgICA8c2VsZWN0IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2VudGl0eUNvbnRyb2wnKVwiIFsobmdNb2RlbCldPVwicnVsZS5lbnRpdHlcIiAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VFbnRpdHkoJGV2ZW50LCBydWxlLGksZGF0YSlcIlxyXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIj5cclxuICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgZW50aXR5IG9mIGVudGl0aWVzXCIgW25nVmFsdWVdPVwiZW50aXR5LnZhbHVlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAge3tlbnRpdHkubmFtZX19XHJcbiAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgPC9zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcblxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0RmllbGRUZW1wbGF0ZSgpIGFzIHRlbXBsYXRlOyBlbHNlIGRlZmF1bHRGaWVsZFwiPlxyXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0ZW1wbGF0ZTsgY29udGV4dDogZ2V0RmllbGRDb250ZXh0KHJ1bGUpXCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0RmllbGQ+XHJcbiAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdmaWVsZENvbnRyb2xTaXplJylcIj5cclxuICAgICAgICAgICAgICAgIDxzZWxlY3QgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnZmllbGRDb250cm9sJylcIiBbKG5nTW9kZWwpXT1cInJ1bGUuZmllbGRcIiAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VGaWVsZCgkZXZlbnQsIHJ1bGUpXCJcclxuICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGZpZWxkIG9mIGdldEZpZWxkcyhydWxlLmVudGl0eSlcIiBbbmdWYWx1ZV09XCJmaWVsZC52YWx1ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIHt7ZmllbGQubmFtZX19XHJcbiAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgPC9zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcblxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0T3BlcmF0b3JUZW1wbGF0ZSgpIGFzIHRlbXBsYXRlOyBlbHNlIGRlZmF1bHRPcGVyYXRvclwiPlxyXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0ZW1wbGF0ZTsgY29udGV4dDogZ2V0T3BlcmF0b3JDb250ZXh0KHJ1bGUpXCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0T3BlcmF0b3I+XHJcbiAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdvcGVyYXRvckNvbnRyb2xTaXplJylcIj5cclxuICAgICAgICAgICAgICAgIDxzZWxlY3QgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnb3BlcmF0b3JDb250cm9sJylcIiBbKG5nTW9kZWwpXT1cInJ1bGUub3BlcmF0b3JcIiAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VPcGVyYXRvcihydWxlKVwiXHJcbiAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiPlxyXG4gICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcGVyYXRvciBvZiBnZXRPcGVyYXRvcnMocnVsZS5maWVsZClcIiBbbmdWYWx1ZV09XCJvcGVyYXRvclwiPlxyXG4gICAgICAgICAgICAgICAgICAgIHt7b3BlcmF0b3J9fVxyXG4gICAgICAgICAgICAgICAgICA8L29wdGlvbj5cclxuICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxyXG4gICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImZpbmRUZW1wbGF0ZUZvclJ1bGUocnVsZSkgYXMgdGVtcGxhdGU7IGVsc2UgZGVmYXVsdElucHV0XCI+XHJcbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRlbXBsYXRlOyBjb250ZXh0OiBnZXRJbnB1dENvbnRleHQocnVsZSlcIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRJbnB1dD5cclxuICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2lucHV0Q29udHJvbFNpemUnKVwiIFtuZ1N3aXRjaF09XCJnZXRJbnB1dFR5cGUocnVsZS5maWVsZCwgcnVsZS5vcGVyYXRvcilcIj5cclxuICAgICAgICAgICAgICAgIDxpbnB1dCBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdpbnB1dENvbnRyb2wnKVwiIFsobmdNb2RlbCldPVwicnVsZS52YWx1ZVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoYW5nZUlucHV0KClcIlxyXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiAqbmdTd2l0Y2hDYXNlPVwiJ3N0cmluZydcIiB0eXBlPVwidGV4dFwiPlxyXG4gICAgICAgICAgICAgICAgPGlucHV0IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2lucHV0Q29udHJvbCcpXCIgWyhuZ01vZGVsKV09XCJydWxlLnZhbHVlXCIgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlSW5wdXQoKVwiXHJcbiAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiICpuZ1N3aXRjaENhc2U9XCInbnVtYmVyJ1wiIHR5cGU9XCJudW1iZXJcIj5cclxuICAgICAgICAgICAgICAgIDxpbnB1dCBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdpbnB1dENvbnRyb2wnKVwiIFsobmdNb2RlbCldPVwicnVsZS52YWx1ZVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoYW5nZUlucHV0KClcIlxyXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiAqbmdTd2l0Y2hDYXNlPVwiJ2RhdGUnXCIgdHlwZT1cImRhdGVcIj5cclxuICAgICAgICAgICAgICAgIDxpbnB1dCBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdpbnB1dENvbnRyb2wnKVwiIFsobmdNb2RlbCldPVwicnVsZS52YWx1ZVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoYW5nZUlucHV0KClcIlxyXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiAqbmdTd2l0Y2hDYXNlPVwiJ3RpbWUnXCIgdHlwZT1cInRpbWVcIj5cclxuICAgICAgICAgICAgICAgIDxzZWxlY3QgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnaW5wdXRDb250cm9sJylcIiBbKG5nTW9kZWwpXT1cInJ1bGUudmFsdWVcIiAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VJbnB1dCgpXCJcclxuICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCIgKm5nU3dpdGNoQ2FzZT1cIidjYXRlZ29yeSdcIj5cclxuICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0IG9mIGdldE9wdGlvbnMocnVsZS5maWVsZClcIiBbbmdWYWx1ZV09XCJvcHQudmFsdWVcIj5cclxuICAgICAgICAgICAgICAgICAgICB7e29wdC5uYW1lfX1cclxuICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XHJcbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidtdWx0aXNlbGVjdCdcIj5cclxuICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdpbnB1dENvbnRyb2wnKVwiIFsobmdNb2RlbCldPVwicnVsZS52YWx1ZVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoYW5nZUlucHV0KClcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiIG11bHRpcGxlPlxyXG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdCBvZiBnZXRPcHRpb25zKHJ1bGUuZmllbGQpXCIgW25nVmFsdWVdPVwib3B0LnZhbHVlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICB7e29wdC5uYW1lfX1cclxuICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgIDxpbnB1dCBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdpbnB1dENvbnRyb2wnKVwiIFsobmdNb2RlbCldPVwicnVsZS52YWx1ZVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoYW5nZUlucHV0KClcIlxyXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiAqbmdTd2l0Y2hDYXNlPVwiJ2Jvb2xlYW4nXCIgdHlwZT1cImNoZWNrYm94XCI+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcblxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICA8cXVlcnktYnVpbGRlciAqbmdJZj1cImxvY2FsLnJ1bGVzZXRcIiBbZGF0YV09XCJydWxlXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkXCIgW3BhcmVudFRvdWNoZWRDYWxsYmFja109XCJwYXJlbnRUb3VjaGVkQ2FsbGJhY2sgfHwgb25Ub3VjaGVkQ2FsbGJhY2tcIlxyXG4gICAgICAgICAgICBbcGFyZW50Q2hhbmdlQ2FsbGJhY2tdPVwicGFyZW50Q2hhbmdlQ2FsbGJhY2sgfHwgb25DaGFuZ2VDYWxsYmFja1wiIFtwYXJlbnRJbnB1dFRlbXBsYXRlc109XCJwYXJlbnRJbnB1dFRlbXBsYXRlcyB8fCBpbnB1dFRlbXBsYXRlc1wiXHJcbiAgICAgICAgICAgIFtwYXJlbnRPcGVyYXRvclRlbXBsYXRlXT1cInBhcmVudE9wZXJhdG9yVGVtcGxhdGUgfHwgb3BlcmF0b3JUZW1wbGF0ZVwiIFtwYXJlbnRGaWVsZFRlbXBsYXRlXT1cInBhcmVudEZpZWxkVGVtcGxhdGUgfHwgZmllbGRUZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgIFtwYXJlbnRFbnRpdHlUZW1wbGF0ZV09XCJwYXJlbnRFbnRpdHlUZW1wbGF0ZSB8fCBlbnRpdHlUZW1wbGF0ZVwiIFtwYXJlbnRTd2l0Y2hHcm91cFRlbXBsYXRlXT1cInBhcmVudFN3aXRjaEdyb3VwVGVtcGxhdGUgfHwgc3dpdGNoR3JvdXBUZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgIFtwYXJlbnRCdXR0b25Hcm91cFRlbXBsYXRlXT1cInBhcmVudEJ1dHRvbkdyb3VwVGVtcGxhdGUgfHwgYnV0dG9uR3JvdXBUZW1wbGF0ZVwiIFtwYXJlbnRSZW1vdmVCdXR0b25UZW1wbGF0ZV09XCJwYXJlbnRSZW1vdmVCdXR0b25UZW1wbGF0ZSB8fCByZW1vdmVCdXR0b25UZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgIFtwYXJlbnRFbXB0eVdhcm5pbmdUZW1wbGF0ZV09XCJwYXJlbnRFbXB0eVdhcm5pbmdUZW1wbGF0ZSB8fCBlbXB0eVdhcm5pbmdUZW1wbGF0ZVwiIFtwYXJlbnRBcnJvd0ljb25UZW1wbGF0ZV09XCJwYXJlbnRBcnJvd0ljb25UZW1wbGF0ZSB8fCBhcnJvd0ljb25UZW1wbGF0ZVwiXHJcbiAgICAgICAgICAgIFtwYXJlbnRWYWx1ZV09XCJkYXRhXCIgW2NsYXNzTmFtZXNdPVwiY2xhc3NOYW1lc1wiIFtjb25maWddPVwiY29uZmlnXCIgW2FsbG93UnVsZXNldF09XCJhbGxvd1J1bGVzZXRcIlxyXG4gICAgICAgICAgICBbYWxsb3dDb2xsYXBzZV09XCJhbGxvd0NvbGxhcHNlXCIgW2VtcHR5TWVzc2FnZV09XCJlbXB0eU1lc3NhZ2VcIiBbb3BlcmF0b3JNYXBdPVwib3BlcmF0b3JNYXBcIj5cclxuICAgICAgICAgIDwvcXVlcnktYnVpbGRlcj5cclxuXHJcbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0RW1wdHlXYXJuaW5nVGVtcGxhdGUoKSBhcyB0ZW1wbGF0ZTsgZWxzZSBkZWZhdWx0RW1wdHlXYXJuaW5nXCI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJsb2NhbC5pbnZhbGlkXCI+XHJcbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRlbXBsYXRlOyBjb250ZXh0OiBnZXRFbXB0eVdhcm5pbmdDb250ZXh0KClcIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRFbXB0eVdhcm5pbmc+XHJcbiAgICAgICAgICAgIDxwIFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2VtcHR5V2FybmluZycpXCIgKm5nSWY9XCJsb2NhbC5pbnZhbGlkXCI+XHJcbiAgICAgICAgICAgICAge3tlbXB0eU1lc3NhZ2V9fVxyXG4gICAgICAgICAgICA8L3A+XHJcbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgIDwvbGk+XHJcbiAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcbiAgPC91bD5cclxuPC9kaXY+Il19