ng-configcat-publicapi-ui 4.2.2 → 5.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.
- package/README.md +2 -2
- package/fesm2022/ng-configcat-publicapi-ui.mjs +4240 -3534
- package/fesm2022/ng-configcat-publicapi-ui.mjs.map +1 -1
- package/index.d.ts +476 -3
- package/package.json +11 -10
- package/src/css/button.scss +83 -0
- package/src/css/controls.scss +390 -0
- package/src/css/dialog.scss +63 -0
- package/src/css/icon.scss +7 -0
- package/src/css/slider.scss +82 -0
- package/src/css/snackbar.scss +16 -0
- package/src/css/table.scss +142 -0
- package/src/css/theme.scss +47 -0
- package/src/css/tooltip.scss +12 -0
- package/src/css/variables.scss +324 -0
- package/src/css/vars/auth.scss +24 -0
- package/src/css/vars/banner.scss +116 -0
- package/src/css/vars/box.scss +48 -0
- package/src/css/vars/config-overview.scss +27 -0
- package/src/css/vars/flag.scss +146 -0
- package/src/css/vars/header.scss +24 -0
- package/src/css/vars/icon.scss +33 -0
- package/src/css/vars/logo.scss +19 -0
- package/src/css/vars/notification.scss +38 -0
- package/src/css/vars/overview.scss +51 -0
- package/src/css/vars/prism.scss +44 -0
- package/src/css/vars/sidenav.scss +42 -0
- package/src/css/vars/theme.scss +78 -0
- package/src/public-api.scss +208 -0
- package/esm2022/lib/_directives/index.mjs +0 -2
- package/esm2022/lib/_directives/input-display-normalizer.directive.mjs +0 -38
- package/esm2022/lib/_models/deleteSettingModel.mjs +0 -2
- package/esm2022/lib/_models/flag-state.mjs +0 -2
- package/esm2022/lib/_models/index.mjs +0 -4
- package/esm2022/lib/_models/setting-value-formgroup.mjs +0 -2
- package/esm2022/lib/_models/settingValuesModel.mjs +0 -2
- package/esm2022/lib/_models/updateSettingValuesModel.mjs +0 -2
- package/esm2022/lib/_models/user-comparator.mjs +0 -100
- package/esm2022/lib/_services/app-data-adapter.mjs +0 -18
- package/esm2022/lib/_services/comparison-value-list-helper.mjs +0 -72
- package/esm2022/lib/_services/date-helper.mjs +0 -56
- package/esm2022/lib/_services/form-generator.mjs +0 -359
- package/esm2022/lib/_services/form-helper.mjs +0 -163
- package/esm2022/lib/_services/index.mjs +0 -3
- package/esm2022/lib/_services/messaging.service.mjs +0 -26
- package/esm2022/lib/_services/platform-helper.mjs +0 -7
- package/esm2022/lib/_services/public-api.service.mjs +0 -77
- package/esm2022/lib/_services/setting-list-form-helper.mjs +0 -171
- package/esm2022/lib/_services/tracking.directive.mjs +0 -16
- package/esm2022/lib/ace-editor/ace-editor.component.mjs +0 -137
- package/esm2022/lib/authorization/authorization.component.mjs +0 -62
- package/esm2022/lib/base/base-select.component.mjs +0 -27
- package/esm2022/lib/base/base.component.mjs +0 -48
- package/esm2022/lib/bootstrap.mjs +0 -11
- package/esm2022/lib/configuration.mjs +0 -14
- package/esm2022/lib/dialogs/confirmation-dialog/confirmation-dialog.mjs +0 -28
- package/esm2022/lib/dialogs/delete-setting-dialog/delete-setting-dialog.component.mjs +0 -27
- package/esm2022/lib/dialogs/expand-dialog/expand-dialog.component.mjs +0 -80
- package/esm2022/lib/dialogs/info-dialog/info-dialog.mjs +0 -29
- package/esm2022/lib/dialogs/reason-dialog/reason-dialog.component.mjs +0 -36
- package/esm2022/lib/dialogs/reroute-dialog/reroute-dialog.mjs +0 -28
- package/esm2022/lib/dialogs/save-snackbar/save-snackbar.component.mjs +0 -14
- package/esm2022/lib/ng-configcat-publicapi-ui.module.mjs +0 -288
- package/esm2022/lib/selects/config-select/config-select.component.mjs +0 -60
- package/esm2022/lib/selects/environment-select/environment-select.component.mjs +0 -47
- package/esm2022/lib/selects/product-select/product-select.component.mjs +0 -40
- package/esm2022/lib/selects/setting-select/setting-select.component.mjs +0 -47
- package/esm2022/lib/setting-item/setting-item.component.mjs +0 -118
- package/esm2022/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.mjs +0 -81
- package/esm2022/lib/setting-list/setting/rollout-rules/rollout-rules.component.mjs +0 -293
- package/esm2022/lib/setting-list/setting/setting.component.mjs +0 -136
- package/esm2022/lib/setting-list/setting/value/value.component.mjs +0 -37
- package/esm2022/lib/setting-list/setting-list.component.mjs +0 -194
- package/esm2022/lib/v2/feature-flag/date-time-picker/date-time-picker.component.mjs +0 -123
- package/esm2022/lib/v2/feature-flag/dependees-dialog/dependees-dialog.component.mjs +0 -30
- package/esm2022/lib/v2/feature-flag/evaluation-formula/evaluation-formula.component.mjs +0 -220
- package/esm2022/lib/v2/feature-flag/evaluation-formula/feature-flag-value/feature-flag-value.component.mjs +0 -61
- package/esm2022/lib/v2/feature-flag/evaluation-formula/popout-text-editor-dialog/popout-text-editor-dialog.component.mjs +0 -72
- package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/condition-chip/condition-chip.component.mjs +0 -25
- package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/conditions.component.mjs +0 -105
- package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/prerequisite-flag-condition/prerequisite-flag-condition.component.mjs +0 -75
- package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/segment-condition/segment-condition.component.mjs +0 -48
- package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/comparator-dialog/comparator-dialog.component.mjs +0 -113
- package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/popout-list-editor-dialog/popout-list-editor-dialog.component.mjs +0 -251
- package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/user-condition.component.mjs +0 -444
- package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/percentage-options/percentage-options.component.mjs +0 -84
- package/esm2022/lib/v2/feature-flag/evaluation-formula/targeting-rule/targeting-rule.component.mjs +0 -129
- package/esm2022/lib/v2/feature-flag/feature-flag.component.mjs +0 -190
- package/esm2022/lib/v2/feature-flag/percentage-evaluation-attribute-dialog/percentage-evaluation-attribute-dialog.component.mjs +0 -65
- package/esm2022/lib/v2/feature-flag-item.component.mjs +0 -330
- package/esm2022/ng-configcat-publicapi-ui.mjs +0 -5
- package/esm2022/public-api.mjs +0 -15
- package/lib/_directives/index.d.ts +0 -1
- package/lib/_directives/input-display-normalizer.directive.d.ts +0 -13
- package/lib/_models/deleteSettingModel.d.ts +0 -6
- package/lib/_models/flag-state.d.ts +0 -20
- package/lib/_models/index.d.ts +0 -3
- package/lib/_models/setting-value-formgroup.d.ts +0 -69
- package/lib/_models/settingValuesModel.d.ts +0 -11
- package/lib/_models/updateSettingValuesModel.d.ts +0 -7
- package/lib/_models/user-comparator.d.ts +0 -84
- package/lib/_services/app-data-adapter.d.ts +0 -7
- package/lib/_services/comparison-value-list-helper.d.ts +0 -17
- package/lib/_services/date-helper.d.ts +0 -6
- package/lib/_services/form-generator.d.ts +0 -59
- package/lib/_services/form-helper.d.ts +0 -21
- package/lib/_services/index.d.ts +0 -2
- package/lib/_services/messaging.service.d.ts +0 -12
- package/lib/_services/platform-helper.d.ts +0 -3
- package/lib/_services/public-api.service.d.ts +0 -21
- package/lib/_services/setting-list-form-helper.d.ts +0 -19
- package/lib/_services/tracking.directive.d.ts +0 -6
- package/lib/ace-editor/ace-editor.component.d.ts +0 -32
- package/lib/authorization/authorization.component.d.ts +0 -21
- package/lib/base/base-select.component.d.ts +0 -10
- package/lib/base/base.component.d.ts +0 -18
- package/lib/bootstrap.d.ts +0 -13
- package/lib/configuration.d.ts +0 -9
- package/lib/dialogs/confirmation-dialog/confirmation-dialog.d.ts +0 -19
- package/lib/dialogs/delete-setting-dialog/delete-setting-dialog.component.d.ts +0 -17
- package/lib/dialogs/expand-dialog/expand-dialog.component.d.ts +0 -25
- package/lib/dialogs/info-dialog/info-dialog.d.ts +0 -17
- package/lib/dialogs/reason-dialog/reason-dialog.component.d.ts +0 -15
- package/lib/dialogs/reroute-dialog/reroute-dialog.d.ts +0 -20
- package/lib/dialogs/save-snackbar/save-snackbar.component.d.ts +0 -8
- package/lib/ng-configcat-publicapi-ui.module.d.ts +0 -75
- package/lib/selects/config-select/config-select.component.d.ts +0 -17
- package/lib/selects/environment-select/environment-select.component.d.ts +0 -17
- package/lib/selects/product-select/product-select.component.d.ts +0 -14
- package/lib/selects/setting-select/setting-select.component.d.ts +0 -17
- package/lib/setting-item/setting-item.component.d.ts +0 -37
- package/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.d.ts +0 -27
- package/lib/setting-list/setting/rollout-rules/rollout-rules.component.d.ts +0 -61
- package/lib/setting-list/setting/setting.component.d.ts +0 -43
- package/lib/setting-list/setting/value/value.component.d.ts +0 -20
- package/lib/setting-list/setting-list.component.d.ts +0 -53
- package/lib/v2/feature-flag/date-time-picker/date-time-picker.component.d.ts +0 -25
- package/lib/v2/feature-flag/dependees-dialog/dependees-dialog.component.d.ts +0 -27
- package/lib/v2/feature-flag/evaluation-formula/evaluation-formula.component.d.ts +0 -41
- package/lib/v2/feature-flag/evaluation-formula/feature-flag-value/feature-flag-value.component.d.ts +0 -18
- package/lib/v2/feature-flag/evaluation-formula/popout-text-editor-dialog/popout-text-editor-dialog.component.d.ts +0 -30
- package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/condition-chip/condition-chip.component.d.ts +0 -10
- package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/conditions.component.d.ts +0 -27
- package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/prerequisite-flag-condition/prerequisite-flag-condition.component.d.ts +0 -36
- package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/segment-condition/segment-condition.component.d.ts +0 -21
- package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/comparator-dialog/comparator-dialog.component.d.ts +0 -79
- package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/popout-list-editor-dialog/popout-list-editor-dialog.component.d.ts +0 -63
- package/lib/v2/feature-flag/evaluation-formula/targeting-rule/conditions/user-condition/user-condition.component.d.ts +0 -94
- package/lib/v2/feature-flag/evaluation-formula/targeting-rule/percentage-options/percentage-options.component.d.ts +0 -31
- package/lib/v2/feature-flag/evaluation-formula/targeting-rule/targeting-rule.component.d.ts +0 -33
- package/lib/v2/feature-flag/feature-flag.component.d.ts +0 -49
- package/lib/v2/feature-flag/percentage-evaluation-attribute-dialog/percentage-evaluation-attribute-dialog.component.d.ts +0 -28
- package/lib/v2/feature-flag-item.component.d.ts +0 -66
- package/public-api.d.ts +0 -11
- package/public-api.scss +0 -350
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
-
import { BaseComponent } from '../base/base.component';
|
|
3
|
-
import { FormArray, FormControl, Validators } from '@angular/forms';
|
|
4
|
-
import { forkJoin, throwError } from 'rxjs';
|
|
5
|
-
import { ConfirmationDialogComponent } from '../dialogs/confirmation-dialog/confirmation-dialog';
|
|
6
|
-
import { ReasonDialogComponent } from '../dialogs/reason-dialog/reason-dialog.component';
|
|
7
|
-
import { SaveSnackbarComponent } from '../dialogs/save-snackbar/save-snackbar.component';
|
|
8
|
-
import { RerouteDialogComponent } from '../bootstrap';
|
|
9
|
-
import * as i0 from "@angular/core";
|
|
10
|
-
import * as i1 from "../_services/form-generator";
|
|
11
|
-
import * as i2 from "@angular/material/dialog";
|
|
12
|
-
import * as i3 from "@angular/material/snack-bar";
|
|
13
|
-
import * as i4 from "../_services";
|
|
14
|
-
import * as i5 from "@angular/common";
|
|
15
|
-
import * as i6 from "@angular/forms";
|
|
16
|
-
import * as i7 from "@angular/material/button";
|
|
17
|
-
import * as i8 from "@angular/material/icon";
|
|
18
|
-
import * as i9 from "./feature-flag/feature-flag.component";
|
|
19
|
-
import * as i10 from "../_services/tracking.directive";
|
|
20
|
-
export class FeatureFlagItemComponent extends BaseComponent {
|
|
21
|
-
constructor(formGenerator, dialog, snackBar, publicApiService) {
|
|
22
|
-
super(publicApiService);
|
|
23
|
-
this.formGenerator = formGenerator;
|
|
24
|
-
this.dialog = dialog;
|
|
25
|
-
this.snackBar = snackBar;
|
|
26
|
-
this.canDeleteSetting = true;
|
|
27
|
-
this.deleteSettingText = 'Delete setting';
|
|
28
|
-
this.showEnvironmentName = true;
|
|
29
|
-
this.deleteSettingRequested = new EventEmitter();
|
|
30
|
-
this.loadSucceeded = new EventEmitter();
|
|
31
|
-
this.loadFailed = new EventEmitter();
|
|
32
|
-
this.saveSucceeded = new EventEmitter();
|
|
33
|
-
this.saveFailed = new EventEmitter();
|
|
34
|
-
this.expandedStateChanged = new EventEmitter();
|
|
35
|
-
this.formValuesChanged = new EventEmitter();
|
|
36
|
-
this.loading = true;
|
|
37
|
-
this.showFeedBackMessage = false;
|
|
38
|
-
this.hasSettingValues = false;
|
|
39
|
-
this.hasOtherEnvironment = false;
|
|
40
|
-
this.dashboardBasePath = publicApiService.getDashboardBasePath();
|
|
41
|
-
}
|
|
42
|
-
ngOnInit() {
|
|
43
|
-
this.reloadSettingValues();
|
|
44
|
-
}
|
|
45
|
-
ngOnDestroy() {
|
|
46
|
-
this.unsubscribeFormValueChangesSubscription();
|
|
47
|
-
}
|
|
48
|
-
reloadSettingValues() {
|
|
49
|
-
this.loading = true;
|
|
50
|
-
this.createSettingValuesV2Service();
|
|
51
|
-
forkJoin({
|
|
52
|
-
segments: this.createSegmentsService().getSegments(this.productId),
|
|
53
|
-
settings: this.createSettingsService().getSettings(this.configId),
|
|
54
|
-
settingFormula: this.createSettingValuesV2Service().getSettingValueV2(this.environmentId, this.settingId)
|
|
55
|
-
}).subscribe(result => {
|
|
56
|
-
this.settings = result.settings;
|
|
57
|
-
this.prerequisiteSettings = this.settings.map(sv => {
|
|
58
|
-
return {
|
|
59
|
-
settingId: sv.settingId,
|
|
60
|
-
key: sv.key,
|
|
61
|
-
name: sv.name,
|
|
62
|
-
settingType: sv.settingType
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
this.segments = result.segments;
|
|
66
|
-
this.handleFetchedSettingValues(result.settingFormula);
|
|
67
|
-
this.loading = false;
|
|
68
|
-
this.loadSucceeded.emit();
|
|
69
|
-
}, (error) => {
|
|
70
|
-
this.loadFailed.emit(error);
|
|
71
|
-
return throwError(error);
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
handleFetchedSettingValues(model) {
|
|
75
|
-
this.settingFormula = model;
|
|
76
|
-
// when we have less we had previously
|
|
77
|
-
this.flagState = {
|
|
78
|
-
addButtonRenderState: {
|
|
79
|
-
hasPercentageOnlyRule: false,
|
|
80
|
-
renderTopAddButtons: false,
|
|
81
|
-
addRuleButtonTracker: []
|
|
82
|
-
},
|
|
83
|
-
readOnly: model.readOnly,
|
|
84
|
-
dependeeSettings: [],
|
|
85
|
-
settingValue: model,
|
|
86
|
-
panelExpanded: true,
|
|
87
|
-
prerequisiteSettings: this.getAvailablePrerequisiteSettings(model.setting.settingId)
|
|
88
|
-
};
|
|
89
|
-
this.unsubscribeFormValueChangesSubscription();
|
|
90
|
-
this.createFormGroupFromState(this.settingFormula);
|
|
91
|
-
this.formValueChangesSubscription = this.formGroup.valueChanges.subscribe(() => {
|
|
92
|
-
this.formValuesChanged.emit();
|
|
93
|
-
});
|
|
94
|
-
this.recalcAddButtons();
|
|
95
|
-
this.recalcPrerequisites();
|
|
96
|
-
}
|
|
97
|
-
unsubscribeFormValueChangesSubscription() {
|
|
98
|
-
if (this.formValueChangesSubscription) {
|
|
99
|
-
this.formValueChangesSubscription.unsubscribe();
|
|
100
|
-
this.formValueChangesSubscription = null;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
createFormGroupFromState(model) {
|
|
104
|
-
this.formGroup = this.formGenerator.generateSettingValuesFormGroup(model, model.readOnly, this.prerequisiteSettings, model.featureFlagLimitations);
|
|
105
|
-
}
|
|
106
|
-
getAvailablePrerequisiteSettings(settingId) {
|
|
107
|
-
return this.prerequisiteSettings.filter(ds => ds.settingId !== settingId);
|
|
108
|
-
}
|
|
109
|
-
revert() {
|
|
110
|
-
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
111
|
-
data: {
|
|
112
|
-
title: 'Revert to last saved state?',
|
|
113
|
-
body: 'All changes will be lost.',
|
|
114
|
-
yesButtonLabel: 'Revert',
|
|
115
|
-
noButtonLabel: 'No'
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
dialogRef.afterClosed().subscribe(result => {
|
|
119
|
-
if (result === 'yes') {
|
|
120
|
-
this.revertDirtyValuesFromState();
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
revertDirtyValuesFromState() {
|
|
125
|
-
if (this.formGroup.dirty) {
|
|
126
|
-
this.formGroup.setControl('defaultValue', this.formGenerator.generateValueFormGroup(this.settingFormula.defaultValue, this.settingFormula.setting.settingType, this.settingFormula.readOnly, this.settingFormula.featureFlagLimitations));
|
|
127
|
-
this.formGroup.setControl('percentageEvaluationAttribute', new FormControl({ value: this.settingFormula.percentageEvaluationAttribute, disabled: this.settingFormula.readOnly }, { validators: [Validators.max(1000)] }));
|
|
128
|
-
this.formGroup.setControl('targetingRules', new FormArray(this.settingFormula.targetingRules.map(ft => this.formGenerator.generateTargetingRuleFormGroup(ft, this.settingFormula.setting.settingType, this.settingFormula.readOnly, this.prerequisiteSettings, this.settingFormula.featureFlagLimitations))));
|
|
129
|
-
this.recalcAddButtons();
|
|
130
|
-
}
|
|
131
|
-
this.formGroup.markAsPristine();
|
|
132
|
-
this.formGroup.markAsUntouched();
|
|
133
|
-
this.recalcPrerequisites();
|
|
134
|
-
this.showFeedBackMessage = false;
|
|
135
|
-
}
|
|
136
|
-
submit() {
|
|
137
|
-
if (!this.formGroup) {
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
if (!this.formGroup.valid) {
|
|
141
|
-
this.showFeedBackMessage = true;
|
|
142
|
-
this.formGroup.markAllAsTouched();
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
this.showFeedBackMessage = false;
|
|
146
|
-
const value = {
|
|
147
|
-
...this.formGroup.getRawValue(),
|
|
148
|
-
};
|
|
149
|
-
this.updateSettingValues(value);
|
|
150
|
-
}
|
|
151
|
-
updateSettingValues(updateModel, reason = null) {
|
|
152
|
-
this.createSettingValuesV2Service().replaceSettingValueV2(this.environmentId, this.settingId, updateModel, reason)
|
|
153
|
-
.subscribe({
|
|
154
|
-
next: settingValues => {
|
|
155
|
-
this.handleFetchedSettingValues(settingValues);
|
|
156
|
-
this.snackBar.openFromComponent(SaveSnackbarComponent, { duration: 5000, panelClass: 'green-snackbar' });
|
|
157
|
-
this.saveSucceeded.emit();
|
|
158
|
-
},
|
|
159
|
-
error: (error) => {
|
|
160
|
-
if (error.status === 400 && error.error && error.error.Reason && error.error.Reason[0] === 'Reason required.') {
|
|
161
|
-
const dialogRef = this.dialog.open(ReasonDialogComponent, {
|
|
162
|
-
width: '450px'
|
|
163
|
-
});
|
|
164
|
-
dialogRef.afterClosed()
|
|
165
|
-
.subscribe(result => {
|
|
166
|
-
if (result && result.button === 'save' && result.reason) {
|
|
167
|
-
this.updateSettingValues(updateModel, result.reason);
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
if (error.status === 400 && error.error && error.error.SegmentCondition && error.error.SegmentCondition[0] === 'Segment not found.') {
|
|
173
|
-
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
174
|
-
width: '450px',
|
|
175
|
-
data: {
|
|
176
|
-
title: 'Cannot save feature flags',
|
|
177
|
-
body: 'A segment referenced by one of your feature flags has been deleted. Reload the config to see its latest state, apply your changes and try the save again.',
|
|
178
|
-
yesButtonLabel: 'Reload',
|
|
179
|
-
hideNoButton: true
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
dialogRef.afterClosed()
|
|
183
|
-
.subscribe(() => {
|
|
184
|
-
this.reloadSettingValues();
|
|
185
|
-
});
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
if (error.status === 400 && error.error && ('' + error.error).startsWith('Circular dependency detected.')) {
|
|
189
|
-
const errorMessage = ('' + error.error).slice('Circular dependency detected.'.length + 1);
|
|
190
|
-
this.dialog.open(ConfirmationDialogComponent, {
|
|
191
|
-
width: '450px',
|
|
192
|
-
data: {
|
|
193
|
-
title: 'Cannot save feature flags.',
|
|
194
|
-
body: 'Circular dependency detected between the following feature flags:<p>' + errorMessage + '</p>Please <strong>eliminate the circular dependency</strong> before saving your feature flags.',
|
|
195
|
-
yesButtonLabel: 'I understand',
|
|
196
|
-
hideNoButton: true
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
this.formGroup.setErrors({ internalServerError: 'Internal server error' });
|
|
202
|
-
this.formGroup.markAsTouched();
|
|
203
|
-
this.showFeedBackMessage = true;
|
|
204
|
-
this.saveFailed.emit();
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
onDeleteSettingRequested(setting) {
|
|
209
|
-
if (this.formGroup.dirty) {
|
|
210
|
-
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
211
|
-
data: {
|
|
212
|
-
title: 'Discard changes?',
|
|
213
|
-
body: 'You have unsaved feature flag changes. If you continue, unsaved changes will be lost.',
|
|
214
|
-
yesButtonLabel: 'Discard changes',
|
|
215
|
-
noButtonLabel: 'No'
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
dialogRef.afterClosed()
|
|
219
|
-
.subscribe(result => {
|
|
220
|
-
if (result === 'yes') {
|
|
221
|
-
this.revertDirtyValuesFromState();
|
|
222
|
-
this.deleteSettingInternal(setting);
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
this.deleteSettingInternal(setting);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
deleteSettingInternal(setting) {
|
|
231
|
-
this.deleteSettingRequested.emit({ config: this.settingFormula.config, environment: this.settingFormula.environment, setting: setting.setting });
|
|
232
|
-
}
|
|
233
|
-
subscriptionLimitReachedCalled() {
|
|
234
|
-
this.dialog.open(RerouteDialogComponent, {
|
|
235
|
-
data: {
|
|
236
|
-
title: 'You have reached the limits of your plan',
|
|
237
|
-
body: ` Upgrade your plan or join our <a href="https://configcat.com/referrals" target="_blank" rel="noopener noreferrer">referral program</a> to increase your limits.`,
|
|
238
|
-
yesButtonLabel: `See plans`,
|
|
239
|
-
yesButtonLink: this.dashboardBasePath + "/organization/plans",
|
|
240
|
-
noButtonLabel: `Close`
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
addSegmentConditionRequestedWithoutSegments() {
|
|
245
|
-
this.dialog.open(RerouteDialogComponent, {
|
|
246
|
-
data: {
|
|
247
|
-
title: 'There are no segments in this product yet.',
|
|
248
|
-
body: `Go ahead to the ConfiCat Dashboard and create your first user segment before adding it to a targeting rule.`,
|
|
249
|
-
yesButtonLabel: `Go to the dashboard`,
|
|
250
|
-
yesButtonLink: this.dashboardBasePath + "/product/" + this.productId + "/segments"
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
trackByIndex(index) {
|
|
255
|
-
return index;
|
|
256
|
-
}
|
|
257
|
-
recalcPrerequisites() {
|
|
258
|
-
const settingValue = this.settingFormula;
|
|
259
|
-
this.flagState.dependeeSettings = this.settings.filter(s => settingValue.settingIdsWherePrerequisite?.includes(s.settingId))
|
|
260
|
-
.map(s => { return { key: s.key, name: s.name, settingId: s.settingId }; });
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
recalcAddButtons() {
|
|
264
|
-
const state = this.flagState;
|
|
265
|
-
const group = this.formGroup;
|
|
266
|
-
state.addButtonRenderState.renderTopAddButtons = !group.controls.targetingRules.controls.length ||
|
|
267
|
-
this.hasOnlyPercentageRule(group);
|
|
268
|
-
if (!group.controls.targetingRules.controls.length) {
|
|
269
|
-
state.addButtonRenderState.addRuleButtonTracker = [];
|
|
270
|
-
state.addButtonRenderState.hasPercentageOnlyRule = false;
|
|
271
|
-
}
|
|
272
|
-
else {
|
|
273
|
-
const hasPercOnly = state.addButtonRenderState.hasPercentageOnlyRule = group.controls.targetingRules.controls.length > 0
|
|
274
|
-
&& this.formGenerator.isPercentageOnlyTargetingRule(group.controls.targetingRules.controls[group.controls.targetingRules.controls.length - 1]);
|
|
275
|
-
state.addButtonRenderState.addRuleButtonTracker = group.controls.targetingRules.controls.map((item, i, rules) => {
|
|
276
|
-
const isLastRule = i === group.controls.targetingRules.controls.length - 1;
|
|
277
|
-
const isBeforeLast = i === group.controls.targetingRules.controls.length - 2;
|
|
278
|
-
return {
|
|
279
|
-
showAddRuleButtons: hasPercOnly ? i === rules.length - 2 : i === rules.length - 1,
|
|
280
|
-
showOrChip: hasPercOnly ? i < rules.length - 2 : i < rules.length - 1,
|
|
281
|
-
renderSeparationArea: this.formGenerator.isPercentageOnlyTargetingRule(item) ||
|
|
282
|
-
(this.settingFormula.readOnly && (isLastRule || (hasPercOnly && isBeforeLast))),
|
|
283
|
-
};
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
hasOnlyPercentageRule(group) {
|
|
288
|
-
return group.controls.targetingRules.controls.length === 1 &&
|
|
289
|
-
this.formGenerator.isPercentageOnlyTargetingRule(group.controls.targetingRules.controls[0]);
|
|
290
|
-
}
|
|
291
|
-
expandedChanged(expandedState) {
|
|
292
|
-
this.flagState.panelExpanded = expandedState;
|
|
293
|
-
this.expandedStateChanged.emit();
|
|
294
|
-
}
|
|
295
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeatureFlagItemComponent, deps: [{ token: i1.FormGenerator }, { token: i2.MatDialog }, { token: i3.MatSnackBar }, { token: i4.PublicApiService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
296
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FeatureFlagItemComponent, selector: "configcat-feature-flag-item", inputs: { productId: "productId", environmentId: "environmentId", configId: "configId", settingId: "settingId", canDeleteSetting: "canDeleteSetting", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName" }, outputs: { deleteSettingRequested: "deleteSettingRequested", loadSucceeded: "loadSucceeded", loadFailed: "loadFailed", saveSucceeded: "saveSucceeded", saveFailed: "saveFailed", expandedStateChanged: "expandedStateChanged", formValuesChanged: "formValuesChanged" }, usesInheritance: true, ngImport: i0, template: "<div class=\"container\">\n <ng-container *ngIf=\"!loading\">\n <form [formGroup]=\"formGroup\" (ngSubmit)=\"submit()\" id=\"feature-flag-form\">\n <div [ngClass]=\"{'invalid-flag': formGroup.invalid}\">\n <app-feature-flag [formGroup]=\"formGroup\" [flagState]=\"flagState\" [segments]=\"segments\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\"\n [featureFlagLimitations]=\"settingFormula.featureFlagLimitations\" [hasOtherEnvironment]=\"false\"\n (subscriptionLimitReached)=\"subscriptionLimitReachedCalled()\"\n (addSegmentConditionRequestedWithoutSegments)=\"addSegmentConditionRequestedWithoutSegments()\"\n (prerequisiteConditionChanged)=\"recalcPrerequisites()\" (recalcAddButtons)=\"recalcAddButtons()\"\n (expandedChanged)=\"expandedChanged($event)\"\n [showEnvironmentName]=\"showEnvironmentName\" [environmentName]=\"settingFormula.environment.name\"\n [deleteSettingText]=\"deleteSettingText\" [canDeleteSetting]=\"canDeleteSetting\">\n </app-feature-flag>\n </div>\n <div class=\"save\" *ngIf=\"!settingFormula.readOnly && formGroup?.dirty\">\n <button class=\"save-button\" mat-flat-button color=\"warn\" type=\"submit\" [class.animate]=\"formGroup.dirty\"\n [track]=\"['save & publish click', 'feature flags and settings']\">\n <mat-icon>backup</mat-icon> <span> Save & publish changes</span>\n </button>\n <button type=\"button\" class=\"revert-button\" mat-stroked-button (click)=\"revert()\"\n [track]=\"['revert click', 'feature flags and settings']\">\n <span>Revert</span>\n </button>\n <div class=\"feedback\" *ngIf=\"formGroup.touched && formGroup.invalid && showFeedBackMessage\">\n <div class=\"error\" *ngIf=\"formGroup.errors && formGroup.errors.internalServerError\">\n <span>Something went wrong and we could not save your settings. You can try again or <a\n href=\"https://configcat.com/support\" target=\"_blank\" rel=\"noopener noreferrer\">contact\n us.</a></span>\n </div>\n <div class=\"error\" *ngIf=\"!formGroup.errors || !formGroup.errors.internalServerError\">\n <span>Oh no! A feature flag has invalid or missing data. </span>\n </div>\n </div>\n </div>\n </form>\n\n </ng-container>\n</div>", styles: [".container .expand-collapse{--mdc-text-button-container-height: 24px;--mdc-filled-button-container-height: 24px;--mdc-protected-button-container-height: 24px;--mdc-outlined-button-container-height: 24px;--mat-text-button-touch-target-display: none;--mat-filled-button-touch-target-display: none;--mat-protected-button-touch-target-display: none;--mat-outlined-button-touch-target-display: none;margin-left:auto;margin-top:.3rem;display:flex;flex-wrap:nowrap}.container .expand-collapse .btn{font-size:.6em;padding:0 8px;min-width:105px}.container .expand-collapse .btn mat-icon{font-size:14px;width:14px;height:14px;margin-right:4px;color:#838383}.container .expand-collapse .expand{margin-right:6px}.container .read-only-notification{margin-top:.6rem}.container .save{position:sticky;bottom:0;background-color:#fff;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;z-index:999;padding-top:.5rem;padding-bottom:.5rem}.container .save .save-button{animation:shadow-pulse 1s 3}.container .save .save-button:disabled{animation:none}.container .save>*{margin-top:.5rem;margin-bottom:.5rem;margin-right:.6em}.container .error{color:#f44336;padding:5px;font-size:.9em}.container .error a{color:#f44336;text-decoration:underline}@media (max-width: 750px){.expand-collapse{flex-wrap:wrap!important}.expand-collapse .btn{margin-bottom:2px}}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i7.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.FeatureFlagComponent, selector: "app-feature-flag", inputs: ["formGroup", "flagState", "segments", "featureFlagLimitations", "hasOtherEnvironment", "environmentName", "showEnvironmentName", "deleteSettingText", "canDeleteSetting"], outputs: ["addSegmentConditionRequestedWithoutSegments", "expandedChanged", "deleteSettingRequested", "subscriptionLimitReached", "prerequisiteConditionChanged", "recalcAddButtons"] }, { kind: "directive", type: i10.TrackingDirective, selector: "[track]", inputs: ["track"] }] }); }
|
|
297
|
-
}
|
|
298
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeatureFlagItemComponent, decorators: [{
|
|
299
|
-
type: Component,
|
|
300
|
-
args: [{ selector: 'configcat-feature-flag-item', template: "<div class=\"container\">\n <ng-container *ngIf=\"!loading\">\n <form [formGroup]=\"formGroup\" (ngSubmit)=\"submit()\" id=\"feature-flag-form\">\n <div [ngClass]=\"{'invalid-flag': formGroup.invalid}\">\n <app-feature-flag [formGroup]=\"formGroup\" [flagState]=\"flagState\" [segments]=\"segments\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\"\n [featureFlagLimitations]=\"settingFormula.featureFlagLimitations\" [hasOtherEnvironment]=\"false\"\n (subscriptionLimitReached)=\"subscriptionLimitReachedCalled()\"\n (addSegmentConditionRequestedWithoutSegments)=\"addSegmentConditionRequestedWithoutSegments()\"\n (prerequisiteConditionChanged)=\"recalcPrerequisites()\" (recalcAddButtons)=\"recalcAddButtons()\"\n (expandedChanged)=\"expandedChanged($event)\"\n [showEnvironmentName]=\"showEnvironmentName\" [environmentName]=\"settingFormula.environment.name\"\n [deleteSettingText]=\"deleteSettingText\" [canDeleteSetting]=\"canDeleteSetting\">\n </app-feature-flag>\n </div>\n <div class=\"save\" *ngIf=\"!settingFormula.readOnly && formGroup?.dirty\">\n <button class=\"save-button\" mat-flat-button color=\"warn\" type=\"submit\" [class.animate]=\"formGroup.dirty\"\n [track]=\"['save & publish click', 'feature flags and settings']\">\n <mat-icon>backup</mat-icon> <span> Save & publish changes</span>\n </button>\n <button type=\"button\" class=\"revert-button\" mat-stroked-button (click)=\"revert()\"\n [track]=\"['revert click', 'feature flags and settings']\">\n <span>Revert</span>\n </button>\n <div class=\"feedback\" *ngIf=\"formGroup.touched && formGroup.invalid && showFeedBackMessage\">\n <div class=\"error\" *ngIf=\"formGroup.errors && formGroup.errors.internalServerError\">\n <span>Something went wrong and we could not save your settings. You can try again or <a\n href=\"https://configcat.com/support\" target=\"_blank\" rel=\"noopener noreferrer\">contact\n us.</a></span>\n </div>\n <div class=\"error\" *ngIf=\"!formGroup.errors || !formGroup.errors.internalServerError\">\n <span>Oh no! A feature flag has invalid or missing data. </span>\n </div>\n </div>\n </div>\n </form>\n\n </ng-container>\n</div>", styles: [".container .expand-collapse{--mdc-text-button-container-height: 24px;--mdc-filled-button-container-height: 24px;--mdc-protected-button-container-height: 24px;--mdc-outlined-button-container-height: 24px;--mat-text-button-touch-target-display: none;--mat-filled-button-touch-target-display: none;--mat-protected-button-touch-target-display: none;--mat-outlined-button-touch-target-display: none;margin-left:auto;margin-top:.3rem;display:flex;flex-wrap:nowrap}.container .expand-collapse .btn{font-size:.6em;padding:0 8px;min-width:105px}.container .expand-collapse .btn mat-icon{font-size:14px;width:14px;height:14px;margin-right:4px;color:#838383}.container .expand-collapse .expand{margin-right:6px}.container .read-only-notification{margin-top:.6rem}.container .save{position:sticky;bottom:0;background-color:#fff;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;z-index:999;padding-top:.5rem;padding-bottom:.5rem}.container .save .save-button{animation:shadow-pulse 1s 3}.container .save .save-button:disabled{animation:none}.container .save>*{margin-top:.5rem;margin-bottom:.5rem;margin-right:.6em}.container .error{color:#f44336;padding:5px;font-size:.9em}.container .error a{color:#f44336;text-decoration:underline}@media (max-width: 750px){.expand-collapse{flex-wrap:wrap!important}.expand-collapse .btn{margin-bottom:2px}}\n"] }]
|
|
301
|
-
}], ctorParameters: () => [{ type: i1.FormGenerator }, { type: i2.MatDialog }, { type: i3.MatSnackBar }, { type: i4.PublicApiService }], propDecorators: { productId: [{
|
|
302
|
-
type: Input
|
|
303
|
-
}], environmentId: [{
|
|
304
|
-
type: Input
|
|
305
|
-
}], configId: [{
|
|
306
|
-
type: Input
|
|
307
|
-
}], settingId: [{
|
|
308
|
-
type: Input
|
|
309
|
-
}], canDeleteSetting: [{
|
|
310
|
-
type: Input
|
|
311
|
-
}], deleteSettingText: [{
|
|
312
|
-
type: Input
|
|
313
|
-
}], showEnvironmentName: [{
|
|
314
|
-
type: Input
|
|
315
|
-
}], deleteSettingRequested: [{
|
|
316
|
-
type: Output
|
|
317
|
-
}], loadSucceeded: [{
|
|
318
|
-
type: Output
|
|
319
|
-
}], loadFailed: [{
|
|
320
|
-
type: Output
|
|
321
|
-
}], saveSucceeded: [{
|
|
322
|
-
type: Output
|
|
323
|
-
}], saveFailed: [{
|
|
324
|
-
type: Output
|
|
325
|
-
}], expandedStateChanged: [{
|
|
326
|
-
type: Output
|
|
327
|
-
}], formValuesChanged: [{
|
|
328
|
-
type: Output
|
|
329
|
-
}] } });
|
|
330
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVhdHVyZS1mbGFnLWl0ZW0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctY29uZmlnY2F0LXB1YmxpY2FwaS11aS9zcmMvbGliL3YyL2ZlYXR1cmUtZmxhZy1pdGVtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWNvbmZpZ2NhdC1wdWJsaWNhcGktdWkvc3JjL2xpYi92Mi9mZWF0dXJlLWZsYWctaXRlbS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQzFGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUd2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBYSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUcvRSxPQUFPLEVBQWdCLFFBQVEsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUQsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sb0RBQW9ELENBQUM7QUFDakcsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sa0RBQWtELENBQUM7QUFJekYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sa0RBQWtELENBQUM7QUFFekYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sY0FBYyxDQUFDOzs7Ozs7Ozs7Ozs7QUFPdEQsTUFBTSxPQUFPLHdCQUF5QixTQUFRLGFBQWE7SUF3Q3pELFlBQ1UsYUFBNEIsRUFDNUIsTUFBaUIsRUFDakIsUUFBcUIsRUFDN0IsZ0JBQWtDO1FBRWxDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBTGhCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLFdBQU0sR0FBTixNQUFNLENBQVc7UUFDakIsYUFBUSxHQUFS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Q0FBQyxNQUFNLEtBQUssQ0FBQztZQUN4RCxJQUFJLENBQUMsYUFBYSxDQUFDLDZCQUE2QixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQy9GLENBQUM7SUFFRCxlQUFlLENBQUMsYUFBc0I7UUFDcEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDO1FBQzdDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNuQyxDQUFDOytHQTNWVSx3QkFBd0I7bUdBQXhCLHdCQUF3Qiwra0JDdEJyQyxnc0ZBc0NNOzs0RkRoQk8sd0JBQXdCO2tCQUxwQyxTQUFTOytCQUNFLDZCQUE2QjttS0FNOUIsU0FBUztzQkFBakIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFFRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFFSSxzQkFBc0I7c0JBQS9CLE1BQU07Z0JBRUcsYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxvQkFBb0I7c0JBQTdCLE1BQU07Z0JBQ0csaUJBQWlCO3NCQUExQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCYXNlQ29tcG9uZW50IH0gZnJvbSAnLi4vYmFzZS9iYXNlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTZWdtZW50TGlzdE1vZGVsLCBTZXR0aW5nRGF0YU1vZGVsLCBTZXR0aW5nRm9ybXVsYU1vZGVsLCBVcGRhdGVFdmFsdWF0aW9uRm9ybXVsYU1vZGVsIH0gZnJvbSAnbmctY29uZmlnY2F0LXB1YmxpY2FwaSc7XG5pbXBvcnQgeyBJRmxhZ1N0YXRlIH0gZnJvbSAnLi4vX21vZGVscy9mbGFnLXN0YXRlJztcbmltcG9ydCB7IEZvcm1BcnJheSwgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IElQcmVyZXF1aXNpdGVTZXR0aW5nLCBUYXJnZXRpbmdSdWxlRm9ybSwgVXBkYXRlU2V0dGluZ1ZhbHVlRm9ybSB9IGZyb20gJy4uL19tb2RlbHMvc2V0dGluZy12YWx1ZS1mb3JtZ3JvdXAnO1xuaW1wb3J0IHsgUHVibGljQXBpU2VydmljZSB9IGZyb20gJy4uL19zZXJ2aWNlcyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIGZvcmtKb2luLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBDb25maXJtYXRpb25EaWFsb2dDb21wb25lbnQgfSBmcm9tICcuLi9kaWFsb2dzL2NvbmZpcm1hdGlvbi1kaWFsb2cvY29uZmlybWF0aW9uLWRpYWxvZyc7XG5pbXBvcnQgeyBSZWFzb25EaWFsb2dDb21wb25lbnQgfSBmcm9tICcuLi9kaWFsb2dzL3JlYXNvbi1kaWFsb2cvcmVhc29uLWRpYWxvZy5jb21wb25lbnQnO1xuaW1wb3J0IHsgRm9ybUdlbmVyYXRvciB9IGZyb20gJy4uL19zZXJ2aWNlcy9mb3JtLWdlbmVyYXRvcic7XG5pbXBvcnQgeyBNYXREaWFsb2cgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgTWF0U25hY2tCYXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zbmFjay1iYXInO1xuaW1wb3J0IHsgU2F2ZVNuYWNrYmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vZGlhbG9ncy9zYXZlLXNuYWNrYmFyL3NhdmUtc25hY2tiYXIuY29tcG9uZW50JztcbmltcG9ydCB7IERlbGV0ZVNldHRpbmdNb2RlbCB9IGZyb20gJy4uL19tb2RlbHMnO1xuaW1wb3J0IHsgUmVyb3V0ZURpYWxvZ0NvbXBvbmVudCB9IGZyb20gJy4uL2Jvb3RzdHJhcCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2NvbmZpZ2NhdC1mZWF0dXJlLWZsYWctaXRlbScsXG4gIHRlbXBsYXRlVXJsOiAnLi9mZWF0dXJlLWZsYWctaXRlbS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2ZlYXR1cmUtZmxhZy1pdGVtLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgRmVhdHVyZUZsYWdJdGVtQ29tcG9uZW50IGV4dGVuZHMgQmFzZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICBASW5wdXQoKSBwcm9kdWN0SWQhOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGVudmlyb25tZW50SWQhOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGNvbmZpZ0lkITogc3RyaW5nO1xuICBASW5wdXQoKSBzZXR0aW5nSWQhOiBudW1iZXI7XG5cbiAgQElucHV0KCkgY2FuRGVsZXRlU2V0dGluZyA9IHRydWU7XG4gIEBJbnB1dCgpIGRlbGV0ZVNldHRpbmdUZXh0ID0gJ0RlbGV0ZSBzZXR0aW5nJztcbiAgQElucHV0KCkgc2hvd0Vudmlyb25tZW50TmFtZSA9IHRydWU7XG5cbiAgQE91dHB1dCgpIGRlbGV0ZVNldHRpbmdSZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgQE91dHB1dCgpIGxvYWRTdWNjZWVkZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBsb2FkRmFpbGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgc2F2ZVN1Y2NlZWRlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHNhdmVGYWlsZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBleHBhbmRlZFN0YXRlQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGZvcm1WYWx1ZXNDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHNlZ21lbnRzITogU2VnbWVudExpc3RNb2RlbFtdO1xuICBkYXNoYm9hcmRCYXNlUGF0aDogc3RyaW5nO1xuICBsb2FkaW5nID0gdHJ1ZTtcblxuICBmb3JtR3JvdXA6IEZvcm1Hcm91cDxVcGRhdGVTZXR0aW5nVmFsdWVGb3JtPjtcbiAgZm9ybVZhbHVlQ2hhbmdlc1N1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gIHNldHRpbmdzOiBTZXR0aW5nRGF0YU1vZGVsW107XG5cbiAgZmxhZ1N0YXRlOiBJRmxhZ1N0YXRlO1xuXG4gIHNldHRpbmdGb3JtdWxhOiBTZXR0aW5nRm9ybXVsYU1vZGVsO1xuICBwcmVyZXF1aXNpdGVTZXR0aW5nczogSVByZXJlcXVpc2l0ZVNldHRpbmdbXTtcblxuICBzaG93RmVlZEJhY2tNZXNzYWdlID0gZmFsc2U7XG5cbiAgaGFzU2V0dGluZ1ZhbHVlcyA9IGZhbHNlO1xuXG4gIGhhc090aGVyRW52aXJvbm1lbnQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGZvcm1HZW5lcmF0b3I6IEZvcm1HZW5lcmF0b3IsXG4gICAgcHJpdmF0ZSBkaWFsb2c6IE1hdERpYWxvZyxcbiAgICBwcml2YXRlIHNuYWNrQmFyOiBNYXRTbmFja0JhcixcbiAgICBwdWJsaWNBcGlTZXJ2aWNlOiBQdWJsaWNBcGlTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKHB1YmxpY0FwaVNlcnZpY2UpO1xuICAgIHRoaXMuZGFzaGJvYXJkQmFzZVBhdGggPSBwdWJsaWNBcGlTZXJ2aWNlLmdldERhc2hib2FyZEJhc2VQYXRoKCk7XG4gIH1cblxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMucmVsb2FkU2V0dGluZ1ZhbHVlcygpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy51bnN1YnNjcmliZUZvcm1WYWx1ZUNoYW5nZXNTdWJzY3JpcHRpb24oKTtcbiAgfVxuXG4gIHJlbG9hZFNldHRpbmdWYWx1ZXMoKSB7XG5cbiAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgIHRoaXMuY3JlYXRlU2V0dGluZ1ZhbHVlc1YyU2VydmljZSgpXG5cbiAgICBmb3JrSm9pbih7XG4gICAgICBzZWdtZW50czogdGhpcy5jcmVhdGVTZWdtZW50c1NlcnZpY2UoKS5nZXRTZWdtZW50cyh0aGlzLnByb2R1Y3RJZCksXG4gICAgICBzZXR0aW5nczogdGhpcy5jcmVhdGVTZXR0aW5nc1NlcnZpY2UoKS5nZXRTZXR0aW5ncyh0aGlzLmNvbmZpZ0lkKSxcbiAgICAgIHNldHRpbmdGb3JtdWxhOiB0aGlzLmNyZWF0ZVNldHRpbmdWYWx1ZXNWMlNlcnZpY2UoKS5nZXRTZXR0aW5nVmFsdWVWMih0aGlzLmVudmlyb25tZW50SWQsIHRoaXMuc2V0dGluZ0lkKVxuICAgIH0pLnN1YnNjcmliZShyZXN1bHQgPT4ge1xuICAgICAgdGhpcy5zZXR0aW5ncyA9IHJlc3VsdC5zZXR0aW5ncztcbiAgICAgIHRoaXMucHJlcmVxdWlzaXRlU2V0dGluZ3MgPSB0aGlzLnNldHRpbmdzLm1hcChzdiA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc2V0dGluZ0lkOiBzdi5zZXR0aW5nSWQsXG4gICAgICAgICAga2V5OiBzdi5rZXksXG4gICAgICAgICAgbmFtZTogc3YubmFtZSxcbiAgICAgICAgICBzZXR0aW5nVHlwZTogc3Yuc2V0dGluZ1R5cGVcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLnNlZ21lbnRzID0gcmVzdWx0LnNlZ21lbnRzO1xuICAgICAgdGhpcy5oYW5kbGVGZXRjaGVkU2V0dGluZ1ZhbHVlcyhyZXN1bHQuc2V0dGluZ0Zvcm11bGEpO1xuICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmxvYWRTdWNjZWVkZWQuZW1pdCgpO1xuICAgIH0sXG4gICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5sb2FkRmFpbGVkLmVtaXQoZXJyb3IpO1xuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvcik7XG4gICAgICB9KTtcbiAgfVxuXG4gIGhhbmRsZUZldGNoZWRTZXR0aW5nVmFsdWVzKG1vZGVsOiBTZXR0aW5nRm9ybXVsYU1vZGVsKSB7XG4gICAgdGhpcy5zZXR0aW5nRm9ybXVsYSA9IG1vZGVsO1xuICAgIC8vIHdoZW4gd2UgaGF2ZSBsZXNzIHdlIGhhZCBwcmV2aW91c2x5XG4gICAgdGhpcy5mbGFnU3RhdGUgPSB7XG4gICAgICBhZGRCdXR0b25SZW5kZXJTdGF0ZToge1xuICAgICAgICBoYXNQZXJjZW50YWdlT25seVJ1bGU6IGZhbHNlLFxuICAgICAgICByZW5kZXJUb3BBZGRCdXR0b25zOiBmYWxzZSxcbiAgICAgICAgYWRkUnVsZUJ1dHRvblRyYWNrZXI6IFtdXG4gICAgICB9LFxuICAgICAgcmVhZE9ubHk6IG1vZGVsLnJlYWRPbmx5LFxuICAgICAgZGVwZW5kZWVTZXR0aW5nczogW10sXG4gICAgICBzZXR0aW5nVmFsdWU6IG1vZGVsLFxuICAgICAgcGFuZWxFeHBhbmRlZDogdHJ1ZSxcbiAgICAgIHByZXJlcXVpc2l0ZVNldHRpbmdzOiB0aGlzLmdldEF2YWlsYWJsZVByZXJlcXVpc2l0ZVNldHRpbmdzKG1vZGVsLnNldHRpbmcuc2V0dGluZ0lkKVxuICAgIH1cblxuICAgIHRoaXMudW5zdWJzY3JpYmVGb3JtVmFsdWVDaGFuZ2VzU3Vic2NyaXB0aW9uKCk7XG5cbiAgICB0aGlzLmNyZWF0ZUZvcm1Hcm91cEZyb21TdGF0ZSh0aGlzLnNldHRpbmdGb3JtdWxhKTtcblxuICAgIHRoaXMuZm9ybVZhbHVlQ2hhbmdlc1N1YnNjcmlwdGlvbiA9IHRoaXMuZm9ybUdyb3VwLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5mb3JtVmFsdWVzQ2hhbmdlZC5lbWl0KCk7XG4gICAgfSlcblxuICAgIHRoaXMucmVjYWxjQWRkQnV0dG9ucygpO1xuICAgIHRoaXMucmVjYWxjUHJlcmVxdWlzaXRlcygpO1xuICB9XG5cbiAgdW5zdWJzY3JpYmVGb3JtVmFsdWVDaGFuZ2VzU3Vic2NyaXB0aW9uKCkge1xuICAgIGlmICh0aGlzLmZvcm1WYWx1ZUNoYW5nZXNTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuZm9ybVZhbHVlQ2hhbmdlc1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5mb3JtVmFsdWVDaGFuZ2VzU3Vic2NyaXB0aW9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUZvcm1Hcm91cEZyb21TdGF0ZShtb2RlbDogU2V0dGluZ0Zvcm11bGFNb2RlbCkge1xuICAgIHRoaXMuZm9ybUdyb3VwID0gdGhpcy5mb3JtR2VuZXJhdG9yLmdlbmVyYXRlU2V0dGluZ1ZhbHVlc0Zvcm1Hcm91cChtb2RlbCwgbW9kZWwucmVhZE9ubHksIHRoaXMucHJlcmVxdWlzaXRlU2V0dGluZ3MsIG1vZGVsLmZlYXR1cmVGbGFnTGltaXRhdGlvbnMpO1xuICB9XG5cbiAgZ2V0QXZhaWxhYmxlUHJlcmVxdWlzaXRlU2V0dGluZ3Moc2V0dGluZ0lkOiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5wcmVyZXF1aXNpdGVTZXR0aW5ncy5maWx0ZXIoZHMgPT4gZHMuc2V0dGluZ0lkICE9PSBzZXR0aW5nSWQpO1xuICB9XG5cbiAgcmV2ZXJ0KCkge1xuICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oQ29uZmlybWF0aW9uRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICBkYXRhOiB7XG4gICAgICAgIHRpdGxlOiAnUmV2ZXJ0IHRvIGxhc3Qgc2F2ZWQgc3RhdGU/JyxcbiAgICAgICAgYm9keTogJ0FsbCBjaGFuZ2VzIHdpbGwgYmUgbG9zdC4nLFxuICAgICAgICB5ZXNCdXR0b25MYWJlbDogJ1JldmVydCcsXG4gICAgICAgIG5vQnV0dG9uTGFiZWw6ICdObydcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShyZXN1bHQgPT4ge1xuICAgICAgaWYgKHJlc3VsdCA9PT0gJ3llcycpIHtcbiAgICAgICAgdGhpcy5yZXZlcnREaXJ0eVZhbHVlc0Zyb21TdGF0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcmV2ZXJ0RGlydHlWYWx1ZXNGcm9tU3RhdGUoKSB7XG5cbiAgICBpZiAodGhpcy5mb3JtR3JvdXAuZGlydHkpIHtcbiAgICAgIHRoaXMuZm9ybUdyb3VwLnNldENvbnRyb2woJ2RlZmF1bHRWYWx1ZScsXG4gICAgICAgIHRoaXMuZm9ybUdlbmVyYXRvci5nZW5lcmF0ZVZhbHVlRm9ybUdyb3VwKHRoaXMuc2V0dGluZ0Zvcm11bGEuZGVmYXVsdFZhbHVlLCB0aGlzLnNldHRpbmdGb3JtdWxhLnNldHRpbmcuc2V0dGluZ1R5cGUsIHRoaXMuc2V0dGluZ0Zvcm11bGEucmVhZE9ubHksIHRoaXMuc2V0dGluZ0Zvcm11bGEuZmVhdHVyZUZsYWdMaW1pdGF0aW9ucykpO1xuICAgICAgdGhpcy5mb3JtR3JvdXAuc2V0Q29udHJvbCgncGVyY2VudGFnZUV2YWx1YXRpb25BdHRyaWJ1dGUnLFxuICAgICAgICBuZXcgRm9ybUNvbnRyb2woeyB2YWx1ZTogdGhpcy5zZXR0aW5nRm9ybXVsYS5wZXJjZW50YWdlRXZhbHVhdGlvbkF0dHJpYnV0ZSwgZGlzYWJsZWQ6IHRoaXMuc2V0dGluZ0Zvcm11bGEucmVhZE9ubHkgfSwgeyB2YWxpZGF0b3JzOiBbVmFsaWRhdG9ycy5tYXgoMTAwMCldIH0pLCk7XG4gICAgICB0aGlzLmZvcm1Hcm91cC5zZXRDb250cm9sKCd0YXJnZXRpbmdSdWxlcycsXG4gICAgICAgIG5ldyBGb3JtQXJyYXk8Rm9ybUdyb3VwPFRhcmdldGluZ1J1bGVGb3JtPj4oXG4gICAgICAgICAgdGhpcy5zZXR0aW5nRm9ybXVsYS50YXJnZXRpbmdSdWxlcy5tYXAoZnQgPT4gdGhpcy5mb3JtR2VuZXJhdG9yLmdlbmVyYXRlVGFyZ2V0aW5nUnVsZUZvcm1Hcm91cChmdCwgdGhpcy5zZXR0aW5nRm9ybXVsYS5zZXR0aW5nLnNldHRpbmdUeXBlLCB0aGlzLnNldHRpbmdGb3JtdWxhLnJlYWRPbmx5LCB0aGlzLnByZXJlcXVpc2l0ZVNldHRpbmdzLCB0aGlzLnNldHRpbmdGb3JtdWxhLmZlYXR1cmVGbGFnTGltaXRhdGlvbnMpKVxuICAgICAgICApKTtcbiAgICAgIHRoaXMucmVjYWxjQWRkQnV0dG9ucygpO1xuICAgIH1cblxuICAgIHRoaXMuZm9ybUdyb3VwLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgdGhpcy5mb3JtR3JvdXAubWFya0FzVW50b3VjaGVkKCk7XG4gICAgdGhpcy5yZWNhbGNQcmVyZXF1aXNpdGVzKCk7XG4gICAgdGhpcy5zaG93RmVlZEJhY2tNZXNzYWdlID0gZmFsc2U7XG4gIH1cblxuICBzdWJtaXQoKSB7XG4gICAgaWYgKCF0aGlzLmZvcm1Hcm91cCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5mb3JtR3JvdXAudmFsaWQpIHtcbiAgICAgIHRoaXMuc2hvd0ZlZWRCYWNrTWVzc2FnZSA9IHRydWU7XG4gICAgICB0aGlzLmZvcm1Hcm91cC5tYXJrQWxsQXNUb3VjaGVkKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zaG93RmVlZEJhY2tNZXNzYWdlID0gZmFsc2U7XG4gICAgY29uc3QgdmFsdWU6IFVwZGF0ZUV2YWx1YXRpb25Gb3JtdWxhTW9kZWwgPSB7XG4gICAgICAuLi50aGlzLmZvcm1Hcm91cC5nZXRSYXdWYWx1ZSgpLFxuICAgIH07XG5cbiAgICB0aGlzLnVwZGF0ZVNldHRpbmdWYWx1ZXModmFsdWUpO1xuICB9XG5cbiAgdXBkYXRlU2V0dGluZ1ZhbHVlcyh1cGRhdGVNb2RlbDogVXBkYXRlRXZhbHVhdGlvbkZvcm11bGFNb2RlbCwgcmVhc29uOiBzdHJpbmcgPSBudWxsKSB7XG5cbiAgICB0aGlzLmNyZWF0ZVNldHRpbmdWYWx1ZXNWMlNlcnZpY2UoKS5yZXBsYWNlU2V0dGluZ1ZhbHVlVjIodGhpcy5lbnZpcm9ubWVudElkLCB0aGlzLnNldHRpbmdJZCwgdXBkYXRlTW9kZWwsIHJlYXNvbilcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiBzZXR0aW5nVmFsdWVzID0+IHtcbiAgICAgICAgICB0aGlzLmhhbmRsZUZldGNoZWRTZXR0aW5nVmFsdWVzKHNldHRpbmdWYWx1ZXMpO1xuXG4gICAgICAgICAgdGhpcy5zbmFja0Jhci5vcGVuRnJvbUNvbXBvbmVudChTYXZlU25hY2tiYXJDb21wb25lbnQsIHsgZHVyYXRpb246IDUwMDAsIHBhbmVsQ2xhc3M6ICdncmVlbi1zbmFja2JhcicgfSk7XG4gICAgICAgICAgdGhpcy5zYXZlU3VjY2VlZGVkLmVtaXQoKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnJvcikgPT4ge1xuXG4gICAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PT0gNDAwICYmIGVycm9yLmVycm9yICYmIGVycm9yLmVycm9yLlJlYXNvbiAmJiBlcnJvci5lcnJvci5SZWFzb25bMF0gPT09ICdSZWFzb24gcmVxdWlyZWQuJykge1xuICAgICAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihSZWFzb25EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgICAgd2lkdGg6ICc0NTBweCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKClcbiAgICAgICAgICAgICAgLnN1YnNjcmliZShyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0LmJ1dHRvbiA9PT0gJ3NhdmUnICYmIHJlc3VsdC5yZWFzb24pIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlU2V0dGluZ1ZhbHVlcyh1cGRhdGVNb2RlbCwgcmVzdWx0LnJlYXNvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzID09PSA0MDAgJiYgZXJyb3IuZXJyb3IgJiYgZXJyb3IuZXJyb3IuU2VnbWVudENvbmRpdGlvbiAmJiBlcnJvci5lcnJvci5TZWdtZW50Q29uZGl0aW9uWzBdID09PSAnU2VnbWVudCBub3QgZm91bmQuJykge1xuICAgICAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihDb25maXJtYXRpb25EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgICAgd2lkdGg6ICc0NTBweCcsXG4gICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0Nhbm5vdCBzYXZlIGZlYXR1cmUgZmxhZ3MnLFxuICAgICAgICAgICAgICAgIGJvZHk6ICdBIHNlZ21lbnQgcmVmZXJlbmNlZCBieSBvbmUgb2YgeW91ciBmZWF0dXJlIGZsYWdzIGhhcyBiZWVuIGRlbGV0ZWQuIFJlbG9hZCB0aGUgY29uZmlnIHRvIHNlZSBpdHMgbGF0ZXN0IHN0YXRlLCBhcHBseSB5b3VyIGNoYW5nZXMgYW5kIHRyeSB0aGUgc2F2ZSBhZ2Fpbi4nLFxuICAgICAgICAgICAgICAgIHllc0J1dHRvbkxhYmVsOiAnUmVsb2FkJyxcbiAgICAgICAgICAgICAgICBoaWRlTm9CdXR0b246IHRydWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKVxuICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbG9hZFNldHRpbmdWYWx1ZXMoKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PT0gNDAwICYmIGVycm9yLmVycm9yICYmICgnJyArIGVycm9yLmVycm9yKS5zdGFydHNXaXRoKCdDaXJjdWxhciBkZXBlbmRlbmN5IGRldGVjdGVkLicpKSB7XG4gICAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSAoJycgKyBlcnJvci5lcnJvcikuc2xpY2UoJ0NpcmN1bGFyIGRlcGVuZGVuY3kgZGV0ZWN0ZWQuJy5sZW5ndGggKyAxKTtcbiAgICAgICAgICAgIHRoaXMuZGlhbG9nLm9wZW4oQ29uZmlybWF0aW9uRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICAgICAgICAgIHdpZHRoOiAnNDUwcHgnLFxuICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdDYW5ub3Qgc2F2ZSBmZWF0dXJlIGZsYWdzLicsXG4gICAgICAgICAgICAgICAgYm9keTogJ0NpcmN1bGFyIGRlcGVuZGVuY3kgZGV0ZWN0ZWQgYmV0d2VlbiB0aGUgZm9sbG93aW5nIGZlYXR1cmUgZmxhZ3M6PHA+JyArIGVycm9yTWVzc2FnZSArICc8L3A+UGxlYXNlIDxzdHJvbmc+ZWxpbWluYXRlIHRoZSBjaXJjdWxhciBkZXBlbmRlbmN5PC9zdHJvbmc+IGJlZm9yZSBzYXZpbmcgeW91ciBmZWF0dXJlIGZsYWdzLicsXG4gICAgICAgICAgICAgICAgeWVzQnV0dG9uTGFiZWw6ICdJIHVuZGVyc3RhbmQnLFxuICAgICAgICAgICAgICAgIGhpZGVOb0J1dHRvbjogdHJ1ZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmZvcm1Hcm91cC5zZXRFcnJvcnMoeyBpbnRlcm5hbFNlcnZlckVycm9yOiAnSW50ZXJuYWwgc2VydmVyIGVycm9yJyB9KTtcbiAgICAgICAgICB0aGlzLmZvcm1Hcm91cC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgICAgICAgdGhpcy5zaG93RmVlZEJhY2tNZXNzYWdlID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLnNhdmVGYWlsZWQuZW1pdCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIG9uRGVsZXRlU2V0dGluZ1JlcXVlc3RlZChzZXR0aW5nKSB7XG4gICAgaWYgKHRoaXMuZm9ybUdyb3VwLmRpcnR5KSB7XG4gICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKENvbmZpcm1hdGlvbkRpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgdGl0bGU6ICdEaXNjYXJkIGNoYW5nZXM/JyxcbiAgICAgICAgICBib2R5OiAnWW91IGhhdmUgdW5zYXZlZCBmZWF0dXJlIGZsYWcgY2hhbmdlcy4gSWYgeW91IGNvbnRpbnVlLCB1bnNhdmVkIGNoYW5nZXMgd2lsbCBiZSBsb3N0LicsXG4gICAgICAgICAgeWVzQnV0dG9uTGFiZWw6ICdEaXNjYXJkIGNoYW5nZXMnLFxuICAgICAgICAgIG5vQnV0dG9uTGFiZWw6ICdObydcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpXG4gICAgICAgIC5zdWJzY3JpYmUocmVzdWx0ID0+IHtcbiAgICAgICAgICBpZiAocmVzdWx0ID09PSAneWVzJykge1xuICAgICAgICAgICAgdGhpcy5yZXZlcnREaXJ0eVZhbHVlc0Zyb21TdGF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5kZWxldGVTZXR0aW5nSW50ZXJuYWwoc2V0dGluZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZWxldGVTZXR0aW5nSW50ZXJuYWwoc2V0dGluZyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZWxldGVTZXR0aW5nSW50ZXJuYWwoc2V0dGluZykge1xuICAgIHRoaXMuZGVsZXRlU2V0dGluZ1JlcXVlc3RlZC5lbWl0KDxEZWxldGVTZXR0aW5nTW9kZWw+eyBjb25maWc6IHRoaXMuc2V0dGluZ0Zvcm11bGEuY29uZmlnLCBlbnZpcm9ubWVudDogdGhpcy5zZXR0aW5nRm9ybXVsYS5lbnZpcm9ubWVudCwgc2V0dGluZzogc2V0dGluZy5zZXR0aW5nIH0pXG4gIH1cblxuICBzdWJzY3JpcHRpb25MaW1pdFJlYWNoZWRDYWxsZWQoKSB7XG4gICAgdGhpcy5kaWFsb2cub3BlbihSZXJvdXRlRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICBkYXRhOiB7XG4gICAgICAgIHRpdGxlOiAnWW91IGhhdmUgcmVhY2hlZCB0aGUgbGltaXRzIG9mIHlvdXIgcGxhbicsXG4gICAgICAgIGJvZHk6IGAgVXBncmFkZSB5b3VyIHBsYW4gb3Igam9pbiBvdXIgPGEgaHJlZj1cImh0dHBzOi8vY29uZmlnY2F0LmNvbS9yZWZlcnJhbHNcIiB0YXJnZXQ9XCJfYmxhbmtcIiByZWw9XCJub29wZW5lciBub3JlZmVycmVyXCI+cmVmZXJyYWwgcHJvZ3JhbTwvYT4gdG8gaW5jcmVhc2UgeW91ciBsaW1pdHMuYCxcbiAgICAgICAgeWVzQnV0dG9uTGFiZWw6IGBTZWUgcGxhbnNgLFxuICAgICAgICB5ZXNCdXR0b25MaW5rOiB0aGlzLmRhc2hib2FyZEJhc2VQYXRoICsgXCIvb3JnYW5pemF0aW9uL3BsYW5zXCIsXG4gICAgICAgIG5vQnV0dG9uTGFiZWw6IGBDbG9zZWBcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGFkZFNlZ21lbnRDb25kaXRpb25SZXF1ZXN0ZWRXaXRob3V0U2VnbWVudHMoKSB7XG4gICAgdGhpcy5kaWFsb2cub3BlbihSZXJvdXRlRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICBkYXRhOiB7XG4gICAgICAgIHRpdGxlOiAnVGhlcmUgYXJlIG5vIHNlZ21lbnRzIGluIHRoaXMgcHJvZHVjdCB5ZXQuJyxcbiAgICAgICAgYm9keTogYEdvIGFoZWFkIHRvIHRoZSBDb25maUNhdCBEYXNoYm9hcmQgYW5kIGNyZWF0ZSB5b3VyIGZpcnN0IHVzZXIgc2VnbWVudCBiZWZvcmUgYWRkaW5nIGl0IHRvIGEgdGFyZ2V0aW5nIHJ1bGUuYCxcbiAgICAgICAgeWVzQnV0dG9uTGFiZWw6IGBHbyB0byB0aGUgZGFzaGJvYXJkYCxcbiAgICAgICAgeWVzQnV0dG9uTGluazogdGhpcy5kYXNoYm9hcmRCYXNlUGF0aCArIFwiL3Byb2R1Y3QvXCIgKyB0aGlzLnByb2R1Y3RJZCArIFwiL3NlZ21lbnRzXCJcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHRyYWNrQnlJbmRleChpbmRleDogbnVtYmVyKTogYW55IHtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICByZWNhbGNQcmVyZXF1aXNpdGVzKCk6IHZvaWQge1xuICAgIGNvbnN0IHNldHRpbmdWYWx1ZSA9IHRoaXMuc2V0dGluZ0Zvcm11bGE7XG4gICAgdGhpcy5mbGFnU3RhdGUuZGVwZW5kZWVTZXR0aW5ncyA9IHRoaXMuc2V0dGluZ3MuZmlsdGVyKHMgPT4gc2V0dGluZ1ZhbHVlLnNldHRpbmdJZHNXaGVyZVByZXJlcXVpc2l0ZT8uaW5jbHVkZXMocy5zZXR0aW5nSWQpKVxuICAgICAgLm1hcChzID0+IHsgcmV0dXJuIHsga2V5OiBzLmtleSwgbmFtZTogcy5uYW1lLCBzZXR0aW5nSWQ6IHMuc2V0dGluZ0lkIH0gfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmVjYWxjQWRkQnV0dG9ucygpOiB2b2lkIHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuZmxhZ1N0YXRlO1xuICAgIGNvbnN0IGdyb3VwID0gdGhpcy5mb3JtR3JvdXA7XG5cbiAgICBzdGF0ZS5hZGRCdXR0b25SZW5kZXJTdGF0ZS5yZW5kZXJUb3BBZGRCdXR0b25zID0gIWdyb3VwLmNvbnRyb2xzLnRhcmdldGluZ1J1bGVzLmNvbnRyb2xzLmxlbmd0aCB8fFxuICAgICAgdGhpcy5oYXNPbmx5UGVyY2VudGFnZVJ1bGUoZ3JvdXApO1xuXG4gICAgaWYgKCFncm91cC5jb250cm9scy50YXJnZXRpbmdSdWxlcy5jb250cm9scy5sZW5ndGgpIHtcbiAgICAgIHN0YXRlLmFkZEJ1dHRvblJlbmRlclN0YXRlLmFkZFJ1bGVCdXR0b25UcmFja2VyID0gW107XG4gICAgICBzdGF0ZS5hZGRCdXR0b25SZW5kZXJTdGF0ZS5oYXNQZXJjZW50YWdlT25seVJ1bGUgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaGFzUGVyY09ubHkgPSBzdGF0ZS5hZGRCdXR0b25SZW5kZXJTdGF0ZS5oYXNQZXJjZW50YWdlT25seVJ1bGUgPSBncm91cC5jb250cm9scy50YXJnZXRpbmdSdWxlcy5jb250cm9scy5sZW5ndGggPiAwXG4gICAgICAgICYmIHRoaXMuZm9ybUdlbmVyYXRvci5pc1BlcmNlbnRhZ2VPbmx5VGFyZ2V0aW5nUnVsZShncm91cC5jb250cm9scy50YXJnZXRpbmdSdWxlcy5jb250cm9sc1tncm91cC5jb250cm9scy50YXJnZXRpbmdSdWxlcy5jb250cm9scy5sZW5ndGggLSAxXSk7XG4gICAgICBzdGF0ZS5hZGRCdXR0b25SZW5kZXJTdGF0ZS5hZGRSdWxlQnV0dG9uVHJhY2tlciA9IGdyb3VwLmNvbnRyb2xzLnRhcmdldGluZ1J1bGVzLmNvbnRyb2xzLm1hcCgoaXRlbSwgaSwgcnVsZXMpID0+IHtcbiAgICAgICAgY29uc3QgaXNMYXN0UnVsZSA9IGkgPT09IGdyb3VwLmNvbnRyb2xzLnRhcmdldGluZ1J1bGVzLmNvbnRyb2xzLmxlbmd0aCAtIDE7XG4gICAgICAgIGNvbnN0IGlzQmVmb3JlTGFzdCA9IGkgPT09IGdyb3VwLmNvbnRyb2xzLnRhcmdldGluZ1J1bGVzLmNvbnRyb2xzLmxlbmd0aCAtIDI7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc2hvd0FkZFJ1bGVCdXR0b25zOiBoYXNQZXJjT25seSA/IGkgPT09IHJ1bGVzLmxlbmd0aCAtIDIgOiBpID09PSBydWxlcy5sZW5ndGggLSAxLFxuICAgICAgICAgIHNob3dPckNoaXA6IGhhc1BlcmNPbmx5ID8gaSA8IHJ1bGVzLmxlbmd0aCAtIDIgOiBpIDwgcnVsZXMubGVuZ3RoIC0gMSxcbiAgICAgICAgICByZW5kZXJTZXBhcmF0aW9uQXJlYTogdGhpcy5mb3JtR2VuZXJhdG9yLmlzUGVyY2VudGFnZU9ubHlUYXJnZXRpbmdSdWxlKGl0ZW0pIHx8XG4gICAgICAgICAgICAodGhpcy5zZXR0aW5nRm9ybXVsYS5yZWFkT25seSAmJiAoaXNMYXN0UnVsZSB8fCAoaGFzUGVyY09ubHkgJiYgaXNCZWZvcmVMYXN0KSkpLFxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBoYXNPbmx5UGVyY2VudGFnZVJ1bGUoZ3JvdXA6IEZvcm1Hcm91cDxVcGRhdGVTZXR0aW5nVmFsdWVGb3JtPik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBncm91cC5jb250cm9scy50YXJnZXRpbmdSdWxlcy5jb250cm9scy5sZW5ndGggPT09IDEgJiZcbiAgICAgIHRoaXMuZm9ybUdlbmVyYXRvci5pc1BlcmNlbnRhZ2VPbmx5VGFyZ2V0aW5nUnVsZShncm91cC5jb250cm9scy50YXJnZXRpbmdSdWxlcy5jb250cm9sc1swXSlcbiAgfVxuXG4gIGV4cGFuZGVkQ2hhbmdlZChleHBhbmRlZFN0YXRlOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5mbGFnU3RhdGUucGFuZWxFeHBhbmRlZCA9IGV4cGFuZGVkU3RhdGU7XG4gICAgdGhpcy5leHBhbmRlZFN0YXRlQ2hhbmdlZC5lbWl0KCk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJjb250YWluZXJcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWxvYWRpbmdcIj5cbiAgICAgICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtR3JvdXBcIiAobmdTdWJtaXQpPVwic3VibWl0KClcIiBpZD1cImZlYXR1cmUtZmxhZy1mb3JtXCI+XG4gICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsnaW52YWxpZC1mbGFnJzogZm9ybUdyb3VwLmludmFsaWR9XCI+XG4gICAgICAgICAgICAgICAgPGFwcC1mZWF0dXJlLWZsYWcgW2Zvcm1Hcm91cF09XCJmb3JtR3JvdXBcIiBbZmxhZ1N0YXRlXT1cImZsYWdTdGF0ZVwiIFtzZWdtZW50c109XCJzZWdtZW50c1wiXG4gICAgICAgICAgICAgICAgICAgIChkZWxldGVTZXR0aW5nUmVxdWVzdGVkKT1cIm9uRGVsZXRlU2V0dGluZ1JlcXVlc3RlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZlYXR1cmVGbGFnTGltaXRhdGlvbnNdPVwic2V0dGluZ0Zvcm11bGEuZmVhdHVyZUZsYWdMaW1pdGF0aW9uc1wiIFtoYXNPdGhlckVudmlyb25tZW50XT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgKHN1YnNjcmlwdGlvbkxpbWl0UmVhY2hlZCk9XCJzdWJzY3JpcHRpb25MaW1pdFJlYWNoZWRDYWxsZWQoKVwiXG4gICAgICAgICAgICAgICAgICAgIChhZGRTZWdtZW50Q29uZGl0aW9uUmVxdWVzdGVkV2l0aG91dFNlZ21lbnRzKT1cImFkZFNlZ21lbnRDb25kaXRpb25SZXF1ZXN0ZWRXaXRob3V0U2VnbWVudHMoKVwiXG4gICAgICAgICAgICAgICAgICAgIChwcmVyZXF1aXNpdGVDb25kaXRpb25DaGFuZ2VkKT1cInJlY2FsY1ByZXJlcXVpc2l0ZXMoKVwiIChyZWNhbGNBZGRCdXR0b25zKT1cInJlY2FsY0FkZEJ1dHRvbnMoKVwiXG4gICAgICAgICAgICAgICAgICAgIChleHBhbmRlZENoYW5nZWQpPVwiZXhwYW5kZWRDaGFuZ2VkKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICBbc2hvd0Vudmlyb25tZW50TmFtZV09XCJzaG93RW52aXJvbm1lbnROYW1lXCIgW2Vudmlyb25tZW50TmFtZV09XCJzZXR0aW5nRm9ybXVsYS5lbnZpcm9ubWVudC5uYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgW2RlbGV0ZVNldHRpbmdUZXh0XT1cImRlbGV0ZVNldHRpbmdUZXh0XCIgW2NhbkRlbGV0ZVNldHRpbmddPVwiY2FuRGVsZXRlU2V0dGluZ1wiPlxuICAgICAgICAgICAgICAgIDwvYXBwLWZlYXR1cmUtZmxhZz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNhdmVcIiAqbmdJZj1cIiFzZXR0aW5nRm9ybXVsYS5yZWFkT25seSAmJiBmb3JtR3JvdXA/LmRpcnR5XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInNhdmUtYnV0dG9uXCIgbWF0LWZsYXQtYnV0dG9uIGNvbG9yPVwid2FyblwiIHR5cGU9XCJzdWJtaXRcIiBbY2xhc3MuYW5pbWF0ZV09XCJmb3JtR3JvdXAuZGlydHlcIlxuICAgICAgICAgICAgICAgICAgICBbdHJhY2tdPVwiWydzYXZlICYgcHVibGlzaCBjbGljaycsICdmZWF0dXJlIGZsYWdzIGFuZCBzZXR0aW5ncyddXCI+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5iYWNrdXA8L21hdC1pY29uPiA8c3Bhbj4gU2F2ZSAmIHB1Ymxpc2ggY2hhbmdlczwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInJldmVydC1idXR0b25cIiBtYXQtc3Ryb2tlZC1idXR0b24gKGNsaWNrKT1cInJldmVydCgpXCJcbiAgICAgICAgICAgICAgICAgICAgW3RyYWNrXT1cIlsncmV2ZXJ0IGNsaWNrJywgJ2ZlYXR1cmUgZmxhZ3MgYW5kIHNldHRpbmdzJ11cIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+UmV2ZXJ0PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmZWVkYmFja1wiICpuZ0lmPVwiZm9ybUdyb3VwLnRvdWNoZWQgJiYgZm9ybUdyb3VwLmludmFsaWQgJiYgc2hvd0ZlZWRCYWNrTWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXJyb3JcIiAqbmdJZj1cImZvcm1Hcm91cC5lcnJvcnMgJiYgZm9ybUdyb3VwLmVycm9ycy5pbnRlcm5hbFNlcnZlckVycm9yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5Tb21ldGhpbmcgd2VudCB3cm9uZyBhbmQgd2UgY291bGQgbm90IHNhdmUgeW91ciBzZXR0aW5ncy4gWW91IGNhbiB0cnkgYWdhaW4gb3IgPGFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHJlZj1cImh0dHBzOi8vY29uZmlnY2F0LmNvbS9zdXBwb3J0XCIgdGFyZ2V0PVwiX2JsYW5rXCIgcmVsPVwibm9vcGVuZXIgbm9yZWZlcnJlclwiPmNvbnRhY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXMuPC9hPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlcnJvclwiICpuZ0lmPVwiIWZvcm1Hcm91cC5lcnJvcnMgfHwgIWZvcm1Hcm91cC5lcnJvcnMuaW50ZXJuYWxTZXJ2ZXJFcnJvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+T2ggbm8hIEEgZmVhdHVyZSBmbGFnIGhhcyBpbnZhbGlkIG9yIG1pc3NpbmcgZGF0YS4mbmJzcDs8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZm9ybT5cblxuICAgIDwvbmctY29udGFpbmVyPlxuPC9kaXY+Il19
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generated bundle index. Do not edit.
|
|
3
|
-
*/
|
|
4
|
-
export * from './public-api';
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctY29uZmlnY2F0LXB1YmxpY2FwaS11aS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL25nLWNvbmZpZ2NhdC1wdWJsaWNhcGktdWkvc3JjL25nLWNvbmZpZ2NhdC1wdWJsaWNhcGktdWkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
|
package/esm2022/public-api.mjs
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Public API Surface of ng-configcat-publicapi-ui
|
|
3
|
-
*/
|
|
4
|
-
export * from './lib/ng-configcat-publicapi-ui.module';
|
|
5
|
-
export * from './lib/_directives';
|
|
6
|
-
export * from './lib/_services';
|
|
7
|
-
export * from './lib/setting-item/setting-item.component';
|
|
8
|
-
export * from './lib/authorization/authorization.component';
|
|
9
|
-
export * from './lib/selects/product-select/product-select.component';
|
|
10
|
-
export * from './lib/selects/config-select/config-select.component';
|
|
11
|
-
export * from './lib/selects/environment-select/environment-select.component';
|
|
12
|
-
export * from './lib/selects/setting-select/setting-select.component';
|
|
13
|
-
export * from './lib/dialogs/delete-setting-dialog/delete-setting-dialog.component';
|
|
14
|
-
export * from './lib/v2/feature-flag-item.component';
|
|
15
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL25nLWNvbmZpZ2NhdC1wdWJsaWNhcGktdWkvc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLHdDQUF3QyxDQUFDO0FBQ3ZELGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxpQkFBaUIsQ0FBQztBQUNoQyxjQUFjLDJDQUEyQyxDQUFDO0FBQzFELGNBQWMsNkNBQTZDLENBQUM7QUFDNUQsY0FBYyx1REFBdUQsQ0FBQztBQUN0RSxjQUFjLHFEQUFxRCxDQUFDO0FBQ3BFLGNBQWMsK0RBQStELENBQUM7QUFDOUUsY0FBYyx1REFBdUQsQ0FBQztBQUN0RSxjQUFjLHFFQUFxRSxDQUFDO0FBQ3BGLGNBQWMsc0NBQXNDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIG5nLWNvbmZpZ2NhdC1wdWJsaWNhcGktdWlcbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2xpYi9uZy1jb25maWdjYXQtcHVibGljYXBpLXVpLm1vZHVsZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9fZGlyZWN0aXZlcyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9fc2VydmljZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvc2V0dGluZy1pdGVtL3NldHRpbmctaXRlbS5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvYXV0aG9yaXphdGlvbi9hdXRob3JpemF0aW9uLmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9zZWxlY3RzL3Byb2R1Y3Qtc2VsZWN0L3Byb2R1Y3Qtc2VsZWN0LmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9zZWxlY3RzL2NvbmZpZy1zZWxlY3QvY29uZmlnLXNlbGVjdC5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvc2VsZWN0cy9lbnZpcm9ubWVudC1zZWxlY3QvZW52aXJvbm1lbnQtc2VsZWN0LmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9zZWxlY3RzL3NldHRpbmctc2VsZWN0L3NldHRpbmctc2VsZWN0LmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9kaWFsb2dzL2RlbGV0ZS1zZXR0aW5nLWRpYWxvZy9kZWxldGUtc2V0dGluZy1kaWFsb2cuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3YyL2ZlYXR1cmUtZmxhZy1pdGVtLmNvbXBvbmVudCc7Il19
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './input-display-normalizer.directive';
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import * as i0 from "@angular/core";
|
|
2
|
-
/**
|
|
3
|
-
* Makes sure that values entered into HTML input fields are displayed in the correct format,
|
|
4
|
-
* where correct means normalized (e.g. `'.10'` --> `'0.1'`) and corresponding to the locale setting.
|
|
5
|
-
*
|
|
6
|
-
* The format is adjusted on the blur event. Only the format of number inputs is adjusted currently.
|
|
7
|
-
*/
|
|
8
|
-
export declare class InputDisplayNormalizerDirective {
|
|
9
|
-
constructor();
|
|
10
|
-
onChange($event: any): void;
|
|
11
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<InputDisplayNormalizerDirective, never>;
|
|
12
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<InputDisplayNormalizerDirective, "input[inputDisplayNormalizer]", never, {}, {}, never, never, false, never>;
|
|
13
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { SettingFormulaModel } from "ng-configcat-publicapi";
|
|
2
|
-
import { IDependeeSetting, IPrerequisiteSetting } from "./setting-value-formgroup";
|
|
3
|
-
export interface IFlagState {
|
|
4
|
-
addButtonRenderState: IAddButtonsRenderState;
|
|
5
|
-
settingValue: SettingFormulaModel;
|
|
6
|
-
dependeeSettings: IDependeeSetting[];
|
|
7
|
-
prerequisiteSettings: IPrerequisiteSetting[];
|
|
8
|
-
panelExpanded: boolean;
|
|
9
|
-
readOnly: boolean;
|
|
10
|
-
}
|
|
11
|
-
export interface IAddButtonsRenderState {
|
|
12
|
-
renderTopAddButtons: boolean;
|
|
13
|
-
hasPercentageOnlyRule: boolean;
|
|
14
|
-
addRuleButtonTracker: IAddRuleButtonTracker[];
|
|
15
|
-
}
|
|
16
|
-
export interface IAddRuleButtonTracker {
|
|
17
|
-
showAddRuleButtons: boolean;
|
|
18
|
-
showOrChip: boolean;
|
|
19
|
-
renderSeparationArea: boolean;
|
|
20
|
-
}
|
package/lib/_models/index.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { FormArray, FormControl, FormGroup } from "@angular/forms";
|
|
2
|
-
import { UserComparator, SegmentComparator, SettingType, PrerequisiteComparator } from "ng-configcat-publicapi";
|
|
3
|
-
export interface ComparisonValueListForm {
|
|
4
|
-
value: FormControl<string>;
|
|
5
|
-
hint?: FormControl<string>;
|
|
6
|
-
index: FormControl<number>;
|
|
7
|
-
}
|
|
8
|
-
export interface ComparisonValueForm {
|
|
9
|
-
stringValue?: FormControl<string>;
|
|
10
|
-
doubleValue?: FormControl<number>;
|
|
11
|
-
listValue?: FormArray<FormGroup<ComparisonValueListForm>>;
|
|
12
|
-
}
|
|
13
|
-
export interface ValueForm {
|
|
14
|
-
boolValue?: FormControl<boolean>;
|
|
15
|
-
stringValue?: FormControl<string>;
|
|
16
|
-
intValue?: FormControl<number>;
|
|
17
|
-
doubleValue?: FormControl<number>;
|
|
18
|
-
}
|
|
19
|
-
export interface UserConditionForm {
|
|
20
|
-
comparisonAttribute: FormControl<string>;
|
|
21
|
-
comparator: FormControl<UserComparator>;
|
|
22
|
-
comparisonValue: FormGroup<ComparisonValueForm>;
|
|
23
|
-
}
|
|
24
|
-
export interface SegmentConditionForm {
|
|
25
|
-
segmentId: FormControl<string>;
|
|
26
|
-
comparator: FormControl<SegmentComparator>;
|
|
27
|
-
}
|
|
28
|
-
export interface PrerequisiteFlagConditionForm {
|
|
29
|
-
prerequisiteSettingId: FormControl<number>;
|
|
30
|
-
comparator: FormControl<PrerequisiteComparator>;
|
|
31
|
-
prerequisiteComparisonValue: FormGroup<ValueForm>;
|
|
32
|
-
}
|
|
33
|
-
export interface ConditionForm {
|
|
34
|
-
userCondition?: FormGroup<UserConditionForm>;
|
|
35
|
-
segmentCondition?: FormGroup<SegmentConditionForm>;
|
|
36
|
-
prerequisiteFlagCondition?: FormGroup<PrerequisiteFlagConditionForm>;
|
|
37
|
-
}
|
|
38
|
-
export interface PercentageOptionForm {
|
|
39
|
-
percentage: FormControl<number>;
|
|
40
|
-
value: FormGroup<ValueForm>;
|
|
41
|
-
}
|
|
42
|
-
export interface TargetingRuleForm {
|
|
43
|
-
conditions: FormArray<FormGroup<ConditionForm>>;
|
|
44
|
-
percentageOptions?: FormArray<FormGroup<PercentageOptionForm>>;
|
|
45
|
-
value?: FormGroup<ValueForm>;
|
|
46
|
-
}
|
|
47
|
-
export interface UpdateSettingValueForm {
|
|
48
|
-
defaultValue: FormGroup<ValueForm>;
|
|
49
|
-
percentageEvaluationAttribute: FormControl<string>;
|
|
50
|
-
targetingRules: FormArray<FormGroup<TargetingRuleForm>>;
|
|
51
|
-
}
|
|
52
|
-
export interface ChangeSetForm {
|
|
53
|
-
updateSettingValues: FormArray<FormGroup<UpdateSettingValueForm>>;
|
|
54
|
-
}
|
|
55
|
-
export interface IPrerequisiteSetting {
|
|
56
|
-
settingId: number;
|
|
57
|
-
key: string;
|
|
58
|
-
name: string;
|
|
59
|
-
settingType: SettingType;
|
|
60
|
-
}
|
|
61
|
-
export interface IDependeeSetting {
|
|
62
|
-
settingId: number;
|
|
63
|
-
key: string;
|
|
64
|
-
name: string;
|
|
65
|
-
}
|
|
66
|
-
export interface IPrerequisiteChanged {
|
|
67
|
-
settingId: number;
|
|
68
|
-
prerequisiteIds: number[];
|
|
69
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { ConfigModel, EnvironmentModel, SettingValueModel } from 'ng-configcat-publicapi';
|
|
2
|
-
export interface SettingValuesModel {
|
|
3
|
-
apiKey?: string;
|
|
4
|
-
apiKey2?: string;
|
|
5
|
-
reasonRequired?: boolean;
|
|
6
|
-
lastUpdatedAt?: Date;
|
|
7
|
-
config: ConfigModel;
|
|
8
|
-
environment: EnvironmentModel;
|
|
9
|
-
readOnly: boolean;
|
|
10
|
-
settingValues: SettingValueModel[];
|
|
11
|
-
}
|