@super-green/query-builder 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/query-builder/fesm2022/query-builder.mjs +72 -45
  2. package/dist/query-builder/fesm2022/query-builder.mjs.map +1 -1
  3. package/dist/query-builder/types/query-builder.d.ts +342 -0
  4. package/package.json +56 -56
  5. package/dist/query-builder/esm2022/lib/query-builder/query-arrow-icon.directive.mjs +0 -15
  6. package/dist/query-builder/esm2022/lib/query-builder/query-builder.component.mjs +0 -769
  7. package/dist/query-builder/esm2022/lib/query-builder/query-builder.interfaces.mjs +0 -2
  8. package/dist/query-builder/esm2022/lib/query-builder/query-button-group.directive.mjs +0 -15
  9. package/dist/query-builder/esm2022/lib/query-builder/query-empty-warning.directive.mjs +0 -15
  10. package/dist/query-builder/esm2022/lib/query-builder/query-entity.directive.mjs +0 -15
  11. package/dist/query-builder/esm2022/lib/query-builder/query-field.directive.mjs +0 -15
  12. package/dist/query-builder/esm2022/lib/query-builder/query-input.directive.mjs +0 -28
  13. package/dist/query-builder/esm2022/lib/query-builder/query-operator.directive.mjs +0 -15
  14. package/dist/query-builder/esm2022/lib/query-builder/query-remove-button.directive.mjs +0 -15
  15. package/dist/query-builder/esm2022/lib/query-builder/query-switch-group.directive.mjs +0 -15
  16. package/dist/query-builder/esm2022/lib/query-builder.module.mjs +0 -73
  17. package/dist/query-builder/esm2022/public-api.mjs +0 -16
  18. package/dist/query-builder/esm2022/query-builder.mjs +0 -5
  19. package/dist/query-builder/index.d.ts +0 -5
  20. package/dist/query-builder/lib/query-builder/query-arrow-icon.directive.d.ts +0 -8
  21. package/dist/query-builder/lib/query-builder/query-builder.component.d.ts +0 -129
  22. package/dist/query-builder/lib/query-builder/query-builder.interfaces.d.ts +0 -143
  23. package/dist/query-builder/lib/query-builder/query-button-group.directive.d.ts +0 -8
  24. package/dist/query-builder/lib/query-builder/query-empty-warning.directive.d.ts +0 -8
  25. package/dist/query-builder/lib/query-builder/query-entity.directive.d.ts +0 -8
  26. package/dist/query-builder/lib/query-builder/query-field.directive.d.ts +0 -8
  27. package/dist/query-builder/lib/query-builder/query-input.directive.d.ts +0 -12
  28. package/dist/query-builder/lib/query-builder/query-operator.directive.d.ts +0 -8
  29. package/dist/query-builder/lib/query-builder/query-remove-button.directive.d.ts +0 -8
  30. package/dist/query-builder/lib/query-builder/query-switch-group.directive.d.ts +0 -8
  31. package/dist/query-builder/lib/query-builder.module.d.ts +0 -18
  32. package/dist/query-builder/public-api.d.ts +0 -12
@@ -1,769 +0,0 @@
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