ng-configcat-publicapi-ui 3.0.7 → 3.1.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 (68) hide show
  1. package/esm2022/lib/_directives/input-display-normalizer.directive.mjs +38 -0
  2. package/esm2022/lib/_services/form-helper.mjs +104 -0
  3. package/{esm2020 → esm2022}/lib/_services/public-api.service.mjs +6 -6
  4. package/esm2022/lib/_services/setting-list-form-helper.mjs +171 -0
  5. package/esm2022/lib/authorization/authorization.component.mjs +62 -0
  6. package/{esm2020 → esm2022}/lib/base/base-select.component.mjs +4 -4
  7. package/{esm2020 → esm2022}/lib/base/base.component.mjs +5 -5
  8. package/{esm2020 → esm2022}/lib/configuration.mjs +4 -4
  9. package/{esm2020 → esm2022}/lib/dialogs/delete-setting-dialog/delete-setting-dialog.component.mjs +6 -6
  10. package/esm2022/lib/dialogs/expand-dialog/expand-dialog.component.mjs +80 -0
  11. package/esm2022/lib/dialogs/reason-dialog/reason-dialog.component.mjs +36 -0
  12. package/{esm2020 → esm2022}/lib/dialogs/save-snackbar/save-snackbar.component.mjs +5 -5
  13. package/esm2022/lib/ng-configcat-publicapi-ui.module.mjs +179 -0
  14. package/esm2022/lib/selects/config-select/config-select.component.mjs +60 -0
  15. package/esm2022/lib/selects/environment-select/environment-select.component.mjs +47 -0
  16. package/esm2022/lib/selects/product-select/product-select.component.mjs +40 -0
  17. package/esm2022/lib/selects/setting-select/setting-select.component.mjs +47 -0
  18. package/esm2022/lib/setting-item/setting-item.component.mjs +116 -0
  19. package/esm2022/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.mjs +81 -0
  20. package/esm2022/lib/setting-list/setting/rollout-rules/rollout-rules.component.mjs +293 -0
  21. package/{esm2020 → esm2022}/lib/setting-list/setting/setting.component.mjs +5 -5
  22. package/esm2022/lib/setting-list/setting/value/value.component.mjs +37 -0
  23. package/esm2022/lib/setting-list/setting-list.component.mjs +194 -0
  24. package/{fesm2020 → fesm2022}/ng-configcat-publicapi-ui.mjs +163 -163
  25. package/{fesm2020 → fesm2022}/ng-configcat-publicapi-ui.mjs.map +1 -1
  26. package/lib/_services/setting-list-form-helper.d.ts +1 -1
  27. package/lib/authorization/authorization.component.d.ts +1 -1
  28. package/lib/base/base-select.component.d.ts +1 -1
  29. package/lib/base/base.component.d.ts +1 -1
  30. package/lib/selects/config-select/config-select.component.d.ts +1 -1
  31. package/lib/selects/environment-select/environment-select.component.d.ts +1 -1
  32. package/lib/selects/product-select/product-select.component.d.ts +1 -1
  33. package/lib/selects/setting-select/setting-select.component.d.ts +1 -1
  34. package/lib/setting-item/setting-item.component.d.ts +1 -1
  35. package/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.d.ts +1 -1
  36. package/lib/setting-list/setting/rollout-rules/rollout-rules.component.d.ts +2 -2
  37. package/lib/setting-list/setting/setting.component.d.ts +1 -1
  38. package/lib/setting-list/setting/value/value.component.d.ts +1 -1
  39. package/lib/setting-list/setting-list.component.d.ts +1 -1
  40. package/package.json +9 -15
  41. package/public-api.scss +15 -1
  42. package/esm2020/lib/_directives/input-display-normalizer.directive.mjs +0 -38
  43. package/esm2020/lib/_services/form-helper.mjs +0 -104
  44. package/esm2020/lib/_services/setting-list-form-helper.mjs +0 -171
  45. package/esm2020/lib/authorization/authorization.component.mjs +0 -62
  46. package/esm2020/lib/dialogs/expand-dialog/expand-dialog.component.mjs +0 -80
  47. package/esm2020/lib/dialogs/reason-dialog/reason-dialog.component.mjs +0 -36
  48. package/esm2020/lib/ng-configcat-publicapi-ui.module.mjs +0 -179
  49. package/esm2020/lib/selects/config-select/config-select.component.mjs +0 -60
  50. package/esm2020/lib/selects/environment-select/environment-select.component.mjs +0 -47
  51. package/esm2020/lib/selects/product-select/product-select.component.mjs +0 -40
  52. package/esm2020/lib/selects/setting-select/setting-select.component.mjs +0 -47
  53. package/esm2020/lib/setting-item/setting-item.component.mjs +0 -116
  54. package/esm2020/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.mjs +0 -81
  55. package/esm2020/lib/setting-list/setting/rollout-rules/rollout-rules.component.mjs +0 -293
  56. package/esm2020/lib/setting-list/setting/value/value.component.mjs +0 -37
  57. package/esm2020/lib/setting-list/setting-list.component.mjs +0 -194
  58. package/fesm2015/ng-configcat-publicapi-ui.mjs +0 -1786
  59. package/fesm2015/ng-configcat-publicapi-ui.mjs.map +0 -1
  60. /package/{esm2020 → esm2022}/lib/_directives/index.mjs +0 -0
  61. /package/{esm2020 → esm2022}/lib/_models/deleteSettingModel.mjs +0 -0
  62. /package/{esm2020 → esm2022}/lib/_models/index.mjs +0 -0
  63. /package/{esm2020 → esm2022}/lib/_models/settingValuesModel.mjs +0 -0
  64. /package/{esm2020 → esm2022}/lib/_models/updateSettingValuesModel.mjs +0 -0
  65. /package/{esm2020 → esm2022}/lib/_services/index.mjs +0 -0
  66. /package/{esm2020 → esm2022}/lib/_services/platform-helper.mjs +0 -0
  67. /package/{esm2020 → esm2022}/ng-configcat-publicapi-ui.mjs +0 -0
  68. /package/{esm2020 → esm2022}/public-api.mjs +0 -0
@@ -12,7 +12,7 @@ export declare class SettingListFormHelper {
12
12
  private getValidatorsForSettingType;
13
13
  private getAllRolloutRules;
14
14
  private getComparisonAttributes;
15
- getComparisonValueType(comparator: RolloutRuleComparator): "text" | "number";
15
+ getComparisonValueType(comparator: RolloutRuleComparator): "number" | "text";
16
16
  normalizeComparisonValue(comparator: RolloutRuleComparator | undefined, comparisonValue: any): any;
17
17
  static ɵfac: i0.ɵɵFactoryDeclaration<SettingListFormHelper, never>;
18
18
  static ɵprov: i0.ɵɵInjectableDeclaration<SettingListFormHelper>;
@@ -17,5 +17,5 @@ export declare class AuthorizationComponent implements OnInit {
17
17
  onSubmit(): void;
18
18
  getPublicApiUrl(): string;
19
19
  static ɵfac: i0.ɵɵFactoryDeclaration<AuthorizationComponent, never>;
20
- static ɵcmp: i0.ɵɵComponentDeclaration<AuthorizationComponent, "configcat-authorization", never, { "basePath": "basePath"; "integrationName": "integrationName"; }, { "authorized": "authorized"; "error": "error"; }, never, never, false, never>;
20
+ static ɵcmp: i0.ɵɵComponentDeclaration<AuthorizationComponent, "configcat-authorization", never, { "basePath": { "alias": "basePath"; "required": false; }; "integrationName": { "alias": "integrationName"; "required": false; }; }, { "authorized": "authorized"; "error": "error"; }, never, never, false, never>;
21
21
  }
@@ -6,5 +6,5 @@ export declare class BaseSelectComponent extends BaseComponent {
6
6
  dropdownOpened: EventEmitter<boolean>;
7
7
  protected openChanged(event: any): void;
8
8
  static ɵfac: i0.ɵɵFactoryDeclaration<BaseSelectComponent, never>;
9
- static ɵcmp: i0.ɵɵComponentDeclaration<BaseSelectComponent, "base-select", never, { "customDropdown": "customDropdown"; }, { "dropdownOpened": "dropdownOpened"; }, never, never, false, never>;
9
+ static ɵcmp: i0.ɵɵComponentDeclaration<BaseSelectComponent, "base-select", never, { "customDropdown": { "alias": "customDropdown"; "required": false; }; }, { "dropdownOpened": "dropdownOpened"; }, never, never, false, never>;
10
10
  }
@@ -13,5 +13,5 @@ export declare class BaseComponent {
13
13
  protected createSettingValuesService(): import("ng-configcat-publicapi").FeatureFlagSettingValuesService;
14
14
  protected createSegmentsService(): import("ng-configcat-publicapi").SegmentsService;
15
15
  static ɵfac: i0.ɵɵFactoryDeclaration<BaseComponent, never>;
16
- static ɵcmp: i0.ɵɵComponentDeclaration<BaseComponent, "base", never, { "basePath": "basePath"; "basicAuthUsername": "basicAuthUsername"; "basicAuthPassword": "basicAuthPassword"; }, {}, never, never, false, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<BaseComponent, "base", never, { "basePath": { "alias": "basePath"; "required": false; }; "basicAuthUsername": { "alias": "basicAuthUsername"; "required": false; }; "basicAuthPassword": { "alias": "basicAuthPassword"; "required": false; }; }, {}, never, never, false, never>;
17
17
  }
@@ -13,5 +13,5 @@ export declare class ConfigSelectComponent extends BaseSelectComponent implement
13
13
  ngOnChanges(): void;
14
14
  reloadConfigs(): void;
15
15
  static ɵfac: i0.ɵɵFactoryDeclaration<ConfigSelectComponent, never>;
16
- static ɵcmp: i0.ɵɵComponentDeclaration<ConfigSelectComponent, "configcat-config-select", never, { "valueFormControl": "valueFormControl"; "productId": "productId"; }, {}, never, never, false, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<ConfigSelectComponent, "configcat-config-select", never, { "valueFormControl": { "alias": "valueFormControl"; "required": false; }; "productId": { "alias": "productId"; "required": false; }; }, {}, never, never, false, never>;
17
17
  }
@@ -13,5 +13,5 @@ export declare class EnvironmentSelectComponent extends BaseSelectComponent impl
13
13
  ngOnChanges(): void;
14
14
  reloadEnvironments(): void;
15
15
  static ɵfac: i0.ɵɵFactoryDeclaration<EnvironmentSelectComponent, never>;
16
- static ɵcmp: i0.ɵɵComponentDeclaration<EnvironmentSelectComponent, "configcat-environment-select", never, { "valueFormControl": "valueFormControl"; "productId": "productId"; }, {}, never, never, false, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<EnvironmentSelectComponent, "configcat-environment-select", never, { "valueFormControl": { "alias": "valueFormControl"; "required": false; }; "productId": { "alias": "productId"; "required": false; }; }, {}, never, never, false, never>;
17
17
  }
@@ -10,5 +10,5 @@ export declare class ProductSelectComponent extends BaseSelectComponent implemen
10
10
  constructor(publicApiService: PublicApiService);
11
11
  ngOnInit(): void;
12
12
  static ɵfac: i0.ɵɵFactoryDeclaration<ProductSelectComponent, never>;
13
- static ɵcmp: i0.ɵɵComponentDeclaration<ProductSelectComponent, "configcat-product-select", never, { "valueFormControl": "valueFormControl"; }, {}, never, never, false, never>;
13
+ static ɵcmp: i0.ɵɵComponentDeclaration<ProductSelectComponent, "configcat-product-select", never, { "valueFormControl": { "alias": "valueFormControl"; "required": false; }; }, {}, never, never, false, never>;
14
14
  }
@@ -13,5 +13,5 @@ export declare class SettingSelectComponent extends BaseSelectComponent implemen
13
13
  ngOnChanges(): void;
14
14
  reloadSettings(): void;
15
15
  static ɵfac: i0.ɵɵFactoryDeclaration<SettingSelectComponent, never>;
16
- static ɵcmp: i0.ɵɵComponentDeclaration<SettingSelectComponent, "configcat-setting-select", never, { "valueFormControl": "valueFormControl"; "configId": "configId"; }, {}, never, never, false, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<SettingSelectComponent, "configcat-setting-select", never, { "valueFormControl": { "alias": "valueFormControl"; "required": false; }; "configId": { "alias": "configId"; "required": false; }; }, {}, never, never, false, never>;
17
17
  }
@@ -31,5 +31,5 @@ export declare class SettingItemComponent extends BaseComponent implements OnIni
31
31
  onDeleteSettingRequested(setting: any): void;
32
32
  onFormValuesChanged(): void;
33
33
  static ɵfac: i0.ɵɵFactoryDeclaration<SettingItemComponent, never>;
34
- static ɵcmp: i0.ɵɵComponentDeclaration<SettingItemComponent, "configcat-setting-item", never, { "productId": "productId"; "environmentId": "environmentId"; "configId": "configId"; "settingId": "settingId"; "canDeleteSetting": "canDeleteSetting"; "deleteSettingText": "deleteSettingText"; "showEnvironmentName": "showEnvironmentName"; }, { "deleteSettingRequested": "deleteSettingRequested"; "loadSucceeded": "loadSucceeded"; "loadFailed": "loadFailed"; "saveSucceeded": "saveSucceeded"; "saveFailed": "saveFailed"; "formValuesChanged": "formValuesChanged"; }, never, never, false, never>;
34
+ static ɵcmp: i0.ɵɵComponentDeclaration<SettingItemComponent, "configcat-setting-item", never, { "productId": { "alias": "productId"; "required": false; }; "environmentId": { "alias": "environmentId"; "required": false; }; "configId": { "alias": "configId"; "required": false; }; "settingId": { "alias": "settingId"; "required": false; }; "canDeleteSetting": { "alias": "canDeleteSetting"; "required": false; }; "deleteSettingText": { "alias": "deleteSettingText"; "required": false; }; "showEnvironmentName": { "alias": "showEnvironmentName"; "required": false; }; }, { "deleteSettingRequested": "deleteSettingRequested"; "loadSucceeded": "loadSucceeded"; "loadFailed": "loadFailed"; "saveSucceeded": "saveSucceeded"; "saveFailed": "saveFailed"; "formValuesChanged": "formValuesChanged"; }, never, never, false, never>;
35
35
  }
@@ -23,5 +23,5 @@ export declare class RolloutPercentageItemsComponent {
23
23
  getRolloutPercentageItemFormGroups(): UntypedFormGroup[];
24
24
  getPercentageFormControl(rolloutPercentageItem: any): UntypedFormControl;
25
25
  static ɵfac: i0.ɵɵFactoryDeclaration<RolloutPercentageItemsComponent, never>;
26
- static ɵcmp: i0.ɵɵComponentDeclaration<RolloutPercentageItemsComponent, "configcat-rollout-percentage-items", never, { "formGroup": "formGroup"; "readOnly": "readOnly"; }, {}, never, never, false, never>;
26
+ static ɵcmp: i0.ɵɵComponentDeclaration<RolloutPercentageItemsComponent, "configcat-rollout-percentage-items", never, { "formGroup": { "alias": "formGroup"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; }, {}, never, never, false, never>;
27
27
  }
@@ -32,7 +32,7 @@ export declare class RolloutRulesComponent {
32
32
  onDrop(event: any): void;
33
33
  attributeChanged(event: any, comparisonAttribute: UntypedFormControl): void;
34
34
  getPlaceHolder(rolloutRule: any): "" | "e.g: user_id1, user_id2, user_id3" | "e.g: jane@example.com, john@example.com" | "e.g: France, Brazil" | "e.g: value1, value2, value3" | "part-of-id" | "e.g: @example.com" | "e.g: United" | "e.g: any-part-of-your-value-string" | "e.g: 1.0.0, 2.0.1" | "e.g: 1.0.0" | "e.g: 42";
35
- getComparisonValueType(rolloutRule: any): "text" | "number";
35
+ getComparisonValueType(rolloutRule: any): "number" | "text";
36
36
  getInfoClass(rolloutRule: any): "warn" | "info";
37
37
  getInfoTooltip(rolloutRule: any): "Learn more about comparators" | "Consider using sensitive text comparators. Click to learn more." | "Click to learn more about comparators";
38
38
  comparatorChanged(rolloutRule: any): void;
@@ -57,5 +57,5 @@ export declare class RolloutRulesComponent {
57
57
  getRolloutRuleSegmentComparatorFormControl(rolloutRule: any): UntypedFormControl;
58
58
  getRolloutRuleSegmentIdFormControl(rolloutRule: any): UntypedFormControl;
59
59
  static ɵfac: i0.ɵɵFactoryDeclaration<RolloutRulesComponent, never>;
60
- static ɵcmp: i0.ɵɵComponentDeclaration<RolloutRulesComponent, "configcat-rollout-rules", never, { "formGroup": "formGroup"; "readOnly": "readOnly"; "segments": "segments"; }, {}, never, never, false, never>;
60
+ static ɵcmp: i0.ɵɵComponentDeclaration<RolloutRulesComponent, "configcat-rollout-rules", never, { "formGroup": { "alias": "formGroup"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; "segments": { "alias": "segments"; "required": false; }; }, {}, never, never, false, never>;
61
61
  }
@@ -39,5 +39,5 @@ export declare class SettingComponent implements OnInit {
39
39
  deleteSetting(): void;
40
40
  getDashboardUrl(): string;
41
41
  static ɵfac: i0.ɵɵFactoryDeclaration<SettingComponent, never>;
42
- static ɵcmp: i0.ɵɵComponentDeclaration<SettingComponent, "setting", never, { "dashboardBasePath": "dashboardBasePath"; "productId": "productId"; "environmentId": "environmentId"; "configId": "configId"; "formGroup": "formGroup"; "readOnly": "readOnly"; "canDeleteSetting": "canDeleteSetting"; "deleteSettingText": "deleteSettingText"; "showEnvironmentName": "showEnvironmentName"; "segments": "segments"; }, { "deleteSettingRequested": "deleteSettingRequested"; }, never, never, false, never>;
42
+ static ɵcmp: i0.ɵɵComponentDeclaration<SettingComponent, "setting", never, { "dashboardBasePath": { "alias": "dashboardBasePath"; "required": false; }; "productId": { "alias": "productId"; "required": false; }; "environmentId": { "alias": "environmentId"; "required": false; }; "configId": { "alias": "configId"; "required": false; }; "formGroup": { "alias": "formGroup"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; "canDeleteSetting": { "alias": "canDeleteSetting"; "required": false; }; "deleteSettingText": { "alias": "deleteSettingText"; "required": false; }; "showEnvironmentName": { "alias": "showEnvironmentName"; "required": false; }; "segments": { "alias": "segments"; "required": false; }; }, { "deleteSettingRequested": "deleteSettingRequested"; }, never, never, false, never>;
43
43
  }
@@ -16,5 +16,5 @@ export declare class ValueComponent {
16
16
  popOut(): void;
17
17
  formatDecimalNumber(value: number): string;
18
18
  static ɵfac: i0.ɵɵFactoryDeclaration<ValueComponent, never>;
19
- static ɵcmp: i0.ɵɵComponentDeclaration<ValueComponent, "configcat-value", never, { "valueFormControl": "valueFormControl"; "setting": "setting"; }, {}, never, never, false, never>;
19
+ static ɵcmp: i0.ɵɵComponentDeclaration<ValueComponent, "configcat-value", never, { "valueFormControl": { "alias": "valueFormControl"; "required": false; }; "setting": { "alias": "setting"; "required": false; }; }, {}, never, never, false, never>;
20
20
  }
@@ -49,5 +49,5 @@ export declare class SettingListComponent implements OnChanges, OnDestroy {
49
49
  setting: SettingModel;
50
50
  }): void;
51
51
  static ɵfac: i0.ɵɵFactoryDeclaration<SettingListComponent, never>;
52
- static ɵcmp: i0.ɵɵComponentDeclaration<SettingListComponent, "configcat-setting-list", never, { "productId": "productId"; "environmentId": "environmentId"; "configId": "configId"; "dashboardBasePath": "dashboardBasePath"; "canDeleteSetting": "canDeleteSetting"; "onSave": "onSave"; "loadSettingValues": "loadSettingValues"; "loadSegments": "loadSegments"; "deleteSettingText": "deleteSettingText"; "showEnvironmentName": "showEnvironmentName"; }, { "loadSucceeded": "loadSucceeded"; "deleteSettingRequested": "deleteSettingRequested"; "formValuesChanged": "formValuesChanged"; }, never, never, false, never>;
52
+ static ɵcmp: i0.ɵɵComponentDeclaration<SettingListComponent, "configcat-setting-list", never, { "productId": { "alias": "productId"; "required": false; }; "environmentId": { "alias": "environmentId"; "required": false; }; "configId": { "alias": "configId"; "required": false; }; "dashboardBasePath": { "alias": "dashboardBasePath"; "required": false; }; "canDeleteSetting": { "alias": "canDeleteSetting"; "required": false; }; "onSave": { "alias": "onSave"; "required": false; }; "loadSettingValues": { "alias": "loadSettingValues"; "required": false; }; "loadSegments": { "alias": "loadSegments"; "required": false; }; "deleteSettingText": { "alias": "deleteSettingText"; "required": false; }; "showEnvironmentName": { "alias": "showEnvironmentName"; "required": false; }; }, { "loadSucceeded": "loadSucceeded"; "deleteSettingRequested": "deleteSettingRequested"; "formValuesChanged": "formValuesChanged"; }, never, never, false, never>;
53
53
  }
package/package.json CHANGED
@@ -1,20 +1,16 @@
1
1
  {
2
2
  "name": "ng-configcat-publicapi-ui",
3
- "version": "3.0.7",
3
+ "version": "3.1.0",
4
4
  "peerDependencies": {
5
- "@angular/common": "^15.2.10",
6
- "@angular/core": "^15.2.10",
7
- "ng-configcat-publicapi": "^4.1.2",
5
+ "@angular/common": "^17.1.3",
6
+ "@angular/core": "^17.1.3",
7
+ "ng-configcat-publicapi": "^4.3.0",
8
8
  "semver": "^7.5.3"
9
9
  },
10
10
  "dependencies": {
11
- "tslib": "^2.3.0"
11
+ "tslib": "^2.4.0"
12
12
  },
13
- "module": "fesm2015/ng-configcat-publicapi-ui.mjs",
14
- "es2020": "fesm2020/ng-configcat-publicapi-ui.mjs",
15
- "esm2020": "esm2020/ng-configcat-publicapi-ui.mjs",
16
- "fesm2020": "fesm2020/ng-configcat-publicapi-ui.mjs",
17
- "fesm2015": "fesm2015/ng-configcat-publicapi-ui.mjs",
13
+ "module": "fesm2022/ng-configcat-publicapi-ui.mjs",
18
14
  "typings": "index.d.ts",
19
15
  "exports": {
20
16
  "./package.json": {
@@ -22,11 +18,9 @@
22
18
  },
23
19
  ".": {
24
20
  "types": "./index.d.ts",
25
- "esm2020": "./esm2020/ng-configcat-publicapi-ui.mjs",
26
- "es2020": "./fesm2020/ng-configcat-publicapi-ui.mjs",
27
- "es2015": "./fesm2015/ng-configcat-publicapi-ui.mjs",
28
- "node": "./fesm2015/ng-configcat-publicapi-ui.mjs",
29
- "default": "./fesm2020/ng-configcat-publicapi-ui.mjs"
21
+ "esm2022": "./esm2022/ng-configcat-publicapi-ui.mjs",
22
+ "esm": "./esm2022/ng-configcat-publicapi-ui.mjs",
23
+ "default": "./fesm2022/ng-configcat-publicapi-ui.mjs"
30
24
  }
31
25
  },
32
26
  "sideEffects": false
package/public-api.scss CHANGED
@@ -1,5 +1,4 @@
1
1
  @use '@angular/material' as mat;
2
- @import '@angular/material/theming';
3
2
 
4
3
  @include mat.core();
5
4
 
@@ -25,6 +24,21 @@ $configcat-typography: mat.define-typography-config($font-family: 'Montserrat, R
25
24
  @include mat.form-field-density(-2);
26
25
  @include mat.checkbox-density(-3);
27
26
 
27
+ /* Fix Trello Dark Mode bugs. */
28
+ html[data-color-mode='dark'] {
29
+ input {
30
+ color: #000;
31
+ }
32
+
33
+ select {
34
+ color: #000;
35
+
36
+ option{
37
+ color: #000;
38
+ }
39
+ }
40
+ }
41
+
28
42
  html {
29
43
  overflow: visible;
30
44
  overflow-y: visible;
@@ -1,38 +0,0 @@
1
- import { Directive, HostListener } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- /**
4
- * Makes sure that values entered into HTML input fields are displayed in the correct format,
5
- * where correct means normalized (e.g. `'.10'` --> `'0.1'`) and corresponding to the locale setting.
6
- *
7
- * The format is adjusted on the blur event. Only the format of number inputs is adjusted currently.
8
- */
9
- export class InputDisplayNormalizerDirective {
10
- constructor() { }
11
- onChange($event) {
12
- const target = $event.target;
13
- if (target.type === 'number') {
14
- let value = target.value;
15
- value = value.trim() !== '' ? Number(value) : NaN;
16
- if (isFinite(value)) {
17
- // The string returned by the `value` property and the string displayed in the input field are not necessarily equal.
18
- // HACK: When the returned and the displayed value differs only in the decimal separator,
19
- // Chrome won't update the displayed value unless the value is changed first...
20
- target.value = '';
21
- target.value = value;
22
- }
23
- }
24
- }
25
- }
26
- InputDisplayNormalizerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputDisplayNormalizerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
27
- InputDisplayNormalizerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: InputDisplayNormalizerDirective, selector: "input[inputDisplayNormalizer]", host: { listeners: { "blur": "onChange($event)" } }, ngImport: i0 });
28
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputDisplayNormalizerDirective, decorators: [{
29
- type: Directive,
30
- args: [{
31
- // eslint-disable-next-line @angular-eslint/directive-selector
32
- selector: 'input[inputDisplayNormalizer]'
33
- }]
34
- }], ctorParameters: function () { return []; }, propDecorators: { onChange: [{
35
- type: HostListener,
36
- args: ['blur', ['$event']]
37
- }] } });
38
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtZGlzcGxheS1ub3JtYWxpemVyLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWNvbmZpZ2NhdC1wdWJsaWNhcGktdWkvc3JjL2xpYi9fZGlyZWN0aXZlcy9pbnB1dC1kaXNwbGF5LW5vcm1hbGl6ZXIuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQUV4RDs7Ozs7R0FLRztBQUtILE1BQU0sT0FBTywrQkFBK0I7SUFDeEMsZ0JBQWdCLENBQUM7SUFHakIsUUFBUSxDQUFDLE1BQVc7UUFDaEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUM3QixJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO1lBQzFCLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7WUFDekIsS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQ2xELElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUNqQixxSEFBcUg7Z0JBQ3JILHlGQUF5RjtnQkFDekYsK0VBQStFO2dCQUMvRSxNQUFNLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztnQkFDbEIsTUFBTSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7YUFDeEI7U0FDSjtJQUNMLENBQUM7OzZIQWpCUSwrQkFBK0I7aUhBQS9CLCtCQUErQjs0RkFBL0IsK0JBQStCO2tCQUozQyxTQUFTO21CQUFDO29CQUNQLDhEQUE4RDtvQkFDOUQsUUFBUSxFQUFFLCtCQUErQjtpQkFDNUM7MEVBS0csUUFBUTtzQkFEUCxZQUFZO3VCQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgSG9zdExpc3RlbmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogTWFrZXMgc3VyZSB0aGF0IHZhbHVlcyBlbnRlcmVkIGludG8gSFRNTCBpbnB1dCBmaWVsZHMgYXJlIGRpc3BsYXllZCBpbiB0aGUgY29ycmVjdCBmb3JtYXQsXG4gKiB3aGVyZSBjb3JyZWN0IG1lYW5zIG5vcm1hbGl6ZWQgKGUuZy4gYCcuMTAnYCAtLT4gYCcwLjEnYCkgYW5kIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGxvY2FsZSBzZXR0aW5nLlxuICogXG4gKiBUaGUgZm9ybWF0IGlzIGFkanVzdGVkIG9uIHRoZSBibHVyIGV2ZW50LiBPbmx5IHRoZSBmb3JtYXQgb2YgbnVtYmVyIGlucHV0cyBpcyBhZGp1c3RlZCBjdXJyZW50bHkuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvZGlyZWN0aXZlLXNlbGVjdG9yXG4gICAgc2VsZWN0b3I6ICdpbnB1dFtpbnB1dERpc3BsYXlOb3JtYWxpemVyXSdcbn0pXG5leHBvcnQgY2xhc3MgSW5wdXREaXNwbGF5Tm9ybWFsaXplckRpcmVjdGl2ZSB7XG4gICAgY29uc3RydWN0b3IoKSB7IH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ2JsdXInLCBbJyRldmVudCddKVxuICAgIG9uQ2hhbmdlKCRldmVudDogYW55KSB7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9ICRldmVudC50YXJnZXQ7XG4gICAgICAgIGlmICh0YXJnZXQudHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IHRhcmdldC52YWx1ZTtcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUudHJpbSgpICE9PSAnJyA/IE51bWJlcih2YWx1ZSkgOiBOYU47XG4gICAgICAgICAgICBpZiAoaXNGaW5pdGUodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIHN0cmluZyByZXR1cm5lZCBieSB0aGUgYHZhbHVlYCBwcm9wZXJ0eSBhbmQgdGhlIHN0cmluZyBkaXNwbGF5ZWQgaW4gdGhlIGlucHV0IGZpZWxkIGFyZSBub3QgbmVjZXNzYXJpbHkgZXF1YWwuXG4gICAgICAgICAgICAgICAgLy8gSEFDSzogV2hlbiB0aGUgcmV0dXJuZWQgYW5kIHRoZSBkaXNwbGF5ZWQgdmFsdWUgZGlmZmVycyBvbmx5IGluIHRoZSBkZWNpbWFsIHNlcGFyYXRvcixcbiAgICAgICAgICAgICAgICAvLyBDaHJvbWUgd29uJ3QgdXBkYXRlIHRoZSBkaXNwbGF5ZWQgdmFsdWUgdW5sZXNzIHRoZSB2YWx1ZSBpcyBjaGFuZ2VkIGZpcnN0Li4uXG4gICAgICAgICAgICAgICAgdGFyZ2V0LnZhbHVlID0gJyc7XG4gICAgICAgICAgICAgICAgdGFyZ2V0LnZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59Il19
@@ -1,104 +0,0 @@
1
- import { HttpErrorResponse } from '@angular/common/http';
2
- import { PlatformHelper } from './platform-helper';
3
- export class FormHelper {
4
- static getErrorMessage(control, hint = '') {
5
- if (!control || control.valid) {
6
- return;
7
- }
8
- if (control.hasError('required')) {
9
- return `${hint} The field is required.`;
10
- }
11
- if (control.hasError('pattern')) {
12
- return 'Not a valid e-mail address.';
13
- }
14
- if (control.hasError('minlength')) {
15
- return 'The field must be at least ' + control.getError('minlength').requiredLength + ' characters long';
16
- }
17
- if (control.hasError('maxlength')) {
18
- return 'The field must be at max ' + control.getError('maxlength').requiredLength + ' characters long';
19
- }
20
- return;
21
- }
22
- static handleErrors(formGroup, error) {
23
- if (error instanceof HttpErrorResponse) {
24
- const response = error;
25
- switch (response.status) {
26
- case 400:
27
- let unknownFieldName = false;
28
- for (const fieldName in error.error) {
29
- if (error.error.hasOwnProperty(fieldName) && error.error[fieldName] &&
30
- (error.error[fieldName]?.length > 0 || error.error[fieldName]?.Errors?.length > 0)) {
31
- let jsonFieldName = fieldName;
32
- if (jsonFieldName.length > 0) {
33
- jsonFieldName = jsonFieldName[0].toLowerCase() + jsonFieldName.slice(1);
34
- }
35
- const errorMessage = error.error[fieldName]?.Errors?.length > 0 ?
36
- (error.error[fieldName]?.Errors.map((e) => e.ErrorMessage)).join(', ')
37
- : error.error[fieldName];
38
- if (formGroup.controls.hasOwnProperty(jsonFieldName)) {
39
- formGroup.controls[jsonFieldName].setErrors({ serverSide: errorMessage });
40
- }
41
- else {
42
- unknownFieldName = true;
43
- }
44
- }
45
- }
46
- if (unknownFieldName) {
47
- formGroup.setErrors({ serverSide: 'Something went wrong.' });
48
- }
49
- break;
50
- // in these cases we do not show errors on the form, they're handled by the http
51
- // interceptor in src\app\_interceptors\httpstatuscode.interceptor.ts
52
- case 402:
53
- case 429:
54
- return;
55
- }
56
- }
57
- else {
58
- formGroup.setErrors({ serverSide: 'Something went wrong on our side. This is not your fault. Please try again.' });
59
- }
60
- }
61
- /**
62
- * Converts a value representing a number to a `number` value.
63
- * Returns `NaN` in the case of non-numerical values.
64
- */
65
- static normalizeNumber(value) {
66
- switch (typeof value) {
67
- case "number":
68
- return value;
69
- case "string":
70
- // NOTE: `Number()` converts whitespace strings to 0.
71
- return value.trim() === '' ? NaN : Number(value);
72
- case "bigint":
73
- return Number(value);
74
- default:
75
- return NaN;
76
- }
77
- }
78
- /**
79
- * Converts a value representing a number to the normalized `string`
80
- * representation of the number. (e.g. `.1` --> `'0.1'`, `3.14e2` --> `'314'`).
81
- * Returns `''` in the case of non-numerical values or non-finite numerical values.
82
- */
83
- static normalizeNumberStoredAsString(value) {
84
- value = FormHelper.normalizeNumber(value);
85
- // NOTE: `NaN` is not considered finite.
86
- return isFinite(value) ? value + '' : '';
87
- }
88
- static formatNumberForDisplay(value) {
89
- if (!isFinite(value)) {
90
- return '';
91
- }
92
- // Chromium-based browsers don't respect the `lang` attribute,
93
- // they use a display format corresponding to the browser's language setting.
94
- if (PlatformHelper.isChromium()) {
95
- return value.toLocaleString();
96
- }
97
- // Firefox (and probably other browsers) respect the `lang` attribute,
98
- // which is currently set to the fixed value of "en" (see index.html),
99
- // so in these cases dot should be used as the decimal separator.
100
- // (In case localization is implemented in the application, this logic should be revised!)
101
- return value + '';
102
- }
103
- }
104
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1oZWxwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1jb25maWdjYXQtcHVibGljYXBpLXVpL3NyYy9saWIvX3NlcnZpY2VzL2Zvcm0taGVscGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXpELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVuRCxNQUFNLE9BQU8sVUFBVTtJQUVaLE1BQU0sQ0FBQyxlQUFlLENBQUMsT0FBd0IsRUFBRSxPQUFlLEVBQUU7UUFDckUsSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFO1lBQzNCLE9BQU87U0FDVjtRQUVELElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUM5QixPQUFPLEdBQUcsSUFBSSx5QkFBeUIsQ0FBQztTQUMzQztRQUVELElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUM3QixPQUFPLDZCQUE2QixDQUFDO1NBQ3hDO1FBRUQsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQy9CLE9BQU8sNkJBQTZCLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxjQUFjLEdBQUcsa0JBQWtCLENBQUM7U0FDNUc7UUFFRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDL0IsT0FBTywyQkFBMkIsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLGNBQWMsR0FBRyxrQkFBa0IsQ0FBQztTQUMxRztRQUVELE9BQU87SUFDWCxDQUFDO0lBR00sTUFBTSxDQUFDLFlBQVksQ0FBQyxTQUFvQixFQUFFLEtBQVU7UUFDdkQsSUFBSSxLQUFLLFlBQVksaUJBQWlCLEVBQUU7WUFDcEMsTUFBTSxRQUFRLEdBQUcsS0FBMEIsQ0FBQztZQUM1QyxRQUFRLFFBQVEsQ0FBQyxNQUFNLEVBQUU7Z0JBQ3JCLEtBQUssR0FBRztvQkFDSixJQUFJLGdCQUFnQixHQUFHLEtBQUssQ0FBQztvQkFDN0IsS0FBSyxNQUFNLFNBQVMsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO3dCQUNqQyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDOzRCQUMvRCxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsTUFBTSxHQUFHLENBQUMsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUU7NEJBQ3BGLElBQUksYUFBYSxHQUFHLFNBQVMsQ0FBQzs0QkFDOUIsSUFBSSxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQ0FDMUIsYUFBYSxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDOzZCQUMzRTs0QkFFRCxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0NBQzdELENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dDQUMzRSxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQzs0QkFFN0IsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsRUFBRTtnQ0FDbEQsU0FBUyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxTQUFTLENBQUMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQzs2QkFDN0U7aUNBQU07Z0NBQ0gsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDOzZCQUMzQjt5QkFDSjtxQkFDSjtvQkFDRCxJQUFJLGdCQUFnQixFQUFFO3dCQUNsQixTQUFTLENBQUMsU0FBUyxDQUFDLEVBQUUsVUFBVSxFQUFFLHVCQUF1QixFQUFFLENBQUMsQ0FBQztxQkFDaEU7b0JBQ0QsTUFBTTtnQkFDVixnRkFBZ0Y7Z0JBQ2hGLHFFQUFxRTtnQkFDckUsS0FBSyxHQUFHLENBQUM7Z0JBQ1QsS0FBSyxHQUFHO29CQUNKLE9BQU87YUFDZDtTQUNKO2FBQU07WUFDSCxTQUFTLENBQUMsU0FBUyxDQUFDLEVBQUUsVUFBVSxFQUFFLDZFQUE2RSxFQUFFLENBQUMsQ0FBQztTQUN0SDtJQUNMLENBQUM7SUFFRDs7O09BR0c7SUFDSSxNQUFNLENBQUMsZUFBZSxDQUFDLEtBQVU7UUFDcEMsUUFBUSxPQUFPLEtBQUssRUFBRTtZQUNsQixLQUFLLFFBQVE7Z0JBQ1QsT0FBTyxLQUFLLENBQUM7WUFDakIsS0FBSyxRQUFRO2dCQUNULHFEQUFxRDtnQkFDckQsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRCxLQUFLLFFBQVE7Z0JBQ1QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDekI7Z0JBQ0ksT0FBTyxHQUFHLENBQUM7U0FDbEI7SUFDTCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyw2QkFBNkIsQ0FBQyxLQUFVO1FBQ2xELEtBQUssR0FBRyxVQUFVLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFDLHdDQUF3QztRQUN4QyxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQzdDLENBQUM7SUFHSSxNQUFNLENBQUMsc0JBQXNCLENBQUMsS0FBYTtRQUNoRCxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ3BCLE9BQU8sRUFBRSxDQUFDO1NBQ1g7UUFFRCw4REFBOEQ7UUFDOUQsNkVBQTZFO1FBQzdFLElBQUksY0FBYyxDQUFDLFVBQVUsRUFBRSxFQUFFO1lBQy9CLE9BQU8sS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQy9CO1FBRUQsc0VBQXNFO1FBQ3RFLHNFQUFzRTtRQUN0RSxpRUFBaUU7UUFDakUsMEZBQTBGO1FBQzFGLE9BQU8sS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUNwQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUGxhdGZvcm1IZWxwZXIgfSBmcm9tICcuL3BsYXRmb3JtLWhlbHBlcic7XG5cbmV4cG9ydCBjbGFzcyBGb3JtSGVscGVyIHtcblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0RXJyb3JNZXNzYWdlKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgaGludDogc3RyaW5nID0gJycpIHtcbiAgICAgICAgaWYgKCFjb250cm9sIHx8IGNvbnRyb2wudmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250cm9sLmhhc0Vycm9yKCdyZXF1aXJlZCcpKSB7XG4gICAgICAgICAgICByZXR1cm4gYCR7aGludH0gVGhlIGZpZWxkIGlzIHJlcXVpcmVkLmA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udHJvbC5oYXNFcnJvcigncGF0dGVybicpKSB7XG4gICAgICAgICAgICByZXR1cm4gJ05vdCBhIHZhbGlkIGUtbWFpbCBhZGRyZXNzLic7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udHJvbC5oYXNFcnJvcignbWlubGVuZ3RoJykpIHtcbiAgICAgICAgICAgIHJldHVybiAnVGhlIGZpZWxkIG11c3QgYmUgYXQgbGVhc3QgJyArIGNvbnRyb2wuZ2V0RXJyb3IoJ21pbmxlbmd0aCcpLnJlcXVpcmVkTGVuZ3RoICsgJyBjaGFyYWN0ZXJzIGxvbmcnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbnRyb2wuaGFzRXJyb3IoJ21heGxlbmd0aCcpKSB7XG4gICAgICAgICAgICByZXR1cm4gJ1RoZSBmaWVsZCBtdXN0IGJlIGF0IG1heCAnICsgY29udHJvbC5nZXRFcnJvcignbWF4bGVuZ3RoJykucmVxdWlyZWRMZW5ndGggKyAnIGNoYXJhY3RlcnMgbG9uZyc7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG5cbiAgICBwdWJsaWMgc3RhdGljIGhhbmRsZUVycm9ycyhmb3JtR3JvdXA6IEZvcm1Hcm91cCwgZXJyb3I6IGFueSkge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBlcnJvciBhcyBIdHRwRXJyb3JSZXNwb25zZTtcbiAgICAgICAgICAgIHN3aXRjaCAocmVzcG9uc2Uuc3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSA0MDA6XG4gICAgICAgICAgICAgICAgICAgIGxldCB1bmtub3duRmllbGROYW1lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIGVycm9yLmVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuZXJyb3IuaGFzT3duUHJvcGVydHkoZmllbGROYW1lKSAmJiBlcnJvci5lcnJvcltmaWVsZE5hbWVdICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yLmVycm9yW2ZpZWxkTmFtZV0/Lmxlbmd0aCA+IDAgfHwgZXJyb3IuZXJyb3JbZmllbGROYW1lXT8uRXJyb3JzPy5sZW5ndGggPiAwKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBqc29uRmllbGROYW1lID0gZmllbGROYW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqc29uRmllbGROYW1lLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganNvbkZpZWxkTmFtZSA9IGpzb25GaWVsZE5hbWVbMF0udG9Mb3dlckNhc2UoKSArIGpzb25GaWVsZE5hbWUuc2xpY2UoMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IuZXJyb3JbZmllbGROYW1lXT8uRXJyb3JzPy5sZW5ndGggPiAwID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yLmVycm9yW2ZpZWxkTmFtZV0/LkVycm9ycy5tYXAoKGU6IGFueSkgPT4gZS5FcnJvck1lc3NhZ2UpKS5qb2luKCcsICcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZXJyb3IuZXJyb3JbZmllbGROYW1lXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3JtR3JvdXAuY29udHJvbHMuaGFzT3duUHJvcGVydHkoanNvbkZpZWxkTmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUdyb3VwLmNvbnRyb2xzW2pzb25GaWVsZE5hbWVdLnNldEVycm9ycyh7IHNlcnZlclNpZGU6IGVycm9yTWVzc2FnZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmtub3duRmllbGROYW1lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHVua25vd25GaWVsZE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Hcm91cC5zZXRFcnJvcnMoeyBzZXJ2ZXJTaWRlOiAnU29tZXRoaW5nIHdlbnQgd3JvbmcuJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAvLyBpbiB0aGVzZSBjYXNlcyB3ZSBkbyBub3Qgc2hvdyBlcnJvcnMgb24gdGhlIGZvcm0sIHRoZXkncmUgaGFuZGxlZCBieSB0aGUgaHR0cFxuICAgICAgICAgICAgICAgIC8vIGludGVyY2VwdG9yIGluIHNyY1xcYXBwXFxfaW50ZXJjZXB0b3JzXFxodHRwc3RhdHVzY29kZS5pbnRlcmNlcHRvci50c1xuICAgICAgICAgICAgICAgIGNhc2UgNDAyOlxuICAgICAgICAgICAgICAgIGNhc2UgNDI5OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3JtR3JvdXAuc2V0RXJyb3JzKHsgc2VydmVyU2lkZTogJ1NvbWV0aGluZyB3ZW50IHdyb25nIG9uIG91ciBzaWRlLiBUaGlzIGlzIG5vdCB5b3VyIGZhdWx0LiBQbGVhc2UgdHJ5IGFnYWluLicgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBhIHZhbHVlIHJlcHJlc2VudGluZyBhIG51bWJlciB0byBhIGBudW1iZXJgIHZhbHVlLlxuICAgICAqIFJldHVybnMgYE5hTmAgaW4gdGhlIGNhc2Ugb2Ygbm9uLW51bWVyaWNhbCB2YWx1ZXMuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBub3JtYWxpemVOdW1iZXIodmFsdWU6IGFueSk6IG51bWJlciB7XG4gICAgICAgIHN3aXRjaCAodHlwZW9mIHZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAgICAgIC8vIE5PVEU6IGBOdW1iZXIoKWAgY29udmVydHMgd2hpdGVzcGFjZSBzdHJpbmdzIHRvIDAuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnRyaW0oKSA9PT0gJycgPyBOYU4gOiBOdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgY2FzZSBcImJpZ2ludFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYSB2YWx1ZSByZXByZXNlbnRpbmcgYSBudW1iZXIgdG8gdGhlIG5vcm1hbGl6ZWQgYHN0cmluZ2BcbiAgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgbnVtYmVyLiAoZS5nLiBgLjFgIC0tPiBgJzAuMSdgLCBgMy4xNGUyYCAtLT4gYCczMTQnYCkuXG4gICAgICogUmV0dXJucyBgJydgIGluIHRoZSBjYXNlIG9mIG5vbi1udW1lcmljYWwgdmFsdWVzIG9yIG5vbi1maW5pdGUgbnVtZXJpY2FsIHZhbHVlcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIG5vcm1hbGl6ZU51bWJlclN0b3JlZEFzU3RyaW5nKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xuICAgICAgICB2YWx1ZSA9IEZvcm1IZWxwZXIubm9ybWFsaXplTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgLy8gTk9URTogYE5hTmAgaXMgbm90IGNvbnNpZGVyZWQgZmluaXRlLlxuICAgICAgICByZXR1cm4gaXNGaW5pdGUodmFsdWUpID8gdmFsdWUgKyAnJyA6ICcnO1xuICAgIH1cblxuICAgIFxuICBwdWJsaWMgc3RhdGljIGZvcm1hdE51bWJlckZvckRpc3BsYXkodmFsdWU6IG51bWJlcikge1xuICAgIGlmICghaXNGaW5pdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLy8gQ2hyb21pdW0tYmFzZWQgYnJvd3NlcnMgZG9uJ3QgcmVzcGVjdCB0aGUgYGxhbmdgIGF0dHJpYnV0ZSxcbiAgICAvLyB0aGV5IHVzZSBhIGRpc3BsYXkgZm9ybWF0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGJyb3dzZXIncyBsYW5ndWFnZSBzZXR0aW5nLlxuICAgIGlmIChQbGF0Zm9ybUhlbHBlci5pc0Nocm9taXVtKCkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS50b0xvY2FsZVN0cmluZygpO1xuICAgIH1cblxuICAgIC8vIEZpcmVmb3ggKGFuZCBwcm9iYWJseSBvdGhlciBicm93c2VycykgcmVzcGVjdCB0aGUgYGxhbmdgIGF0dHJpYnV0ZSxcbiAgICAvLyB3aGljaCBpcyBjdXJyZW50bHkgc2V0IHRvIHRoZSBmaXhlZCB2YWx1ZSBvZiBcImVuXCIgKHNlZSBpbmRleC5odG1sKSxcbiAgICAvLyBzbyBpbiB0aGVzZSBjYXNlcyBkb3Qgc2hvdWxkIGJlIHVzZWQgYXMgdGhlIGRlY2ltYWwgc2VwYXJhdG9yLlxuICAgIC8vIChJbiBjYXNlIGxvY2FsaXphdGlvbiBpcyBpbXBsZW1lbnRlZCBpbiB0aGUgYXBwbGljYXRpb24sIHRoaXMgbG9naWMgc2hvdWxkIGJlIHJldmlzZWQhKVxuICAgIHJldHVybiB2YWx1ZSArICcnO1xuICB9XG59XG4iXX0=
@@ -1,171 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { Validators } from '@angular/forms';
3
- import { RolloutRuleComparator, SettingType } from 'ng-configcat-publicapi';
4
- import { FormHelper } from './form-helper';
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "@angular/forms";
7
- export class SettingListFormHelper {
8
- constructor(formBuilder) {
9
- this.formBuilder = formBuilder;
10
- }
11
- createSettingValuesFormGroup(settingValuesModel) {
12
- const formGroup = this.formBuilder.group({
13
- settingValues: this.formBuilder.array(settingValuesModel.settingValues.map(sv => {
14
- return this.createSettingValueFormGroup(sv, settingValuesModel.readOnly);
15
- })),
16
- // Decorator
17
- environment: this.formBuilder.group({
18
- environmentId: [{ value: settingValuesModel.environment.environmentId, disabled: true }],
19
- name: [{ value: settingValuesModel.environment.name, disabled: true }],
20
- }),
21
- comparisonAttributes: [[]]
22
- });
23
- const rolloutRules = this.getAllRolloutRules(formGroup);
24
- const comparisonAttributes = this.getComparisonAttributes(rolloutRules);
25
- formGroup.patchValue({ comparisonAttributes: comparisonAttributes });
26
- return formGroup;
27
- }
28
- createSettingValueFormGroup(settingValueModel, readOnly) {
29
- if (!settingValueModel.setting) {
30
- return this.formBuilder.group({});
31
- }
32
- return this.formBuilder.group({
33
- settingId: [settingValueModel.setting.settingId],
34
- value: [
35
- { value: settingValueModel.value, disabled: readOnly },
36
- this.getValidatorsForSettingType(settingValueModel.setting.settingType)
37
- ],
38
- rolloutPercentageItems: settingValueModel.rolloutPercentageItems
39
- ? this.formBuilder.array(settingValueModel.rolloutPercentageItems.map(p => {
40
- // @ts-ignore()
41
- return this.createRolloutPercentageItemFormGroup(p, readOnly, settingValueModel.setting.settingType);
42
- }))
43
- : this.formBuilder.array([]), rolloutRules: settingValueModel.rolloutRules
44
- ? this.formBuilder.array(settingValueModel.rolloutRules.map(r => {
45
- // @ts-ignore()
46
- return this.createRolloutRuleFormGroup(r, readOnly, settingValueModel.setting.settingType);
47
- }))
48
- : this.formBuilder.array([]),
49
- updatedAt: [{ value: settingValueModel.updatedAt, disabled: true }],
50
- lastUpdaterUserEmail: [{ value: settingValueModel.lastUpdaterUserEmail, disabled: true }],
51
- lastUpdaterUserFullName: [{ value: settingValueModel.lastUpdaterUserFullName, disabled: true }],
52
- rolloutPercentageItemsSum: [{ value: 100, disabled: false }, [Validators.min(100), Validators.max(100)]],
53
- // Decoration
54
- setting: this.formBuilder.group({
55
- settingId: [{ value: settingValueModel.setting.settingId, disabled: true }],
56
- key: [{ value: settingValueModel.setting.key, disabled: true }],
57
- name: [{ value: settingValueModel.setting.name, disabled: true }],
58
- hint: [{ value: settingValueModel.setting.hint, disabled: true }],
59
- settingType: [{ value: settingValueModel.setting.settingType, disabled: true }],
60
- creatorEmail: [{ value: settingValueModel.setting.creatorEmail, disabled: true }],
61
- creatorFullName: [{ value: settingValueModel.setting.creatorFullName, disabled: true }],
62
- createdAt: [{ value: settingValueModel.setting.createdAt, disabled: true }]
63
- }),
64
- integrationLinks: settingValueModel.integrationLinks ? this.formBuilder.array(settingValueModel.integrationLinks.map(il => {
65
- return this.formBuilder.group({
66
- key: [{ value: il.key, disabled: true }],
67
- description: [{ value: il.description, disabled: true }],
68
- integrationLinkType: [{ value: il.integrationLinkType, disabled: true }],
69
- url: [{ value: il.url, disabled: true }],
70
- });
71
- })) : this.formBuilder.array([])
72
- });
73
- }
74
- createRolloutPercentageItemFormGroup(p, readOnly, settingType) {
75
- return this.formBuilder.group({
76
- percentage: [{ value: p.percentage, disabled: readOnly }, [Validators.required, Validators.min(0), Validators.max(100)]],
77
- value: [
78
- { value: p.value, disabled: readOnly },
79
- this.getValidatorsForSettingType(settingType)
80
- ],
81
- valueDisabled: [
82
- { value: p.value, disabled: true }, // For percentage item value
83
- ]
84
- });
85
- }
86
- createRolloutRuleFormGroup(r, readOnly, settingType) {
87
- if (r.comparator) {
88
- return this.formBuilder.group({
89
- type: [{ value: 0, disabled: true }],
90
- comparisonAttribute: [{ value: r.comparisonAttribute, disabled: readOnly }, [Validators.required]],
91
- comparator: [{ value: r.comparator, disabled: readOnly }, [Validators.required]],
92
- comparisonValue: [{ value: r.comparisonValue, disabled: readOnly }, [Validators.required]],
93
- value: [
94
- { value: r.value, disabled: readOnly },
95
- this.getValidatorsForSettingType(settingType)
96
- ],
97
- });
98
- }
99
- else if (r.segmentComparator) {
100
- return this.formBuilder.group({
101
- type: [{ value: 1, disabled: true }],
102
- segmentComparator: [{ value: r.segmentComparator, disabled: readOnly }, [Validators.required]],
103
- segmentId: [{ value: r.segmentId, disabled: readOnly }, [Validators.required]],
104
- value: [
105
- { value: r.value, disabled: readOnly },
106
- this.getValidatorsForSettingType(settingType)
107
- ],
108
- });
109
- }
110
- else {
111
- throw new Error('Invalid rollout rule');
112
- }
113
- }
114
- getValidatorsForSettingType(settingType) {
115
- switch (settingType) {
116
- case SettingType.Int:
117
- return [Validators.required,
118
- Validators.min(-2147483648), Validators.max(2147483647), Validators.pattern('^[-+]?[0-9]\\d*$')];
119
- case SettingType.Double:
120
- return [Validators.required, Validators.min(-1.79769313486232E+308), Validators.max(1.79769313486232E+308)];
121
- case SettingType.String:
122
- case SettingType.Boolean:
123
- return [Validators.required];
124
- default:
125
- return [];
126
- }
127
- }
128
- getAllRolloutRules(formGroup) {
129
- const settingValues = formGroup.get('settingValues');
130
- const rolloutRules = settingValues.controls.map(cv => cv.get('rolloutRules').value);
131
- return rolloutRules.length === 0 ? rolloutRules : rolloutRules.reduce((a, b) => a.concat(b));
132
- }
133
- getComparisonAttributes(rolloutRules) {
134
- if (rolloutRules.length > 0) {
135
- const currentComparisonAttributes = rolloutRules.map(r => r.comparisonAttribute);
136
- const defaultComparisonAttributes = ['Identifier', 'Email', 'Country'];
137
- const comparisonAttributes = currentComparisonAttributes.filter(c => defaultComparisonAttributes.indexOf(c) === -1);
138
- return Array.from(new Set(comparisonAttributes));
139
- }
140
- else {
141
- return [];
142
- }
143
- }
144
- getComparisonValueType(comparator) {
145
- switch (comparator) {
146
- case RolloutRuleComparator.NumberEquals:
147
- case RolloutRuleComparator.NumberDoesNotEqual:
148
- case RolloutRuleComparator.NumberLess:
149
- case RolloutRuleComparator.NumberLessOrEquals:
150
- case RolloutRuleComparator.NumberGreater:
151
- case RolloutRuleComparator.NumberGreaterOrEquals:
152
- return 'number';
153
- default:
154
- return 'text';
155
- }
156
- }
157
- normalizeComparisonValue(comparator, comparisonValue) {
158
- // In the case of number inputs value is a number but API expects
159
- // a string, so we need to make sure that it's converted to string.
160
- return comparator && this.getComparisonValueType(comparator) === "number"
161
- ? FormHelper.normalizeNumberStoredAsString(comparisonValue)
162
- : comparisonValue;
163
- }
164
- }
165
- SettingListFormHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingListFormHelper, deps: [{ token: i1.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Injectable });
166
- SettingListFormHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingListFormHelper, providedIn: 'root' });
167
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingListFormHelper, decorators: [{
168
- type: Injectable,
169
- args: [{ providedIn: 'root' }]
170
- }], ctorParameters: function () { return [{ type: i1.UntypedFormBuilder }]; } });
171
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZy1saXN0LWZvcm0taGVscGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctY29uZmlnY2F0LXB1YmxpY2FwaS11aS9zcmMvbGliL19zZXJ2aWNlcy9zZXR0aW5nLWxpc3QtZm9ybS1oZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQXNCLFVBQVUsRUFBc0MsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwRyxPQUFPLEVBQThCLHFCQUFxQixFQUFvQixXQUFXLEVBQXFCLE1BQU0sd0JBQXdCLENBQUM7QUFDN0ksT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7O0FBRzNDLE1BQU0sT0FBTyxxQkFBcUI7SUFFOUIsWUFBb0IsV0FBK0I7UUFBL0IsZ0JBQVcsR0FBWCxXQUFXLENBQW9CO0lBQUksQ0FBQztJQUV4RCw0QkFBNEIsQ0FBQyxrQkFBc0M7UUFDL0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7WUFDckMsYUFBYSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUNqQyxrQkFBa0IsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUN0QyxPQUFPLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxFQUFFLEVBQUUsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDN0UsQ0FBQyxDQUFDLENBQUM7WUFFUCxZQUFZO1lBQ1osV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDO2dCQUNoQyxhQUFhLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQztnQkFDeEYsSUFBSSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsa0JBQWtCLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7YUFDekUsQ0FBQztZQUVGLG9CQUFvQixFQUFFLENBQUMsRUFBRSxDQUFDO1NBQzdCLENBQUMsQ0FBQztRQUVILE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4RCxNQUFNLG9CQUFvQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN4RSxTQUFTLENBQUMsVUFBVSxDQUFDLEVBQUUsb0JBQW9CLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1FBQ3JFLE9BQU8sU0FBUyxDQUFDO0lBQ3JCLENBQUM7SUFHRCwyQkFBMkIsQ0FBQyxpQkFBb0MsRUFBRSxRQUFpQjtRQUMvRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFO1lBQzVCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDckM7UUFDRCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDO1lBQzFCLFNBQVMsRUFBRSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7WUFDaEQsS0FBSyxFQUFFO2dCQUNILEVBQUUsS0FBSyxFQUFFLGlCQUFpQixDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFO2dCQUN0RCxJQUFJLENBQUMsMkJBQTJCLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQzthQUMxRTtZQUNELHNCQUFzQixFQUFFLGlCQUFpQixDQUFDLHNCQUFzQjtnQkFDNUQsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDdEUsZUFBZTtvQkFDZixPQUFPLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDekcsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksRUFBRSxpQkFBaUIsQ0FBQyxZQUFZO2dCQUN0RSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDNUQsZUFBZTtvQkFDZixPQUFPLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDL0YsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUVwQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO1lBQ25FLG9CQUFvQixFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsaUJBQWlCLENBQUMsb0JBQW9CLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO1lBQ3pGLHVCQUF1QixFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsaUJBQWlCLENBQUMsdUJBQXVCLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO1lBRS9GLHlCQUF5QixFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3hHLGFBQWE7WUFDYixPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7Z0JBQzVCLFNBQVMsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO2dCQUMzRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQztnQkFDL0QsSUFBSSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsaUJBQWlCLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7Z0JBQ2pFLElBQUksRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO2dCQUNqRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQztnQkFDL0UsWUFBWSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsaUJBQWlCLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7Z0JBQ2pGLGVBQWUsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO2dCQUN2RixTQUFTLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQzthQUM5RSxDQUFDO1lBRUYsZ0JBQWdCLEVBQUUsaUJBQWlCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRTtnQkFDdEgsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztvQkFDMUIsR0FBRyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7b0JBQ3hDLFdBQVcsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO29CQUN4RCxtQkFBbUIsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxtQkFBbUIsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7b0JBQ3hFLEdBQUcsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO2lCQUMzQyxDQUFDLENBQUM7WUFDUCxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7U0FDbkMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELG9DQUFvQyxDQUFDLENBQTZCLEVBQUUsUUFBaUIsRUFBRSxXQUFvQztRQUN2SCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDO1lBQzFCLFVBQVUsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN4SCxLQUFLLEVBQUU7Z0JBQ0gsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFO2dCQUN0QyxJQUFJLENBQUMsMkJBQTJCLENBQUMsV0FBVyxDQUFDO2FBQ2hEO1lBQ0QsYUFBYSxFQUFFO2dCQUNYLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFFLDRCQUE0QjthQUNuRTtTQUNKLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCwwQkFBMEIsQ0FBQyxDQUFtQixFQUFFLFFBQWlCLEVBQUUsV0FBb0M7UUFDbkcsSUFBSSxDQUFDLENBQUMsVUFBVSxFQUFFO1lBQ2QsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztnQkFDMUIsSUFBSSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQztnQkFDcEMsbUJBQW1CLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNsRyxVQUFVLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEYsZUFBZSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLGVBQWUsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzFGLEtBQUssRUFBRTtvQkFDSCxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUU7b0JBQ3RDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxXQUFXLENBQUM7aUJBQ2hEO2FBQ0osQ0FBQyxDQUFDO1NBQ047YUFBTSxJQUFJLENBQUMsQ0FBQyxpQkFBaUIsRUFBRTtZQUM1QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDO2dCQUMxQixJQUFJLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO2dCQUNwQyxpQkFBaUIsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzlGLFNBQVMsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUM5RSxLQUFLLEVBQUU7b0JBQ0gsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFO29CQUN0QyxJQUFJLENBQUMsMkJBQTJCLENBQUMsV0FBVyxDQUFDO2lCQUNoRDthQUNKLENBQUMsQ0FBQztTQUNOO2FBQU07WUFDSCxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7U0FDM0M7SUFDTCxDQUFDO0lBRU8sMkJBQTJCLENBQUMsV0FBb0M7UUFDcEUsUUFBUSxXQUFXLEVBQUU7WUFDakIsS0FBSyxXQUFXLENBQUMsR0FBRztnQkFDaEIsT0FBTyxDQUFDLFVBQVUsQ0FBQyxRQUFRO29CQUMzQixVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxVQUFVLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQztZQUNyRyxLQUFLLFdBQVcsQ0FBQyxNQUFNO2dCQUNuQixPQUFPLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMscUJBQXFCLENBQUMsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQztZQUNoSCxLQUFLLFdBQVcsQ0FBQyxNQUFNLENBQUM7WUFDeEIsS0FBSyxXQUFXLENBQUMsT0FBTztnQkFDcEIsT0FBTyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNqQztnQkFDSSxPQUFPLEVBQUUsQ0FBQztTQUNqQjtJQUNMLENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxTQUEyQjtRQUNsRCxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBcUIsQ0FBQztRQUN6RSxNQUFNLFlBQVksR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFzQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFHLE9BQU8sWUFBWSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqRyxDQUFDO0lBRU8sdUJBQXVCLENBQUMsWUFBbUI7UUFDL0MsSUFBSSxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUN6QixNQUFNLDJCQUEyQixHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsQ0FBQztZQUVqRixNQUFNLDJCQUEyQixHQUFHLENBQUMsWUFBWSxFQUFFLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztZQUN2RSxNQUFNLG9CQUFvQixHQUFHLDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLDJCQUEyQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BILE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUM7U0FDcEQ7YUFBTTtZQUNILE9BQU8sRUFBRSxDQUFDO1NBQ2I7SUFDTCxDQUFDO0lBRUQsc0JBQXNCLENBQUMsVUFBaUM7UUFDcEQsUUFBUSxVQUFVLEVBQUU7WUFDaEIsS0FBSyxxQkFBcUIsQ0FBQyxZQUFZLENBQUM7WUFDeEMsS0FBSyxxQkFBcUIsQ0FBQyxrQkFBa0IsQ0FBQztZQUM5QyxLQUFLLHFCQUFxQixDQUFDLFVBQVUsQ0FBQztZQUN0QyxLQUFLLHFCQUFxQixDQUFDLGtCQUFrQixDQUFDO1lBQzlDLEtBQUsscUJBQXFCLENBQUMsYUFBYSxDQUFDO1lBQ3pDLEtBQUsscUJBQXFCLENBQUMscUJBQXFCO2dCQUM1QyxPQUFPLFFBQVEsQ0FBQztZQUNwQjtnQkFDSSxPQUFPLE1BQU0sQ0FBQztTQUNyQjtJQUNMLENBQUM7SUFFRCx3QkFBd0IsQ0FBQyxVQUE2QyxFQUFFLGVBQW9CO1FBQ3hGLGlFQUFpRTtRQUNqRSxtRUFBbUU7UUFDbkUsT0FBTyxVQUFVLElBQUksSUFBSSxDQUFDLHNCQUFzQixDQUFDLFVBQVUsQ0FBQyxLQUFLLFFBQVE7WUFDckUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyw2QkFBNkIsQ0FBQyxlQUFlLENBQUM7WUFDM0QsQ0FBQyxDQUFDLGVBQWUsQ0FBQztJQUMxQixDQUFDOzttSEExS1EscUJBQXFCO3VIQUFyQixxQkFBcUIsY0FEUixNQUFNOzRGQUNuQixxQkFBcUI7a0JBRGpDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU2V0dGluZ1ZhbHVlc01vZGVsIH0gZnJvbSAnLi4vX21vZGVscy9zZXR0aW5nVmFsdWVzTW9kZWwnO1xuaW1wb3J0IHsgVW50eXBlZEZvcm1CdWlsZGVyLCBWYWxpZGF0b3JzLCBVbnR5cGVkRm9ybUdyb3VwLCBVbnR5cGVkRm9ybUFycmF5IH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUm9sbG91dFBlcmNlbnRhZ2VJdGVtTW9kZWwsIFJvbGxvdXRSdWxlQ29tcGFyYXRvciwgUm9sbG91dFJ1bGVNb2RlbCwgU2V0dGluZ1R5cGUsIFNldHRpbmdWYWx1ZU1vZGVsIH0gZnJvbSAnbmctY29uZmlnY2F0LXB1YmxpY2FwaSc7XG5pbXBvcnQgeyBGb3JtSGVscGVyIH0gZnJvbSAnLi9mb3JtLWhlbHBlcic7XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgU2V0dGluZ0xpc3RGb3JtSGVscGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZm9ybUJ1aWxkZXI6IFVudHlwZWRGb3JtQnVpbGRlcikgeyB9XG5cbiAgICBjcmVhdGVTZXR0aW5nVmFsdWVzRm9ybUdyb3VwKHNldHRpbmdWYWx1ZXNNb2RlbDogU2V0dGluZ1ZhbHVlc01vZGVsKSB7XG4gICAgICAgIGNvbnN0IGZvcm1Hcm91cCA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgICAgICAgc2V0dGluZ1ZhbHVlczogdGhpcy5mb3JtQnVpbGRlci5hcnJheShcbiAgICAgICAgICAgICAgICBzZXR0aW5nVmFsdWVzTW9kZWwuc2V0dGluZ1ZhbHVlcy5tYXAoc3YgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVTZXR0aW5nVmFsdWVGb3JtR3JvdXAoc3YsIHNldHRpbmdWYWx1ZXNNb2RlbC5yZWFkT25seSk7XG4gICAgICAgICAgICAgICAgfSkpLFxuXG4gICAgICAgICAgICAvLyBEZWNvcmF0b3JcbiAgICAgICAgICAgIGVudmlyb25tZW50OiB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcbiAgICAgICAgICAgICAgICBlbnZpcm9ubWVudElkOiBbeyB2YWx1ZTogc2V0dGluZ1ZhbHVlc01vZGVsLmVudmlyb25tZW50LmVudmlyb25tZW50SWQsIGRpc2FibGVkOiB0cnVlIH1dLFxuICAgICAgICAgICAgICAgIG5hbWU6IFt7IHZhbHVlOiBzZXR0aW5nVmFsdWVzTW9kZWwuZW52aXJvbm1lbnQubmFtZSwgZGlzYWJsZWQ6IHRydWUgfV0sXG4gICAgICAgICAgICB9KSxcblxuICAgICAgICAgICAgY29tcGFyaXNvbkF0dHJpYnV0ZXM6IFtbXV1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgcm9sbG91dFJ1bGVzID0gdGhpcy5nZXRBbGxSb2xsb3V0UnVsZXMoZm9ybUdyb3VwKTtcbiAgICAgICAgY29uc3QgY29tcGFyaXNvbkF0dHJpYnV0ZXMgPSB0aGlzLmdldENvbXBhcmlzb25BdHRyaWJ1dGVzKHJvbGxvdXRSdWxlcyk7XG4gICAgICAgIGZvcm1Hcm91cC5wYXRjaFZhbHVlKHsgY29tcGFyaXNvbkF0dHJpYnV0ZXM6IGNvbXBhcmlzb25BdHRyaWJ1dGVzIH0pO1xuICAgICAgICByZXR1cm4gZm9ybUdyb3VwO1xuICAgIH1cblxuXG4gICAgY3JlYXRlU2V0dGluZ1ZhbHVlRm9ybUdyb3VwKHNldHRpbmdWYWx1ZU1vZGVsOiBTZXR0aW5nVmFsdWVNb2RlbCwgcmVhZE9ubHk6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKCFzZXR0aW5nVmFsdWVNb2RlbC5zZXR0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtQnVpbGRlci5ncm91cCh7fSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgICAgICAgc2V0dGluZ0lkOiBbc2V0dGluZ1ZhbHVlTW9kZWwuc2V0dGluZy5zZXR0aW5nSWRdLFxuICAgICAgICAgICAgdmFsdWU6IFtcbiAgICAgICAgICAgICAgICB7IHZhbHVlOiBzZXR0aW5nVmFsdWVNb2RlbC52YWx1ZSwgZGlzYWJsZWQ6IHJlYWRPbmx5IH0sXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRWYWxpZGF0b3JzRm9yU2V0dGluZ1R5cGUoc2V0dGluZ1ZhbHVlTW9kZWwuc2V0dGluZy5zZXR0aW5nVHlwZSlcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByb2xsb3V0UGVyY2VudGFnZUl0ZW1zOiBzZXR0aW5nVmFsdWVNb2RlbC5yb2xsb3V0UGVyY2VudGFnZUl0ZW1zXG4gICAgICAgICAgICAgICAgPyB0aGlzLmZvcm1CdWlsZGVyLmFycmF5KHNldHRpbmdWYWx1ZU1vZGVsLnJvbGxvdXRQZXJjZW50YWdlSXRlbXMubWFwKHAgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlKClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlUm9sbG91dFBlcmNlbnRhZ2VJdGVtRm9ybUdyb3VwKHAsIHJlYWRPbmx5LCBzZXR0aW5nVmFsdWVNb2RlbC5zZXR0aW5nLnNldHRpbmdUeXBlKTtcbiAgICAgICAgICAgICAgICB9KSlcbiAgICAgICAgICAgICAgICA6IHRoaXMuZm9ybUJ1aWxkZXIuYXJyYXkoW10pLCByb2xsb3V0UnVsZXM6IHNldHRpbmdWYWx1ZU1vZGVsLnJvbGxvdXRSdWxlc1xuICAgICAgICAgICAgICAgICAgICA/IHRoaXMuZm9ybUJ1aWxkZXIuYXJyYXkoc2V0dGluZ1ZhbHVlTW9kZWwucm9sbG91dFJ1bGVzLm1hcChyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlUm9sbG91dFJ1bGVGb3JtR3JvdXAociwgcmVhZE9ubHksIHNldHRpbmdWYWx1ZU1vZGVsLnNldHRpbmcuc2V0dGluZ1R5cGUpO1xuICAgICAgICAgICAgICAgICAgICB9KSlcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmZvcm1CdWlsZGVyLmFycmF5KFtdKSxcblxuICAgICAgICAgICAgdXBkYXRlZEF0OiBbeyB2YWx1ZTogc2V0dGluZ1ZhbHVlTW9kZWwudXBkYXRlZEF0LCBkaXNhYmxlZDogdHJ1ZSB9XSxcbiAgICAgICAgICAgIGxhc3RVcGRhdGVyVXNlckVtYWlsOiBbeyB2YWx1ZTogc2V0dGluZ1ZhbHVlTW9kZWwubGFzdFVwZGF0ZXJVc2VyRW1haWwsIGRpc2FibGVkOiB0cnVlIH1dLFxuICAgICAgICAgICAgbGFzdFVwZGF0ZXJVc2VyRnVsbE5hbWU6IFt7IHZhbHVlOiBzZXR0aW5nVmFsdWVNb2RlbC5sYXN0VXBkYXRlclVzZXJGdWxsTmFtZSwgZGlzYWJsZWQ6IHRydWUgfV0sXG5cbiAgICAgICAgICAgIHJvbGxvdXRQZXJjZW50YWdlSXRlbXNTdW06IFt7IHZhbHVlOiAxMDAsIGRpc2FibGVkOiBmYWxzZSB9LCBbVmFsaWRhdG9ycy5taW4oMTAwKSwgVmFsaWRhdG9ycy5tYXgoMTAwKV1dLFxuICAgICAgICAgICAgLy8gRGVjb3JhdGlvblxuICAgICAgICAgICAgc2V0dGluZzogdGhpcy5mb3JtQnVpbGRlci5ncm91cCh7XG4gICAgICAgICAgICAgICAgc2V0dGluZ0lkOiBbeyB2YWx1ZTogc2V0dGluZ1ZhbHVlTW9kZWwuc2V0dGluZy5zZXR0aW5nSWQsIGRpc2FibGVkOiB0cnVlIH1dLFxuICAgICAgICAgICAgICAgIGtleTogW3sgdmFsdWU6IHNldHRpbmdWYWx1ZU1vZGVsLnNldHRpbmcua2V5LCBkaXNhYmxlZDogdHJ1ZSB9XSxcbiAgICAgICAgICAgICAgICBuYW1lOiBbeyB2YWx1ZTogc2V0dGluZ1ZhbHVlTW9kZWwuc2V0dGluZy5uYW1lLCBkaXNhYmxlZDogdHJ1ZSB9XSxcbiAgICAgICAgICAgICAgICBoaW50OiBbeyB2YWx1ZTogc2V0dGluZ1ZhbHVlTW9kZWwuc2V0dGluZy5oaW50LCBkaXNhYmxlZDogdHJ1ZSB9XSxcbiAgICAgICAgICAgICAgICBzZXR0aW5nVHlwZTogW3sgdmFsdWU6IHNldHRpbmdWYWx1ZU1vZGVsLnNldHRpbmcuc2V0dGluZ1R5cGUsIGRpc2FibGVkOiB0cnVlIH1dLFxuICAgICAgICAgICAgICAgIGNyZWF0b3JFbWFpbDogW3sgdmFsdWU6IHNldHRpbmdWYWx1ZU1vZGVsLnNldHRpbmcuY3JlYXRvckVtYWlsLCBkaXNhYmxlZDogdHJ1ZSB9XSxcbiAgICAgICAgICAgICAgICBjcmVhdG9yRnVsbE5hbWU6IFt7IHZhbHVlOiBzZXR0aW5nVmFsdWVNb2RlbC5zZXR0aW5nLmNyZWF0b3JGdWxsTmFtZSwgZGlzYWJsZWQ6IHRydWUgfV0sXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBbeyB2YWx1ZTogc2V0dGluZ1ZhbHVlTW9kZWwuc2V0dGluZy5jcmVhdGVkQXQsIGRpc2FibGVkOiB0cnVlIH1dXG4gICAgICAgICAgICB9KSxcblxuICAgICAgICAgICAgaW50ZWdyYXRpb25MaW5rczogc2V0dGluZ1ZhbHVlTW9kZWwuaW50ZWdyYXRpb25MaW5rcyA/IHRoaXMuZm9ybUJ1aWxkZXIuYXJyYXkoc2V0dGluZ1ZhbHVlTW9kZWwuaW50ZWdyYXRpb25MaW5rcy5tYXAoaWwgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcbiAgICAgICAgICAgICAgICAgICAga2V5OiBbeyB2YWx1ZTogaWwua2V5LCBkaXNhYmxlZDogdHJ1ZSB9XSxcbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IFt7IHZhbHVlOiBpbC5kZXNjcmlwdGlvbiwgZGlzYWJsZWQ6IHRydWUgfV0sXG4gICAgICAgICAgICAgICAgICAgIGludGVncmF0aW9uTGlua1R5cGU6IFt7IHZhbHVlOiBpbC5pbnRlZ3JhdGlvbkxpbmtUeXBlLCBkaXNhYmxlZDogdHJ1ZSB9XSxcbiAgICAgICAgICAgICAgICAgICAgdXJsOiBbeyB2YWx1ZTogaWwudXJsLCBkaXNhYmxlZDogdHJ1ZSB9XSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pKSA6IHRoaXMuZm9ybUJ1aWxkZXIuYXJyYXkoW10pXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNyZWF0ZVJvbGxvdXRQZXJjZW50YWdlSXRlbUZvcm1Hcm91cChwOiBSb2xsb3V0UGVyY2VudGFnZUl0ZW1Nb2RlbCwgcmVhZE9ubHk6IGJvb2xlYW4sIHNldHRpbmdUeXBlOiBTZXR0aW5nVHlwZSB8IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtQnVpbGRlci5ncm91cCh7XG4gICAgICAgICAgICBwZXJjZW50YWdlOiBbeyB2YWx1ZTogcC5wZXJjZW50YWdlLCBkaXNhYmxlZDogcmVhZE9ubHkgfSwgW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWluKDApLCBWYWxpZGF0b3JzLm1heCgxMDApXV0sXG4gICAgICAgICAgICB2YWx1ZTogW1xuICAgICAgICAgICAgICAgIHsgdmFsdWU6IHAudmFsdWUsIGRpc2FibGVkOiByZWFkT25seSB9LFxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0VmFsaWRhdG9yc0ZvclNldHRpbmdUeXBlKHNldHRpbmdUeXBlKVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHZhbHVlRGlzYWJsZWQ6IFtcbiAgICAgICAgICAgICAgICB7IHZhbHVlOiBwLnZhbHVlLCBkaXNhYmxlZDogdHJ1ZSB9LCAvLyBGb3IgcGVyY2VudGFnZSBpdGVtIHZhbHVlXG4gICAgICAgICAgICBdXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNyZWF0ZVJvbGxvdXRSdWxlRm9ybUdyb3VwKHI6IFJvbGxvdXRSdWxlTW9kZWwsIHJlYWRPbmx5OiBib29sZWFuLCBzZXR0aW5nVHlwZTogU2V0dGluZ1R5cGUgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHIuY29tcGFyYXRvcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgICAgICAgICAgIHR5cGU6IFt7IHZhbHVlOiAwLCBkaXNhYmxlZDogdHJ1ZSB9XSxcbiAgICAgICAgICAgICAgICBjb21wYXJpc29uQXR0cmlidXRlOiBbeyB2YWx1ZTogci5jb21wYXJpc29uQXR0cmlidXRlLCBkaXNhYmxlZDogcmVhZE9ubHkgfSwgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcbiAgICAgICAgICAgICAgICBjb21wYXJhdG9yOiBbeyB2YWx1ZTogci5jb21wYXJhdG9yLCBkaXNhYmxlZDogcmVhZE9ubHkgfSwgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcbiAgICAgICAgICAgICAgICBjb21wYXJpc29uVmFsdWU6IFt7IHZhbHVlOiByLmNvbXBhcmlzb25WYWx1ZSwgZGlzYWJsZWQ6IHJlYWRPbmx5IH0sIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgdmFsdWU6IFtcbiAgICAgICAgICAgICAgICAgICAgeyB2YWx1ZTogci52YWx1ZSwgZGlzYWJsZWQ6IHJlYWRPbmx5IH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0VmFsaWRhdG9yc0ZvclNldHRpbmdUeXBlKHNldHRpbmdUeXBlKVxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChyLnNlZ21lbnRDb21wYXJhdG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtQnVpbGRlci5ncm91cCh7XG4gICAgICAgICAgICAgICAgdHlwZTogW3sgdmFsdWU6IDEsIGRpc2FibGVkOiB0cnVlIH1dLFxuICAgICAgICAgICAgICAgIHNlZ21lbnRDb21wYXJhdG9yOiBbeyB2YWx1ZTogci5zZWdtZW50Q29tcGFyYXRvciwgZGlzYWJsZWQ6IHJlYWRPbmx5IH0sIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgc2VnbWVudElkOiBbeyB2YWx1ZTogci5zZWdtZW50SWQsIGRpc2FibGVkOiByZWFkT25seSB9LCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBbXG4gICAgICAgICAgICAgICAgICAgIHsgdmFsdWU6IHIudmFsdWUsIGRpc2FibGVkOiByZWFkT25seSB9LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldFZhbGlkYXRvcnNGb3JTZXR0aW5nVHlwZShzZXR0aW5nVHlwZSlcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcm9sbG91dCBydWxlJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFZhbGlkYXRvcnNGb3JTZXR0aW5nVHlwZShzZXR0aW5nVHlwZTogU2V0dGluZ1R5cGUgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgc3dpdGNoIChzZXR0aW5nVHlwZSkge1xuICAgICAgICAgICAgY2FzZSBTZXR0aW5nVHlwZS5JbnQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtWYWxpZGF0b3JzLnJlcXVpcmVkLFxuICAgICAgICAgICAgICAgIFZhbGlkYXRvcnMubWluKC0yMTQ3NDgzNjQ4KSwgVmFsaWRhdG9ycy5tYXgoMjE0NzQ4MzY0NyksIFZhbGlkYXRvcnMucGF0dGVybignXlstK10/WzAtOV1cXFxcZCokJyldO1xuICAgICAgICAgICAgY2FzZSBTZXR0aW5nVHlwZS5Eb3VibGU6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1pbigtMS43OTc2OTMxMzQ4NjIzMkUrMzA4KSwgVmFsaWRhdG9ycy5tYXgoMS43OTc2OTMxMzQ4NjIzMkUrMzA4KV07XG4gICAgICAgICAgICBjYXNlIFNldHRpbmdUeXBlLlN0cmluZzpcbiAgICAgICAgICAgIGNhc2UgU2V0dGluZ1R5cGUuQm9vbGVhbjpcbiAgICAgICAgICAgICAgICByZXR1cm4gW1ZhbGlkYXRvcnMucmVxdWlyZWRdO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEFsbFJvbGxvdXRSdWxlcyhmb3JtR3JvdXA6IFVudHlwZWRGb3JtR3JvdXApIHtcbiAgICAgICAgY29uc3Qgc2V0dGluZ1ZhbHVlcyA9IGZvcm1Hcm91cC5nZXQoJ3NldHRpbmdWYWx1ZXMnKSBhcyBVbnR5cGVkRm9ybUFycmF5O1xuICAgICAgICBjb25zdCByb2xsb3V0UnVsZXMgPSBzZXR0aW5nVmFsdWVzLmNvbnRyb2xzLm1hcChjdiA9PiAoY3YuZ2V0KCdyb2xsb3V0UnVsZXMnKSBhcyBVbnR5cGVkRm9ybUFycmF5KS52YWx1ZSk7XG4gICAgICAgIHJldHVybiByb2xsb3V0UnVsZXMubGVuZ3RoID09PSAwID8gcm9sbG91dFJ1bGVzIDogcm9sbG91dFJ1bGVzLnJlZHVjZSgoYSwgYikgPT4gYS5jb25jYXQoYikpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q29tcGFyaXNvbkF0dHJpYnV0ZXMocm9sbG91dFJ1bGVzOiBhbnlbXSkge1xuICAgICAgICBpZiAocm9sbG91dFJ1bGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRDb21wYXJpc29uQXR0cmlidXRlcyA9IHJvbGxvdXRSdWxlcy5tYXAociA9PiByLmNvbXBhcmlzb25BdHRyaWJ1dGUpO1xuXG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0Q29tcGFyaXNvbkF0dHJpYnV0ZXMgPSBbJ0lkZW50aWZpZXInLCAnRW1haWwnLCAnQ291bnRyeSddO1xuICAgICAgICAgICAgY29uc3QgY29tcGFyaXNvbkF0dHJpYnV0ZXMgPSBjdXJyZW50Q29tcGFyaXNvbkF0dHJpYnV0ZXMuZmlsdGVyKGMgPT4gZGVmYXVsdENvbXBhcmlzb25BdHRyaWJ1dGVzLmluZGV4T2YoYykgPT09IC0xKTtcbiAgICAgICAgICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoY29tcGFyaXNvbkF0dHJpYnV0ZXMpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldENvbXBhcmlzb25WYWx1ZVR5cGUoY29tcGFyYXRvcjogUm9sbG91dFJ1bGVDb21wYXJhdG9yKSB7XG4gICAgICAgIHN3aXRjaCAoY29tcGFyYXRvcikge1xuICAgICAgICAgICAgY2FzZSBSb2xsb3V0UnVsZUNvbXBhcmF0b3IuTnVtYmVyRXF1YWxzOlxuICAgICAgICAgICAgY2FzZSBSb2xsb3V0UnVsZUNvbXBhcmF0b3IuTnVtYmVyRG9lc05vdEVxdWFsOlxuICAgICAgICAgICAgY2FzZSBSb2xsb3V0UnVsZUNvbXBhcmF0b3IuTnVtYmVyTGVzczpcbiAgICAgICAgICAgIGNhc2UgUm9sbG91dFJ1bGVDb21wYXJhdG9yLk51bWJlckxlc3NPckVxdWFsczpcbiAgICAgICAgICAgIGNhc2UgUm9sbG91dFJ1bGVDb21wYXJhdG9yLk51bWJlckdyZWF0ZXI6XG4gICAgICAgICAgICBjYXNlIFJvbGxvdXRSdWxlQ29tcGFyYXRvci5OdW1iZXJHcmVhdGVyT3JFcXVhbHM6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdudW1iZXInO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gJ3RleHQnO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbm9ybWFsaXplQ29tcGFyaXNvblZhbHVlKGNvbXBhcmF0b3I6IFJvbGxvdXRSdWxlQ29tcGFyYXRvciB8IHVuZGVmaW5lZCwgY29tcGFyaXNvblZhbHVlOiBhbnkpIHtcbiAgICAgICAgLy8gSW4gdGhlIGNhc2Ugb2YgbnVtYmVyIGlucHV0cyB2YWx1ZSBpcyBhIG51bWJlciBidXQgQVBJIGV4cGVjdHNcbiAgICAgICAgLy8gYSBzdHJpbmcsIHNvIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgaXQncyBjb252ZXJ0ZWQgdG8gc3RyaW5nLlxuICAgICAgICByZXR1cm4gY29tcGFyYXRvciAmJiB0aGlzLmdldENvbXBhcmlzb25WYWx1ZVR5cGUoY29tcGFyYXRvcikgPT09IFwibnVtYmVyXCJcbiAgICAgICAgICAgID8gRm9ybUhlbHBlci5ub3JtYWxpemVOdW1iZXJTdG9yZWRBc1N0cmluZyhjb21wYXJpc29uVmFsdWUpXG4gICAgICAgICAgICA6IGNvbXBhcmlzb25WYWx1ZTtcbiAgICB9XG59XG4iXX0=