ng-configcat-publicapi-ui 3.1.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/esm2022/lib/_models/flag-state.mjs +2 -0
  2. package/esm2022/lib/_models/setting-value-formgroup.mjs +2 -0
  3. package/esm2022/lib/_models/user-comparator.mjs +100 -0
  4. package/esm2022/lib/_services/app-data-adapter.mjs +18 -0
  5. package/esm2022/lib/_services/comparison-value-list-helper.mjs +72 -0
  6. package/esm2022/lib/_services/date-helper.mjs +56 -0
  7. package/esm2022/lib/_services/form-generator.mjs +359 -0
  8. package/esm2022/lib/_services/form-helper.mjs +6 -3
  9. package/esm2022/lib/_services/messaging.service.mjs +26 -0
  10. package/esm2022/lib/_services/public-api.service.mjs +8 -2
  11. package/esm2022/lib/_services/tracking.directive.mjs +16 -0
  12. package/esm2022/lib/ace-editor/ace-editor.component.mjs +137 -0
  13. package/esm2022/lib/authorization/authorization.component.mjs +3 -3
  14. package/esm2022/lib/base/base.component.mjs +4 -1
  15. package/esm2022/lib/bootstrap.mjs +10 -0
  16. package/esm2022/lib/dialogs/confirmation-dialog/confirmation-dialog.mjs +28 -0
  17. package/esm2022/lib/dialogs/info-dialog/info-dialog.mjs +29 -0
  18. package/esm2022/lib/dialogs/reason-dialog/reason-dialog.component.mjs +3 -3
  19. package/esm2022/lib/ng-configcat-publicapi-ui.module.mjs +114 -8
  20. package/esm2022/lib/setting-item/setting-item.component.mjs +4 -2
  21. package/esm2022/lib/setting-list/setting-list.component.mjs +3 -3
  22. package/esm2022/lib/v2/feature-flag/date-time-picker/date-time-picker.component.mjs +123 -0
  23. package/esm2022/lib/v2/feature-flag/dependees-dialog/dependees-dialog.component.mjs +30 -0
  24. package/esm2022/lib/v2/feature-flag/evaluation-formula/evaluation-formula.component.mjs +220 -0
  25. package/esm2022/lib/v2/feature-flag/evaluation-formula/feature-flag-value/feature-flag-value.component.mjs +61 -0
  26. package/esm2022/lib/v2/feature-flag/evaluation-formula/popout-text-editor-dialog/popout-text-editor-dialog.component.mjs +72 -0
  27. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/condition-chip/condition-chip.component.mjs +25 -0
  28. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/conditions.component.mjs +105 -0
  29. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/prerequisite-flag-condition/prerequisite-flag-condition.component.mjs +75 -0
  30. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/segment-condition/segment-condition.component.mjs +48 -0
  31. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/comparator-dialog/comparator-dialog.component.mjs +113 -0
  32. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/popout-list-editor-dialog/popout-list-editor-dialog.component.mjs +251 -0
  33. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/user-condition.component.mjs +444 -0
  34. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/percentage-options/percentage-options.component.mjs +84 -0
  35. package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/targeting-rule.component.mjs +129 -0
  36. package/esm2022/lib/v2/feature-flag/feature-flag.component.mjs +190 -0
  37. package/esm2022/lib/v2/feature-flag/percentage-evaluation-attribute-dialog/percentage-evaluation-attribute-dialog.component.mjs +65 -0
  38. package/esm2022/lib/v2/feature-flag-item.component.mjs +319 -0
  39. package/esm2022/public-api.mjs +2 -1
  40. package/fesm2022/ng-configcat-publicapi-ui.mjs +3194 -167
  41. package/fesm2022/ng-configcat-publicapi-ui.mjs.map +1 -1
  42. package/lib/_models/flag-state.d.ts +20 -0
  43. package/lib/_models/setting-value-formgroup.d.ts +69 -0
  44. package/lib/_models/user-comparator.d.ts +84 -0
  45. package/lib/_services/app-data-adapter.d.ts +7 -0
  46. package/lib/_services/comparison-value-list-helper.d.ts +17 -0
  47. package/lib/_services/date-helper.d.ts +6 -0
  48. package/lib/_services/form-generator.d.ts +59 -0
  49. package/lib/_services/form-helper.d.ts +4 -1
  50. package/lib/_services/messaging.service.d.ts +12 -0
  51. package/lib/_services/public-api.service.d.ts +2 -1
  52. package/lib/_services/tracking.directive.d.ts +6 -0
  53. package/lib/ace-editor/ace-editor.component.d.ts +32 -0
  54. package/lib/authorization/authorization.component.d.ts +1 -1
  55. package/lib/base/base.component.d.ts +1 -0
  56. package/lib/bootstrap.d.ts +12 -0
  57. package/lib/dialogs/confirmation-dialog/confirmation-dialog.d.ts +19 -0
  58. package/lib/dialogs/info-dialog/info-dialog.d.ts +17 -0
  59. package/lib/ng-configcat-publicapi-ui.module.d.ts +47 -19
  60. package/lib/setting-item/setting-item.component.d.ts +4 -2
  61. package/lib/setting-list/setting/rollout-rules/rollout-rules.component.d.ts +2 -2
  62. package/lib/v2/feature-flag/date-time-picker/date-time-picker.component.d.ts +25 -0
  63. package/lib/v2/feature-flag/dependees-dialog/dependees-dialog.component.d.ts +27 -0
  64. package/lib/v2/feature-flag/evaluation-formula/evaluation-formula.component.d.ts +41 -0
  65. package/lib/v2/feature-flag/evaluation-formula/feature-flag-value/feature-flag-value.component.d.ts +18 -0
  66. package/lib/v2/feature-flag/evaluation-formula/popout-text-editor-dialog/popout-text-editor-dialog.component.d.ts +30 -0
  67. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/condition-chip/condition-chip.component.d.ts +10 -0
  68. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/conditions.component.d.ts +27 -0
  69. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/prerequisite-flag-condition/prerequisite-flag-condition.component.d.ts +36 -0
  70. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/segment-condition/segment-condition.component.d.ts +21 -0
  71. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/comparator-dialog/comparator-dialog.component.d.ts +79 -0
  72. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/popout-list-editor-dialog/popout-list-editor-dialog.component.d.ts +63 -0
  73. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/user-condition.component.d.ts +94 -0
  74. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/percentage-options/percentage-options.component.d.ts +31 -0
  75. package/lib/v2/feature-flag/evaluation-formula/targeting-rule/targeting-rule.component.d.ts +33 -0
  76. package/lib/v2/feature-flag/feature-flag.component.d.ts +49 -0
  77. package/lib/v2/feature-flag/percentage-evaluation-attribute-dialog/percentage-evaluation-attribute-dialog.component.d.ts +28 -0
  78. package/lib/v2/feature-flag-item.component.d.ts +66 -0
  79. package/package.json +4 -2
  80. package/public-api.d.ts +1 -0
  81. package/public-api.scss +205 -2
@@ -0,0 +1,48 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { FormHelper, SegmentComparator } from '../../../../../../bootstrap';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/common";
5
+ import * as i2 from "@angular/forms";
6
+ import * as i3 from "@angular/material/form-field";
7
+ import * as i4 from "@angular/material/button";
8
+ import * as i5 from "@angular/material/input";
9
+ import * as i6 from "@angular/material/icon";
10
+ import * as i7 from "@angular/material/tooltip";
11
+ import * as i8 from "@angular/material/menu";
12
+ import * as i9 from "../condition-chip/condition-chip.component";
13
+ import * as i10 from "../../../../../../_services/tracking.directive";
14
+ export class SegmentConditionComponent {
15
+ constructor() {
16
+ this.createSegmentRequested = new EventEmitter();
17
+ this.manageSegmentsRequested = new EventEmitter();
18
+ this.FormHelper = FormHelper;
19
+ this.segmentComparators = [
20
+ { value: SegmentComparator.IsIn, label: 'IS IN SEGMENT' },
21
+ { value: SegmentComparator.IsNotIn, label: 'IS NOT IN SEGMENT' },
22
+ ];
23
+ }
24
+ createSegment() {
25
+ this.createSegmentRequested.emit();
26
+ }
27
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SegmentConditionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
28
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: SegmentConditionComponent, selector: "app-segment-condition", inputs: { targetingRuleIndex: "targetingRuleIndex", conditionIndex: "conditionIndex", formGroup: "formGroup", segments: "segments", canManageSegments: "canManageSegments" }, outputs: { createSegmentRequested: "createSegmentRequested", manageSegmentsRequested: "manageSegmentsRequested" }, ngImport: i0, template: "<div class=\"targeting-rule-line smallest-form-field\">\n <div class=\"explanation-wrapper\">\n <app-condition-chip [targetingRuleIndex]=\"targetingRuleIndex\"\n [conditionIndex]=\"conditionIndex\"></app-condition-chip>\n\n <div class=\"explanation\"><a href=\"https://configcat.com/docs/V2/targeting/targeting-rule/segment-condition/\" target=\"_blank\"\n rel=\"noopener noreferrer\" class=\"user-link\">user</a></div>\n </div>\n\n <div class=\"targeting-rule-component pad-right\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <select matNativeControl [formControl]=\"formGroup.controls.comparator\" matTooltip=\"Segment comparator\">\n <option *ngFor=\"let comparator of segmentComparators\" [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </select>\n <mat-error *ngIf=\"formGroup.controls.comparator.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.comparator)}}\n </mat-error>\n </mat-form-field>\n </div>\n <div class=\"wrapper-group\">\n <div class=\"targeting-rule-component\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <select matNativeControl [formControl]=\"formGroup.controls.segmentId\" matTooltip=\"Segment\">\n <option [ngValue]=\"null\" disabled selected hidden *ngIf=\"segments.length\">Select segment ...\n </option>\n <option *ngFor=\"let segment of segments\" [ngValue]=\"segment.segmentId\"\n [title]=\"segment.description\">\n {{segment.name}}\n </option>\n <option *ngIf=\"segments.length === 0\" disabled>\n no segments available\n </option>\n </select>\n <mat-error *ngIf=\"formGroup.controls.segmentId.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.segmentId)}}\n </mat-error>\n </mat-form-field>\n </div>\n <button class=\"segment-more\" type=\"button\" mat-icon-button *ngIf=\"canManageSegments\"\n matTooltip=\"Create and manage segments\" [matMenuTriggerFor]=\"segmentMenu\"\n [track]=\"['segment menu click', 'feature flags and settings']\">\n <mat-icon [inline]=\"true\">more_vert</mat-icon>\n </button>\n </div>\n</div>\n\n<mat-menu #segmentMenu=\"matMenu\">\n <ng-template matMenuContent>\n <a mat-menu-item (click)=\"createSegmentRequested.emit()\"\n [track]=\"['create segment click', 'Feature flags & settings V2 page']\">\n <mat-icon>add</mat-icon><span>Create new segment</span>\n </a>\n <a mat-menu-item (click)=\"manageSegmentsRequested.emit()\"\n [track]=\"['manage segment click', 'Feature flags & settings V2 page']\">\n <mat-icon>pie_chart</mat-icon><span>Manage segments</span>\n </a>\n </ng-template>\n</mat-menu>", styles: [".targeting-rule-line{display:flex;flex-wrap:wrap;margin:2px 0}.targeting-rule-line .wrapper-group{display:flex;flex-wrap:wrap}.targeting-rule-line .wrapper-group.grow{flex-grow:1}.targeting-rule-component{margin:2px 0;width:212px}.targeting-rule-component[hidden]{display:none}.targeting-rule-component.small{width:102px}.targeting-rule-component.grow{flex-grow:1}.targeting-rule-component.pad-right{margin-right:8px}.targeting-rule-component mat-form-field{width:100%;font-size:12px}.delete-button{margin-top:4px;color:#b1b1b1}.delete-button mat-icon{font-size:18px;height:18px;width:18px}.explanation-wrapper{display:flex;margin-top:2px}.explanation-wrapper .explanation{min-width:44px;margin-top:6px;margin-right:8px}@media (max-width: 500px){.targeting-rule-component{max-width:calc(100% - 4px);width:160px}.targeting-rule-component.small{width:78px}.targeting-rule-component.pad-right{margin-right:4px}}\n", ".segment-more{padding:0;line-height:1;margin-top:4px;height:28px;width:28px;display:inline-flex;align-items:center;justify-content:center}.segment-more .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 28px;width:var(--mdc-icon-button-state-layer-size);height:var(--mdc-icon-button-state-layer-size);padding:2px}.segment-more .mat-mdc-icon-button.mat-mdc-button-base .mat-mdc-button-touch-target{display:none}.segment-more mat-icon{font-size:18px;width:18px;height:18px;color:#818181}select.ng-invalid{color:#00000061}select.ng-invalid option{color:#000}\n"], dependencies: [{ 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: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i8.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i8.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i8.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i8.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i9.ConditionChipComponent, selector: "app-condition-chip", inputs: ["targetingRuleIndex", "conditionIndex"] }, { kind: "directive", type: i10.TrackingDirective, selector: "[track]", inputs: ["track"] }] }); }
29
+ }
30
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SegmentConditionComponent, decorators: [{
31
+ type: Component,
32
+ args: [{ selector: 'app-segment-condition', template: "<div class=\"targeting-rule-line smallest-form-field\">\n <div class=\"explanation-wrapper\">\n <app-condition-chip [targetingRuleIndex]=\"targetingRuleIndex\"\n [conditionIndex]=\"conditionIndex\"></app-condition-chip>\n\n <div class=\"explanation\"><a href=\"https://configcat.com/docs/V2/targeting/targeting-rule/segment-condition/\" target=\"_blank\"\n rel=\"noopener noreferrer\" class=\"user-link\">user</a></div>\n </div>\n\n <div class=\"targeting-rule-component pad-right\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <select matNativeControl [formControl]=\"formGroup.controls.comparator\" matTooltip=\"Segment comparator\">\n <option *ngFor=\"let comparator of segmentComparators\" [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </select>\n <mat-error *ngIf=\"formGroup.controls.comparator.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.comparator)}}\n </mat-error>\n </mat-form-field>\n </div>\n <div class=\"wrapper-group\">\n <div class=\"targeting-rule-component\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <select matNativeControl [formControl]=\"formGroup.controls.segmentId\" matTooltip=\"Segment\">\n <option [ngValue]=\"null\" disabled selected hidden *ngIf=\"segments.length\">Select segment ...\n </option>\n <option *ngFor=\"let segment of segments\" [ngValue]=\"segment.segmentId\"\n [title]=\"segment.description\">\n {{segment.name}}\n </option>\n <option *ngIf=\"segments.length === 0\" disabled>\n no segments available\n </option>\n </select>\n <mat-error *ngIf=\"formGroup.controls.segmentId.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.segmentId)}}\n </mat-error>\n </mat-form-field>\n </div>\n <button class=\"segment-more\" type=\"button\" mat-icon-button *ngIf=\"canManageSegments\"\n matTooltip=\"Create and manage segments\" [matMenuTriggerFor]=\"segmentMenu\"\n [track]=\"['segment menu click', 'feature flags and settings']\">\n <mat-icon [inline]=\"true\">more_vert</mat-icon>\n </button>\n </div>\n</div>\n\n<mat-menu #segmentMenu=\"matMenu\">\n <ng-template matMenuContent>\n <a mat-menu-item (click)=\"createSegmentRequested.emit()\"\n [track]=\"['create segment click', 'Feature flags & settings V2 page']\">\n <mat-icon>add</mat-icon><span>Create new segment</span>\n </a>\n <a mat-menu-item (click)=\"manageSegmentsRequested.emit()\"\n [track]=\"['manage segment click', 'Feature flags & settings V2 page']\">\n <mat-icon>pie_chart</mat-icon><span>Manage segments</span>\n </a>\n </ng-template>\n</mat-menu>", styles: [".targeting-rule-line{display:flex;flex-wrap:wrap;margin:2px 0}.targeting-rule-line .wrapper-group{display:flex;flex-wrap:wrap}.targeting-rule-line .wrapper-group.grow{flex-grow:1}.targeting-rule-component{margin:2px 0;width:212px}.targeting-rule-component[hidden]{display:none}.targeting-rule-component.small{width:102px}.targeting-rule-component.grow{flex-grow:1}.targeting-rule-component.pad-right{margin-right:8px}.targeting-rule-component mat-form-field{width:100%;font-size:12px}.delete-button{margin-top:4px;color:#b1b1b1}.delete-button mat-icon{font-size:18px;height:18px;width:18px}.explanation-wrapper{display:flex;margin-top:2px}.explanation-wrapper .explanation{min-width:44px;margin-top:6px;margin-right:8px}@media (max-width: 500px){.targeting-rule-component{max-width:calc(100% - 4px);width:160px}.targeting-rule-component.small{width:78px}.targeting-rule-component.pad-right{margin-right:4px}}\n", ".segment-more{padding:0;line-height:1;margin-top:4px;height:28px;width:28px;display:inline-flex;align-items:center;justify-content:center}.segment-more .mat-mdc-icon-button.mat-mdc-button-base{--mdc-icon-button-state-layer-size: 28px;width:var(--mdc-icon-button-state-layer-size);height:var(--mdc-icon-button-state-layer-size);padding:2px}.segment-more .mat-mdc-icon-button.mat-mdc-button-base .mat-mdc-button-touch-target{display:none}.segment-more mat-icon{font-size:18px;width:18px;height:18px;color:#818181}select.ng-invalid{color:#00000061}select.ng-invalid option{color:#000}\n"] }]
33
+ }], propDecorators: { targetingRuleIndex: [{
34
+ type: Input
35
+ }], conditionIndex: [{
36
+ type: Input
37
+ }], formGroup: [{
38
+ type: Input
39
+ }], segments: [{
40
+ type: Input
41
+ }], canManageSegments: [{
42
+ type: Input
43
+ }], createSegmentRequested: [{
44
+ type: Output
45
+ }], manageSegmentsRequested: [{
46
+ type: Output
47
+ }] } });
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VnbWVudC1jb25kaXRpb24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctY29uZmlnY2F0LXB1YmxpY2FwaS11aS9zcmMvbGliL3YyL2ZlYXR1cmUtZmxhZy9ldmFsdWF0aW9uLWZvcm11bGEvdGFyZ2V0aW5nLXJ1bGUvY29uZGl0aW9ucy9zZWdtZW50LWNvbmRpdGlvbi9zZWdtZW50LWNvbmRpdGlvbi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1jb25maWdjYXQtcHVibGljYXBpLXVpL3NyYy9saWIvdjIvZmVhdHVyZS1mbGFnL2V2YWx1YXRpb24tZm9ybXVsYS90YXJnZXRpbmctcnVsZS9jb25kaXRpb25zL3NlZ21lbnQtY29uZGl0aW9uL3NlZ21lbnQtY29uZGl0aW9uLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdkUsT0FBTyxFQUFFLFVBQVUsRUFBa0MsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7Ozs7Ozs7Ozs7O0FBVTVHLE1BQU0sT0FBTyx5QkFBeUI7SUFSdEM7UUFjWSwyQkFBc0IsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzVDLDRCQUF1QixHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFFdkQsZUFBVSxHQUFHLFVBQVUsQ0FBQztRQUV4Qix1QkFBa0IsR0FBRztZQUNuQixFQUFFLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRTtZQUN6RCxFQUFFLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLG1CQUFtQixFQUFFO1NBQ2pFLENBQUM7S0FLSDtJQUhDLGFBQWE7UUFDWCxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDckMsQ0FBQzs4R0FsQlUseUJBQXlCO2tHQUF6Qix5QkFBeUIsOFZDWnRDLGltR0EyRFc7OzJGRC9DRSx5QkFBeUI7a0JBUnJDLFNBQVM7K0JBQ0UsdUJBQXVCOzhCQVF4QixrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNJLHNCQUFzQjtzQkFBL0IsTUFBTTtnQkFDRyx1QkFBdUI7c0JBQWhDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgRm9ybUhlbHBlciwgU2VnbWVudENvbmRpdGlvbkZvcm0sIElTZWdtZW50LCBTZWdtZW50Q29tcGFyYXRvciB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL2Jvb3RzdHJhcCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1zZWdtZW50LWNvbmRpdGlvbicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zZWdtZW50LWNvbmRpdGlvbi5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogW1xuICAgICcuLi8uLi8uLi9jb21wb25lbnRzLnNjc3MnLFxuICAgICcuL3NlZ21lbnQtY29uZGl0aW9uLmNvbXBvbmVudC5zY3NzJ1xuICBdXG59KVxuZXhwb3J0IGNsYXNzIFNlZ21lbnRDb25kaXRpb25Db21wb25lbnQge1xuICBASW5wdXQoKSB0YXJnZXRpbmdSdWxlSW5kZXg6IG51bWJlcjtcbiAgQElucHV0KCkgY29uZGl0aW9uSW5kZXg6IG51bWJlcjtcbiAgQElucHV0KCkgZm9ybUdyb3VwOiBGb3JtR3JvdXA8U2VnbWVudENvbmRpdGlvbkZvcm0+O1xuICBASW5wdXQoKSBzZWdtZW50czogSVNlZ21lbnRbXTtcbiAgQElucHV0KCkgY2FuTWFuYWdlU2VnbWVudHM6IGJvb2xlYW47XG4gIEBPdXRwdXQoKSBjcmVhdGVTZWdtZW50UmVxdWVzdGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgbWFuYWdlU2VnbWVudHNSZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgRm9ybUhlbHBlciA9IEZvcm1IZWxwZXI7XG5cbiAgc2VnbWVudENvbXBhcmF0b3JzID0gW1xuICAgIHsgdmFsdWU6IFNlZ21lbnRDb21wYXJhdG9yLklzSW4sIGxhYmVsOiAnSVMgSU4gU0VHTUVOVCcgfSxcbiAgICB7IHZhbHVlOiBTZWdtZW50Q29tcGFyYXRvci5Jc05vdEluLCBsYWJlbDogJ0lTIE5PVCBJTiBTRUdNRU5UJyB9LFxuICBdO1xuXG4gIGNyZWF0ZVNlZ21lbnQoKSB7XG4gICAgdGhpcy5jcmVhdGVTZWdtZW50UmVxdWVzdGVkLmVtaXQoKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInRhcmdldGluZy1ydWxlLWxpbmUgc21hbGxlc3QtZm9ybS1maWVsZFwiPlxuICAgIDxkaXYgY2xhc3M9XCJleHBsYW5hdGlvbi13cmFwcGVyXCI+XG4gICAgICAgIDxhcHAtY29uZGl0aW9uLWNoaXAgW3RhcmdldGluZ1J1bGVJbmRleF09XCJ0YXJnZXRpbmdSdWxlSW5kZXhcIlxuICAgICAgICAgICAgW2NvbmRpdGlvbkluZGV4XT1cImNvbmRpdGlvbkluZGV4XCI+PC9hcHAtY29uZGl0aW9uLWNoaXA+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImV4cGxhbmF0aW9uXCI+PGEgaHJlZj1cImh0dHBzOi8vY29uZmlnY2F0LmNvbS9kb2NzL1YyL3RhcmdldGluZy90YXJnZXRpbmctcnVsZS9zZWdtZW50LWNvbmRpdGlvbi9cIiB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgIHJlbD1cIm5vb3BlbmVyIG5vcmVmZXJyZXJcIiBjbGFzcz1cInVzZXItbGlua1wiPnVzZXI8L2E+PC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwidGFyZ2V0aW5nLXJ1bGUtY29tcG9uZW50IHBhZC1yaWdodFwiPlxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBzdWJzY3JpcHRTaXppbmc9XCJkeW5hbWljXCI+XG4gICAgICAgICAgICA8c2VsZWN0IG1hdE5hdGl2ZUNvbnRyb2wgW2Zvcm1Db250cm9sXT1cImZvcm1Hcm91cC5jb250cm9scy5jb21wYXJhdG9yXCIgbWF0VG9vbHRpcD1cIlNlZ21lbnQgY29tcGFyYXRvclwiPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGNvbXBhcmF0b3Igb2Ygc2VnbWVudENvbXBhcmF0b3JzXCIgW25nVmFsdWVdPVwiY29tcGFyYXRvci52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICB7e2NvbXBhcmF0b3IubGFiZWx9fVxuICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybUdyb3VwLmNvbnRyb2xzLmNvbXBhcmF0b3IuaW52YWxpZFwiPlxuICAgICAgICAgICAgICAgIHt7Rm9ybUhlbHBlci5nZXRFcnJvck1lc3NhZ2UoZm9ybUdyb3VwLmNvbnRyb2xzLmNvbXBhcmF0b3IpfX1cbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJ3cmFwcGVyLWdyb3VwXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0YXJnZXRpbmctcnVsZS1jb21wb25lbnRcIj5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIHN1YnNjcmlwdFNpemluZz1cImR5bmFtaWNcIj5cbiAgICAgICAgICAgICAgICA8c2VsZWN0IG1hdE5hdGl2ZUNvbnRyb2wgW2Zvcm1Db250cm9sXT1cImZvcm1Hcm91cC5jb250cm9scy5zZWdtZW50SWRcIiBtYXRUb29sdGlwPVwiU2VnbWVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFtuZ1ZhbHVlXT1cIm51bGxcIiBkaXNhYmxlZCBzZWxlY3RlZCBoaWRkZW4gKm5nSWY9XCJzZWdtZW50cy5sZW5ndGhcIj5TZWxlY3Qgc2VnbWVudCAuLi5cbiAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHNlZ21lbnQgb2Ygc2VnbWVudHNcIiBbbmdWYWx1ZV09XCJzZWdtZW50LnNlZ21lbnRJZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwic2VnbWVudC5kZXNjcmlwdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3tzZWdtZW50Lm5hbWV9fVxuICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdJZj1cInNlZ21lbnRzLmxlbmd0aCA9PT0gMFwiIGRpc2FibGVkPlxuICAgICAgICAgICAgICAgICAgICAgICAgbm8gc2VnbWVudHMgYXZhaWxhYmxlXG4gICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtR3JvdXAuY29udHJvbHMuc2VnbWVudElkLmludmFsaWRcIj5cbiAgICAgICAgICAgICAgICAgICAge3tGb3JtSGVscGVyLmdldEVycm9yTWVzc2FnZShmb3JtR3JvdXAuY29udHJvbHMuc2VnbWVudElkKX19XG4gICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInNlZ21lbnQtbW9yZVwiIHR5cGU9XCJidXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCJjYW5NYW5hZ2VTZWdtZW50c1wiXG4gICAgICAgICAgICBtYXRUb29sdGlwPVwiQ3JlYXRlIGFuZCBtYW5hZ2Ugc2VnbWVudHNcIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwic2VnbWVudE1lbnVcIlxuICAgICAgICAgICAgW3RyYWNrXT1cIlsnc2VnbWVudCBtZW51IGNsaWNrJywgJ2ZlYXR1cmUgZmxhZ3MgYW5kIHNldHRpbmdzJ11cIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBbaW5saW5lXT1cInRydWVcIj5tb3JlX3ZlcnQ8L21hdC1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuXG48bWF0LW1lbnUgI3NlZ21lbnRNZW51PVwibWF0TWVudVwiPlxuICAgIDxuZy10ZW1wbGF0ZSBtYXRNZW51Q29udGVudD5cbiAgICAgICAgPGEgbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwiY3JlYXRlU2VnbWVudFJlcXVlc3RlZC5lbWl0KClcIlxuICAgICAgICAgICAgW3RyYWNrXT1cIlsnY3JlYXRlIHNlZ21lbnQgY2xpY2snLCAnRmVhdHVyZSBmbGFncyAmIHNldHRpbmdzIFYyIHBhZ2UnXVwiPlxuICAgICAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+PHNwYW4+Q3JlYXRlIG5ldyBzZWdtZW50PC9zcGFuPlxuICAgICAgICA8L2E+XG4gICAgICAgIDxhIG1hdC1tZW51LWl0ZW0gKGNsaWNrKT1cIm1hbmFnZVNlZ21lbnRzUmVxdWVzdGVkLmVtaXQoKVwiXG4gICAgICAgICAgICBbdHJhY2tdPVwiWydtYW5hZ2Ugc2VnbWVudCBjbGljaycsICdGZWF0dXJlIGZsYWdzICYgc2V0dGluZ3MgVjIgcGFnZSddXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+cGllX2NoYXJ0PC9tYXQtaWNvbj48c3Bhbj5NYW5hZ2Ugc2VnbWVudHM8L3NwYW4+XG4gICAgICAgIDwvYT5cbiAgICA8L25nLXRlbXBsYXRlPlxuPC9tYXQtbWVudT4iXX0=
@@ -0,0 +1,113 @@
1
+ import { Component, Inject } from '@angular/core';
2
+ import { MAT_DIALOG_DATA } from '@angular/material/dialog';
3
+ import { UserComparator } from '../../../../../../../bootstrap';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/material/dialog";
6
+ import * as i2 from "@angular/common";
7
+ import * as i3 from "@angular/forms";
8
+ import * as i4 from "@angular/material/button";
9
+ import * as i5 from "@angular/material/icon";
10
+ import * as i6 from "@angular/material/tooltip";
11
+ import * as i7 from "@angular/cdk/drag-drop";
12
+ import * as i8 from "@angular/material/button-toggle";
13
+ import * as i9 from "@angular/material/radio";
14
+ var ComparatorGroup;
15
+ (function (ComparatorGroup) {
16
+ ComparatorGroup[ComparatorGroup["Text"] = 0] = "Text";
17
+ ComparatorGroup[ComparatorGroup["Number"] = 1] = "Number";
18
+ ComparatorGroup[ComparatorGroup["Semver"] = 2] = "Semver";
19
+ ComparatorGroup[ComparatorGroup["DateTime"] = 3] = "DateTime";
20
+ ComparatorGroup[ComparatorGroup["Array"] = 4] = "Array";
21
+ })(ComparatorGroup || (ComparatorGroup = {}));
22
+ export class ComparatorDialogComponent {
23
+ constructor(dialogRef, data) {
24
+ this.dialogRef = dialogRef;
25
+ this.data = data;
26
+ this.ComparatorGroup = ComparatorGroup;
27
+ this.selectedGroup = ComparatorGroup.Text;
28
+ this.selectedComparator = UserComparator.TextEquals;
29
+ this.isConfidential = true;
30
+ this.lastConfidentialValue = true;
31
+ this.confidentialEnabled = true;
32
+ this.UserComparator = UserComparator;
33
+ this.comparisonAttributeTooltip = "User object's value passed to the SDK (Comparison attribute)";
34
+ this.comparisonValueTooltip = "Comparison value set on the ConfigCat Dashboard";
35
+ this.comparators = [
36
+ { value: UserComparator.TextEquals, sensitiveValue: UserComparator.SensitiveTextEquals, group: ComparatorGroup.Text, label: 'EQUALS', description: "Matches when the user object's comparison attribute passed to the SDK is equal to the comparison value set on the ConfigCat Dashboard" },
37
+ { value: UserComparator.TextDoesNotEqual, sensitiveValue: UserComparator.SensitiveTextDoesNotEqual, group: ComparatorGroup.Text, label: 'NOT EQUALS', description: "Matches when the user object's comparison attribute passed to the SDK is not equal to the comparison value" },
38
+ { value: UserComparator.IsOneOf, sensitiveValue: UserComparator.SensitiveIsOneOf, group: ComparatorGroup.Text, label: 'IS ONE OF', description: "Matches when the user object's comparison attribute passed to the SDK is equal to any of the comparison values" },
39
+ { value: UserComparator.IsNotOneOf, sensitiveValue: UserComparator.SensitiveIsNotOneOf, group: ComparatorGroup.Text, label: 'IS NOT ONE OF', description: "Matches when the user object's comparison attribute passed to the SDK is not equal to any of the comparison values" },
40
+ { value: UserComparator.TextStartsWithAnyOf, sensitiveValue: UserComparator.SensitiveTextStartsWithAnyOf, group: ComparatorGroup.Text, label: 'STARTS WITH ANY OF', description: "Matches when the user object's comparison attribute passed to the SDK starts with any of the comparison values" },
41
+ { value: UserComparator.TextNotStartsWithAnyOf, sensitiveValue: UserComparator.SensitiveTextNotStartsWithAnyOf, group: ComparatorGroup.Text, label: 'NOT STARTS WITH ANY OF', description: "Matches when the user object's comparison attribute passed to the SDK does not start with any of the comparison values" },
42
+ { value: UserComparator.TextEndsWithAnyOf, sensitiveValue: UserComparator.SensitiveTextEndsWithAnyOf, group: ComparatorGroup.Text, label: 'ENDS WITH ANY OF', description: "Matches when the user object's comparison attribute passed to the SDK ends with any of the comparison values" },
43
+ { value: UserComparator.TextNotEndsWithAnyOf, sensitiveValue: UserComparator.SensitiveTextNotEndsWithAnyOf, group: ComparatorGroup.Text, label: 'NOT ENDS WITH ANY OF', description: "Matches when the user object's comparison attribute passed to the SDK does not end with any of the comparison values" },
44
+ { value: UserComparator.ContainsAnyOf, group: ComparatorGroup.Text, label: 'CONTAINS ANY OF', description: "Matches when the user object's comparison attribute passed to the SDK contains any comparison values as a substring" },
45
+ { value: UserComparator.DoesNotContainAnyOf, group: ComparatorGroup.Text, label: 'DOES NOT CONTAIN ANY OF', description: "Matches when the user object's comparison attribute passed to the SDK does not contain any comparison values as a substring" },
46
+ { value: UserComparator.NumberEquals, group: ComparatorGroup.Number, label: '= (EQUALS)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a decimal number) is equal to the comparison value" },
47
+ { value: UserComparator.NumberDoesNotEqual, group: ComparatorGroup.Number, label: '!= (NOT EQUALS)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a decimal number) is not equal to the comparison value" },
48
+ { value: UserComparator.NumberLess, group: ComparatorGroup.Number, label: '< (LESS THAN)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a decimal number) is less than the comparison value" },
49
+ { value: UserComparator.NumberLessOrEquals, group: ComparatorGroup.Number, label: '<= (LESS THAN OR EQUAL)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a decimal number) is less than or equal to the comparison value" },
50
+ { value: UserComparator.NumberGreater, group: ComparatorGroup.Number, label: '> (GREATER THAN)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a decimal number) is greater than the comparison value" },
51
+ { value: UserComparator.NumberGreaterOrEquals, group: ComparatorGroup.Number, label: '>= (GRATER THAN OR EQUAL)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a decimal number) is greater than or equal to the comparison value" },
52
+ { value: UserComparator.SemVerIsOneOf, group: ComparatorGroup.Semver, label: 'IS ONE OF', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a semantic version) is equal to any of the comparison values" },
53
+ { value: UserComparator.SemVerIsNotOneOf, group: ComparatorGroup.Semver, label: 'IS NOT ONE OF', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a semantic version) is not equal to any of the comparison values" },
54
+ { value: UserComparator.SemVerLess, group: ComparatorGroup.Semver, label: '< (LESS THAN)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a semantic version) is less than the comparison value" },
55
+ { value: UserComparator.SemVerLessOrEquals, group: ComparatorGroup.Semver, label: '<= (LESS THAN OR EQUAL)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a semantic version) is less than or equal to the comparison value" },
56
+ { value: UserComparator.SemVerGreater, group: ComparatorGroup.Semver, label: '> (GREATER THAN)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a semantic version) is greater than the comparison value" },
57
+ { value: UserComparator.SemVerGreaterOrEquals, group: ComparatorGroup.Semver, label: '>= (GRATER THAN OR EQUAL)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a semantic version) is greater than or equal to the comparison value" },
58
+ { value: UserComparator.DateTimeBefore, group: ComparatorGroup.DateTime, label: 'BEFORE (UTC)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as the seconds elapsed since Unix Epoch) is less than the comparison value" },
59
+ { value: UserComparator.DateTimeAfter, group: ComparatorGroup.DateTime, label: 'AFTER (UTC)', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as the seconds elapsed since Unix Epoch) is greater than the comparison value.value" },
60
+ { value: UserComparator.ArrayContainsAnyOf, group: ComparatorGroup.Array, sensitiveValue: UserComparator.SensitiveArrayContainsAnyOf, label: 'ARRAY CONTAINS ANY OF', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a string list) contains any of the comparison values" },
61
+ { value: UserComparator.ArrayDoesNotContainAnyOf, group: ComparatorGroup.Array, sensitiveValue: UserComparator.SensitiveArrayDoesNotContainAnyOf, label: 'ARRAY NOT CONTAINS ANY OF', description: "Matches when the user object's comparison attribute passed to the SDK (interpreted as a string list) does not contain any of the comparison values" },
62
+ ];
63
+ }
64
+ ngOnInit() {
65
+ const selected = this.comparators.find(c => c.value === this.data.selectedComparator || c.sensitiveValue === this.data.selectedComparator);
66
+ this.selectedGroup = selected.group;
67
+ this.selectedComparator = selected.value;
68
+ this.isConfidential = this.data.selectedComparator === selected.sensitiveValue;
69
+ this.lastConfidentialValue = !selected.sensitiveValue ? true : this.isConfidential;
70
+ this.confidentialEnabled = !!selected.sensitiveValue;
71
+ }
72
+ listComparators(group) {
73
+ return this.comparators.filter(c => c.group === group);
74
+ }
75
+ changeGroup(group) {
76
+ this.selectedGroup = group;
77
+ }
78
+ confidentialChange(confidential) {
79
+ if (!this.confidentialEnabled || this.data.readOnly) {
80
+ return;
81
+ }
82
+ this.isConfidential = this.lastConfidentialValue = confidential;
83
+ }
84
+ comparatorChange(comp) {
85
+ if (this.data.readOnly) {
86
+ return;
87
+ }
88
+ this.selectedComparator = comp;
89
+ const selected = this.comparators.find(c => c.value === comp || c.sensitiveValue === comp);
90
+ this.confidentialEnabled = !!selected.sensitiveValue;
91
+ if (!this.confidentialEnabled) {
92
+ this.isConfidential = false;
93
+ }
94
+ else {
95
+ this.isConfidential = this.lastConfidentialValue;
96
+ }
97
+ }
98
+ set() {
99
+ const selected = this.comparators.find(c => c.value === this.selectedComparator || c.sensitiveValue === this.selectedComparator);
100
+ const result = this.isConfidential && selected.sensitiveValue ? selected.sensitiveValue : selected.value;
101
+ this.dialogRef.close(result);
102
+ }
103
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ComparatorDialogComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component }); }
104
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: ComparatorDialogComponent, selector: "app-comparator-dialog", ngImport: i0, template: "<h2 mat-dialog-title cdkDrag cdkDragRootElement=\".cdk-overlay-pane\" cdkDragHandle class=\"draggable\">Comparator selector</h2>\n<div class=\"tabs\">\n <mat-button-toggle-group [ngModel]=\"selectedGroup\" (ngModelChange)=\"changeGroup($event)\">\n <mat-button-toggle [value]=\"ComparatorGroup.Text\">Text</mat-button-toggle>\n <mat-button-toggle [value]=\"ComparatorGroup.Number\">Number</mat-button-toggle>\n <mat-button-toggle [value]=\"ComparatorGroup.Semver\">Semantic version</mat-button-toggle>\n <mat-button-toggle [value]=\"ComparatorGroup.DateTime\">Datetime</mat-button-toggle>\n <mat-button-toggle [value]=\"ComparatorGroup.Array\">Array</mat-button-toggle>\n </mat-button-toggle-group>\n</div>\n\n<div mat-dialog-content class=\"container\" [ngSwitch]=\"selectedGroup\">\n <div *ngSwitchCase=\"ComparatorGroup.Text\">\n <p>The following comparators assume that the <i>comparison attribute's</i> value (set on the SDK's <a href=\"https://configcat.com/docs/V2/targeting/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user object</a>) and the <i>comparison value</i> contain string/text.</p>\n <ng-container [ngTemplateOutlet]=\"comparators\" [ngTemplateOutletContext]=\"{group:ComparatorGroup.Text}\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"confidential\"></ng-container>\n </div>\n\n <div *ngSwitchCase=\"ComparatorGroup.Number\">\n <p>The following comparators assume that the <i>comparison attribute's</i> value (set on the SDK's <a href=\"https://configcat.com/docs/V2/targeting/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user object</a>) and the <i>comparison value</i> contain numbers.</p>\n <ng-container [ngTemplateOutlet]=\"comparators\" [ngTemplateOutletContext]=\"{group:ComparatorGroup.Number}\"></ng-container>\n </div>\n\n <div *ngSwitchCase=\"ComparatorGroup.Semver\">\n <p>The following comparators assume that the <i>comparison attribute's</i> value (set on the SDK's <a href=\"https://configcat.com/docs/V2/targeting/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user object</a>) and the <i>comparison value</i> contain semantic versions.</p>\n <ng-container [ngTemplateOutlet]=\"comparators\" [ngTemplateOutletContext]=\"{group:ComparatorGroup.Semver}\"></ng-container>\n </div>\n\n <div *ngSwitchCase=\"ComparatorGroup.DateTime\">\n <p>The following comparators assume that the <i>comparison attribute's</i> value (set on the SDK's <a href=\"https://configcat.com/docs/V2/targeting/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user object</a>) and the <i>comparison value</i> contain datetimes.</p>\n <ng-container [ngTemplateOutlet]=\"comparators\" [ngTemplateOutletContext]=\"{group:ComparatorGroup.DateTime}\"></ng-container>\n </div>\n\n <div *ngSwitchCase=\"ComparatorGroup.Array\">\n <p>The following comparators assume that the <i>comparison attribute's</i> value (set on the SDK's <a href=\"https://configcat.com/docs/V2/targeting/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user object</a>) and the <i>comparison value</i> contain items of a string/text list.</p>\n <ng-container [ngTemplateOutlet]=\"comparators\" [ngTemplateOutletContext]=\"{group:ComparatorGroup.Array}\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"confidential\"></ng-container>\n </div>\n</div>\n<div mat-dialog-actions>\n <button *ngIf=\"!data.readOnly\" type=\"button\" mat-flat-button color=\"primary\" (click)=\"set()\">Set</button>\n <button *ngIf=\"!data.readOnly\" type=\"button\" mat-stroked-button mat-dialog-close>Cancel</button>\n <button *ngIf=\"data.readOnly\" type=\"button\" mat-stroked-button color=\"primary\" mat-dialog-close>Close</button>\n</div>\n\n<ng-template #comparators let-group=\"group\">\n <div>\n <mat-radio-group (change)=\"comparatorChange($event.value)\">\n <div class=\"comparator-container\">\n <div class=\"item\" [ngClass]=\"'col-' + i % 2\" [class.selected]=\"comparator.value === selectedComparator\" \n *ngFor=\"let comparator of listComparators(group); let i = index\" (click)=\"comparatorChange(comparator.value)\"> \n <mat-radio-button color=\"primary\" [value]=\"comparator.value\" [disabled]=\"data.readOnly\"\n [checked]=\"comparator.value === selectedComparator\" [matTooltip]=\"comparator.description\">\n <div class=\"title\">\n {{comparator.label}}\n </div>\n </mat-radio-button>\n <div class=\"description\">\n <div class=\"example\">\n <ng-container [ngSwitch]=\"comparator.value\">\n\n <!-- TEXT -->\n <ng-container *ngSwitchCase=\"UserComparator.TextEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">bob&#64;foo.com</span> EQUALS <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">bob&#64;foo.com</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.TextDoesNotEqual\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">alice&#64;foo.com</span> NOT EQUALS <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">bob&#64;foo.com</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.IsOneOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">iOS</span> IS ONE OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ Android, macOS, <span class=\"match-val\">iOS</span> ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.IsNotOneOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">iOS</span> IS NOT ONE OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ Android, macOS, Windows ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.TextStartsWithAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">bob&#64;foo.com</span> STARTS WITH ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ <span class=\"match-val\">bob</span>, jane ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.TextNotStartsWithAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">alice&#64;foo.com</span> NOT STARTS WITH ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ bob, jane ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.TextEndsWithAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">bob&#64;foo.com</span> ENDS WITH ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ <span class=\"match-val\">&#64;foo.com</span>, &#64;bar.com ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.TextNotEndsWithAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">bob&#64;example.com</span> NOT ENDS WITH ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ &#64;foo.com, &#64;bar.com ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.ContainsAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">https://test-app.foo.com</span> CONTAINS ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ <span class=\"match-val\">test</span>, localhost ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.DoesNotContainAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">https://app.foo.com</span> DOES NOT CONTAINS ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ test, localhost ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n\n <!-- NUMBER -->\n\n <ng-container *ngSwitchCase=\"UserComparator.NumberEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">42</span> = <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">42</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.NumberDoesNotEqual\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">42</span> != <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">3.14</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.NumberLess\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">3.14</span> &lt; <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">42</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.NumberLessOrEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">3.14</span> &lt;= <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">42</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.NumberGreater\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">69</span> &gt; <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">42</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.NumberGreaterOrEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">69</span> &gt;= <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">42</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n\n\n <!-- SEMVER -->\n\n <ng-container *ngSwitchCase=\"UserComparator.SemVerIsOneOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">1.0.0</span> IS ONE OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ <span class=\"match-val\">1.0.0</span>, 4.3.5 ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.SemVerIsNotOneOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">2.1.0</span> IS NOT ONE OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ 1.0.0, 4.3.5 ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.SemVerLess\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">1.0.0</span> &lt; <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">1.2.0</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.SemVerLessOrEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">1.0.0</span> &lt;= <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">1.2.0</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.SemVerGreater\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">1.0.0</span> &gt; <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">1.0.0-alpha</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.SemVerGreaterOrEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">1.2.0</span> &gt;= <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">1.1.0</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n\n <!-- DATETIME -->\n\n <ng-container *ngSwitchCase=\"UserComparator.DateTimeBefore\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">2020.11.05 10:36:24</span> BEFORE <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">2020.11.05 12:00:00</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.DateTimeAfter\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">2020.11.05 15:41:06</span> AFTER <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">2020.11.05 12:00:00</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n\n <!-- ARRAY -->\n\n <ng-container *ngSwitchCase=\"UserComparator.ArrayContainsAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">[ Writer, Reader ]</span> ARRAY CONTAINS ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ <span class=\"match-val\">Writer</span>, Admin ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.ArrayDoesNotContainAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">[ Guest, Reader ]</span> ARRAY NOT CONTAINS ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ Writer, Admin ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </mat-radio-group>\n </div>\n</ng-template>\n\n<ng-template #confidential>\n <p>Select how the <i>comparison values</i> should be persisted:</p>\n <div matTooltip=\"The currently selected comparator does not support hashed comparison values, they will be presented as cleartext in the config JSON.\"\n [matTooltipDisabled]=\"confidentialEnabled\">\n <mat-radio-group class=\"confidential-container\" (change)=\"confidentialChange($event.value)\">\n <div class=\"confidential item\" (click)=\"confidentialChange(true)\">\n <mat-radio-button color=\"primary\" [value]=\"true\" [checked]=\"isConfidential\" [disabled]=\"!confidentialEnabled || data.readOnly\">\n <div class=\"title\">\n <div class=\"text\">Hashed</div>\n <div class=\"icon\"><mat-icon>lock</mat-icon></div>\n </div>\n </mat-radio-button>\n <div class=\"description\">\n We recommend using this option in case of frontend applications targeting users based on sensitive data (like email addresses, names, etc). \n \n </div>\n </div>\n <div class=\"cleartext item\" (click)=\"confidentialChange(false)\">\n <mat-radio-button color=\"primary\" [value]=\"false\" [checked]=\"!isConfidential\" [disabled]=\"!confidentialEnabled || data.readOnly\">\n <div class=\"title\">\n <div class=\"text\">Cleartext</div>\n <div class=\"icon\"><mat-icon>lock_open_right</mat-icon></div>\n </div>\n </mat-radio-button>\n <div class=\"description\">\n You can use this option when you target users based on non-sensitive data. Comparison values will be presented as plain text in the <i>config JSON</i>.\n </div>\n </div>\n </mat-radio-group>\n </div>\n</ng-template>", styles: [".container{width:100%;padding:0 24px!important}.container .confidential-container{display:flex;flex-direction:row;margin-bottom:15px}.container .confidential-container .item{flex:50%;border:1px solid rgb(224,224,224);cursor:pointer;padding:5px 5px 10px;border-radius:5px}.container .confidential-container .confidential{margin-right:5px}.container .confidential-container .cleartext{margin-left:5px}.container .confidential-container .title{cursor:pointer;display:flex;flex-direction:row;align-items:center}.container .confidential-container .title .text{font-weight:700}.container .confidential-container .title .icon{margin-left:3px}.container .confidential-container .title .icon mat-icon{font-size:18px;width:18px;height:18px}.container .confidential-container .description{font-size:12px;padding-left:10px;line-height:16px}.container .comparator-container{display:flex;flex-direction:row;flex-wrap:wrap;width:100%}.container .comparator-container .item{flex:0 0 calc(50% - 17px);border:1px solid rgb(224,224,224);cursor:pointer;padding:5px 5px 10px;border-radius:5px;margin-bottom:10px}.container .comparator-container .col-0{margin-right:5px}.container .comparator-container .col-1{margin-left:5px}.container .comparator-container .title{cursor:pointer;font-weight:700}.container .comparator-container .description{font-size:12px;line-height:16px;padding-left:10px;cursor:pointer}.container .comparator-container .description .example{background-color:#f1f1f1;opacity:.8;padding:3px 5px;border-radius:5px;display:inline-block}.container .comparator-container .description .example .comp-attr{font-weight:600;font-style:italic;padding-right:3px}.container .comparator-container .description .example .comp-val{padding-left:3px;padding-right:3px;font-style:italic}.container .comparator-container .description .example .match-val{font-weight:600}.container .comparator-container .description .example .arrow{color:#636363}.container .comparator-container .selected{border-color:#f7a224}.tabs{margin:0 24px}.mat-button-toggle-group{flex-wrap:wrap}@media (max-width: 500px){.container .comparator-container .item{flex:100%}.container .comparator-container .col-0{margin-right:0}.container .comparator-container .col-1{margin-left:0}.container .confidential-container{flex-wrap:wrap}.container .confidential-container .item{flex:100%}.container .confidential-container .confidential{margin-right:0;margin-bottom:10px}.container .confidential-container .cleartext{margin-left:0}}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i7.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i7.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i8.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i8.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "directive", type: i9.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i9.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color"], outputs: ["change"], exportAs: ["matRadioButton"] }] }); }
105
+ }
106
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ComparatorDialogComponent, decorators: [{
107
+ type: Component,
108
+ args: [{ selector: 'app-comparator-dialog', template: "<h2 mat-dialog-title cdkDrag cdkDragRootElement=\".cdk-overlay-pane\" cdkDragHandle class=\"draggable\">Comparator selector</h2>\n<div class=\"tabs\">\n <mat-button-toggle-group [ngModel]=\"selectedGroup\" (ngModelChange)=\"changeGroup($event)\">\n <mat-button-toggle [value]=\"ComparatorGroup.Text\">Text</mat-button-toggle>\n <mat-button-toggle [value]=\"ComparatorGroup.Number\">Number</mat-button-toggle>\n <mat-button-toggle [value]=\"ComparatorGroup.Semver\">Semantic version</mat-button-toggle>\n <mat-button-toggle [value]=\"ComparatorGroup.DateTime\">Datetime</mat-button-toggle>\n <mat-button-toggle [value]=\"ComparatorGroup.Array\">Array</mat-button-toggle>\n </mat-button-toggle-group>\n</div>\n\n<div mat-dialog-content class=\"container\" [ngSwitch]=\"selectedGroup\">\n <div *ngSwitchCase=\"ComparatorGroup.Text\">\n <p>The following comparators assume that the <i>comparison attribute's</i> value (set on the SDK's <a href=\"https://configcat.com/docs/V2/targeting/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user object</a>) and the <i>comparison value</i> contain string/text.</p>\n <ng-container [ngTemplateOutlet]=\"comparators\" [ngTemplateOutletContext]=\"{group:ComparatorGroup.Text}\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"confidential\"></ng-container>\n </div>\n\n <div *ngSwitchCase=\"ComparatorGroup.Number\">\n <p>The following comparators assume that the <i>comparison attribute's</i> value (set on the SDK's <a href=\"https://configcat.com/docs/V2/targeting/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user object</a>) and the <i>comparison value</i> contain numbers.</p>\n <ng-container [ngTemplateOutlet]=\"comparators\" [ngTemplateOutletContext]=\"{group:ComparatorGroup.Number}\"></ng-container>\n </div>\n\n <div *ngSwitchCase=\"ComparatorGroup.Semver\">\n <p>The following comparators assume that the <i>comparison attribute's</i> value (set on the SDK's <a href=\"https://configcat.com/docs/V2/targeting/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user object</a>) and the <i>comparison value</i> contain semantic versions.</p>\n <ng-container [ngTemplateOutlet]=\"comparators\" [ngTemplateOutletContext]=\"{group:ComparatorGroup.Semver}\"></ng-container>\n </div>\n\n <div *ngSwitchCase=\"ComparatorGroup.DateTime\">\n <p>The following comparators assume that the <i>comparison attribute's</i> value (set on the SDK's <a href=\"https://configcat.com/docs/V2/targeting/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user object</a>) and the <i>comparison value</i> contain datetimes.</p>\n <ng-container [ngTemplateOutlet]=\"comparators\" [ngTemplateOutletContext]=\"{group:ComparatorGroup.DateTime}\"></ng-container>\n </div>\n\n <div *ngSwitchCase=\"ComparatorGroup.Array\">\n <p>The following comparators assume that the <i>comparison attribute's</i> value (set on the SDK's <a href=\"https://configcat.com/docs/V2/targeting/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user object</a>) and the <i>comparison value</i> contain items of a string/text list.</p>\n <ng-container [ngTemplateOutlet]=\"comparators\" [ngTemplateOutletContext]=\"{group:ComparatorGroup.Array}\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"confidential\"></ng-container>\n </div>\n</div>\n<div mat-dialog-actions>\n <button *ngIf=\"!data.readOnly\" type=\"button\" mat-flat-button color=\"primary\" (click)=\"set()\">Set</button>\n <button *ngIf=\"!data.readOnly\" type=\"button\" mat-stroked-button mat-dialog-close>Cancel</button>\n <button *ngIf=\"data.readOnly\" type=\"button\" mat-stroked-button color=\"primary\" mat-dialog-close>Close</button>\n</div>\n\n<ng-template #comparators let-group=\"group\">\n <div>\n <mat-radio-group (change)=\"comparatorChange($event.value)\">\n <div class=\"comparator-container\">\n <div class=\"item\" [ngClass]=\"'col-' + i % 2\" [class.selected]=\"comparator.value === selectedComparator\" \n *ngFor=\"let comparator of listComparators(group); let i = index\" (click)=\"comparatorChange(comparator.value)\"> \n <mat-radio-button color=\"primary\" [value]=\"comparator.value\" [disabled]=\"data.readOnly\"\n [checked]=\"comparator.value === selectedComparator\" [matTooltip]=\"comparator.description\">\n <div class=\"title\">\n {{comparator.label}}\n </div>\n </mat-radio-button>\n <div class=\"description\">\n <div class=\"example\">\n <ng-container [ngSwitch]=\"comparator.value\">\n\n <!-- TEXT -->\n <ng-container *ngSwitchCase=\"UserComparator.TextEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">bob&#64;foo.com</span> EQUALS <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">bob&#64;foo.com</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.TextDoesNotEqual\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">alice&#64;foo.com</span> NOT EQUALS <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">bob&#64;foo.com</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.IsOneOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">iOS</span> IS ONE OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ Android, macOS, <span class=\"match-val\">iOS</span> ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.IsNotOneOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">iOS</span> IS NOT ONE OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ Android, macOS, Windows ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.TextStartsWithAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">bob&#64;foo.com</span> STARTS WITH ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ <span class=\"match-val\">bob</span>, jane ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.TextNotStartsWithAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">alice&#64;foo.com</span> NOT STARTS WITH ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ bob, jane ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.TextEndsWithAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">bob&#64;foo.com</span> ENDS WITH ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ <span class=\"match-val\">&#64;foo.com</span>, &#64;bar.com ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.TextNotEndsWithAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">bob&#64;example.com</span> NOT ENDS WITH ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ &#64;foo.com, &#64;bar.com ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.ContainsAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">https://test-app.foo.com</span> CONTAINS ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ <span class=\"match-val\">test</span>, localhost ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.DoesNotContainAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">https://app.foo.com</span> DOES NOT CONTAINS ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ test, localhost ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n\n <!-- NUMBER -->\n\n <ng-container *ngSwitchCase=\"UserComparator.NumberEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">42</span> = <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">42</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.NumberDoesNotEqual\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">42</span> != <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">3.14</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.NumberLess\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">3.14</span> &lt; <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">42</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.NumberLessOrEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">3.14</span> &lt;= <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">42</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.NumberGreater\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">69</span> &gt; <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">42</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.NumberGreaterOrEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">69</span> &gt;= <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">42</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n\n\n <!-- SEMVER -->\n\n <ng-container *ngSwitchCase=\"UserComparator.SemVerIsOneOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">1.0.0</span> IS ONE OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ <span class=\"match-val\">1.0.0</span>, 4.3.5 ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.SemVerIsNotOneOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">2.1.0</span> IS NOT ONE OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ 1.0.0, 4.3.5 ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.SemVerLess\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">1.0.0</span> &lt; <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">1.2.0</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.SemVerLessOrEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">1.0.0</span> &lt;= <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">1.2.0</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.SemVerGreater\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">1.0.0</span> &gt; <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">1.0.0-alpha</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.SemVerGreaterOrEquals\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">1.2.0</span> &gt;= <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">1.1.0</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n\n <!-- DATETIME -->\n\n <ng-container *ngSwitchCase=\"UserComparator.DateTimeBefore\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">2020.11.05 10:36:24</span> BEFORE <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">2020.11.05 12:00:00</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.DateTimeAfter\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">2020.11.05 15:41:06</span> AFTER <span class=\"comp-val match-val\" [matTooltip]=\"comparisonValueTooltip\">2020.11.05 12:00:00</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n\n <!-- ARRAY -->\n\n <ng-container *ngSwitchCase=\"UserComparator.ArrayContainsAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">[ Writer, Reader ]</span> ARRAY CONTAINS ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ <span class=\"match-val\">Writer</span>, Admin ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n <ng-container *ngSwitchCase=\"UserComparator.ArrayDoesNotContainAnyOf\">\n <span class=\"comp-attr\" [matTooltip]=\"comparisonAttributeTooltip\">[ Guest, Reader ]</span> ARRAY NOT CONTAINS ANY OF <span class=\"comp-val\" [matTooltip]=\"comparisonValueTooltip\">[ Writer, Admin ]</span> <span class=\"arrow\">\u2794</span> match\n </ng-container>\n\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </mat-radio-group>\n </div>\n</ng-template>\n\n<ng-template #confidential>\n <p>Select how the <i>comparison values</i> should be persisted:</p>\n <div matTooltip=\"The currently selected comparator does not support hashed comparison values, they will be presented as cleartext in the config JSON.\"\n [matTooltipDisabled]=\"confidentialEnabled\">\n <mat-radio-group class=\"confidential-container\" (change)=\"confidentialChange($event.value)\">\n <div class=\"confidential item\" (click)=\"confidentialChange(true)\">\n <mat-radio-button color=\"primary\" [value]=\"true\" [checked]=\"isConfidential\" [disabled]=\"!confidentialEnabled || data.readOnly\">\n <div class=\"title\">\n <div class=\"text\">Hashed</div>\n <div class=\"icon\"><mat-icon>lock</mat-icon></div>\n </div>\n </mat-radio-button>\n <div class=\"description\">\n We recommend using this option in case of frontend applications targeting users based on sensitive data (like email addresses, names, etc). \n \n </div>\n </div>\n <div class=\"cleartext item\" (click)=\"confidentialChange(false)\">\n <mat-radio-button color=\"primary\" [value]=\"false\" [checked]=\"!isConfidential\" [disabled]=\"!confidentialEnabled || data.readOnly\">\n <div class=\"title\">\n <div class=\"text\">Cleartext</div>\n <div class=\"icon\"><mat-icon>lock_open_right</mat-icon></div>\n </div>\n </mat-radio-button>\n <div class=\"description\">\n You can use this option when you target users based on non-sensitive data. Comparison values will be presented as plain text in the <i>config JSON</i>.\n </div>\n </div>\n </mat-radio-group>\n </div>\n</ng-template>", styles: [".container{width:100%;padding:0 24px!important}.container .confidential-container{display:flex;flex-direction:row;margin-bottom:15px}.container .confidential-container .item{flex:50%;border:1px solid rgb(224,224,224);cursor:pointer;padding:5px 5px 10px;border-radius:5px}.container .confidential-container .confidential{margin-right:5px}.container .confidential-container .cleartext{margin-left:5px}.container .confidential-container .title{cursor:pointer;display:flex;flex-direction:row;align-items:center}.container .confidential-container .title .text{font-weight:700}.container .confidential-container .title .icon{margin-left:3px}.container .confidential-container .title .icon mat-icon{font-size:18px;width:18px;height:18px}.container .confidential-container .description{font-size:12px;padding-left:10px;line-height:16px}.container .comparator-container{display:flex;flex-direction:row;flex-wrap:wrap;width:100%}.container .comparator-container .item{flex:0 0 calc(50% - 17px);border:1px solid rgb(224,224,224);cursor:pointer;padding:5px 5px 10px;border-radius:5px;margin-bottom:10px}.container .comparator-container .col-0{margin-right:5px}.container .comparator-container .col-1{margin-left:5px}.container .comparator-container .title{cursor:pointer;font-weight:700}.container .comparator-container .description{font-size:12px;line-height:16px;padding-left:10px;cursor:pointer}.container .comparator-container .description .example{background-color:#f1f1f1;opacity:.8;padding:3px 5px;border-radius:5px;display:inline-block}.container .comparator-container .description .example .comp-attr{font-weight:600;font-style:italic;padding-right:3px}.container .comparator-container .description .example .comp-val{padding-left:3px;padding-right:3px;font-style:italic}.container .comparator-container .description .example .match-val{font-weight:600}.container .comparator-container .description .example .arrow{color:#636363}.container .comparator-container .selected{border-color:#f7a224}.tabs{margin:0 24px}.mat-button-toggle-group{flex-wrap:wrap}@media (max-width: 500px){.container .comparator-container .item{flex:100%}.container .comparator-container .col-0{margin-right:0}.container .comparator-container .col-1{margin-left:0}.container .confidential-container{flex-wrap:wrap}.container .confidential-container .item{flex:100%}.container .confidential-container .confidential{margin-right:0;margin-bottom:10px}.container .confidential-container .cleartext{margin-left:0}}\n"] }]
109
+ }], ctorParameters: () => [{ type: i1.MatDialogRef }, { type: undefined, decorators: [{
110
+ type: Inject,
111
+ args: [MAT_DIALOG_DATA]
112
+ }] }] });
113
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGFyYXRvci1kaWFsb2cuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctY29uZmlnY2F0LXB1YmxpY2FwaS11aS9zcmMvbGliL3YyL2ZlYXR1cmUtZmxhZy9ldmFsdWF0aW9uLWZvcm11bGEvdGFyZ2V0aW5nLXJ1bGUvY29uZGl0aW9ucy91c2VyLWNvbmRpdGlvbi9jb21wYXJhdG9yLWRpYWxvZy9jb21wYXJhdG9yLWRpYWxvZy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1jb25maWdjYXQtcHVibGljYXBpLXVpL3NyYy9saWIvdjIvZmVhdHVyZS1mbGFnL2V2YWx1YXRpb24tZm9ybXVsYS90YXJnZXRpbmctcnVsZS9jb25kaXRpb25zL3VzZXItY29uZGl0aW9uL2NvbXBhcmF0b3ItZGlhbG9nL2NvbXBhcmF0b3ItZGlhbG9nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sRUFBRSxlQUFlLEVBQWdCLE1BQU0sMEJBQTBCLENBQUM7QUFDekUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOzs7Ozs7Ozs7OztBQUVoRSxJQUFLLGVBTUo7QUFORCxXQUFLLGVBQWU7SUFDbEIscURBQVEsQ0FBQTtJQUNSLHlEQUFVLENBQUE7SUFDVix5REFBVSxDQUFBO0lBQ1YsNkRBQVksQ0FBQTtJQUNaLHVEQUFTLENBQUE7QUFDWCxDQUFDLEVBTkksZUFBZSxLQUFmLGVBQWUsUUFNbkI7QUFlRCxNQUFNLE9BQU8seUJBQXlCO0lBOENwQyxZQUNTLFNBQWtELEVBQ3pCLElBQVM7UUFEbEMsY0FBUyxHQUFULFNBQVMsQ0FBeUM7UUFDekIsU0FBSSxHQUFK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RlUseUJBQXlCLDhDQWdEMUIsZUFBZTtrR0FoRGQseUJBQXlCLDZEQ3pCdEMsbzhqQkFpTWM7OzJGRHhLRCx5QkFBeUI7a0JBTHJDLFNBQVM7K0JBQ0UsdUJBQXVCOzswQkFvRDlCLE1BQU07MkJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5qZWN0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE1BVF9ESUFMT0dfREFUQSwgTWF0RGlhbG9nUmVmIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IFVzZXJDb21wYXJhdG9yIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vLi4vYm9vdHN0cmFwJztcblxuZW51bSBDb21wYXJhdG9yR3JvdXAge1xuICBUZXh0ID0gMCxcbiAgTnVtYmVyID0gMSxcbiAgU2VtdmVyID0gMixcbiAgRGF0ZVRpbWUgPSAzLFxuICBBcnJheSA9IDRcbn1cblxuaW50ZXJmYWNlIENvbXBhcmF0b3JJdGVtIHtcbiAgdmFsdWU6IFVzZXJDb21wYXJhdG9yLFxuICBzZW5zaXRpdmVWYWx1ZT86IFVzZXJDb21wYXJhdG9yLFxuICBsYWJlbDogc3RyaW5nLFxuICBkZXNjcmlwdGlvbjogc3RyaW5nLFxuICBncm91cDogQ29tcGFyYXRvckdyb3VwLFxufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtY29tcGFyYXRvci1kaWFsb2cnLFxuICB0ZW1wbGF0ZVVybDogJy4vY29tcGFyYXRvci1kaWFsb2cuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jb21wYXJhdG9yLWRpYWxvZy5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBDb21wYXJhdG9yRGlhbG9nQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBDb21wYXJhdG9yR3JvdXAgPSBDb21wYXJhdG9yR3JvdXA7XG4gIHNlbGVjdGVkR3JvdXAgPSBDb21wYXJhdG9yR3JvdXAuVGV4dDtcbiAgc2VsZWN0ZWRDb21wYXJhdG9yID0gVXNlckNvbXBhcmF0b3IuVGV4dEVxdWFscztcbiAgaXNDb25maWRlbnRpYWwgPSB0cnVlO1xuICBsYXN0Q29uZmlkZW50aWFsVmFsdWUgPSB0cnVlO1xuICBjb25maWRlbnRpYWxFbmFibGVkID0gdHJ1ZTtcbiAgVXNlckNvbXBhcmF0b3IgPSBVc2VyQ29tcGFyYXRvcjtcblxuICBjb21wYXJpc29uQXR0cmlidXRlVG9vbHRpcCA9IFwiVXNlciBvYmplY3QncyB2YWx1ZSBwYXNzZWQgdG8gdGhlIFNESyAoQ29tcGFyaXNvbiBhdHRyaWJ1dGUpXCI7XG4gIGNvbXBhcmlzb25WYWx1ZVRvb2x0aXAgPSBcIkNvbXBhcmlzb24gdmFsdWUgc2V0IG9uIHRoZSBDb25maWdDYXQgRGFzaGJvYXJkXCI7XG5cbiAgY29tcGFyYXRvcnM6IENvbXBhcmF0b3JJdGVtW10gPSBbXG4gICAgeyB2YWx1ZTogVXNlckNvbXBhcmF0b3IuVGV4dEVxdWFscywgc2Vuc2l0aXZlVmFsdWU6IFVzZXJDb21wYXJhdG9yLlNlbnNpdGl2ZVRleHRFcXVhbHMsIGdyb3VwOiBDb21wYXJhdG9yR3JvdXAuVGV4dCwgbGFiZWw6ICdFUVVBTFMnLCBkZXNjcmlwdGlvbjogXCJNYXRjaGVzIHdoZW4gdGhlIHVzZXIgb2JqZWN0J3MgY29tcGFyaXNvbiBhdHRyaWJ1dGUgcGFzc2VkIHRvIHRoZSBTREsgaXMgZXF1YWwgdG8gdGhlIGNvbXBhcmlzb24gdmFsdWUgc2V0IG9uIHRoZSBDb25maWdDYXQgRGFzaGJvYXJkXCIgfSxcbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5UZXh0RG9lc05vdEVxdWFsLCBzZW5zaXRpdmVWYWx1ZTogVXNlckNvbXBhcmF0b3IuU2Vuc2l0aXZlVGV4dERvZXNOb3RFcXVhbCwgZ3JvdXA6IENvbXBhcmF0b3JHcm91cC5UZXh0LCBsYWJlbDogJ05PVCBFUVVBTFMnLCBkZXNjcmlwdGlvbjogXCJNYXRjaGVzIHdoZW4gdGhlIHVzZXIgb2JqZWN0J3MgY29tcGFyaXNvbiBhdHRyaWJ1dGUgcGFzc2VkIHRvIHRoZSBTREsgaXMgbm90IGVxdWFsIHRvIHRoZSBjb21wYXJpc29uIHZhbHVlXCIgfSxcbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5Jc09uZU9mLCBzZW5zaXRpdmVWYWx1ZTogVXNlckNvbXBhcmF0b3IuU2Vuc2l0aXZlSXNPbmVPZiwgZ3JvdXA6IENvbXBhcmF0b3JHcm91cC5UZXh0LCBsYWJlbDogJ0lTIE9ORSBPRicsIGRlc2NyaXB0aW9uOiBcIk1hdGNoZXMgd2hlbiB0aGUgdXNlciBvYmplY3QncyBjb21wYXJpc29uIGF0dHJpYnV0ZSBwYXNzZWQgdG8gdGhlIFNESyBpcyBlcXVhbCB0byBhbnkgb2YgdGhlIGNvbXBhcmlzb24gdmFsdWVzXCIgfSxcbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5Jc05vdE9uZU9mLCBzZW5zaXRpdmVWYWx1ZTogVXNlckNvbXBhcmF0b3IuU2Vuc2l0aXZlSXNOb3RPbmVPZiwgZ3JvdXA6IENvbXBhcmF0b3JHcm91cC5UZXh0LCBsYWJlbDogJ0lTIE5PVCBPTkUgT0YnLCBkZXNjcmlwdGlvbjogXCJNYXRjaGVzIHdoZW4gdGhlIHVzZXIgb2JqZWN0J3MgY29tcGFyaXNvbiBhdHRyaWJ1dGUgcGFzc2VkIHRvIHRoZSBTREsgaXMgbm90IGVxdWFsIHRvIGFueSBvZiB0aGUgY29tcGFyaXNvbiB2YWx1ZXNcIiB9LFxuICAgIHsgdmFsdWU6IFVzZXJDb21wYXJhdG9yLlRleHRTdGFydHNXaXRoQW55T2YsIHNlbnNpdGl2ZVZhbHVlOiBVc2VyQ29tcGFyYXRvci5TZW5zaXRpdmVUZXh0U3RhcnRzV2l0aEFueU9mLCBncm91cDogQ29tcGFyYXRvckdyb3VwLlRleHQsIGxhYmVsOiAnU1RBUlRTIFdJVEggQU5ZIE9GJywgZGVzY3JpcHRpb246IFwiTWF0Y2hlcyB3aGVuIHRoZSB1c2VyIG9iamVjdCdzIGNvbXBhcmlzb24gYXR0cmlidXRlIHBhc3NlZCB0byB0aGUgU0RLIHN0YXJ0cyB3aXRoIGFueSBvZiB0aGUgY29tcGFyaXNvbiB2YWx1ZXNcIiB9LFxuICAgIHsgdmFsdWU6IFVzZXJDb21wYXJhdG9yLlRleHROb3RTdGFydHNXaXRoQW55T2YsIHNlbnNpdGl2ZVZhbHVlOiBVc2VyQ29tcGFyYXRvci5TZW5zaXRpdmVUZXh0Tm90U3RhcnRzV2l0aEFueU9mLCBncm91cDogQ29tcGFyYXRvckdyb3VwLlRleHQsIGxhYmVsOiAnTk9UIFNUQVJUUyBXSVRIIEFOWSBPRicsIGRlc2NyaXB0aW9uOiBcIk1hdGNoZXMgd2hlbiB0aGUgdXNlciBvYmplY3QncyBjb21wYXJpc29uIGF0dHJpYnV0ZSBwYXNzZWQgdG8gdGhlIFNESyBkb2VzIG5vdCBzdGFydCB3aXRoIGFueSBvZiB0aGUgY29tcGFyaXNvbiB2YWx1ZXNcIiB9LFxuICAgIHsgdmFsdWU6IFVzZXJDb21wYXJhdG9yLlRleHRFbmRzV2l0aEFueU9mLCBzZW5zaXRpdmVWYWx1ZTogVXNlckNvbXBhcmF0b3IuU2Vuc2l0aXZlVGV4dEVuZHNXaXRoQW55T2YsIGdyb3VwOiBDb21wYXJhdG9yR3JvdXAuVGV4dCwgbGFiZWw6ICdFTkRTIFdJVEggQU5ZIE9GJywgZGVzY3JpcHRpb246IFwiTWF0Y2hlcyB3aGVuIHRoZSB1c2VyIG9iamVjdCdzIGNvbXBhcmlzb24gYXR0cmlidXRlIHBhc3NlZCB0byB0aGUgU0RLIGVuZHMgd2l0aCBhbnkgb2YgdGhlIGNvbXBhcmlzb24gdmFsdWVzXCIgfSxcbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5UZXh0Tm90RW5kc1dpdGhBbnlPZiwgc2Vuc2l0aXZlVmFsdWU6IFVzZXJDb21wYXJhdG9yLlNlbnNpdGl2ZVRleHROb3RFbmRzV2l0aEFueU9mLCBncm91cDogQ29tcGFyYXRvckdyb3VwLlRleHQsIGxhYmVsOiAnTk9UIEVORFMgV0lUSCBBTlkgT0YnLCBkZXNjcmlwdGlvbjogXCJNYXRjaGVzIHdoZW4gdGhlIHVzZXIgb2JqZWN0J3MgY29tcGFyaXNvbiBhdHRyaWJ1dGUgcGFzc2VkIHRvIHRoZSBTREsgZG9lcyBub3QgZW5kIHdpdGggYW55IG9mIHRoZSBjb21wYXJpc29uIHZhbHVlc1wiIH0sXG4gICAgeyB2YWx1ZTogVXNlckNvbXBhcmF0b3IuQ29udGFpbnNBbnlPZiwgZ3JvdXA6IENvbXBhcmF0b3JHcm91cC5UZXh0LCBsYWJlbDogJ0NPTlRBSU5TIEFOWSBPRicsIGRlc2NyaXB0aW9uOiBcIk1hdGNoZXMgd2hlbiB0aGUgdXNlciBvYmplY3QncyBjb21wYXJpc29uIGF0dHJpYnV0ZSBwYXNzZWQgdG8gdGhlIFNESyBjb250YWlucyBhbnkgY29tcGFyaXNvbiB2YWx1ZXMgYXMgYSBzdWJzdHJpbmdcIiB9LFxuICAgIHsgdmFsdWU6IFVzZXJDb21wYXJhdG9yLkRvZXNOb3RDb250YWluQW55T2YsIGdyb3VwOiBDb21wYXJhdG9yR3JvdXAuVGV4dCwgbGFiZWw6ICdET0VTIE5PVCBDT05UQUlOIEFOWSBPRicsIGRlc2NyaXB0aW9uOiBcIk1hdGNoZXMgd2hlbiB0aGUgdXNlciBvYmplY3QncyBjb21wYXJpc29uIGF0dHJpYnV0ZSBwYXNzZWQgdG8gdGhlIFNESyBkb2VzIG5vdCBjb250YWluIGFueSBjb21wYXJpc29uIHZhbHVlcyBhcyBhIHN1YnN0cmluZ1wiIH0sXG5cbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5OdW1iZXJFcXVhbHMsIGdyb3VwOiBDb21wYXJhdG9yR3JvdXAuTnVtYmVyLCBsYWJlbDogJz0gKEVRVUFMUyknLCBkZXNjcmlwdGlvbjogXCJNYXRjaGVzIHdoZW4gdGhlIHVzZXIgb2JqZWN0J3MgY29tcGFyaXNvbiBhdHRyaWJ1dGUgcGFzc2VkIHRvIHRoZSBTREsgKGludGVycHJldGVkIGFzIGEgZGVjaW1hbCBudW1iZXIpIGlzIGVxdWFsIHRvIHRoZSBjb21wYXJpc29uIHZhbHVlXCIgfSxcbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5OdW1iZXJEb2VzTm90RXF1YWwsIGdyb3VwOiBDb21wYXJhdG9yR3JvdXAuTnVtYmVyLCBsYWJlbDogJyE9IChOT1QgRVFVQUxTKScsIGRlc2NyaXB0aW9uOiBcIk1hdGNoZXMgd2hlbiB0aGUgdXNlciBvYmplY3QncyBjb21wYXJpc29uIGF0dHJpYnV0ZSBwYXNzZWQgdG8gdGhlIFNESyAoaW50ZXJwcmV0ZWQgYXMgYSBkZWNpbWFsIG51bWJlcikgaXMgbm90IGVxdWFsIHRvIHRoZSBjb21wYXJpc29uIHZhbHVlXCIgfSxcbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5OdW1iZXJMZXNzLCBncm91cDogQ29tcGFyYXRvckdyb3VwLk51bWJlciwgbGFiZWw6ICc8IChMRVNTIFRIQU4pJywgZGVzY3JpcHRpb246IFwiTWF0Y2hlcyB3aGVuIHRoZSB1c2VyIG9iamVjdCdzIGNvbXBhcmlzb24gYXR0cmlidXRlIHBhc3NlZCB0byB0aGUgU0RLIChpbnRlcnByZXRlZCBhcyBhIGRlY2ltYWwgbnVtYmVyKSBpcyBsZXNzIHRoYW4gdGhlIGNvbXBhcmlzb24gdmFsdWVcIiB9LFxuICAgIHsgdmFsdWU6IFVzZXJDb21wYXJhdG9yLk51bWJlckxlc3NPckVxdWFscywgZ3JvdXA6IENvbXBhcmF0b3JHcm91cC5OdW1iZXIsIGxhYmVsOiAnPD0gKExFU1MgVEhBTiBPUiBFUVVBTCknLCBkZXNjcmlwdGlvbjogXCJNYXRjaGVzIHdoZW4gdGhlIHVzZXIgb2JqZWN0J3MgY29tcGFyaXNvbiBhdHRyaWJ1dGUgcGFzc2VkIHRvIHRoZSBTREsgKGludGVycHJldGVkIGFzIGEgZGVjaW1hbCBudW1iZXIpIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgY29tcGFyaXNvbiB2YWx1ZVwiIH0sXG4gICAgeyB2YWx1ZTogVXNlckNvbXBhcmF0b3IuTnVtYmVyR3JlYXRlciwgZ3JvdXA6IENvbXBhcmF0b3JHcm91cC5OdW1iZXIsIGxhYmVsOiAnPiAoR1JFQVRFUiBUSEFOKScsIGRlc2NyaXB0aW9uOiBcIk1hdGNoZXMgd2hlbiB0aGUgdXNlciBvYmplY3QncyBjb21wYXJpc29uIGF0dHJpYnV0ZSBwYXNzZWQgdG8gdGhlIFNESyAoaW50ZXJwcmV0ZWQgYXMgYSBkZWNpbWFsIG51bWJlcikgaXMgZ3JlYXRlciB0aGFuIHRoZSBjb21wYXJpc29uIHZhbHVlXCIgfSxcbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5OdW1iZXJHcmVhdGVyT3JFcXVhbHMsIGdyb3VwOiBDb21wYXJhdG9yR3JvdXAuTnVtYmVyLCBsYWJlbDogJz49IChHUkFURVIgVEhBTiBPUiBFUVVBTCknLCBkZXNjcmlwdGlvbjogXCJNYXRjaGVzIHdoZW4gdGhlIHVzZXIgb2JqZWN0J3MgY29tcGFyaXNvbiBhdHRyaWJ1dGUgcGFzc2VkIHRvIHRoZSBTREsgKGludGVycHJldGVkIGFzIGEgZGVjaW1hbCBudW1iZXIpIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgY29tcGFyaXNvbiB2YWx1ZVwiIH0sXG5cbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5TZW1WZXJJc09uZU9mLCBncm91cDogQ29tcGFyYXRvckdyb3VwLlNlbXZlciwgbGFiZWw6ICdJUyBPTkUgT0YnLCBkZXNjcmlwdGlvbjogXCJNYXRjaGVzIHdoZW4gdGhlIHVzZXIgb2JqZWN0J3MgY29tcGFyaXNvbiBhdHRyaWJ1dGUgcGFzc2VkIHRvIHRoZSBTREsgKGludGVycHJldGVkIGFzIGEgc2VtYW50aWMgdmVyc2lvbikgaXMgZXF1YWwgdG8gYW55IG9mIHRoZSBjb21wYXJpc29uIHZhbHVlc1wiIH0sXG4gICAgeyB2YWx1ZTogVXNlckNvbXBhcmF0b3IuU2VtVmVySXNOb3RPbmVPZiwgZ3JvdXA6IENvbXBhcmF0b3JHcm91cC5TZW12ZXIsIGxhYmVsOiAnSVMgTk9UIE9ORSBPRicsIGRlc2NyaXB0aW9uOiBcIk1hdGNoZXMgd2hlbiB0aGUgdXNlciBvYmplY3QncyBjb21wYXJpc29uIGF0dHJpYnV0ZSBwYXNzZWQgdG8gdGhlIFNESyAoaW50ZXJwcmV0ZWQgYXMgYSBzZW1hbnRpYyB2ZXJzaW9uKSBpcyBub3QgZXF1YWwgdG8gYW55IG9mIHRoZSBjb21wYXJpc29uIHZhbHVlc1wiIH0sXG4gICAgeyB2YWx1ZTogVXNlckNvbXBhcmF0b3IuU2VtVmVyTGVzcywgZ3JvdXA6IENvbXBhcmF0b3JHcm91cC5TZW12ZXIsIGxhYmVsOiAnPCAoTEVTUyBUSEFOKScsIGRlc2NyaXB0aW9uOiBcIk1hdGNoZXMgd2hlbiB0aGUgdXNlciBvYmplY3QncyBjb21wYXJpc29uIGF0dHJpYnV0ZSBwYXNzZWQgdG8gdGhlIFNESyAoaW50ZXJwcmV0ZWQgYXMgYSBzZW1hbnRpYyB2ZXJzaW9uKSBpcyBsZXNzIHRoYW4gdGhlIGNvbXBhcmlzb24gdmFsdWVcIiB9LFxuICAgIHsgdmFsdWU6IFVzZXJDb21wYXJhdG9yLlNlbVZlckxlc3NPckVxdWFscywgZ3JvdXA6IENvbXBhcmF0b3JHcm91cC5TZW12ZXIsIGxhYmVsOiAnPD0gKExFU1MgVEhBTiBPUiBFUVVBTCknLCBkZXNjcmlwdGlvbjogXCJNYXRjaGVzIHdoZW4gdGhlIHVzZXIgb2JqZWN0J3MgY29tcGFyaXNvbiBhdHRyaWJ1dGUgcGFzc2VkIHRvIHRoZSBTREsgKGludGVycHJldGVkIGFzIGEgc2VtYW50aWMgdmVyc2lvbikgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBjb21wYXJpc29uIHZhbHVlXCIgfSxcbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5TZW1WZXJHcmVhdGVyLCBncm91cDogQ29tcGFyYXRvckdyb3VwLlNlbXZlciwgbGFiZWw6ICc+IChHUkVBVEVSIFRIQU4pJywgZGVzY3JpcHRpb246IFwiTWF0Y2hlcyB3aGVuIHRoZSB1c2VyIG9iamVjdCdzIGNvbXBhcmlzb24gYXR0cmlidXRlIHBhc3NlZCB0byB0aGUgU0RLIChpbnRlcnByZXRlZCBhcyBhIHNlbWFudGljIHZlcnNpb24pIGlzIGdyZWF0ZXIgdGhhbiB0aGUgY29tcGFyaXNvbiB2YWx1ZVwiIH0sXG4gICAgeyB2YWx1ZTogVXNlckNvbXBhcmF0b3IuU2VtVmVyR3JlYXRlck9yRXF1YWxzLCBncm91cDogQ29tcGFyYXRvckdyb3VwLlNlbXZlciwgbGFiZWw6ICc+PSAoR1JBVEVSIFRIQU4gT1IgRVFVQUwpJywgZGVzY3JpcHRpb246IFwiTWF0Y2hlcyB3aGVuIHRoZSB1c2VyIG9iamVjdCdzIGNvbXBhcmlzb24gYXR0cmlidXRlIHBhc3NlZCB0byB0aGUgU0RLIChpbnRlcnByZXRlZCBhcyBhIHNlbWFudGljIHZlcnNpb24pIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgY29tcGFyaXNvbiB2YWx1ZVwiIH0sXG5cbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5EYXRlVGltZUJlZm9yZSwgZ3JvdXA6IENvbXBhcmF0b3JHcm91cC5EYXRlVGltZSwgbGFiZWw6ICdCRUZPUkUgKFVUQyknLCBkZXNjcmlwdGlvbjogXCJNYXRjaGVzIHdoZW4gdGhlIHVzZXIgb2JqZWN0J3MgY29tcGFyaXNvbiBhdHRyaWJ1dGUgcGFzc2VkIHRvIHRoZSBTREsgKGludGVycHJldGVkIGFzIHRoZSBzZWNvbmRzIGVsYXBzZWQgc2luY2UgVW5peCBFcG9jaCkgaXMgbGVzcyB0aGFuIHRoZSBjb21wYXJpc29uIHZhbHVlXCIgfSxcbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5EYXRlVGltZUFmdGVyLCBncm91cDogQ29tcGFyYXRvckdyb3VwLkRhdGVUaW1lLCBsYWJlbDogJ0FGVEVSIChVVEMpJywgZGVzY3JpcHRpb246IFwiTWF0Y2hlcyB3aGVuIHRoZSB1c2VyIG9iamVjdCdzIGNvbXBhcmlzb24gYXR0cmlidXRlIHBhc3NlZCB0byB0aGUgU0RLIChpbnRlcnByZXRlZCBhcyB0aGUgc2Vjb25kcyBlbGFwc2VkIHNpbmNlIFVuaXggRXBvY2gpIGlzIGdyZWF0ZXIgdGhhbiB0aGUgY29tcGFyaXNvbiB2YWx1ZS52YWx1ZVwiIH0sXG5cbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5BcnJheUNvbnRhaW5zQW55T2YsIGdyb3VwOiBDb21wYXJhdG9yR3JvdXAuQXJyYXksIHNlbnNpdGl2ZVZhbHVlOiBVc2VyQ29tcGFyYXRvci5TZW5zaXRpdmVBcnJheUNvbnRhaW5zQW55T2YsIGxhYmVsOiAnQVJSQVkgQ09OVEFJTlMgQU5ZIE9GJywgZGVzY3JpcHRpb246IFwiTWF0Y2hlcyB3aGVuIHRoZSB1c2VyIG9iamVjdCdzIGNvbXBhcmlzb24gYXR0cmlidXRlIHBhc3NlZCB0byB0aGUgU0RLIChpbnRlcnByZXRlZCBhcyBhIHN0cmluZyBsaXN0KSBjb250YWlucyBhbnkgb2YgdGhlIGNvbXBhcmlzb24gdmFsdWVzXCIgfSxcbiAgICB7IHZhbHVlOiBVc2VyQ29tcGFyYXRvci5BcnJheURvZXNOb3RDb250YWluQW55T2YsIGdyb3VwOiBDb21wYXJhdG9yR3JvdXAuQXJyYXksIHNlbnNpdGl2ZVZhbHVlOiBVc2VyQ29tcGFyYXRvci5TZW5zaXRpdmVBcnJheURvZXNOb3RDb250YWluQW55T2YsIGxhYmVsOiAnQVJSQVkgTk9UIENPTlRBSU5TIEFOWSBPRicsIGRlc2NyaXB0aW9uOiBcIk1hdGNoZXMgd2hlbiB0aGUgdXNlciBvYmplY3QncyBjb21wYXJpc29uIGF0dHJpYnV0ZSBwYXNzZWQgdG8gdGhlIFNESyAoaW50ZXJwcmV0ZWQgYXMgYSBzdHJpbmcgbGlzdCkgZG9lcyBub3QgY29udGFpbiBhbnkgb2YgdGhlIGNvbXBhcmlzb24gdmFsdWVzXCIgfSxcbiAgXVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBkaWFsb2dSZWY6IE1hdERpYWxvZ1JlZjxDb21wYXJhdG9yRGlhbG9nQ29tcG9uZW50PixcbiAgICBASW5qZWN0KE1BVF9ESUFMT0dfREFUQSkgcHVibGljIGRhdGE6IGFueSkgeyB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLmNvbXBhcmF0b3JzLmZpbmQoYyA9PiBjLnZhbHVlID09PSB0aGlzLmRhdGEuc2VsZWN0ZWRDb21wYXJhdG9yIHx8IGMuc2Vuc2l0aXZlVmFsdWUgPT09IHRoaXMuZGF0YS5zZWxlY3RlZENvbXBhcmF0b3IpO1xuICAgIHRoaXMuc2VsZWN0ZWRHcm91cCA9IHNlbGVjdGVkLmdyb3VwO1xuICAgIHRoaXMuc2VsZWN0ZWRDb21wYXJhdG9yID0gc2VsZWN0ZWQudmFsdWU7XG4gICAgdGhpcy5pc0NvbmZpZGVudGlhbCA9IHRoaXMuZGF0YS5zZWxlY3RlZENvbXBhcmF0b3IgPT09IHNlbGVjdGVkLnNlbnNpdGl2ZVZhbHVlO1xuICAgIHRoaXMubGFzdENvbmZpZGVudGlhbFZhbHVlID0gIXNlbGVjdGVkLnNlbnNpdGl2ZVZhbHVlID8gdHJ1ZSA6IHRoaXMuaXNDb25maWRlbnRpYWw7XG4gICAgdGhpcy5jb25maWRlbnRpYWxFbmFibGVkID0gISFzZWxlY3RlZC5zZW5zaXRpdmVWYWx1ZTtcbiAgfVxuXG4gIGxpc3RDb21wYXJhdG9ycyhncm91cDogQ29tcGFyYXRvckdyb3VwKTogQ29tcGFyYXRvckl0ZW1bXSB7XG4gICAgcmV0dXJuIHRoaXMuY29tcGFyYXRvcnMuZmlsdGVyKGMgPT4gYy5ncm91cCA9PT0gZ3JvdXApO1xuICB9XG5cbiAgY2hhbmdlR3JvdXAoZ3JvdXA6IENvbXBhcmF0b3JHcm91cCk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0ZWRHcm91cCA9IGdyb3VwO1xuICB9XG5cbiAgY29uZmlkZW50aWFsQ2hhbmdlKGNvbmZpZGVudGlhbDogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb25maWRlbnRpYWxFbmFibGVkIHx8IHRoaXMuZGF0YS5yZWFkT25seSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmlzQ29uZmlkZW50aWFsID0gdGhpcy5sYXN0Q29uZmlkZW50aWFsVmFsdWUgPSBjb25maWRlbnRpYWw7XG4gIH1cblxuICBjb21wYXJhdG9yQ2hhbmdlKGNvbXA6IFVzZXJDb21wYXJhdG9yKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGF0YS5yZWFkT25seSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2VsZWN0ZWRDb21wYXJhdG9yID0gY29tcDtcbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuY29tcGFyYXRvcnMuZmluZChjID0+IGMudmFsdWUgPT09IGNvbXAgfHwgYy5zZW5zaXRpdmVWYWx1ZSA9PT0gY29tcCk7XG4gICAgdGhpcy5jb25maWRlbnRpYWxFbmFibGVkID0gISFzZWxlY3RlZC5zZW5zaXRpdmVWYWx1ZTtcbiAgICBpZiAoIXRoaXMuY29uZmlkZW50aWFsRW5hYmxlZCkge1xuICAgICAgdGhpcy5pc0NvbmZpZGVudGlhbCA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmlzQ29uZmlkZW50aWFsID0gdGhpcy5sYXN0Q29uZmlkZW50aWFsVmFsdWU7XG4gICAgfVxuICB9XG5cbiAgc2V0KCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5jb21wYXJhdG9ycy5maW5kKGMgPT4gYy52YWx1ZSA9PT0gdGhpcy5zZWxlY3RlZENvbXBhcmF0b3IgfHwgYy5zZW5zaXRpdmVWYWx1ZSA9PT0gdGhpcy5zZWxlY3RlZENvbXBhcmF0b3IpO1xuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuaXNDb25maWRlbnRpYWwgJiYgc2VsZWN0ZWQuc2Vuc2l0aXZlVmFsdWUgPyBzZWxlY3RlZC5zZW5zaXRpdmVWYWx1ZSA6IHNlbGVjdGVkLnZhbHVlO1xuICAgIHRoaXMuZGlhbG9nUmVmLmNsb3NlKHJlc3VsdCk7XG4gIH1cbn1cbiIsIjxoMiBtYXQtZGlhbG9nLXRpdGxlIGNka0RyYWcgY2RrRHJhZ1Jvb3RFbGVtZW50PVwiLmNkay1vdmVybGF5LXBhbmVcIiBjZGtEcmFnSGFuZGxlIGNsYXNzPVwiZHJhZ2dhYmxlXCI+Q29tcGFyYXRvciBzZWxlY3RvcjwvaDI+XG48ZGl2IGNsYXNzPVwidGFic1wiPlxuICAgIDxtYXQtYnV0dG9uLXRvZ2dsZS1ncm91cCBbbmdNb2RlbF09XCJzZWxlY3RlZEdyb3VwXCIgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlR3JvdXAoJGV2ZW50KVwiPlxuICAgICAgICA8bWF0LWJ1dHRvbi10b2dnbGUgW3ZhbHVlXT1cIkNvbXBhcmF0b3JHcm91cC5UZXh0XCI+VGV4dDwvbWF0LWJ1dHRvbi10b2dnbGU+XG4gICAgICAgIDxtYXQtYnV0dG9uLXRvZ2dsZSBbdmFsdWVdPVwiQ29tcGFyYXRvckdyb3VwLk51bWJlclwiPk51bWJlcjwvbWF0LWJ1dHRvbi10b2dnbGU+XG4gICAgICAgIDxtYXQtYnV0dG9uLXRvZ2dsZSBbdmFsdWVdPVwiQ29tcGFyYXRvckdyb3VwLlNlbXZlclwiPlNlbWFudGljIHZlcnNpb248L21hdC1idXR0b24tdG9nZ2xlPlxuICAgICAgICA8bWF0LWJ1dHRvbi10b2dnbGUgW3ZhbHVlXT1cIkNvbXBhcmF0b3JHcm91cC5EYXRlVGltZVwiPkRhdGV0aW1lPC9tYXQtYnV0dG9uLXRvZ2dsZT5cbiAgICAgICAgPG1hdC1idXR0b24tdG9nZ2xlIFt2YWx1ZV09XCJDb21wYXJhdG9yR3JvdXAuQXJyYXlcIj5BcnJheTwvbWF0LWJ1dHRvbi10b2dnbGU+XG4gICAgPC9tYXQtYnV0dG9uLXRvZ2dsZS1ncm91cD5cbjwvZGl2PlxuXG48ZGl2IG1hdC1kaWFsb2ctY29udGVudCBjbGFzcz1cImNvbnRhaW5lclwiIFtuZ1N3aXRjaF09XCJzZWxlY3RlZEdyb3VwXCI+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiQ29tcGFyYXRvckdyb3VwLlRleHRcIj5cbiAgICAgICAgPHA+VGhlIGZvbGxvd2luZyBjb21wYXJhdG9ycyBhc3N1bWUgdGhhdCB0aGUgPGk+Y29tcGFyaXNvbiBhdHRyaWJ1dGUnczwvaT4gdmFsdWUgKHNldCBvbiB0aGUgU0RLJ3MgPGEgaHJlZj1cImh0dHBzOi8vY29uZmlnY2F0LmNvbS9kb2NzL1YyL3RhcmdldGluZy91c2VyLW9iamVjdFwiIHRhcmdldD1cIl9ibGFua1wiIHJlbD1cIm5vb3BlbmVyIG5vcmVmZXJyZXJcIj51c2VyIG9iamVjdDwvYT4pIGFuZCB0aGUgPGk+Y29tcGFyaXNvbiB2YWx1ZTwvaT4gY29udGFpbiBzdHJpbmcvdGV4dC48L3A+XG4gICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29tcGFyYXRvcnNcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2dyb3VwOkNvbXBhcmF0b3JHcm91cC5UZXh0fVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbmZpZGVudGlhbFwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiQ29tcGFyYXRvckdyb3VwLk51bWJlclwiPlxuICAgICAgICA8cD5UaGUgZm9sbG93aW5nIGNvbXBhcmF0b3JzIGFzc3VtZSB0aGF0IHRoZSA8aT5jb21wYXJpc29uIGF0dHJpYnV0ZSdzPC9pPiB2YWx1ZSAoc2V0IG9uIHRoZSBTREsncyA8YSBocmVmPVwiaHR0cHM6Ly9jb25maWdjYXQuY29tL2RvY3MvVjIvdGFyZ2V0aW5nL3VzZXItb2JqZWN0XCIgdGFyZ2V0PVwiX2JsYW5rXCIgcmVsPVwibm9vcGVuZXIgbm9yZWZlcnJlclwiPnVzZXIgb2JqZWN0PC9hPikgYW5kIHRoZSA8aT5jb21wYXJpc29uIHZhbHVlPC9pPiBjb250YWluIG51bWJlcnMuPC9wPlxuICAgICAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbXBhcmF0b3JzXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntncm91cDpDb21wYXJhdG9yR3JvdXAuTnVtYmVyfVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiQ29tcGFyYXRvckdyb3VwLlNlbXZlclwiPlxuICAgICAgICA8cD5UaGUgZm9sbG93aW5nIGNvbXBhcmF0b3JzIGFzc3VtZSB0aGF0IHRoZSA8aT5jb21wYXJpc29uIGF0dHJpYnV0ZSdzPC9pPiB2YWx1ZSAoc2V0IG9uIHRoZSBTREsncyA8YSBocmVmPVwiaHR0cHM6Ly9jb25maWdjYXQuY29tL2RvY3MvVjIvdGFyZ2V0aW5nL3VzZXItb2JqZWN0XCIgdGFyZ2V0PVwiX2JsYW5rXCIgcmVsPVwibm9vcGVuZXIgbm9yZWZlcnJlclwiPnVzZXIgb2JqZWN0PC9hPikgYW5kIHRoZSA8aT5jb21wYXJpc29uIHZhbHVlPC9pPiBjb250YWluIHNlbWFudGljIHZlcnNpb25zLjwvcD5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjb21wYXJhdG9yc1wiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7Z3JvdXA6Q29tcGFyYXRvckdyb3VwLlNlbXZlcn1cIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkNvbXBhcmF0b3JHcm91cC5EYXRlVGltZVwiPlxuICAgICAgICA8cD5UaGUgZm9sbG93aW5nIGNvbXBhcmF0b3JzIGFzc3VtZSB0aGF0IHRoZSA8aT5jb21wYXJpc29uIGF0dHJpYnV0ZSdzPC9pPiB2YWx1ZSAoc2V0IG9uIHRoZSBTREsncyA8YSBocmVmPVwiaHR0cHM6Ly9jb25maWdjYXQuY29tL2RvY3MvVjIvdGFyZ2V0aW5nL3VzZXItb2JqZWN0XCIgdGFyZ2V0PVwiX2JsYW5rXCIgcmVsPVwibm9vcGVuZXIgbm9yZWZlcnJlclwiPnVzZXIgb2JqZWN0PC9hPikgYW5kIHRoZSA8aT5jb21wYXJpc29uIHZhbHVlPC9pPiBjb250YWluIGRhdGV0aW1lcy48L3A+XG4gICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29tcGFyYXRvcnNcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2dyb3VwOkNvbXBhcmF0b3JHcm91cC5EYXRlVGltZX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkNvbXBhcmF0b3JHcm91cC5BcnJheVwiPlxuICAgICAgICA8cD5UaGUgZm9sbG93aW5nIGNvbXBhcmF0b3JzIGFzc3VtZSB0aGF0IHRoZSA8aT5jb21wYXJpc29uIGF0dHJpYnV0ZSdzPC9pPiB2YWx1ZSAoc2V0IG9uIHRoZSBTREsncyA8YSBocmVmPVwiaHR0cHM6Ly9jb25maWdjYXQuY29tL2RvY3MvVjIvdGFyZ2V0aW5nL3VzZXItb2JqZWN0XCIgdGFyZ2V0PVwiX2JsYW5rXCIgcmVsPVwibm9vcGVuZXIgbm9yZWZlcnJlclwiPnVzZXIgb2JqZWN0PC9hPikgYW5kIHRoZSA8aT5jb21wYXJpc29uIHZhbHVlPC9pPiBjb250YWluIGl0ZW1zIG9mIGEgc3RyaW5nL3RleHQgbGlzdC48L3A+XG4gICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29tcGFyYXRvcnNcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2dyb3VwOkNvbXBhcmF0b3JHcm91cC5BcnJheX1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjb25maWRlbnRpYWxcIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuPGRpdiBtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgPGJ1dHRvbiAqbmdJZj1cIiFkYXRhLnJlYWRPbmx5XCIgdHlwZT1cImJ1dHRvblwiIG1hdC1mbGF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwic2V0KClcIj5TZXQ8L2J1dHRvbj5cbiAgICA8YnV0dG9uICpuZ0lmPVwiIWRhdGEucmVhZE9ubHlcIiB0eXBlPVwiYnV0dG9uXCIgbWF0LXN0cm9rZWQtYnV0dG9uIG1hdC1kaWFsb2ctY2xvc2U+Q2FuY2VsPC9idXR0b24+XG4gICAgPGJ1dHRvbiAqbmdJZj1cImRhdGEucmVhZE9ubHlcIiB0eXBlPVwiYnV0dG9uXCIgbWF0LXN0cm9rZWQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIG1hdC1kaWFsb2ctY2xvc2U+Q2xvc2U8L2J1dHRvbj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI2NvbXBhcmF0b3JzIGxldC1ncm91cD1cImdyb3VwXCI+XG4gICAgPGRpdj5cbiAgICAgICAgPG1hdC1yYWRpby1ncm91cCAoY2hhbmdlKT1cImNvbXBhcmF0b3JDaGFuZ2UoJGV2ZW50LnZhbHVlKVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBhcmF0b3ItY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIml0ZW1cIiBbbmdDbGFzc109XCInY29sLScgKyBpICUgMlwiIFtjbGFzcy5zZWxlY3RlZF09XCJjb21wYXJhdG9yLnZhbHVlID09PSBzZWxlY3RlZENvbXBhcmF0b3JcIiBcbiAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNvbXBhcmF0b3Igb2YgbGlzdENvbXBhcmF0b3JzKGdyb3VwKTsgbGV0IGkgPSBpbmRleFwiIChjbGljayk9XCJjb21wYXJhdG9yQ2hhbmdlKGNvbXBhcmF0b3IudmFsdWUpXCI+ICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1yYWRpby1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgW3ZhbHVlXT1cImNvbXBhcmF0b3IudmFsdWVcIiBbZGlzYWJsZWRdPVwiZGF0YS5yZWFkT25seVwiXG4gICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImNvbXBhcmF0b3IudmFsdWUgPT09IHNlbGVjdGVkQ29tcGFyYXRvclwiIFttYXRUb29sdGlwXT1cImNvbXBhcmF0b3IuZGVzY3JpcHRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Y29tcGFyYXRvci5sYWJlbH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtcmFkaW8tYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGVzY3JpcHRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJleGFtcGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdTd2l0Y2hdPVwiY29tcGFyYXRvci52YWx1ZVwiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gVEVYVCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiVXNlckNvbXBhcmF0b3IuVGV4dEVxdWFsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb21wLWF0dHJcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uQXR0cmlidXRlVG9vbHRpcFwiPmJvYiYjNjQ7Zm9vLmNvbTwvc3Bhbj4gRVFVQUxTIDxzcGFuIGNsYXNzPVwiY29tcC12YWwgbWF0Y2gtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPmJvYiYjNjQ7Zm9vLmNvbTwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJhcnJvd1wiPuKelDwvc3Bhbj4gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIlVzZXJDb21wYXJhdG9yLlRleHREb2VzTm90RXF1YWxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC1hdHRyXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvbkF0dHJpYnV0ZVRvb2x0aXBcIj5hbGljZSYjNjQ7Zm9vLmNvbTwvc3Bhbj4gTk9UIEVRVUFMUyA8c3BhbiBjbGFzcz1cImNvbXAtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPmJvYiYjNjQ7Zm9vLmNvbTwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJhcnJvd1wiPuKelDwvc3Bhbj4gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIlVzZXJDb21wYXJhdG9yLklzT25lT2ZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC1hdHRyXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvbkF0dHJpYnV0ZVRvb2x0aXBcIj5pT1M8L3NwYW4+IElTIE9ORSBPRiA8c3BhbiBjbGFzcz1cImNvbXAtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPlsgQW5kcm9pZCwgbWFjT1MsIDxzcGFuIGNsYXNzPVwibWF0Y2gtdmFsXCI+aU9TPC9zcGFuPiBdPC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiVXNlckNvbXBhcmF0b3IuSXNOb3RPbmVPZlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb21wLWF0dHJcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uQXR0cmlidXRlVG9vbHRpcFwiPmlPUzwvc3Bhbj4gSVMgTk9UIE9ORSBPRiA8c3BhbiBjbGFzcz1cImNvbXAtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPlsgQW5kcm9pZCwgbWFjT1MsIFdpbmRvd3MgXTwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJhcnJvd1wiPuKelDwvc3Bhbj4gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIlVzZXJDb21wYXJhdG9yLlRleHRTdGFydHNXaXRoQW55T2ZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC1hdHRyXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvbkF0dHJpYnV0ZVRvb2x0aXBcIj5ib2ImIzY0O2Zvby5jb208L3NwYW4+IFNUQVJUUyBXSVRIIEFOWSBPRiA8c3BhbiBjbGFzcz1cImNvbXAtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPlsgPHNwYW4gY2xhc3M9XCJtYXRjaC12YWxcIj5ib2I8L3NwYW4+LCBqYW5lIF08L3NwYW4+IDxzcGFuIGNsYXNzPVwiYXJyb3dcIj7inpQ8L3NwYW4+IG1hdGNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJVc2VyQ29tcGFyYXRvci5UZXh0Tm90U3RhcnRzV2l0aEFueU9mXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbXAtYXR0clwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25BdHRyaWJ1dGVUb29sdGlwXCI+YWxpY2UmIzY0O2Zvby5jb208L3NwYW4+IE5PVCBTVEFSVFMgV0lUSCBBTlkgT0YgPHNwYW4gY2xhc3M9XCJjb21wLXZhbFwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25WYWx1ZVRvb2x0aXBcIj5bIGJvYiwgamFuZSBdPC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiVXNlckNvbXBhcmF0b3IuVGV4dEVuZHNXaXRoQW55T2ZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC1hdHRyXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvbkF0dHJpYnV0ZVRvb2x0aXBcIj5ib2ImIzY0O2Zvby5jb208L3NwYW4+IEVORFMgV0lUSCBBTlkgT0YgPHNwYW4gY2xhc3M9XCJjb21wLXZhbFwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25WYWx1ZVRvb2x0aXBcIj5bIDxzcGFuIGNsYXNzPVwibWF0Y2gtdmFsXCI+JiM2NDtmb28uY29tPC9zcGFuPiwgJiM2NDtiYXIuY29tIF08L3NwYW4+IDxzcGFuIGNsYXNzPVwiYXJyb3dcIj7inpQ8L3NwYW4+IG1hdGNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJVc2VyQ29tcGFyYXRvci5UZXh0Tm90RW5kc1dpdGhBbnlPZlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb21wLWF0dHJcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uQXR0cmlidXRlVG9vbHRpcFwiPmJvYiYjNjQ7ZXhhbXBsZS5jb208L3NwYW4+IE5PVCBFTkRTIFdJVEggQU5ZIE9GIDxzcGFuIGNsYXNzPVwiY29tcC12YWxcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uVmFsdWVUb29sdGlwXCI+WyAmIzY0O2Zvby5jb20sICYjNjQ7YmFyLmNvbSBdPC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiVXNlckNvbXBhcmF0b3IuQ29udGFpbnNBbnlPZlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb21wLWF0dHJcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uQXR0cmlidXRlVG9vbHRpcFwiPmh0dHBzOi8vdGVzdC1hcHAuZm9vLmNvbTwvc3Bhbj4gQ09OVEFJTlMgQU5ZIE9GIDxzcGFuIGNsYXNzPVwiY29tcC12YWxcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uVmFsdWVUb29sdGlwXCI+WyA8c3BhbiBjbGFzcz1cIm1hdGNoLXZhbFwiPnRlc3Q8L3NwYW4+LCBsb2NhbGhvc3QgXTwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJhcnJvd1wiPuKelDwvc3Bhbj4gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIlVzZXJDb21wYXJhdG9yLkRvZXNOb3RDb250YWluQW55T2ZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC1hdHRyXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvbkF0dHJpYnV0ZVRvb2x0aXBcIj5odHRwczovL2FwcC5mb28uY29tPC9zcGFuPiBET0VTIE5PVCBDT05UQUlOUyBBTlkgT0YgPHNwYW4gY2xhc3M9XCJjb21wLXZhbFwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25WYWx1ZVRvb2x0aXBcIj5bIHRlc3QsIGxvY2FsaG9zdCBdPC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE5VTUJFUiAtLT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJVc2VyQ29tcGFyYXRvci5OdW1iZXJFcXVhbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC1hdHRyXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvbkF0dHJpYnV0ZVRvb2x0aXBcIj40Mjwvc3Bhbj4gPSA8c3BhbiBjbGFzcz1cImNvbXAtdmFsIG1hdGNoLXZhbFwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25WYWx1ZVRvb2x0aXBcIj40Mjwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJhcnJvd1wiPuKelDwvc3Bhbj4gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIlVzZXJDb21wYXJhdG9yLk51bWJlckRvZXNOb3RFcXVhbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb21wLWF0dHJcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uQXR0cmlidXRlVG9vbHRpcFwiPjQyPC9zcGFuPiAhPSA8c3BhbiBjbGFzcz1cImNvbXAtdmFsIG1hdGNoLXZhbFwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25WYWx1ZVRvb2x0aXBcIj4zLjE0PC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiVXNlckNvbXBhcmF0b3IuTnVtYmVyTGVzc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb21wLWF0dHJcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uQXR0cmlidXRlVG9vbHRpcFwiPjMuMTQ8L3NwYW4+ICZsdDsgPHNwYW4gY2xhc3M9XCJjb21wLXZhbCBtYXRjaC12YWxcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uVmFsdWVUb29sdGlwXCI+NDI8L3NwYW4+IDxzcGFuIGNsYXNzPVwiYXJyb3dcIj7inpQ8L3NwYW4+IG1hdGNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJVc2VyQ29tcGFyYXRvci5OdW1iZXJMZXNzT3JFcXVhbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC1hdHRyXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvbkF0dHJpYnV0ZVRvb2x0aXBcIj4zLjE0PC9zcGFuPiAmbHQ7PSA8c3BhbiBjbGFzcz1cImNvbXAtdmFsIG1hdGNoLXZhbFwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25WYWx1ZVRvb2x0aXBcIj40Mjwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJhcnJvd1wiPuKelDwvc3Bhbj4gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIlVzZXJDb21wYXJhdG9yLk51bWJlckdyZWF0ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC1hdHRyXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvbkF0dHJpYnV0ZVRvb2x0aXBcIj42OTwvc3Bhbj4gJmd0OyA8c3BhbiBjbGFzcz1cImNvbXAtdmFsIG1hdGNoLXZhbFwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25WYWx1ZVRvb2x0aXBcIj40Mjwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJhcnJvd1wiPuKelDwvc3Bhbj4gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIlVzZXJDb21wYXJhdG9yLk51bWJlckdyZWF0ZXJPckVxdWFsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb21wLWF0dHJcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uQXR0cmlidXRlVG9vbHRpcFwiPjY5PC9zcGFuPiAmZ3Q7PSA8c3BhbiBjbGFzcz1cImNvbXAtdmFsIG1hdGNoLXZhbFwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25WYWx1ZVRvb2x0aXBcIj40Mjwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJhcnJvd1wiPuKelDwvc3Bhbj4gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFNFTVZFUiAtLT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJVc2VyQ29tcGFyYXRvci5TZW1WZXJJc09uZU9mXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbXAtYXR0clwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25BdHRyaWJ1dGVUb29sdGlwXCI+MS4wLjA8L3NwYW4+IElTIE9ORSBPRiA8c3BhbiBjbGFzcz1cImNvbXAtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPlsgPHNwYW4gY2xhc3M9XCJtYXRjaC12YWxcIj4xLjAuMDwvc3Bhbj4sIDQuMy41IF08L3NwYW4+IDxzcGFuIGNsYXNzPVwiYXJyb3dcIj7inpQ8L3NwYW4+IG1hdGNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJVc2VyQ29tcGFyYXRvci5TZW1WZXJJc05vdE9uZU9mXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbXAtYXR0clwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25BdHRyaWJ1dGVUb29sdGlwXCI+Mi4xLjA8L3NwYW4+IElTIE5PVCBPTkUgT0YgPHNwYW4gY2xhc3M9XCJjb21wLXZhbFwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25WYWx1ZVRvb2x0aXBcIj5bIDEuMC4wLCA0LjMuNSBdPC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiVXNlckNvbXBhcmF0b3IuU2VtVmVyTGVzc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb21wLWF0dHJcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uQXR0cmlidXRlVG9vbHRpcFwiPjEuMC4wPC9zcGFuPiAmbHQ7IDxzcGFuIGNsYXNzPVwiY29tcC12YWwgbWF0Y2gtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPjEuMi4wPC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiVXNlckNvbXBhcmF0b3IuU2VtVmVyTGVzc09yRXF1YWxzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbXAtYXR0clwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25BdHRyaWJ1dGVUb29sdGlwXCI+MS4wLjA8L3NwYW4+ICZsdDs9IDxzcGFuIGNsYXNzPVwiY29tcC12YWwgbWF0Y2gtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPjEuMi4wPC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiVXNlckNvbXBhcmF0b3IuU2VtVmVyR3JlYXRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb21wLWF0dHJcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uQXR0cmlidXRlVG9vbHRpcFwiPjEuMC4wPC9zcGFuPiAmZ3Q7IDxzcGFuIGNsYXNzPVwiY29tcC12YWwgbWF0Y2gtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPjEuMC4wLWFscGhhPC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiVXNlckNvbXBhcmF0b3IuU2VtVmVyR3JlYXRlck9yRXF1YWxzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbXAtYXR0clwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25BdHRyaWJ1dGVUb29sdGlwXCI+MS4yLjA8L3NwYW4+ICZndDs9IDxzcGFuIGNsYXNzPVwiY29tcC12YWwgbWF0Y2gtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPjEuMS4wPC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIERBVEVUSU1FIC0tPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIlVzZXJDb21wYXJhdG9yLkRhdGVUaW1lQmVmb3JlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbXAtYXR0clwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25BdHRyaWJ1dGVUb29sdGlwXCI+MjAyMC4xMS4wNSAxMDozNjoyNDwvc3Bhbj4gQkVGT1JFIDxzcGFuIGNsYXNzPVwiY29tcC12YWwgbWF0Y2gtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPjIwMjAuMTEuMDUgMTI6MDA6MDA8L3NwYW4+IDxzcGFuIGNsYXNzPVwiYXJyb3dcIj7inpQ8L3NwYW4+IG1hdGNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJVc2VyQ29tcGFyYXRvci5EYXRlVGltZUFmdGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbXAtYXR0clwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25BdHRyaWJ1dGVUb29sdGlwXCI+MjAyMC4xMS4wNSAxNTo0MTowNjwvc3Bhbj4gQUZURVIgPHNwYW4gY2xhc3M9XCJjb21wLXZhbCBtYXRjaC12YWxcIiBbbWF0VG9vbHRpcF09XCJjb21wYXJpc29uVmFsdWVUb29sdGlwXCI+MjAyMC4xMS4wNSAxMjowMDowMDwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJhcnJvd1wiPuKelDwvc3Bhbj4gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBBUlJBWSAtLT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJVc2VyQ29tcGFyYXRvci5BcnJheUNvbnRhaW5zQW55T2ZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC1hdHRyXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvbkF0dHJpYnV0ZVRvb2x0aXBcIj5bIFdyaXRlciwgUmVhZGVyIF08L3NwYW4+IEFSUkFZIENPTlRBSU5TIEFOWSBPRiA8c3BhbiBjbGFzcz1cImNvbXAtdmFsXCIgW21hdFRvb2x0aXBdPVwiY29tcGFyaXNvblZhbHVlVG9vbHRpcFwiPlsgPHNwYW4gY2xhc3M9XCJtYXRjaC12YWxcIj5Xcml0ZXI8L3NwYW4+LCBBZG1pbiBdPC9zcGFuPiA8c3BhbiBjbGFzcz1cImFycm93XCI+4p6UPC9zcGFuPiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiVXNlckNvbXBhcmF0b3IuQXJyYXlEb2VzTm90Q29udGFpbkFueU9mXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbXAtYXR0clwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25BdHRyaWJ1dGVUb29sdGlwXCI+WyBHdWVzdCwgUmVhZGVyIF08L3NwYW4+IEFSUkFZIE5PVCBDT05UQUlOUyBBTlkgT0YgPHNwYW4gY2xhc3M9XCJjb21wLXZhbFwiIFttYXRUb29sdGlwXT1cImNvbXBhcmlzb25WYWx1ZVRvb2x0aXBcIj5bIFdyaXRlciwgQWRtaW4gXTwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJhcnJvd1wiPuKelDwvc3Bhbj4gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC1yYWRpby1ncm91cD5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjY29uZmlkZW50aWFsPlxuICAgIDxwPlNlbGVjdCBob3cgdGhlIDxpPmNvbXBhcmlzb24gdmFsdWVzPC9pPiBzaG91bGQgYmUgcGVyc2lzdGVkOjwvcD5cbiAgICA8ZGl2IG1hdFRvb2x0aXA9XCJUaGUgY3VycmVudGx5IHNlbGVjdGVkIGNvbXBhcmF0b3IgZG9lcyBub3Qgc3VwcG9ydCBoYXNoZWQgY29tcGFyaXNvbiB2YWx1ZXMsIHRoZXkgd2lsbCBiZSBwcmVzZW50ZWQgYXMgY2xlYXJ0ZXh0IGluIHRoZSBjb25maWcgSlNPTi5cIlxuICAgICAgICBbbWF0VG9vbHRpcERpc2FibGVkXT1cImNvbmZpZGVudGlhbEVuYWJsZWRcIj5cbiAgICAgICAgPG1hdC1yYWRpby1ncm91cCBjbGFzcz1cImNvbmZpZGVudGlhbC1jb250YWluZXJcIiAoY2hhbmdlKT1cImNvbmZpZGVudGlhbENoYW5nZSgkZXZlbnQudmFsdWUpXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlkZW50aWFsIGl0ZW1cIiAoY2xpY2spPVwiY29uZmlkZW50aWFsQ2hhbmdlKHRydWUpXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1yYWRpby1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgW3ZhbHVlXT1cInRydWVcIiBbY2hlY2tlZF09XCJpc0NvbmZpZGVudGlhbFwiIFtkaXNhYmxlZF09XCIhY29uZmlkZW50aWFsRW5hYmxlZCB8fCBkYXRhLnJlYWRPbmx5XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHRcIj5IYXNoZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpY29uXCI+PG1hdC1pY29uPmxvY2s8L21hdC1pY29uPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L21hdC1yYWRpby1idXR0b24+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRlc2NyaXB0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgIFdlIHJlY29tbWVuZCB1c2luZyB0aGlzIG9wdGlvbiBpbiBjYXNlIG9mIGZyb250ZW5kIGFwcGxpY2F0aW9ucyB0YXJnZXRpbmcgdXNlcnMgYmFzZWQgb24gc2Vuc2l0aXZlIGRhdGEgKGxpa2UgZW1haWwgYWRkcmVzc2VzLCBuYW1lcywgZXRjKS4gXG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2xlYXJ0ZXh0IGl0ZW1cIiAoY2xpY2spPVwiY29uZmlkZW50aWFsQ2hhbmdlKGZhbHNlKVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtcmFkaW8tYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIFt2YWx1ZV09XCJmYWxzZVwiIFtjaGVja2VkXT1cIiFpc0NvbmZpZGVudGlhbFwiIFtkaXNhYmxlZF09XCIhY29uZmlkZW50aWFsRW5hYmxlZCB8fCBkYXRhLnJlYWRPbmx5XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHRcIj5DbGVhcnRleHQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpY29uXCI+PG1hdC1pY29uPmxvY2tfb3Blbl9yaWdodDwvbWF0LWljb24+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LXJhZGlvLWJ1dHRvbj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGVzY3JpcHRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgWW91IGNhbiB1c2UgdGhpcyBvcHRpb24gd2hlbiB5b3UgdGFyZ2V0IHVzZXJzIGJhc2VkIG9uIG5vbi1zZW5zaXRpdmUgZGF0YS4gQ29tcGFyaXNvbiB2YWx1ZXMgd2lsbCBiZSBwcmVzZW50ZWQgYXMgcGxhaW4gdGV4dCBpbiB0aGUgPGk+Y29uZmlnIEpTT048L2k+LlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LXJhZGlvLWdyb3VwPlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT4iXX0=