@solidev/data 0.4.8 → 0.5.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/fesm2022/solidev-data.mjs +158 -157
- package/fesm2022/solidev-data.mjs.map +1 -1
- package/lib/modellist/model-list-fields/model-list-field-header/model-list-field-header.component.d.ts +2 -2
- package/package.json +5 -7
- package/esm2022/lib/auth/auth-interceptor.service.mjs +0 -113
- package/esm2022/lib/auth/auth.service.mjs +0 -216
- package/esm2022/lib/auth/jwt.mjs +0 -21
- package/esm2022/lib/data/data-backend.mjs +0 -162
- package/esm2022/lib/data/data-collection.mjs +0 -125
- package/esm2022/lib/data/data-collection.mock.mjs +0 -39
- package/esm2022/lib/data/data-model.mjs +0 -291
- package/esm2022/lib/data/data-parameters.mjs +0 -34
- package/esm2022/lib/data/data-query.mjs +0 -154
- package/esm2022/lib/data/data-query.mock.mjs +0 -46
- package/esm2022/lib/data/fields/base.mjs +0 -144
- package/esm2022/lib/data/fields/boolean.mjs +0 -38
- package/esm2022/lib/data/fields/computed.mjs +0 -10
- package/esm2022/lib/data/fields/datetime.mjs +0 -167
- package/esm2022/lib/data/fields/index.mjs +0 -8
- package/esm2022/lib/data/fields/numbers.mjs +0 -38
- package/esm2022/lib/data/fields/primaryfield.mjs +0 -9
- package/esm2022/lib/data/fields/relations.mjs +0 -53
- package/esm2022/lib/data/fields/stringfields.mjs +0 -71
- package/esm2022/lib/dispedit/choice.pipe.mjs +0 -79
- package/esm2022/lib/dispedit/dispedit/dispedit.component.mjs +0 -480
- package/esm2022/lib/dispedit/dispedit/dispedit.constants.mjs +0 -2
- package/esm2022/lib/dispedit/factor.pipe.mjs +0 -81
- package/esm2022/lib/dispedit/factorc.pipe.mjs +0 -99
- package/esm2022/lib/dispedit/fkselect/fkselect.component.mjs +0 -139
- package/esm2022/lib/dispedit/flags/flags.component.mjs +0 -137
- package/esm2022/lib/dispedit/m2mselect/m2mselect.component.mjs +0 -312
- package/esm2022/lib/dispedit/richedit/richedit.component.mjs +0 -126
- package/esm2022/lib/dispedit/sdelete/sdelete.component.mjs +0 -103
- package/esm2022/lib/messages/message-zone/message-zone.component.mjs +0 -53
- package/esm2022/lib/messages/message.service.mjs +0 -151
- package/esm2022/lib/modellist/model-list-fields/model-list-field-header/messages.mjs +0 -2
- package/esm2022/lib/modellist/model-list-fields/model-list-field-header/model-list-field-header.component.mjs +0 -61
- package/esm2022/lib/modellist/model-list-fields/model-list-fields-selector/model-list-fields-selector.component.mjs +0 -64
- package/esm2022/lib/modellist/model-list-fields/model-list-fields.mjs +0 -273
- package/esm2022/lib/modellist/model-list-filters/filters/filtertypes.mjs +0 -3
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-autocomplete-filter/model-list-autocomplete-filter.component.mjs +0 -109
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-autocomplete-filter/model-list-autocomplete-filter.mjs +0 -28
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter.component.mjs +0 -29
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-autocomplete-multi-filter/model-list-autocomplete-multi-filter.mjs +0 -9
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-date-filter/model-list-date-filter.component.mjs +0 -40
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-date-filter/model-list-date-filter.mjs +0 -14
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-datetime-filter/model-list-datetime-filter.component.mjs +0 -40
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-datetime-filter/model-list-datetime-filter.mjs +0 -14
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-datetimerange-filter/model-list-datetime-range-filter.component.mjs +0 -21
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-datetimerange-filter/model-list-datetimerange-filter.mjs +0 -14
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-flags-filter/model-list-flags-filter.component.mjs +0 -49
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-flags-filter/model-list-flags-filter.mjs +0 -23
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/adapters/ban.mjs +0 -24
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/model-list-geodistance-filter.component.mjs +0 -63
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-geodistance-filter/model-list-geodistance-filter.mjs +0 -16
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-number-filter/model-list-number-filter.component.mjs +0 -46
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-number-filter/model-list-number-filter.mjs +0 -49
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-select-filter/model-list-select-filter.component.mjs +0 -56
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-select-filter/model-list-select-filter.mjs +0 -40
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-select-multi-filter/model-list-select-multi-filter.component.mjs +0 -51
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-select-multi-filter/model-list-select-multi-filter.mjs +0 -21
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-text-filter/model-list-text-filter.component.mjs +0 -40
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-text-filter/model-list-text-filter.mjs +0 -17
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-tree-filter/model-list-tree-filter.component.mjs +0 -174
- package/esm2022/lib/modellist/model-list-filters/filters/model-list-tree-filter/model-list-tree-filter.mjs +0 -18
- package/esm2022/lib/modellist/model-list-filters/model-list-filter-group.mjs +0 -19
- package/esm2022/lib/modellist/model-list-filters/model-list-filter.mjs +0 -157
- package/esm2022/lib/modellist/model-list-filters/model-list-filters/model-list-filters.component.mjs +0 -50
- package/esm2022/lib/modellist/model-list-filters/model-list-filters-select/model-list-filters-select.component.mjs +0 -51
- package/esm2022/lib/modellist/model-list-filters/model-list-filters.mjs +0 -134
- package/esm2022/lib/modellist/model-list-paginator/model-list-paginator/model-list-paginator.component.mjs +0 -69
- package/esm2022/lib/modellist/model-list-paginator/model-list-paginator.mjs +0 -47
- package/esm2022/lib/modellist/model-list-sorter/model-list-sorter/model-list-sorter.component.mjs +0 -49
- package/esm2022/lib/modellist/model-list-sorter/model-list-sorter.mjs +0 -116
- package/esm2022/lib/modellist/model-list.service.mjs +0 -168
- package/esm2022/lib/routing/breadcrumb/breadcrumb.component.mjs +0 -138
- package/esm2022/lib/routing/routing.mjs +0 -57
- package/esm2022/lib/updates/update/update.component.mjs +0 -17
- package/esm2022/lib/updates/update.service.mjs +0 -58
- package/esm2022/lib/uploader/index.mjs +0 -6
- package/esm2022/lib/uploader/interfaces.mjs +0 -8
- package/esm2022/lib/uploader/ng-file-drop.directive.mjs +0 -81
- package/esm2022/lib/uploader/ng-file-select.directive.mjs +0 -51
- package/esm2022/lib/uploader/ngx-uploader.class.mjs +0 -308
- package/esm2022/lib/uploader/ngx-uploader.module.mjs +0 -17
- package/esm2022/lib/utils/slugify.mjs +0 -16
- package/esm2022/lib/utils/tab-memory.service.mjs +0 -80
- package/esm2022/lib/utils/template.mjs +0 -72
- package/esm2022/public-api.mjs +0 -56
- package/esm2022/solidev-data.mjs +0 -5
- package/solidev-data-0.4.8.tgz +0 -0
|
@@ -1,480 +0,0 @@
|
|
|
1
|
-
import { Component, EventEmitter, Inject, Input, Optional, Output, } from '@angular/core';
|
|
2
|
-
import { ReactiveFormsModule, UntypedFormGroup, } from '@angular/forms';
|
|
3
|
-
import { firstValueFrom } from 'rxjs';
|
|
4
|
-
import { FkselectComponent } from '../fkselect/fkselect.component';
|
|
5
|
-
import { BootstrapDataDisplayConfig, DATA_DISPLAY_CONFIG, } from '../../data/data-parameters';
|
|
6
|
-
import { CommonModule } from '@angular/common';
|
|
7
|
-
import { M2mselectComponent } from '../m2mselect/m2mselect.component';
|
|
8
|
-
import { ChoicePipe } from '../choice.pipe';
|
|
9
|
-
import * as i0 from "@angular/core";
|
|
10
|
-
import * as i1 from "../../messages/message.service";
|
|
11
|
-
import * as i2 from "@angular/common";
|
|
12
|
-
import * as i3 from "@angular/forms";
|
|
13
|
-
export class DispeditComponent {
|
|
14
|
-
/**
|
|
15
|
-
* Constructor, can be given DATA_DISPLAY_CONFIG injection token to override display classes.
|
|
16
|
-
* By default, bs5 config is used
|
|
17
|
-
* @param dconf DataDisplayConfig item
|
|
18
|
-
* @param _msgs messages service
|
|
19
|
-
*/
|
|
20
|
-
constructor(dconf, _msgs) {
|
|
21
|
-
this.dconf = dconf;
|
|
22
|
-
this._msgs = _msgs;
|
|
23
|
-
/**
|
|
24
|
-
* Starting edit mode
|
|
25
|
-
* If mode is inline, edit is always true.
|
|
26
|
-
*/
|
|
27
|
-
this.edit = false;
|
|
28
|
-
/**
|
|
29
|
-
* Can be switched to edit mode?
|
|
30
|
-
* default : true
|
|
31
|
-
*/
|
|
32
|
-
this.editable = true;
|
|
33
|
-
/**
|
|
34
|
-
* Display mode
|
|
35
|
-
* - dd provides display / edit within a dt/dd block
|
|
36
|
-
* - inline (to be renamed to form) provides a (label? and) form control
|
|
37
|
-
* */
|
|
38
|
-
this.mode = 'inline';
|
|
39
|
-
/**
|
|
40
|
-
* Custom choices
|
|
41
|
-
* If provided, a select form control will be used instead of base editor
|
|
42
|
-
*/
|
|
43
|
-
this.choices = [];
|
|
44
|
-
/**
|
|
45
|
-
* Override placeholder, if provided.
|
|
46
|
-
* By default, manager.description is used
|
|
47
|
-
*/
|
|
48
|
-
this.placeholder = '';
|
|
49
|
-
/**
|
|
50
|
-
* Override help, if provided.
|
|
51
|
-
* By default, manager.help is used.
|
|
52
|
-
*/
|
|
53
|
-
this.help = '';
|
|
54
|
-
/**
|
|
55
|
-
* Hide label (for inline forms)
|
|
56
|
-
*/
|
|
57
|
-
this.hideLabel = false;
|
|
58
|
-
/** Fk filter */
|
|
59
|
-
this.filter = {};
|
|
60
|
-
/** Output emitter, output model on every change */
|
|
61
|
-
this.changed = new EventEmitter();
|
|
62
|
-
/** Computed editor type */
|
|
63
|
-
this.realEditor = 'input.text';
|
|
64
|
-
/** Computed display type */
|
|
65
|
-
this.realDisplay = 'text';
|
|
66
|
-
/** Computed chocies type */
|
|
67
|
-
this.realChoices = [];
|
|
68
|
-
if (this.dconf === null) {
|
|
69
|
-
this.dconf = BootstrapDataDisplayConfig;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Init sequence.
|
|
74
|
-
* - Sets mode
|
|
75
|
-
* - Sets display function
|
|
76
|
-
* - Loads manager
|
|
77
|
-
* - Run misc checks on special values
|
|
78
|
-
* - Get help, placeholder strings
|
|
79
|
-
*/
|
|
80
|
-
ngOnInit() {
|
|
81
|
-
this._setMode();
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Upgrade all values on any change.
|
|
85
|
-
* @param changes
|
|
86
|
-
*/
|
|
87
|
-
ngOnChanges(changes) {
|
|
88
|
-
this._setDisplayFn();
|
|
89
|
-
this.manager = this.model?.FM(this.field);
|
|
90
|
-
this.required = this.manager?.required || false;
|
|
91
|
-
this._checks();
|
|
92
|
-
this.realHelp = this.help || this.manager?.help || '';
|
|
93
|
-
this.realPlaceholder = this.placeholder || this.manager?.description || '';
|
|
94
|
-
this.realDefault = this.default;
|
|
95
|
-
this.save = this.save === undefined ? this.mode === 'dd' : this.save;
|
|
96
|
-
if ((!this.edit && this.mode === 'dd') ||
|
|
97
|
-
(!this.editable && this.mode === 'inline')) {
|
|
98
|
-
this.enableDisplayMode();
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
this.enableEditMode();
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Set up display mode.
|
|
106
|
-
* - get choices if available
|
|
107
|
-
* - get display type
|
|
108
|
-
* - process current value for display
|
|
109
|
-
* - set display classes
|
|
110
|
-
*/
|
|
111
|
-
enableDisplayMode() {
|
|
112
|
-
this._getChoices();
|
|
113
|
-
this._getRealDisplay();
|
|
114
|
-
this._getDisplayValue();
|
|
115
|
-
this._setDisplayClasses();
|
|
116
|
-
this.edit = false;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Set up edit mode :
|
|
120
|
-
* - get choices if available
|
|
121
|
-
* - get editor type
|
|
122
|
-
* - prepare form controle
|
|
123
|
-
* - set form control value
|
|
124
|
-
* - update form control classes
|
|
125
|
-
*/
|
|
126
|
-
enableEditMode() {
|
|
127
|
-
if (!this.editable) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
this._getChoices();
|
|
131
|
-
this._getRealEditor();
|
|
132
|
-
this._setFormControl();
|
|
133
|
-
this._setFormControlValue();
|
|
134
|
-
this._setEditorClasses();
|
|
135
|
-
this.edit = true;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Update model field from form control value (if value is valid).
|
|
139
|
-
* If save boolean is true, save values to API.
|
|
140
|
-
*/
|
|
141
|
-
async update() {
|
|
142
|
-
if (this.fg && this.model && this.fg.valid) {
|
|
143
|
-
switch (this.realEditor) {
|
|
144
|
-
case 'input.decimal':
|
|
145
|
-
this.model[this.field] = Math.round(this.fg.value[this.field] * this.manager.factor);
|
|
146
|
-
break;
|
|
147
|
-
default:
|
|
148
|
-
this.model[this.field] = this.fg.value[this.field];
|
|
149
|
-
}
|
|
150
|
-
if (this.save === true) {
|
|
151
|
-
return this._save();
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
unsetEdit() {
|
|
156
|
-
if (this.mode == 'dd' && this.edit) {
|
|
157
|
-
this.edit = false;
|
|
158
|
-
delete this.fg;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
toggleEdit() {
|
|
162
|
-
if (!this.edit) {
|
|
163
|
-
this.enableEditMode();
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
this.unsetEdit();
|
|
167
|
-
this.enableDisplayMode();
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Reset field to default value
|
|
172
|
-
* TODO: check if edit mode needs to be changed / saved
|
|
173
|
-
*/
|
|
174
|
-
async setDefault() {
|
|
175
|
-
if (this.model) {
|
|
176
|
-
this.model[this.field] = this.realDefault;
|
|
177
|
-
this.fg.controls[this.field].setValue(this.realDefault, {
|
|
178
|
-
emitEvent: false,
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
await this.update();
|
|
182
|
-
}
|
|
183
|
-
async selectedRefItem($event) {
|
|
184
|
-
if (this.model) {
|
|
185
|
-
if ($event !== null) {
|
|
186
|
-
this.model[this.field] = $event.id;
|
|
187
|
-
this.model[`${this.field}_details`] = $event;
|
|
188
|
-
if (this.form) {
|
|
189
|
-
const fv = {};
|
|
190
|
-
fv[this.field] = $event.id;
|
|
191
|
-
this.form.patchValue(fv, { emitEvent: true });
|
|
192
|
-
this.form.markAsTouched();
|
|
193
|
-
this.form.markAsDirty();
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
this.model[this.field] = null;
|
|
198
|
-
delete this.model[`${this.field}_details`];
|
|
199
|
-
if (this.form) {
|
|
200
|
-
const fv = {};
|
|
201
|
-
fv[this.field] = null;
|
|
202
|
-
this.form.patchValue(fv, { emitEvent: true });
|
|
203
|
-
this.form.markAsTouched();
|
|
204
|
-
this.form.markAsDirty();
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return this._save();
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
onM2MValuesChanges(v) {
|
|
211
|
-
this.m2mValues = v;
|
|
212
|
-
}
|
|
213
|
-
_checks() {
|
|
214
|
-
if (this.editor === 'quill' && !this.viewer) {
|
|
215
|
-
this.viewer = 'quill';
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Save value to database, only if model have an id.
|
|
220
|
-
* If mode is dd, toggle edit / display mode.
|
|
221
|
-
* @private
|
|
222
|
-
*/
|
|
223
|
-
async _save() {
|
|
224
|
-
if (this.model) {
|
|
225
|
-
if (this.model.id) {
|
|
226
|
-
try {
|
|
227
|
-
await firstValueFrom(this.model.update([this.field], { updateModel: true }));
|
|
228
|
-
}
|
|
229
|
-
catch (e) {
|
|
230
|
-
console.error(e);
|
|
231
|
-
let msg = '';
|
|
232
|
-
if (e && e.error && e.error[this.field]) {
|
|
233
|
-
msg = `${e.error[this.field]}`;
|
|
234
|
-
}
|
|
235
|
-
this._msgs.error("Erreur lors de l'enregistrement", msg, JSON.stringify(e));
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
if (this.mode === 'dd') {
|
|
240
|
-
this.unsetEdit();
|
|
241
|
-
this.enableDisplayMode();
|
|
242
|
-
}
|
|
243
|
-
this.changed.next(this.model);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
_display(x) {
|
|
247
|
-
if (x) {
|
|
248
|
-
if (x._display) {
|
|
249
|
-
if (x._display instanceof Function) {
|
|
250
|
-
return x._display();
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
return x._display;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
if (this._tpl) {
|
|
257
|
-
return this._tpl(x);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return '';
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Set display mode based on current display config
|
|
264
|
-
* @private
|
|
265
|
-
*/
|
|
266
|
-
_setMode() {
|
|
267
|
-
if (!this.mode) {
|
|
268
|
-
this.mode = this.dconf.dispEdit.defaultMode;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
_setDisplayFn() {
|
|
272
|
-
if (this.display) {
|
|
273
|
-
if (this.display && typeof this.display === 'string') {
|
|
274
|
-
this._tpl = (model) => `${model[this.display]}`;
|
|
275
|
-
}
|
|
276
|
-
else if (this.display && typeof this.display === 'function') {
|
|
277
|
-
this._tpl = this.display.bind(this);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
this._tpl = (model) => `${model['name'] ||
|
|
282
|
-
model['title'] ||
|
|
283
|
-
model['id']}`;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
_getChoices() {
|
|
287
|
-
// Set display choices
|
|
288
|
-
let choices;
|
|
289
|
-
if (this.choices && this.choices.length) {
|
|
290
|
-
choices = this.choices;
|
|
291
|
-
}
|
|
292
|
-
else if (this.manager?.choices) {
|
|
293
|
-
choices = this.manager?.choices;
|
|
294
|
-
}
|
|
295
|
-
// Set display value
|
|
296
|
-
if (choices && choices.length > 0) {
|
|
297
|
-
this.realChoices = choices;
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
delete this.realChoices;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
_getRealDisplay() {
|
|
304
|
-
this.realDisplay = this.viewer
|
|
305
|
-
? this.viewer
|
|
306
|
-
: this.manager?.displayType
|
|
307
|
-
? this.manager.displayType
|
|
308
|
-
: 'text';
|
|
309
|
-
if (this.realChoices && this.realChoices.length) {
|
|
310
|
-
this.realDisplay = 'choice';
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
_getRealEditor() {
|
|
314
|
-
this.realEditor = this.editor
|
|
315
|
-
? this.editor
|
|
316
|
-
: this.manager?.editorType || 'input.text';
|
|
317
|
-
if (this.realChoices && this.realChoices.length) {
|
|
318
|
-
this.realEditor = 'select';
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
_setFormControl() {
|
|
322
|
-
if (!this.form) {
|
|
323
|
-
const fgc = {};
|
|
324
|
-
fgc[this.field] = this.model.FC(this.field);
|
|
325
|
-
this.fg = new UntypedFormGroup(fgc);
|
|
326
|
-
}
|
|
327
|
-
else {
|
|
328
|
-
this.fg = this.form;
|
|
329
|
-
this.fg.setControl(this.field, this.model.FC(this.field), {
|
|
330
|
-
emitEvent: false,
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
if (this.mode === 'inline') {
|
|
334
|
-
this.fg.valueChanges.subscribe(() => {
|
|
335
|
-
this.update();
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
_setFormControlValue() {
|
|
340
|
-
switch (this.realEditor) {
|
|
341
|
-
case 'input.datetime':
|
|
342
|
-
const value = this.model[this.field];
|
|
343
|
-
const now = new Date();
|
|
344
|
-
const localnow = new Date(now.getTime() - now.getTimezoneOffset() * 60000);
|
|
345
|
-
if (value === null) {
|
|
346
|
-
this.fg.controls[this.field].setValue(null, { emitEvent: true });
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
const time = value ? new Date(value) : new Date();
|
|
350
|
-
const offset = time.getTimezoneOffset();
|
|
351
|
-
const localtime = new Date(time.getTime() - offset * 60000);
|
|
352
|
-
this.fg.controls[this.field].setValue(localtime.toISOString().substring(0, 16), { emitEvent: true });
|
|
353
|
-
}
|
|
354
|
-
this.realDefault =
|
|
355
|
-
this.default || this.manager?.required
|
|
356
|
-
? localnow.toISOString().substring(0, 16)
|
|
357
|
-
: null;
|
|
358
|
-
break;
|
|
359
|
-
case 'input.date':
|
|
360
|
-
const dt = this.model.toJson([this.field])[this.field];
|
|
361
|
-
this.fg.controls[this.field].setValue(dt);
|
|
362
|
-
break;
|
|
363
|
-
case 'input.decimal':
|
|
364
|
-
this.fg.controls[this.field].setValue(this.model[this.field] /
|
|
365
|
-
(this.manager.factor || 1));
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
_setEditorClasses() {
|
|
369
|
-
// FIXME: use realEditorClasses
|
|
370
|
-
if (!this.inputClasses) {
|
|
371
|
-
this.inputClasses =
|
|
372
|
-
this.dconf.dispEdit.inputClasses[this.realEditor] || '';
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
_getDisplayValue() {
|
|
376
|
-
const value = this.model[this.field];
|
|
377
|
-
this.dispValue = value;
|
|
378
|
-
if (this.realChoices) {
|
|
379
|
-
for (const c of this.realChoices) {
|
|
380
|
-
if (c === value) {
|
|
381
|
-
this.txtValue = c;
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
else if (c.value !== undefined && c.value === value) {
|
|
385
|
-
this.txtValue = c.desc;
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
// Set display text depending on value and realDisplay value
|
|
391
|
-
if (value === true) {
|
|
392
|
-
this.txtValue = 'OUI';
|
|
393
|
-
}
|
|
394
|
-
else if (value === false) {
|
|
395
|
-
this.txtValue = 'NON';
|
|
396
|
-
}
|
|
397
|
-
else if (value === undefined || value === null) {
|
|
398
|
-
this.txtValue = 'non défini';
|
|
399
|
-
}
|
|
400
|
-
else {
|
|
401
|
-
switch (this.realDisplay) {
|
|
402
|
-
case 'fkdetails':
|
|
403
|
-
const details = this.model[`${this.field}_details`];
|
|
404
|
-
this.txtValue = this._display(details);
|
|
405
|
-
break;
|
|
406
|
-
case 'm2mdetails':
|
|
407
|
-
const m2mDetails = this.m2mValues ||
|
|
408
|
-
this.model[`${this.field}_details`];
|
|
409
|
-
this.txtValues = [];
|
|
410
|
-
for (const v of m2mDetails || []) {
|
|
411
|
-
this.txtValues.push(this._display(v));
|
|
412
|
-
}
|
|
413
|
-
break;
|
|
414
|
-
case 'decimal':
|
|
415
|
-
this.txtValue = `${value /
|
|
416
|
-
(this.manager.factor || 1)}`;
|
|
417
|
-
break;
|
|
418
|
-
default:
|
|
419
|
-
this.txtValue = `${value}`;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
_setDisplayClasses() { }
|
|
424
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: DispeditComponent, deps: [{ token: DATA_DISPLAY_CONFIG, optional: true }, { token: i1.DataMessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
425
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.5", type: DispeditComponent, isStandalone: true, selector: "data-dispedit", inputs: { model: "model", field: "field", form: "form", edit: "edit", editable: "editable", mode: "mode", choices: "choices", inputClasses: "inputClasses", editor: "editor", viewer: "viewer", default: "default", placeholder: "placeholder", help: "help", hideLabel: "hideLabel", queryset: "queryset", collection: "collection", display: "display", filter: "filter" }, outputs: { changed: "changed" }, usesOnChanges: true, ngImport: i0, template: "\n<ng-template #titleTpl>\n <ng-content></ng-content>\n</ng-template>\n<ng-template #dispTpl>\n <ng-container [ngSwitch]=\"realDisplay\"><span class=\"editable disp-text\" *ngSwitchCase=\"'text'\" (click)=\"enableEditMode()\">{{txtValue}}</span><span class=\"editable disp-choice\" *ngSwitchCase=\"'choice'\" (click)=\"enableEditMode()\">{{txtValue}}</span><span class=\"editable disp-decimal\" *ngSwitchCase=\"'decimal'\" (click)=\"enableEditMode()\">{{txtValue}}</span><span class=\"editable disp-boolean\" *ngSwitchCase=\"'boolean'\" (click)=\"enableEditMode()\">{{txtValue}}</span><span class=\"editable disp-fkdetails\" *ngSwitchCase=\"'fkdetails'\" (click)=\"enableEditMode()\">\n <div class=\"fkitem\">{{txtValue}}</div></span><span class=\"editable disp-m2mdetails\" *ngSwitchCase=\"'m2mdetails'\" (click)=\"enableEditMode()\">\n <div class=\"m2mitem\" *ngFor=\"let v of txtValues\">{{v}}</div></span><span class=\"editable disp-datetime\" *ngSwitchCase=\"'datetime'\" (click)=\"enableEditMode()\">\n <ng-container *ngIf=\"dispValue\">{{txtValue|date:'short'}}</ng-container>\n <ng-container *ngIf=\"!dispValue\">{{txtValue}}</ng-container></span><span class=\"editable disp-datetime\" *ngSwitchCase=\"'date'\" (click)=\"enableEditMode()\">\n <ng-container *ngIf=\"dispValue\">{{txtValue|date:'shortDate'}}</ng-container>\n <ng-container *ngIf=\"!dispValue\">{{txtValue}}</ng-container></span></ng-container>\n</ng-template>\n<ng-template #editTpl let-form=\"form\">\n <ng-container [ngSwitch]=\"realEditor\">\n <ng-container *ngSwitchCase=\"'input.text'\">\n <input type=\"text\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" [placeholder]=\"realPlaceholder\">\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minlength']\">Trop court : {{$any(manager).minLength}} caract\u00E8res minimum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxlength']\">Trop long : {{$any(manager).maxLength}} caract\u00E8res maximum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['pattern']\">Format invalide...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.email'\">\n <input type=\"email\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" [placeholder]=\"realPlaceholder\">\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minlength']\">Trop court : {{$any(manager).minLength}} caract\u00E8res minimum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxlength']\">Trop long : {{$any(manager).maxLength}} caract\u00E8res maximum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['pattern']\">Format invalide...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['email']\">Format d'email invalide...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.password'\">\n <input type=\"password\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" [placeholder]=\"realPlaceholder\">\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minlength']\">Trop court : {{$any(manager).minLength}} caract\u00E8res minimum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxlength']\">Trop long : {{$any(manager).maxLength}} caract\u00E8res maximum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['pattern']\">Format invalide...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.datetime'\">\n <input type=\"datetime-local\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" (keyup.enter)=\"update()\">\n <div class=\"form-text\">{{realHelp}}</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minDate']\">Doit \u00EAtre post\u00E9rieur \u00E0 {{$any(manager).min|date:'short'}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxDate']\">Doit \u00EAtre ant\u00E9rieur \u00E0 {{$any(manager).max|date:'short'}}...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.date'\">\n <input type=\"date\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" (keyup.enter)=\"update()\">\n <div class=\"form-text\">{{realHelp}}</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minDate']\">Doit \u00EAtre post\u00E9rieur \u00E0 {{$any(manager).min|date:'short'}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxDate']\">Doit \u00EAtre ant\u00E9rieur \u00E0 {{$any(manager).max|date:'short'}}...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.number'\">\n <input type=\"number\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" [placeholder]=\"realPlaceholder\">\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['min']\">Trop petit : minimum {{$any(manager).min}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['max']\">Trop grand : maximum {{$any(manager).max}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.decimal'\">\n <input type=\"number\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" [placeholder]=\"realPlaceholder\">\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['min']\">Trop petit : minimum {{$any(manager).min}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['max']\">Trop grand : maximum {{$any(manager).max}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.checkbox'\">\n <input class=\"form-check-input\" type=\"checkbox\" [formControl]=\"form.get(field)\" (keyup.escape)=\"unsetEdit()\" (change)=\"update()\">\n <div class=\"form-text\">{{realHelp}}</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'textarea'\">\n <textarea [formControl]=\"form.get(field)\" (keyup.escape)=\"unsetEdit()\" [ngClass]=\"inputClasses\" (keyup.control.enter)=\"update()\" [placeholder]=\"realPlaceholder\"></textarea>\n <button class=\"btn btn-sm btn-link w-100 dispedit-text-update-button\" (click)=\"update()\" *ngIf=\"mode==='dd'\"><i class=\"bi bi-save\"></i></button>\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minlength']\">Trop court : {{$any(manager).minLength}} caract\u00E8res minimum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxlength']\">Trop long : {{$any(manager).maxLength}} caract\u00E8res maximum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['pattern']\">Format invalide...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'fkselect'\">\n <data-fkselect [collection]=\"collection\" [filter]=\"filter\" [display]=\"display\" (selected)=\"selectedRefItem($event)\" [placeholder]=\"placeholder\" (cancelled)=\"unsetEdit()\" (cleared)=\"selectedRefItem(null)\"></data-fkselect>\n </ng-container>\n <ng-container *ngSwitchCase=\"'m2mselect'\">\n <data-m2mselect [collection]=\"collection\" [filter]=\"filter\" (changed)=\"update()\" [formControl]=\"form.get(field)\" (detailsChanged)=\"onM2MValuesChanges($event)\" [model]=\"model\" [field]=\"field\" [placeholder]=\"placeholder\"></data-m2mselect>\n </ng-container>\n <ng-container *ngSwitchCase=\"'select'\">\n <select [formControl]=\"form.get(field)\" (keyup.escape)=\"unsetEdit()\" (change)=\"update()\" [ngClass]=\"inputClasses\">\n <option *ngFor=\"let c of realChoices\" [ngValue]=\"c.value!==undefined ? c.value : c\">{{c.desc ? c.desc : c}}</option>\n </select>\n <div class=\"form-text\">{{realHelp}}</div>\n </ng-container>\n </ng-container>\n</ng-template>\n<!-- Disp/edit toggler-->\n<ng-template #dispeditTpl>\n <ng-container *ngIf=\"!edit\">\n <ng-container *ngTemplateOutlet=\"dispTpl\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"edit\">\n <ng-container *ngIf=\"fg\">\n <form [formGroup]=\"fg\" (submit)=\"update()\">\n <ng-container *ngTemplateOutlet=\"editTpl; context: {form: fg}\"></ng-container>\n </form>\n </ng-container>\n </ng-container>\n</ng-template>\n<!-- DispEdit noform-->\n<ng-template #dispeditFormTpl>\n <ng-container *ngIf=\"!edit\">\n <ng-container *ngTemplateOutlet=\"dispTpl\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"edit\">\n <ng-container *ngIf=\"form\">\n <ng-container *ngTemplateOutlet=\"editTpl; context: {form: form}\"></ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n<!-- Dd display-->\n<ng-container *ngIf=\"mode==='dd'\">\n <dt [class.required]=\"required\" *ngIf=\"!hideLabel\"><span class=\"editable\" (click)=\"toggleEdit()\">\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container></span><span class=\"pointer float-end\" (click)=\"setDefault()\" *ngIf=\"realDefault!== undefined && edit\"><i class=\"bi bi-trash ms-2\"></i></span></dt>\n <dd [class.mb-0]=\"hideLabel\">\n <ng-container *ngTemplateOutlet=\"dispeditTpl\"></ng-container>\n </dd>\n</ng-container>\n<!-- Inline display-->\n<ng-container *ngIf=\"mode==='inline'\">\n <ng-container *ngIf=\"!hideLabel\"><span class=\"pointer float-end\" (click)=\"setDefault()\" *ngIf=\"realDefault!== undefined && edit\"><i class=\"bi bi-trash ms-2\"></i></span>\n <label [class.required]=\"required\">\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container>\n </label>\n </ng-container>\n <ng-container *ngTemplateOutlet=\"dispeditTpl\"></ng-container>\n</ng-container>\n<!-- Form display-->\n<ng-container *ngIf=\"mode==='form'\">\n <ng-container *ngIf=\"!hideLabel\"><span class=\"pointer float-end\" (click)=\"setDefault()\" *ngIf=\"realDefault!== undefined && edit\"><i class=\"bi bi-trash ms-2\"></i></span>\n <label [class.required]=\"required\">\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container>\n </label>\n </ng-container>\n <ng-container *ngTemplateOutlet=\"dispeditFormTpl\"></ng-container>\n</ng-container>", styles: [".editable{cursor:pointer}form.inline{display:inline-block}.required{font-weight:700}.required:after{content:\" (*)\"}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "pipe", type: i2.DatePipe, name: "date" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FkselectComponent, selector: "data-fkselect", inputs: ["model", "field", "edit", "value", "queryset", "collection", "update", "filter", "mode", "display", "search", "label", "placeholder", "inputClasses"], outputs: ["selected", "cancelled", "cleared"] }, { kind: "component", type: M2mselectComponent, selector: "data-m2mselect", inputs: ["model", "field", "edit", "values", "queryset", "collection", "filter", "mode", "display", "search", "label", "placeholder", "emptyLabel", "inputClasses"], outputs: ["added", "removed", "cancelled", "cleared", "detailsChanged", "changed"] }] }); }
|
|
426
|
-
}
|
|
427
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: DispeditComponent, decorators: [{
|
|
428
|
-
type: Component,
|
|
429
|
-
args: [{ selector: 'data-dispedit', standalone: true, imports: [
|
|
430
|
-
CommonModule,
|
|
431
|
-
ReactiveFormsModule,
|
|
432
|
-
FkselectComponent,
|
|
433
|
-
M2mselectComponent,
|
|
434
|
-
ChoicePipe,
|
|
435
|
-
], template: "\n<ng-template #titleTpl>\n <ng-content></ng-content>\n</ng-template>\n<ng-template #dispTpl>\n <ng-container [ngSwitch]=\"realDisplay\"><span class=\"editable disp-text\" *ngSwitchCase=\"'text'\" (click)=\"enableEditMode()\">{{txtValue}}</span><span class=\"editable disp-choice\" *ngSwitchCase=\"'choice'\" (click)=\"enableEditMode()\">{{txtValue}}</span><span class=\"editable disp-decimal\" *ngSwitchCase=\"'decimal'\" (click)=\"enableEditMode()\">{{txtValue}}</span><span class=\"editable disp-boolean\" *ngSwitchCase=\"'boolean'\" (click)=\"enableEditMode()\">{{txtValue}}</span><span class=\"editable disp-fkdetails\" *ngSwitchCase=\"'fkdetails'\" (click)=\"enableEditMode()\">\n <div class=\"fkitem\">{{txtValue}}</div></span><span class=\"editable disp-m2mdetails\" *ngSwitchCase=\"'m2mdetails'\" (click)=\"enableEditMode()\">\n <div class=\"m2mitem\" *ngFor=\"let v of txtValues\">{{v}}</div></span><span class=\"editable disp-datetime\" *ngSwitchCase=\"'datetime'\" (click)=\"enableEditMode()\">\n <ng-container *ngIf=\"dispValue\">{{txtValue|date:'short'}}</ng-container>\n <ng-container *ngIf=\"!dispValue\">{{txtValue}}</ng-container></span><span class=\"editable disp-datetime\" *ngSwitchCase=\"'date'\" (click)=\"enableEditMode()\">\n <ng-container *ngIf=\"dispValue\">{{txtValue|date:'shortDate'}}</ng-container>\n <ng-container *ngIf=\"!dispValue\">{{txtValue}}</ng-container></span></ng-container>\n</ng-template>\n<ng-template #editTpl let-form=\"form\">\n <ng-container [ngSwitch]=\"realEditor\">\n <ng-container *ngSwitchCase=\"'input.text'\">\n <input type=\"text\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" [placeholder]=\"realPlaceholder\">\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minlength']\">Trop court : {{$any(manager).minLength}} caract\u00E8res minimum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxlength']\">Trop long : {{$any(manager).maxLength}} caract\u00E8res maximum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['pattern']\">Format invalide...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.email'\">\n <input type=\"email\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" [placeholder]=\"realPlaceholder\">\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minlength']\">Trop court : {{$any(manager).minLength}} caract\u00E8res minimum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxlength']\">Trop long : {{$any(manager).maxLength}} caract\u00E8res maximum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['pattern']\">Format invalide...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['email']\">Format d'email invalide...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.password'\">\n <input type=\"password\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" [placeholder]=\"realPlaceholder\">\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minlength']\">Trop court : {{$any(manager).minLength}} caract\u00E8res minimum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxlength']\">Trop long : {{$any(manager).maxLength}} caract\u00E8res maximum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['pattern']\">Format invalide...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.datetime'\">\n <input type=\"datetime-local\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" (keyup.enter)=\"update()\">\n <div class=\"form-text\">{{realHelp}}</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minDate']\">Doit \u00EAtre post\u00E9rieur \u00E0 {{$any(manager).min|date:'short'}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxDate']\">Doit \u00EAtre ant\u00E9rieur \u00E0 {{$any(manager).max|date:'short'}}...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.date'\">\n <input type=\"date\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" (keyup.enter)=\"update()\">\n <div class=\"form-text\">{{realHelp}}</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minDate']\">Doit \u00EAtre post\u00E9rieur \u00E0 {{$any(manager).min|date:'short'}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxDate']\">Doit \u00EAtre ant\u00E9rieur \u00E0 {{$any(manager).max|date:'short'}}...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.number'\">\n <input type=\"number\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" [placeholder]=\"realPlaceholder\">\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['min']\">Trop petit : minimum {{$any(manager).min}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['max']\">Trop grand : maximum {{$any(manager).max}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.decimal'\">\n <input type=\"number\" [formControl]=\"form.get(field)\" [ngClass]=\"inputClasses\" (keyup.escape)=\"unsetEdit()\" [placeholder]=\"realPlaceholder\">\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['min']\">Trop petit : minimum {{$any(manager).min}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['max']\">Trop grand : maximum {{$any(manager).max}}...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'input.checkbox'\">\n <input class=\"form-check-input\" type=\"checkbox\" [formControl]=\"form.get(field)\" (keyup.escape)=\"unsetEdit()\" (change)=\"update()\">\n <div class=\"form-text\">{{realHelp}}</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'textarea'\">\n <textarea [formControl]=\"form.get(field)\" (keyup.escape)=\"unsetEdit()\" [ngClass]=\"inputClasses\" (keyup.control.enter)=\"update()\" [placeholder]=\"realPlaceholder\"></textarea>\n <button class=\"btn btn-sm btn-link w-100 dispedit-text-update-button\" (click)=\"update()\" *ngIf=\"mode==='dd'\"><i class=\"bi bi-save\"></i></button>\n <div class=\"form-text\" *ngIf=\"realHelp\">{{realHelp}}<span class=\"ms-1\" *ngIf=\"required\">(requis)</span></div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['minlength']\">Trop court : {{$any(manager).minLength}} caract\u00E8res minimum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['maxlength']\">Trop long : {{$any(manager).maxLength}} caract\u00E8res maximum...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['pattern']\">Format invalide...</div>\n <div class=\"invalid-feedback mt-0\" [class.d-block]=\"form && !form.controls[field].pristine && form.controls[field].errors?.['required']\">Ce champ est requis...</div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'fkselect'\">\n <data-fkselect [collection]=\"collection\" [filter]=\"filter\" [display]=\"display\" (selected)=\"selectedRefItem($event)\" [placeholder]=\"placeholder\" (cancelled)=\"unsetEdit()\" (cleared)=\"selectedRefItem(null)\"></data-fkselect>\n </ng-container>\n <ng-container *ngSwitchCase=\"'m2mselect'\">\n <data-m2mselect [collection]=\"collection\" [filter]=\"filter\" (changed)=\"update()\" [formControl]=\"form.get(field)\" (detailsChanged)=\"onM2MValuesChanges($event)\" [model]=\"model\" [field]=\"field\" [placeholder]=\"placeholder\"></data-m2mselect>\n </ng-container>\n <ng-container *ngSwitchCase=\"'select'\">\n <select [formControl]=\"form.get(field)\" (keyup.escape)=\"unsetEdit()\" (change)=\"update()\" [ngClass]=\"inputClasses\">\n <option *ngFor=\"let c of realChoices\" [ngValue]=\"c.value!==undefined ? c.value : c\">{{c.desc ? c.desc : c}}</option>\n </select>\n <div class=\"form-text\">{{realHelp}}</div>\n </ng-container>\n </ng-container>\n</ng-template>\n<!-- Disp/edit toggler-->\n<ng-template #dispeditTpl>\n <ng-container *ngIf=\"!edit\">\n <ng-container *ngTemplateOutlet=\"dispTpl\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"edit\">\n <ng-container *ngIf=\"fg\">\n <form [formGroup]=\"fg\" (submit)=\"update()\">\n <ng-container *ngTemplateOutlet=\"editTpl; context: {form: fg}\"></ng-container>\n </form>\n </ng-container>\n </ng-container>\n</ng-template>\n<!-- DispEdit noform-->\n<ng-template #dispeditFormTpl>\n <ng-container *ngIf=\"!edit\">\n <ng-container *ngTemplateOutlet=\"dispTpl\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"edit\">\n <ng-container *ngIf=\"form\">\n <ng-container *ngTemplateOutlet=\"editTpl; context: {form: form}\"></ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n<!-- Dd display-->\n<ng-container *ngIf=\"mode==='dd'\">\n <dt [class.required]=\"required\" *ngIf=\"!hideLabel\"><span class=\"editable\" (click)=\"toggleEdit()\">\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container></span><span class=\"pointer float-end\" (click)=\"setDefault()\" *ngIf=\"realDefault!== undefined && edit\"><i class=\"bi bi-trash ms-2\"></i></span></dt>\n <dd [class.mb-0]=\"hideLabel\">\n <ng-container *ngTemplateOutlet=\"dispeditTpl\"></ng-container>\n </dd>\n</ng-container>\n<!-- Inline display-->\n<ng-container *ngIf=\"mode==='inline'\">\n <ng-container *ngIf=\"!hideLabel\"><span class=\"pointer float-end\" (click)=\"setDefault()\" *ngIf=\"realDefault!== undefined && edit\"><i class=\"bi bi-trash ms-2\"></i></span>\n <label [class.required]=\"required\">\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container>\n </label>\n </ng-container>\n <ng-container *ngTemplateOutlet=\"dispeditTpl\"></ng-container>\n</ng-container>\n<!-- Form display-->\n<ng-container *ngIf=\"mode==='form'\">\n <ng-container *ngIf=\"!hideLabel\"><span class=\"pointer float-end\" (click)=\"setDefault()\" *ngIf=\"realDefault!== undefined && edit\"><i class=\"bi bi-trash ms-2\"></i></span>\n <label [class.required]=\"required\">\n <ng-container *ngTemplateOutlet=\"titleTpl\"></ng-container>\n </label>\n </ng-container>\n <ng-container *ngTemplateOutlet=\"dispeditFormTpl\"></ng-container>\n</ng-container>", styles: [".editable{cursor:pointer}form.inline{display:inline-block}.required{font-weight:700}.required:after{content:\" (*)\"}\n"] }]
|
|
436
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
437
|
-
type: Optional
|
|
438
|
-
}, {
|
|
439
|
-
type: Inject,
|
|
440
|
-
args: [DATA_DISPLAY_CONFIG]
|
|
441
|
-
}] }, { type: i1.DataMessageService }], propDecorators: { model: [{
|
|
442
|
-
type: Input
|
|
443
|
-
}], field: [{
|
|
444
|
-
type: Input
|
|
445
|
-
}], form: [{
|
|
446
|
-
type: Input
|
|
447
|
-
}], edit: [{
|
|
448
|
-
type: Input
|
|
449
|
-
}], editable: [{
|
|
450
|
-
type: Input
|
|
451
|
-
}], mode: [{
|
|
452
|
-
type: Input
|
|
453
|
-
}], choices: [{
|
|
454
|
-
type: Input
|
|
455
|
-
}], inputClasses: [{
|
|
456
|
-
type: Input
|
|
457
|
-
}], editor: [{
|
|
458
|
-
type: Input
|
|
459
|
-
}], viewer: [{
|
|
460
|
-
type: Input
|
|
461
|
-
}], default: [{
|
|
462
|
-
type: Input
|
|
463
|
-
}], placeholder: [{
|
|
464
|
-
type: Input
|
|
465
|
-
}], help: [{
|
|
466
|
-
type: Input
|
|
467
|
-
}], hideLabel: [{
|
|
468
|
-
type: Input
|
|
469
|
-
}], queryset: [{
|
|
470
|
-
type: Input
|
|
471
|
-
}], collection: [{
|
|
472
|
-
type: Input
|
|
473
|
-
}], display: [{
|
|
474
|
-
type: Input
|
|
475
|
-
}], filter: [{
|
|
476
|
-
type: Input
|
|
477
|
-
}], changed: [{
|
|
478
|
-
type: Output
|
|
479
|
-
}] } });
|
|
480
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzcGVkaXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGF0YS9zcmMvbGliL2Rpc3BlZGl0L2Rpc3BlZGl0L2Rpc3BlZGl0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2RhdGEvc3JjL2xpYi9kaXNwZWRpdC9kaXNwZWRpdC9kaXNwZWRpdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUdMLFFBQVEsRUFDUixNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUNMLG1CQUFtQixFQUVuQixnQkFBZ0IsR0FDakIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBUXRDLE9BQU8sRUFBRSxpQkFBaUIsRUFBVSxNQUFNLGdDQUFnQyxDQUFDO0FBRTNFLE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIsbUJBQW1CLEdBRXBCLE1BQU0sNEJBQTRCLENBQUM7QUFFcEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7QUFlNUMsTUFBTSxPQUFPLGlCQUFpQjtJQTJHNUI7Ozs7O09BS0c7SUFDSCxZQUNrRCxLQUF3QixFQUNoRSxLQUF5QjtRQURlLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBQ2hFLFVBQUssR0FBTCxLQUFLLENBQW9CO1FBMUduQzs7O1dBR0c7UUFDYSxTQUFJLEdBQUcsS0FBSyxDQUFDO1FBQzdCOzs7V0FHRztRQUNhLGFBQVEsR0FBRyxJQUFJLENBQUM7UUFRaEM7Ozs7YUFJ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O2dCQUVVLE9BQU87c0JBQXRCLEtBQUs7Z0JBS1UsV0FBVztzQkFBMUIsS0FBSztnQkFLVSxJQUFJO3NCQUFuQixLQUFLO2dCQUlVLFNBQVM7c0JBQXhCLEtBQUs7Z0JBS1UsUUFBUTtzQkFBdkIsS0FBSztnQkFFVSxVQUFVO3NCQUF6QixLQUFLO2dCQUVVLE9BQU87c0JBQXRCLEtBQUs7Z0JBRVUsTUFBTTtzQkFBckIsS0FBSztnQkFHVyxPQUFPO3NCQUF2QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERhdGFNb2RlbCB9IGZyb20gJy4uLy4uL2RhdGEvZGF0YS1tb2RlbCc7XG5pbXBvcnQgeyBCYXNlRmllbGRNYW5hZ2VyIH0gZnJvbSAnLi4vLi4vZGF0YS9maWVsZHMvYmFzZSc7XG5pbXBvcnQge1xuICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICBVbnR5cGVkRm9ybUNvbnRyb2wsXG4gIFVudHlwZWRGb3JtR3JvdXAsXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IGZpcnN0VmFsdWVGcm9tIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBESVNQRURJVF9ESVNQTEFZX1RZUEVTLFxuICBESVNQRURJVF9FRElUT1JfVFlQRVMsXG4gIElEaXNwRWRpdENob2ljZSxcbn0gZnJvbSAnLi9kaXNwZWRpdC5jb25zdGFudHMnO1xuaW1wb3J0IHsgRmlsdGVyRGF0YSwgUXVlcnlzZXQgfSBmcm9tICcuLi8uLi9kYXRhL2RhdGEtcXVlcnknO1xuaW1wb3J0IHsgQ29sbGVjdGlvbiB9IGZyb20gJy4uLy4uL2RhdGEvZGF0YS1jb2xsZWN0aW9uJztcbmltcG9ydCB7IEZrc2VsZWN0Q29tcG9uZW50LCBUcGxGdW4gfSBmcm9tICcuLi9ma3NlbGVjdC9ma3NlbGVjdC5jb21wb25lbnQnO1xuaW1wb3J0IHsgRGVjaW1hbEZpZWxkTWFuYWdlciB9IGZyb20gJy4uLy4uL2RhdGEvZmllbGRzL251bWJlcnMnO1xuaW1wb3J0IHtcbiAgQm9vdHN0cmFwRGF0YURpc3BsYXlDb25maWcsXG4gIERBVEFfRElTUExBWV9DT05GSUcsXG4gIERhdGFEaXNwbGF5Q29uZmlnLFxufSBmcm9tICcuLi8uLi9kYXRhL2RhdGEtcGFyYW1ldGVycyc7XG5pbXBvcnQgeyBEYXRhTWVzc2FnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9tZXNzYWdlcy9tZXNzYWdlLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE0ybXNlbGVjdENvbXBvbmVudCB9IGZyb20gJy4uL20ybXNlbGVjdC9tMm1zZWxlY3QuY29tcG9uZW50JztcbmltcG9ydCB7IENob2ljZVBpcGUgfSBmcm9tICcuLi9jaG9pY2UucGlwZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2RhdGEtZGlzcGVkaXQnLFxuICB0ZW1wbGF0ZVVybDogJy4vZGlzcGVkaXQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9kaXNwZWRpdC5jb21wb25lbnQuc2FzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgRmtzZWxlY3RDb21wb25lbnQsXG4gICAgTTJtc2VsZWN0Q29tcG9uZW50LFxuICAgIENob2ljZVBpcGUsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIERpc3BlZGl0Q29tcG9uZW50PEZULCBUIGV4dGVuZHMgRGF0YU1vZGVsLCBSIGV4dGVuZHMgRGF0YU1vZGVsPlxuICBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzXG57XG4gIC8qKiBNb2RlbCAobWFuZGF0b3J5KSAqL1xuICBASW5wdXQoKSBwdWJsaWMgbW9kZWwhOiBUO1xuICAvKiogRmllbGQgKG1hbmRhdG9yeSkgKi9cbiAgQElucHV0KCkgcHVibGljIGZpZWxkITogc3RyaW5nO1xuICAvKiogRXh0ZXJuYWwgZm9ybSAqL1xuICBASW5wdXQoKSBwdWJsaWMgZm9ybT86IFVudHlwZWRGb3JtR3JvdXA7XG4gIC8qKlxuICAgKiBTdGFydGluZyBlZGl0IG1vZGVcbiAgICogSWYgbW9kZSBpcyBpbmxpbmUsIGVkaXQgaXMgYWx3YXlzIHRydWUuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgZWRpdCA9IGZhbHNlO1xuICAvKipcbiAgICogQ2FuIGJlIHN3aXRjaGVkIHRvIGVkaXQgbW9kZT9cbiAgICogZGVmYXVsdCA6IHRydWVcbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBlZGl0YWJsZSA9IHRydWU7XG4gIC8qKlxuICAgKiBTYXZlIHVwZGF0ZWQgdmFsdWVzID9cbiAgICogSWYgbm90IGdpdmVuLCBkZWZhdWx0IHZhbHVlIGRlcGVuZHMgb24gbW9kZSA6XG4gICAqIC0gc2F2ZSBpZiBtb2RlIGlzIGRkXG4gICAqIC0gZG9uJ3Qgc2F2ZSBpZiBtb2RlIGlzIGlubGluZVxuICAgKi9cbiAgcHVibGljIHNhdmU/OiBib29sZWFuO1xuICAvKipcbiAgICogRGlzcGxheSBtb2RlXG4gICAqIC0gZGQgcHJvdmlkZXMgZGlzcGxheSAvIGVkaXQgd2l0aGluIGEgZHQvZGQgYmxvY2tcbiAgICogLSBpbmxpbmUgKHRvIGJlIHJlbmFtZWQgdG8gZm9ybSkgcHJvdmlkZXMgYSAobGFiZWw/IGFuZCkgZm9ybSBjb250cm9sXG4gICAqICovXG4gIEBJbnB1dCgpIHB1YmxpYyBtb2RlOiAnZGQnIHwgJ2lubGluZScgfCAnZm9ybScgPSAnaW5saW5lJztcbiAgLyoqXG4gICAqIEN1c3RvbSBjaG9pY2VzXG4gICAqIElmIHByb3ZpZGVkLCBhIHNlbGVjdCBmb3JtIGNvbnRyb2wgd2lsbCBiZSB1c2VkIGluc3RlYWQgb2YgYmFzZSBlZGl0b3JcbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBjaG9pY2VzOiBJRGlzcEVkaXRDaG9pY2VbXSA9IFtdO1xuICAvKiogQ3VzdG9tIGlucHV0IGNsYXNzZXMgKi9cbiAgQElucHV0KCkgcHVibGljIGlucHV0Q2xhc3NlcyE6IHN0cmluZ1tdIHwgc3RyaW5nO1xuICAvKiogT3ZlcnJpZGUgZWRpdG9yLCBpZiBwcm92aWRlZCAqL1xuICBASW5wdXQoKSBwdWJsaWMgZWRpdG9yPzogRElTUEVESVRfRURJVE9SX1RZUEVTO1xuICAvKiogT3ZlcnJpZGUgdmlld2VyLCBpZiBwcm92aWRlZCAqL1xuICBASW5wdXQoKSBwdWJsaWMgdmlld2VyPzogRElTUEVESVRfRElTUExBWV9UWVBFUztcbiAgLyoqIE92ZXJyaWRlIGRlZmF1bHQgdmFsdWUgKi9cbiAgQElucHV0KCkgcHVibGljIGRlZmF1bHQ/OiBhbnk7XG4gIC8qKlxuICAgKiBPdmVycmlkZSBwbGFjZWhvbGRlciwgaWYgcHJvdmlkZWQuXG4gICAqIEJ5IGRlZmF1bHQsIG1hbmFnZXIuZGVzY3JpcHRpb24gaXMgdXNlZFxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIHBsYWNlaG9sZGVyOiBzdHJpbmcgPSAnJztcbiAgLyoqXG4gICAqIE92ZXJyaWRlIGhlbHAsIGlmIHByb3ZpZGVkLlxuICAgKiBCeSBkZWZhdWx0LCBtYW5hZ2VyLmhlbHAgaXMgdXNlZC5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBoZWxwOiBzdHJpbmcgPSAnJztcbiAgLyoqXG4gICAqICBIaWRlIGxhYmVsIChmb3IgaW5saW5lIGZvcm1zKVxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIGhpZGVMYWJlbDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIEZLIGZpZWxkc1xuICAvLyBUT0RPOiByZW5hbWUgYXMgZmtfIG9yIHJlbGF0ZWRfXG4gIC8qKiBGayBxdWVyeXNldCAqL1xuICBASW5wdXQoKSBwdWJsaWMgcXVlcnlzZXQ/OiBRdWVyeXNldDxSPjtcbiAgLyoqIEZrIGNvbGxlY3Rpb24gKi9cbiAgQElucHV0KCkgcHVibGljIGNvbGxlY3Rpb24/OiBDb2xsZWN0aW9uPFI+O1xuICAvKiogRmsgZGlzcGxheSAqL1xuICBASW5wdXQoKSBwdWJsaWMgZGlzcGxheT86IHN0cmluZyB8IFRwbEZ1bjxSPjtcbiAgLyoqIEZrIGZpbHRlciAqL1xuICBASW5wdXQoKSBwdWJsaWMgZmlsdGVyOiBGaWx0ZXJEYXRhID0ge307XG5cbiAgLyoqIE91dHB1dCBlbWl0dGVyLCBvdXRwdXQgbW9kZWwgb24gZXZlcnkgY2hhbmdlICovXG4gIEBPdXRwdXQoKSBwdWJsaWMgY2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8VD4oKTtcblxuICAvKiogRmllbGQgbWFuYWdlciAqL1xuICBwdWJsaWMgbWFuYWdlcj86IEJhc2VGaWVsZE1hbmFnZXI8RlQ+O1xuXG4gIC8qKiBUZXh0IHZhbHVlIHVzZWQgZm9yIGRpc3BsYXkgKi9cbiAgcHVibGljIHR4dFZhbHVlPzogc3RyaW5nO1xuICAvKiogVGV4dCB2YWx1ZXMgdXNlZCBmb3IgbWFueSBkaXNwbGF5cyAqL1xuICBwdWJsaWMgdHh0VmFsdWVzPzogc3RyaW5nW107XG5cbiAgLyoqIENvbXB1dGVkIGVkaXRvciB0eXBlICovXG4gIHB1YmxpYyByZWFsRWRpdG9yOiBESVNQRURJVF9FRElUT1JfVFlQRVMgPSAnaW5wdXQudGV4dCc7XG4gIC8qKiBDb21wdXRlZCBkaXNwbGF5IHR5cGUgKi9cbiAgcHVibGljIHJlYWxEaXNwbGF5OiBESVNQRURJVF9ESVNQTEFZX1RZUEVTID0gJ3RleHQnO1xuICAvKiogQ3VycmVudCBkaXNwIHJhdyB2YWx1ZSAqL1xuICBwdWJsaWMgZGlzcFZhbHVlPzogYW55O1xuICAvKiogQ29tcHV0ZWQgY2hvY2llcyB0eXBlICovXG4gIHB1YmxpYyByZWFsQ2hvaWNlcz86IElEaXNwRWRpdENob2ljZVtdID0gW107XG4gIC8qKiBDb21wdXRlZCBoZWxwICovXG4gIHB1YmxpYyByZWFsSGVscCE6IHN0cmluZztcbiAgLyoqIENvbXB1dGVkIHBsYWNlaG9sZGVyICovXG4gIHB1YmxpYyByZWFsUGxhY2Vob2xkZXIhOiBzdHJpbmc7XG4gIC8qKiBDb21wdXRlZCByZXF1aXJlZCAqL1xuICBwdWJsaWMgcmVxdWlyZWQhOiBib29sZWFuO1xuICAvKiogQ29tcHV0ZWQgZGVmYXVsdCB2YWx1ZSAqL1xuICBwdWJsaWMgcmVhbERlZmF1bHQhOiBhbnk7XG5cbiAgcHVibGljIG0ybVZhbHVlcz86IGFueVtdO1xuXG4gIC8vIExvY2FsIGZvcm0gZ3JvdXBcbiAgcHVibGljIGZnPzogVW50eXBlZEZvcm1Hcm91cDtcblxuICAvLyBEaXNwbGF5IHRlbXBsYXRlIGZ1bmN0aW9uXG4gIHByaXZhdGUgX3RwbCE6IFRwbEZ1bjxSPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0b3IsIGNhbiBiZSBnaXZlbiBEQVRBX0RJU1BMQVlfQ09ORklHIGluamVjdGlvbiB0b2tlbiB0byBvdmVycmlkZSBkaXNwbGF5IGNsYXNzZXMuXG4gICAqIEJ5IGRlZmF1bHQsIGJzNSBjb25maWcgaXMgdXNlZFxuICAgKiBAcGFyYW0gZGNvbmYgRGF0YURpc3BsYXlDb25maWcgaXRlbVxuICAgKiBAcGFyYW0gX21zZ3MgbWVzc2FnZXMgc2VydmljZVxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChEQVRBX0RJU1BMQVlfQ09ORklHKSBwdWJsaWMgZGNvbmY6IERhdGFEaXNwbGF5Q29uZmlnLFxuICAgIHByaXZhdGUgX21zZ3M6IERhdGFNZXNzYWdlU2VydmljZSxcbiAgKSB7XG4gICAgaWYgKHRoaXMuZGNvbmYgPT09IG51bGwpIHtcbiAgICAgIHRoaXMuZGNvbmYgPSBCb290c3RyYXBEYXRhRGlzcGxheUNvbmZpZztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5pdCBzZXF1ZW5jZS5cbiAgICogLSBTZXRzIG1vZGVcbiAgICogLSBTZXRzIGRpc3BsYXkgZnVuY3Rpb25cbiAgICogLSBMb2FkcyBtYW5hZ2VyXG4gICAqIC0gUnVuIG1pc2MgY2hlY2tzIG9uIHNwZWNpYWwgdmFsdWVzXG4gICAqIC0gR2V0IGhlbHAsIHBsYWNlaG9sZGVyIHN0cmluZ3NcbiAgICovXG4gIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLl9zZXRNb2RlKCk7XG4gIH1cblxuICAvKipcbiAgICogVXBncmFkZSBhbGwgdmFsdWVzIG9uIGFueSBjaGFuZ2UuXG4gICAqIEBwYXJhbSBjaGFuZ2VzXG4gICAqL1xuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIHRoaXMuX3NldERpc3BsYXlGbigpO1xuICAgIHRoaXMubWFuYWdlciA9IHRoaXMubW9kZWw/LkZNKHRoaXMuZmllbGQpO1xuICAgIHRoaXMucmVxdWlyZWQgPSB0aGlzLm1hbmFnZXI/LnJlcXVpcmVkIHx8IGZhbHNlO1xuICAgIHRoaXMuX2NoZWNrcygpO1xuICAgIHRoaXMucmVhbEhlbHAgPSB0aGlzLmhlbHAgfHwgdGhpcy5tYW5hZ2VyPy5oZWxwIHx8ICcnO1xuICAgIHRoaXMucmVhbFBsYWNlaG9sZGVyID0gdGhpcy5wbGFjZWhvbGRlciB8fCB0aGlzLm1hbmFnZXI/LmRlc2NyaXB0aW9uIHx8ICcnO1xuICAgIHRoaXMucmVhbERlZmF1bHQgPSB0aGlzLmRlZmF1bHQ7XG4gICAgdGhpcy5zYXZlID0gdGhpcy5zYXZlID09PSB1bmRlZmluZWQgPyB0aGlzLm1vZGUgPT09ICdkZCcgOiB0aGlzLnNhdmU7XG4gICAgaWYgKFxuICAgICAgKCF0aGlzLmVkaXQgJiYgdGhpcy5tb2RlID09PSAnZGQnKSB8fFxuICAgICAgKCF0aGlzLmVkaXRhYmxlICYmIHRoaXMubW9kZSA9PT0gJ2lubGluZScpXG4gICAgKSB7XG4gICAgICB0aGlzLmVuYWJsZURpc3BsYXlNb2RlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW5hYmxlRWRpdE1vZGUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IHVwIGRpc3BsYXkgbW9kZS5cbiAgICogLSBnZXQgY2hvaWNlcyBpZiBhdmFpbGFibGVcbiAgICogLSBnZXQgZGlzcGxheSB0eXBlXG4gICAqIC0gcHJvY2VzcyBjdXJyZW50IHZhbHVlIGZvciBkaXNwbGF5XG4gICAqIC0gc2V0IGRpc3BsYXkgY2xhc3Nlc1xuICAgKi9cbiAgcHVibGljIGVuYWJsZURpc3BsYXlNb2RlKCkge1xuICAgIHRoaXMuX2dldENob2ljZXMoKTtcbiAgICB0aGlzLl9nZXRSZWFsRGlzcGxheSgpO1xuICAgIHRoaXMuX2dldERpc3BsYXlWYWx1ZSgpO1xuICAgIHRoaXMuX3NldERpc3BsYXlDbGFzc2VzKCk7XG4gICAgdGhpcy5lZGl0ID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHVwIGVkaXQgbW9kZSA6XG4gICAqIC0gZ2V0IGNob2ljZXMgaWYgYXZhaWxhYmxlXG4gICAqIC0gZ2V0IGVkaXRvciB0eXBlXG4gICAqIC0gcHJlcGFyZSBmb3JtIGNvbnRyb2xlXG4gICAqIC0gc2V0IGZvcm0gY29udHJvbCB2YWx1ZVxuICAgKiAtIHVwZGF0ZSBmb3JtIGNvbnRyb2wgY2xhc3Nlc1xuICAgKi9cbiAgcHVibGljIGVuYWJsZUVkaXRNb2RlKCkge1xuICAgIGlmICghdGhpcy5lZGl0YWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9nZXRDaG9pY2VzKCk7XG4gICAgdGhpcy5fZ2V0UmVhbEVkaXRvcigpO1xuICAgIHRoaXMuX3NldEZvcm1Db250cm9sKCk7XG4gICAgdGhpcy5fc2V0Rm9ybUNvbnRyb2xWYWx1ZSgpO1xuICAgIHRoaXMuX3NldEVkaXRvckNsYXNzZXMoKTtcbiAgICB0aGlzLmVkaXQgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBtb2RlbCBmaWVsZCBmcm9tIGZvcm0gY29udHJvbCB2YWx1ZSAoaWYgdmFsdWUgaXMgdmFsaWQpLlxuICAgKiBJZiBzYXZlIGJvb2xlYW4gaXMgdHJ1ZSwgc2F2ZSB2YWx1ZXMgdG8gQVBJLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHVwZGF0ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5mZyAmJiB0aGlzLm1vZGVsICYmIHRoaXMuZmcudmFsaWQpIHtcbiAgICAgIHN3aXRjaCAodGhpcy5yZWFsRWRpdG9yKSB7XG4gICAgICAgIGNhc2UgJ2lucHV0LmRlY2ltYWwnOlxuICAgICAgICAgICh0aGlzLm1vZGVsIGFzIGFueSlbdGhpcy5maWVsZF0gPSBNYXRoLnJvdW5kKFxuICAgICAgICAgICAgdGhpcy5mZy52YWx1ZVt0aGlzLmZpZWxkXSAqICh0aGlzLm1hbmFnZXIgYXMgYW55KS5mYWN0b3IsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAodGhpcy5tb2RlbCBhcyBhbnkpW3RoaXMuZmllbGRdID0gdGhpcy5mZy52YWx1ZVt0aGlzLmZpZWxkXTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnNhdmUgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NhdmUoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB1bnNldEVkaXQoKSB7XG4gICAgaWYgKHRoaXMubW9kZSA9PSAnZGQnICYmIHRoaXMuZWRpdCkge1xuICAgICAgdGhpcy5lZGl0ID0gZmFsc2U7XG4gICAgICBkZWxldGUgdGhpcy5mZztcbiAgICB9XG4gIH1cblxuICB0b2dnbGVFZGl0KCkge1xuICAgIGlmICghdGhpcy5lZGl0KSB7XG4gICAgICB0aGlzLmVuYWJsZUVkaXRNb2RlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudW5zZXRFZGl0KCk7XG4gICAgICB0aGlzLmVuYWJsZURpc3BsYXlNb2RlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IGZpZWxkIHRvIGRlZmF1bHQgdmFsdWVcbiAgICogVE9ETzogY2hlY2sgaWYgZWRpdCBtb2RlIG5lZWRzIHRvIGJlIGNoYW5nZWQgLyBzYXZlZFxuICAgKi9cbiAgcHVibGljIGFzeW5jIHNldERlZmF1bHQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMubW9kZWwpIHtcbiAgICAgICh0aGlzLm1vZGVsIGFzIGFueSlbdGhpcy5maWVsZF0gPSB0aGlzLnJlYWxEZWZhdWx0O1xuICAgICAgdGhpcy5mZyEuY29udHJvbHNbdGhpcy5maWVsZF0uc2V0VmFsdWUodGhpcy5yZWFsRGVmYXVsdCwge1xuICAgICAgICBlbWl0RXZlbnQ6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGF3YWl0IHRoaXMudXBkYXRlKCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2VsZWN0ZWRSZWZJdGVtKCRldmVudDogVCB8IG51bGwpIHtcbiAgICBpZiAodGhpcy5tb2RlbCkge1xuICAgICAgaWYgKCRldmVudCAhPT0gbnVsbCkge1xuICAgICAgICAodGhpcy5tb2RlbCBhcyBhbnkpW3RoaXMuZmllbGRdID0gJGV2ZW50LmlkO1xuICAgICAgICAodGhpcy5tb2RlbCBhcyBhbnkpW2Ake3RoaXMuZmllbGR9X2RldGFpbHNgXSA9ICRldmVudDtcbiAgICAgICAgaWYgKHRoaXMuZm9ybSkge1xuICAgICAgICAgIGNvbnN0IGZ2OiB7IFtpbmRleDogc3RyaW5nXTogbnVtYmVyIHwgbnVsbCB9ID0ge307XG4gICAgICAgICAgZnZbdGhpcy5maWVsZF0gPSAkZXZlbnQuaWQ7XG4gICAgICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoZnYsIHsgZW1pdEV2ZW50OiB0cnVlIH0pO1xuICAgICAgICAgIHRoaXMuZm9ybS5tYXJrQXNUb3VjaGVkKCk7XG4gICAgICAgICAgdGhpcy5mb3JtLm1hcmtBc0RpcnR5KCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICh0aGlzLm1vZGVsIGFzIGFueSlbdGhpcy5maWVsZF0gPSBudWxsO1xuICAgICAgICBkZWxldGUgKHRoaXMubW9kZWwgYXMgYW55KVtgJHt0aGlzLmZpZWxkfV9kZXRhaWxzYF07XG4gICAgICAgIGlmICh0aGlzLmZvcm0pIHtcbiAgICAgICAgICBjb25zdCBmdjogeyBbaW5kZXg6IHN0cmluZ106IG51bWJlciB8IG51bGwgfSA9IHt9O1xuICAgICAgICAgIGZ2W3RoaXMuZmllbGRdID0gbnVsbDtcbiAgICAgICAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZShmdiwgeyBlbWl0RXZlbnQ6IHRydWUgfSk7XG4gICAgICAgICAgdGhpcy5mb3JtLm1hcmtBc1RvdWNoZWQoKTtcbiAgICAgICAgICB0aGlzLmZvcm0ubWFya0FzRGlydHkoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuX3NhdmUoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgb25NMk1WYWx1ZXNDaGFuZ2VzKHY6IGFueVtdKSB7XG4gICAgdGhpcy5tMm1WYWx1ZXMgPSB2O1xuICB9XG5cbiAgcHJpdmF0ZSBfY2hlY2tzKCkge1xuICAgIGlmICh0aGlzLmVkaXRvciA9PT0gJ3F1aWxsJyAmJiAhdGhpcy52aWV3ZXIpIHtcbiAgICAgIHRoaXMudmlld2VyID0gJ3F1aWxsJztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSB2YWx1ZSB0byBkYXRhYmFzZSwgb25seSBpZiBtb2RlbCBoYXZlIGFuIGlkLlxuICAgKiBJZiBtb2RlIGlzIGRkLCB0b2dnbGUgZWRpdCAvIGRpc3BsYXkgbW9kZS5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX3NhdmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMubW9kZWwpIHtcbiAgICAgIGlmICh0aGlzLm1vZGVsLmlkKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZmlyc3RWYWx1ZUZyb20oXG4gICAgICAgICAgICB0aGlzLm1vZGVsLnVwZGF0ZShbdGhpcy5maWVsZF0sIHsgdXBkYXRlTW9kZWw6IHRydWUgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgbGV0IG1zZzogc3RyaW5nID0gJyc7XG4gICAgICAgICAgaWYgKGUgJiYgKGUgYXMgYW55KS5lcnJvciAmJiAoZSBhcyBhbnkpLmVycm9yW3RoaXMuZmllbGRdKSB7XG4gICAgICAgICAgICBtc2cgPSBgJHsoZSBhcyBhbnkpLmVycm9yW3RoaXMuZmllbGRdfWA7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuX21zZ3MuZXJyb3IoXG4gICAgICAgICAgICBcIkVycmV1ciBsb3JzIGRlIGwnZW5yZWdpc3RyZW1lbnRcIixcbiAgICAgICAgICAgIG1zZyxcbiAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGUpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5tb2RlID09PSAnZGQnKSB7XG4gICAgICAgIHRoaXMudW5zZXRFZGl0KCk7XG4gICAgICAgIHRoaXMuZW5hYmxlRGlzcGxheU1vZGUoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2hhbmdlZC5uZXh0KHRoaXMubW9kZWwpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2Rpc3BsYXkoeDogYW55KTogYW55IHtcbiAgICBpZiAoeCkge1xuICAgICAgaWYgKHguX2Rpc3BsYXkpIHtcbiAgICAgICAgaWYgKHguX2Rpc3BsYXkgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICAgIHJldHVybiB4Ll9kaXNwbGF5KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHguX2Rpc3BsYXk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl90cGwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RwbCh4KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCBkaXNwbGF5IG1vZGUgYmFzZWQgb24gY3VycmVudCBkaXNwbGF5IGNvbmZpZ1xuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfc2V0TW9kZSgpIHtcbiAgICBpZiAoIXRoaXMubW9kZSkge1xuICAgICAgdGhpcy5tb2RlID0gdGhpcy5kY29uZi5kaXNwRWRpdC5kZWZhdWx0TW9kZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9zZXREaXNwbGF5Rm4oKSB7XG4gICAgaWYgKHRoaXMuZGlzcGxheSkge1xuICAgICAgaWYgKHRoaXMuZGlzcGxheSAmJiB0eXBlb2YgdGhpcy5kaXNwbGF5ID09PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLl90cGwgPSAobW9kZWw6IFIpID0+IGAkeyhtb2RlbCBhcyBhbnkpW3RoaXMuZGlzcGxheSBhcyBzdHJpbmddfWA7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuZGlzcGxheSAmJiB0eXBlb2YgdGhpcy5kaXNwbGF5ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRoaXMuX3RwbCA9IHRoaXMuZGlzcGxheS5iaW5kKHRoaXMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl90cGwgPSAobW9kZWw6IFIpID0+XG4gICAgICAgIGAke1xuICAgICAgICAgIChtb2RlbCBhcyBhbnkpWyduYW1lJ10gfHxcbiAgICAgICAgICAobW9kZWwgYXMgYW55KVsndGl0bGUnXSB8fFxuICAgICAgICAgIChtb2RlbCBhcyBhbnkpWydpZCddXG4gICAgICAgIH1gO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2dldENob2ljZXMoKSB7XG4gICAgLy8gU2V0IGRpc3BsYXkgY2hvaWNlc1xuICAgIGxldCBjaG9pY2VzOiBJRGlzcEVkaXRDaG9pY2VbXSB8IHVuZGVmaW5lZDtcbiAgICBpZiAodGhpcy5jaG9pY2VzICYmIHRoaXMuY2hvaWNlcy5sZW5ndGgpIHtcbiAgICAgIGNob2ljZXMgPSB0aGlzLmNob2ljZXM7XG4gICAgfSBlbHNlIGlmICgodGhpcy5tYW5hZ2VyIGFzIGFueSk/LmNob2ljZXMpIHtcbiAgICAgIGNob2ljZXMgPSAodGhpcy5tYW5hZ2VyIGFzIGFueSk/LmNob2ljZXM7XG4gICAgfVxuICAgIC8vIFNldCBkaXNwbGF5IHZhbHVlXG4gICAgaWYgKGNob2ljZXMgJiYgY2hvaWNlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnJlYWxDaG9pY2VzID0gY2hvaWNlcztcbiAgICB9IGVsc2Uge1xuICAgICAgZGVsZXRlIHRoaXMucmVhbENob2ljZXM7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0UmVhbERpc3BsYXkoKSB7XG4gICAgdGhpcy5yZWFsRGlzcGxheSA9IHRoaXMudmlld2VyXG4gICAgICA/IHRoaXMudmlld2VyXG4gICAgICA6IHRoaXMubWFuYWdlcj8uZGlzcGxheVR5cGVcbiAgICAgICAgPyB0aGlzLm1hbmFnZXIuZGlzcGxheVR5cGVcbiAgICAgICAgOiAndGV4dCc7XG4gICAgaWYgKHRoaXMucmVhbENob2ljZXMgJiYgdGhpcy5yZWFsQ2hvaWNlcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMucmVhbERpc3BsYXkgPSAnY2hvaWNlJztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9nZXRSZWFsRWRpdG9yKCkge1xuICAgIHRoaXMucmVhbEVkaXRvciA9IHRoaXMuZWRpdG9yXG4gICAgICA/IHRoaXMuZWRpdG9yXG4gICAgICA6IHRoaXMubWFuYWdlcj8uZWRpdG9yVHlwZSB8fCAnaW5wdXQudGV4dCc7XG4gICAgaWYgKHRoaXMucmVhbENob2ljZXMgJiYgdGhpcy5yZWFsQ2hvaWNlcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMucmVhbEVkaXRvciA9ICdzZWxlY3QnO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3NldEZvcm1Db250cm9sKCkge1xuICAgIGlmICghdGhpcy5mb3JtKSB7XG4gICAgICBjb25zdCBmZ2M6IHsgW2luZGV4OiBzdHJpbmddOiBVbnR5cGVkRm9ybUNvbnRyb2wgfSA9IHt9O1xuICAgICAgZmdjW3RoaXMuZmllbGRdID0gdGhpcy5tb2RlbC5GQyh0aGlzLmZpZWxkKTtcbiAgICAgIHRoaXMuZmcgPSBuZXcgVW50eXBlZEZvcm1Hcm91cChmZ2MpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZnID0gdGhpcy5mb3JtO1xuICAgICAgdGhpcy5mZy5zZXRDb250cm9sKHRoaXMuZmllbGQsIHRoaXMubW9kZWwuRkModGhpcy5maWVsZCksIHtcbiAgICAgICAgZW1pdEV2ZW50OiBmYWxzZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAodGhpcy5tb2RlID09PSAnaW5saW5lJykge1xuICAgICAgdGhpcy5mZy52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy51cGRhdGUoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3NldEZvcm1Db250cm9sVmFsdWUoKSB7XG4gICAgc3dpdGNoICh0aGlzLnJlYWxFZGl0b3IpIHtcbiAgICAgIGNhc2UgJ2lucHV0LmRhdGV0aW1lJzpcbiAgICAgICAgY29uc3QgdmFsdWUgPSAodGhpcy5tb2RlbCBhcyBhbnkpW3RoaXMuZmllbGRdO1xuICAgICAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgICAgICBjb25zdCBsb2NhbG5vdyA9IG5ldyBEYXRlKFxuICAgICAgICAgIG5vdy5nZXRUaW1lKCkgLSBub3cuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwMDAwLFxuICAgICAgICApO1xuICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLmZnIS5jb250cm9sc1t0aGlzLmZpZWxkXS5zZXRWYWx1ZShudWxsLCB7IGVtaXRFdmVudDogdHJ1ZSB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCB0aW1lID0gdmFsdWUgPyBuZXcgRGF0ZSh2YWx1ZSkgOiBuZXcgRGF0ZSgpO1xuICAgICAgICAgIGNvbnN0IG9mZnNldCA9IHRpbWUuZ2V0VGltZXpvbmVPZmZzZXQoKTtcbiAgICAgICAgICBjb25zdCBsb2NhbHRpbWUgPSBuZXcgRGF0ZSh0aW1lLmdldFRpbWUoKSAtIG9mZnNldCAqIDYwMDAwKTtcbiAgICAgICAgICB0aGlzLmZnIS5jb250cm9sc1t0aGlzLmZpZWxkXS5zZXRWYWx1ZShcbiAgICAgICAgICAgIGxvY2FsdGltZS50b0lTT1N0cmluZygpLnN1YnN0cmluZygwLCAxNiksXG4gICAgICAgICAgICB7IGVtaXRFdmVudDogdHJ1ZSB9LFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWFsRGVmYXVsdCA9XG4gICAgICAgICAgdGhpcy5kZWZhdWx0IHx8IHRoaXMubWFuYWdlcj8ucmVxdWlyZWRcbiAgICAgICAgICAgID8gbG9jYWxub3cudG9JU09TdHJpbmcoKS5zdWJzdHJpbmcoMCwgMTYpXG4gICAgICAgICAgICA6IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW5wdXQuZGF0ZSc6XG4gICAgICAgIGNvbnN0IGR0ID0gdGhpcy5tb2RlbC50b0pzb24oW3RoaXMuZmllbGRdKVt0aGlzLmZpZWxkXTtcbiAgICAgICAgdGhpcy5mZyEuY29udHJvbHNbdGhpcy5maWVsZF0uc2V0VmFsdWUoZHQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2lucHV0LmRlY2ltYWwnOlxuICAgICAgICB0aGlzLmZnIS5jb250cm9sc1t0aGlzLmZpZWxkXS5zZXRWYWx1ZShcbiAgICAgICAgICAodGhpcy5tb2RlbCBhcyBhbnkpW3RoaXMuZmllbGRdIC9cbiAgICAgICAgICAgICgodGhpcy5tYW5hZ2VyIGFzIHVua25vd24gYXMgRGVjaW1hbEZpZWxkTWFuYWdlcikuZmFjdG9yIHx8IDEpLFxuICAgICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3NldEVkaXRvckNsYXNzZXMoKSB7XG4gICAgLy8gRklYTUU6IHVzZSByZWFsRWRpdG9yQ2xhc3Nlc1xuICAgIGlmICghdGhpcy5pbnB1dENsYXNzZXMpIHtcbiAgICAgIHRoaXMuaW5wdXRDbGFzc2VzID1cbiAgICAgICAgdGhpcy5kY29uZi5kaXNwRWRpdC5pbnB1dENsYXNzZXNbdGhpcy5yZWFsRWRpdG9yXSB8fCAnJztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9nZXREaXNwbGF5VmFsdWUoKSB7XG4gICAgY29uc3QgdmFsdWUgPSAodGhpcy5tb2RlbCBhcyBhbnkpW3RoaXMuZmllbGRdO1xuICAgIHRoaXMuZGlzcFZhbHVlID0gdmFsdWU7XG4gICAgaWYgKHRoaXMucmVhbENob2ljZXMpIHtcbiAgICAgIGZvciAoY29uc3QgYyBvZiB0aGlzLnJlYWxDaG9pY2VzKSB7XG4gICAgICAgIGlmIChjID09PSB2YWx1ZSkge1xuICAgICAgICAgIHRoaXMudHh0VmFsdWUgPSBjIGFzIGFueTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSBpZiAoYy52YWx1ZSAhPT0gdW5kZWZpbmVkICYmIGMudmFsdWUgPT09IHZhbHVlKSB7XG4gICAgICAgICAgdGhpcy50eHRWYWx1ZSA9IGMuZGVzYztcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gU2V0IGRpc3BsYXkgdGV4dCBkZXBlbmRpbmcgb24gdmFsdWUgYW5kIHJlYWxEaXNwbGF5IHZhbHVlXG4gICAgaWYgKHZhbHVlID09PSB0cnVlKSB7XG4gICAgICB0aGlzLnR4dFZhbHVlID0gJ09VSSc7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgIHRoaXMudHh0VmFsdWUgPSAnTk9OJztcbiAgICB9IGVsc2UgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwpIHtcbiAgICAgIHRoaXMudHh0VmFsdWUgPSAnbm9uIGTDqWZpbmknO1xuICAgIH0gZWxzZSB7XG4gICAgICBzd2l0Y2ggKHRoaXMucmVhbERpc3BsYXkpIHtcbiAgICAgICAgY2FzZSAnZmtkZXRhaWxzJzpcbiAgICAgICAgICBjb25zdCBkZXRhaWxzID0gKHRoaXMubW9kZWwgYXMgYW55KVtgJHt0aGlzLmZpZWxkfV9kZXRhaWxzYF0gYXMgYW55O1xuICAgICAgICAgIHRoaXMudHh0VmFsdWUgPSB0aGlzLl9kaXNwbGF5KGRldGFpbHMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdtMm1kZXRhaWxzJzpcbiAgICAgICAgICBjb25zdCBtMm1EZXRhaWxzID1cbiAgICAgICAgICAgIHRoaXMubTJtVmFsdWVzIHx8XG4gICAgICAgICAgICAoKHRoaXMubW9kZWwgYXMgYW55KVtgJHt0aGlzLmZpZWxkfV9kZXRhaWxzYF0gYXMgYW55W10pO1xuICAgICAgICAgIHRoaXMudHh0VmFsdWVzID0gW107XG4gICAgICAgICAgZm9yIChjb25zdCB2IG9mIG0ybURldGFpbHMgfHwgW10pIHtcbiAgICAgICAgICAgIHRoaXMudHh0VmFsdWVzLnB1c2godGhpcy5fZGlzcGxheSh2KSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdkZWNpbWFsJzpcbiAgICAgICAgICB0aGlzLnR4dFZhbHVlID0gYCR7XG4gICAgICAgICAgICB2YWx1ZSAvXG4gICAgICAgICAgICAoKHRoaXMubWFuYWdlciBhcyB1bmtub3duIGFzIERlY2ltYWxGaWVsZE1hbmFnZXIpLmZhY3RvciB8fCAxKVxuICAgICAgICAgIH1gO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRoaXMudHh0VmFsdWUgPSBgJHt2YWx1ZX1gO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3NldERpc3BsYXlDbGFzc2VzKCkge31cbn1cbiIsIlxuPG5nLXRlbXBsYXRlICN0aXRsZVRwbD5cbiAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuPC9uZy10ZW1wbGF0ZT5cbjxuZy10ZW1wbGF0ZSAjZGlzcFRwbD5cbiAgPG5nLWNvbnRhaW5lciBbbmdTd2l0Y2hdPVwicmVhbERpc3BsYXlcIj48c3BhbiBjbGFzcz1cImVkaXRhYmxlIGRpc3AtdGV4dFwiICpuZ1N3aXRjaENhc2U9XCIndGV4dCdcIiAoY2xpY2spPVwiZW5hYmxlRWRpdE1vZGUoKVwiPnt7dHh0VmFsdWV9fTwvc3Bhbj48c3BhbiBjbGFzcz1cImVkaXRhYmxlIGRpc3AtY2hvaWNlXCIgKm5nU3dpdGNoQ2FzZT1cIidjaG9pY2UnXCIgKGNsaWNrKT1cImVuYWJsZUVkaXRNb2RlKClcIj57e3R4dFZhbHVlfX08L3NwYW4+PHNwYW4gY2xhc3M9XCJlZGl0YWJsZSBkaXNwLWRlY2ltYWxcIiAqbmdTd2l0Y2hDYXNlPVwiJ2RlY2ltYWwnXCIgKGNsaWNrKT1cImVuYWJsZUVkaXRNb2RlKClcIj57e3R4dFZhbHVlfX08L3NwYW4+PHNwYW4gY2xhc3M9XCJlZGl0YWJsZSBkaXNwLWJvb2xlYW5cIiAqbmdTd2l0Y2hDYXNlPVwiJ2Jvb2xlYW4nXCIgKGNsaWNrKT1cImVuYWJsZUVkaXRNb2RlKClcIj57e3R4dFZhbHVlfX08L3NwYW4+PHNwYW4gY2xhc3M9XCJlZGl0YWJsZSBkaXNwLWZrZGV0YWlsc1wiICpuZ1N3aXRjaENhc2U9XCInZmtkZXRhaWxzJ1wiIChjbGljayk9XCJlbmFibGVFZGl0TW9kZSgpXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZmtpdGVtXCI+e3t0eHRWYWx1ZX19PC9kaXY+PC9zcGFuPjxzcGFuIGNsYXNzPVwiZWRpdGFibGUgZGlzcC1tMm1kZXRhaWxzXCIgKm5nU3dpdGNoQ2FzZT1cIidtMm1kZXRhaWxzJ1wiIChjbGljayk9XCJlbmFibGVFZGl0TW9kZSgpXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibTJtaXRlbVwiICpuZ0Zvcj1cImxldCB2IG9mIHR4dFZhbHVlc1wiPnt7dn19PC9kaXY+PC9zcGFuPjxzcGFuIGNsYXNzPVwiZWRpdGFibGUgZGlzcC1kYXRldGltZVwiICpuZ1N3aXRjaENhc2U9XCInZGF0ZXRpbWUnXCIgKGNsaWNrKT1cImVuYWJsZUVkaXRNb2RlKClcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJkaXNwVmFsdWVcIj57e3R4dFZhbHVlfGRhdGU6J3Nob3J0J319PC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWRpc3BWYWx1ZVwiPnt7dHh0VmFsdWV9fTwvbmctY29udGFpbmVyPjwvc3Bhbj48c3BhbiBjbGFzcz1cImVkaXRhYmxlIGRpc3AtZGF0ZXRpbWVcIiAqbmdTd2l0Y2hDYXNlPVwiJ2RhdGUnXCIgKGNsaWNrKT1cImVuYWJsZUVkaXRNb2RlKClcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJkaXNwVmFsdWVcIj57e3R4dFZhbHVlfGRhdGU6J3Nob3J0RGF0ZSd9fTwvbmctY29udGFpbmVyPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFkaXNwVmFsdWVcIj57e3R4dFZhbHVlfX08L25nLWNvbnRhaW5lcj48L3NwYW4+PC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuPG5nLXRlbXBsYXRlICNlZGl0VHBsIGxldC1mb3JtPVwiZm9ybVwiPlxuICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJyZWFsRWRpdG9yXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2lucHV0LnRleHQnXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbZm9ybUNvbnRyb2xdPVwiZm9ybS5nZXQoZmllbGQpXCIgW25nQ2xhc3NdPVwiaW5wdXRDbGFzc2VzXCIgKGtleXVwLmVzY2FwZSk9XCJ1bnNldEVkaXQoKVwiIFtwbGFjZWhvbGRlcl09XCJyZWFsUGxhY2Vob2xkZXJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXRleHRcIiAqbmdJZj1cInJlYWxIZWxwXCI+e3tyZWFsSGVscH19PHNwYW4gY2xhc3M9XCJtcy0xXCIgKm5nSWY9XCJyZXF1aXJlZFwiPihyZXF1aXMpPC9zcGFuPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgbXQtMFwiIFtjbGFzcy5kLWJsb2NrXT1cImZvcm0gJmFtcDsmYW1wOyAhZm9ybS5jb250cm9sc1tmaWVsZF0ucHJpc3RpbmUgJmFtcDsmYW1wOyBmb3JtLmNvbnRyb2xzW2ZpZWxkXS5lcnJvcnM/LlsnbWlubGVuZ3RoJ11cIj5Ucm9wIGNvdXJ0IDoge3skYW55KG1hbmFnZXIpLm1pbkxlbmd0aH19IGNhcmFjdMOocmVzIG1pbmltdW0uLi48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIG10LTBcIiBbY2xhc3MuZC1ibG9ja109XCJmb3JtICZhbXA7JmFtcDsgIWZvcm0uY29udHJvbHNbZmllbGRdLnByaXN0aW5lICZhbXA7JmFtcDsgZm9ybS5jb250cm9sc1tmaWVsZF0uZXJyb3JzPy5bJ21heGxlbmd0aCddXCI+VHJvcCBsb25nIDoge3skYW55KG1hbmFnZXIpLm1heExlbmd0aH19IGNhcmFjdMOocmVzIG1heGltdW0uLi48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIG10LTBcIiBbY2xhc3MuZC1ibG9ja109XCJmb3JtICZhbXA7JmFtcDsgIWZvcm0uY29udHJvbHNbZmllbGRdLnByaXN0aW5lICZhbXA7JmFtcDsgZm9ybS5jb250cm9sc1tmaWVsZF0uZXJyb3JzPy5bJ3BhdHRlcm4nXVwiPkZvcm1hdCBpbnZhbGlkZS4uLjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgbXQtMFwiIFtjbGFzcy5kLWJsb2NrXT1cImZvcm0gJmFtcDsmYW1wOyAhZm9ybS5jb250cm9sc1tmaWVsZF0ucHJpc3RpbmUgJmFtcDsmYW1wOyBmb3JtLmNvbnRyb2xzW2ZpZWxkXS5lcnJvcnM/LlsncmVxdWlyZWQnXVwiPkNlIGNoYW1wIGVzdCByZXF1aXMuLi48L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaW5wdXQuZW1haWwnXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cImVtYWlsXCIgW2Zvcm1Db250cm9sXT1cImZvcm0uZ2V0KGZpZWxkKVwiIFtuZ0NsYXNzXT1cImlucHV0Q2xhc3Nlc1wiIChrZXl1cC5lc2NhcGUpPVwidW5zZXRFZGl0KClcIiBbcGxhY2Vob2xkZXJdPVwicmVhbFBsYWNlaG9sZGVyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZm9ybS10ZXh0XCIgKm5nSWY9XCJyZWFsSGVscFwiPnt7cmVhbEhlbHB9fTxzcGFuIGNsYXNzPVwibXMtMVwiICpuZ0lmPVwicmVxdWlyZWRcIj4ocmVxdWlzKTwvc3Bhbj48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIG10LTBcIiBbY2xhc3MuZC1ibG9ja109XCJmb3JtICZhbXA7JmFtcDsgIWZvcm0uY29udHJvbHNbZmllbGRdLnByaXN0aW5lICZhbXA7JmFtcDsgZm9ybS5jb250cm9sc1tmaWVsZF0uZXJyb3JzPy5bJ21pbmxlbmd0aCddXCI+VHJvcCBjb3VydCA6IHt7JGFueShtYW5hZ2VyKS5taW5MZW5ndGh9fSBjYXJhY3TDqHJlcyBtaW5pbXVtLi4uPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBtdC0wXCIgW2NsYXNzLmQtYmxvY2tdPVwiZm9ybSAmYW1wOyZhbXA7ICFmb3JtLmNvbnRyb2xzW2ZpZWxkXS5wcmlzdGluZSAmYW1wOyZhbXA7IGZvcm0uY29udHJvbHNbZmllbGRdLmVycm9ycz8uWydtYXhsZW5ndGgnXVwiPlRyb3AgbG9uZyA6IHt7JGFueShtYW5hZ2VyKS5tYXhMZW5ndGh9fSBjYXJhY3TDqHJlcyBtYXhpbXVtLi4uPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBtdC0wXCIgW2NsYXNzLmQtYmxvY2tdPVwiZm9ybSAmYW1wOyZhbXA7ICFmb3JtLmNvbnRyb2xzW2ZpZWxkXS5wcmlzdGluZSAmYW1wOyZhbXA7IGZvcm0uY29udHJvbHNbZmllbGRdLmVycm9ycz8uWydwYXR0ZXJuJ11cIj5Gb3JtYXQgaW52YWxpZGUuLi48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIG10LTBcIiBbY2xhc3MuZC1ibG9ja109XCJmb3JtICZhbXA7JmFtcDsgIWZvcm0uY29udHJvbHNbZmllbGRdLnByaXN0aW5lICZhbXA7JmFtcDsgZm9ybS5jb250cm9sc1tmaWVsZF0uZXJyb3JzPy5bJ2VtYWlsJ11cIj5Gb3JtYXQgZCdlbWFpbCBpbnZhbGlkZS4uLjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgbXQtMFwiIFtjbGFzcy5kLWJsb2NrXT1cImZvcm0gJmFtcDsmYW1wOyAhZm9ybS5jb250cm9sc1tmaWVsZF0ucHJpc3RpbmUgJmFtcDsmYW1wOyBmb3JtLmNvbnRyb2xzW2ZpZWxkXS5lcnJvcnM/LlsncmVxdWlyZWQnXVwiPkNlIGNoYW1wIGVzdCByZXF1aXMuLi48L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInaW5wdXQucGFzc3dvcmQnXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cInBhc3N3b3JkXCIgW2Zvcm1Db250cm9sXT1cImZvcm0uZ2V0KGZpZWxkKVwiIFtuZ0NsYXNzXT1cImlucHV0Q2xhc3Nlc1wiIChrZXl1cC5lc2NhcGUpPVwidW5zZXRFZGl0KClcIiBbcGxhY2Vob2xkZXJdPVwicmVhbFBsYWNlaG9sZGVyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZm9ybS10ZXh0XCIgKm5nSWY9XCJyZWFsSGVscFwiPnt7cmVhbEhlbHB9fTxzcGFuIGNsYXNzPVwibXMtMVwiICpuZ0lmPVwicmVxdWlyZWRcIj4ocmVxdWlzKTwvc3Bhbj48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIG10LTBcIiBbY2xhc3MuZC1ibG9ja109XCJmb3JtICZhbXA7JmFtcDsgIWZvcm0uY29udHJvbHNbZmllbGRdLnByaXN0aW5lICZhbXA7JmFtcDsgZm9ybS5jb250cm9sc1tmaWVsZF0uZXJyb3JzPy5bJ21pbmxlbmd0aCddXCI+VHJvcCBjb3VydCA6IHt7JGFueShtYW5hZ2VyKS5taW5MZW5ndGh9fSBjYXJhY3TDqHJlcyBtaW5pbXVtLi4uPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBtdC0wXCIgW2NsYXNzLmQtYmxvY2tdPVwiZm9ybSAmYW1wOyZhbXA7ICFmb3JtLmNvbnRyb2xzW2ZpZWxkXS5wcmlzdGluZSAmYW1wOyZhbXA7IGZvcm0uY29udHJvbHNbZmllbGRdLmVycm9ycz8uWydtYXhsZW5ndGgnXVwiPlRyb3AgbG9uZyA6IHt7JGFueShtYW5hZ2VyKS5tYXhMZW5ndGh9fSBjYXJhY3TDqHJlcyBtYXhpbXVtLi4uPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBtdC0wXCIgW2NsYXNzLmQtYmxvY2tdPVwiZm9ybSAmYW1wOyZhbXA7ICFmb3JtLmNvbnRyb2xzW2ZpZWxkXS5wcmlzdGluZSAmYW1wOyZhbXA7IGZvcm0uY29udHJvbHNbZmllbGRdLmVycm9ycz8uWydwYXR0ZXJuJ11cIj5Gb3JtYXQgaW52YWxpZGUuLi48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIG10LTBcIiBbY2xhc3MuZC1ibG9ja109XCJmb3JtICZhbXA7JmFtcDsgIWZvcm0uY29udHJvbHNbZmllbGRdLnByaXN0aW5lICZhbXA7JmFtcDsgZm9ybS5jb250cm9sc1tmaWVsZF0uZXJyb3JzPy5bJ3JlcXVpcmVkJ11cIj5DZSBjaGFtcCBlc3QgcmVxdWlzLi4uPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2lucHV0LmRhdGV0aW1lJ1wiPlxuICAgICAgPGlucHV0IHR5cGU9XCJkYXRldGltZS1sb2NhbFwiIFtmb3JtQ29udHJvbF09XCJmb3JtLmdldChmaWVsZClcIiBbbmdDbGFzc109XCJpbnB1dENsYXNzZXNcIiAoa2V5dXAuZXNjYXBlKT1cInVuc2V0RWRpdCgpXCIgKGtleXVwLmVudGVyKT1cInVwZGF0ZSgpXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZm9ybS10ZXh0XCI+e3tyZWFsSGVscH19PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBtdC0wXCIgW2NsYXNzLmQtYmxvY2tdPVwiZm9ybSAmYW1wOyZhbXA7ICFmb3JtLmNvbnRyb2xzW2ZpZWxkXS5wcmlzdGluZSAmYW1wOyZhbXA7IGZvcm0uY29udHJvbHNbZmllbGRdLmVycm9ycz8uWydyZXF1aXJlZCddXCI+Q2UgY2hhbXAgZXN0IHJlcXVpcy4uLjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgbXQtMFwiIFtjbGFzcy5kLWJsb2NrXT1cImZvcm0gJmFtcDsmYW1wOyAhZm9ybS5jb250cm9sc1tmaWVsZF0ucHJpc3RpbmUgJmFtcDsmYW1wOyBmb3JtLmNvbnRyb2xzW2ZpZWxkXS5lcnJvcnM/LlsnbWluRGF0ZSddXCI+RG9pdCDDqnRyZSBwb3N0w6lyaWV1ciDDoCAge3skYW55KG1hbmFnZXIpLm1pbnxkYXRlOidzaG9ydCd9fS4uLjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgbXQtMFwiIFtjbGFzcy5kLWJsb2NrXT1cImZvcm0gJmFtcDsmYW1wOyAhZm9ybS5jb250cm9sc1tmaWVsZF0ucHJpc3RpbmUgJmFtcDsmYW1wOyBmb3JtLmNvbnRyb2xzW2ZpZWxkXS5lcnJvcnM/LlsnbWF4RGF0ZSddXCI+RG9pdCDDqnRyZSBhbnTDqXJpZXVyIMOgICB7eyRhbnkobWFuYWdlcikubWF4fGRhdGU6J3Nob3J0J319Li4uPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2lucHV0LmRhdGUnXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cImRhdGVcIiBbZm9ybUNvbnRyb2xdPVwiZm9ybS5nZXQoZmllbGQpXCIgW25nQ2xhc3NdPVwiaW5wdXRDbGFzc2VzXCIgKGtleXVwLmVzY2FwZSk9XCJ1bnNldEVkaXQoKVwiIChrZXl1cC5lbnRlcik9XCJ1cGRhdGUoKVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tdGV4dFwiPnt7cmVhbEhlbHB9fTwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgbXQtMFwiIFtjbGFzcy5kLWJsb2NrXT1cImZvcm0gJmFtcDsmYW1wOyAhZm9ybS5jb250cm9sc1tmaWVsZF0ucHJpc3RpbmUgJmFtcDsmYW1wOyBmb3JtLmNvbnRyb2xzW2ZpZWxkXS5lcnJvcnM/LlsncmVxdWlyZWQnXVwiPkNlIGNoYW1wIGVzdCByZXF1aXMuLi48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIG10LTBcIiBbY2xhc3MuZC1ibG9ja109XCJmb3JtICZhbXA7JmFtcDsgIWZvcm0uY29udHJvbHNbZmllbGRdLnByaXN0aW5lICZhbXA7JmFtcDsgZm9ybS5jb250cm9sc1tmaWVsZF0uZXJyb3JzPy5bJ21pbkRhdGUnXVwiPkRvaXQgw6p0cmUgcG9zdMOpcmlldXIgw6AgIHt7JGFueShtYW5hZ2VyKS5taW58ZGF0ZTonc2hvcnQnfX0uLi48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIG10LTBcIiBbY2xhc3MuZC1ibG9ja109XCJmb3JtICZhbXA7JmFtcDsgIWZvcm0uY29udHJvbHNbZmllbGRdLnByaXN0aW5lICZhbXA7JmFtcDsgZm9ybS5jb250cm9sc1tmaWVsZF0uZXJyb3JzPy5bJ21heERhdGUnXVwiPkRvaXQgw6p0cmUgYW50w6lyaWV1ciDDoCAge3skYW55KG1hbmFnZXIpLm1heHxkYXRlOidzaG9ydCd9fS4uLjwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidpbnB1dC5udW1iZXInXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIFtmb3JtQ29udHJvbF09XCJmb3JtLmdldChmaWVsZClcIiBbbmdDbGFzc109XCJpbnB1dENsYXNzZXNcIiAoa2V5dXAuZXNjYXBlKT1cInVuc2V0RWRpdCgpXCIgW3BsYWNlaG9sZGVyXT1cInJlYWxQbGFjZWhvbGRlclwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tdGV4dFwiICpuZ0lmPVwicmVhbEhlbHBcIj57e3JlYWxIZWxwfX08c3BhbiBjbGFzcz1cIm1zLTFcIiAqbmdJZj1cInJlcXVpcmVkXCI+KHJlcXVpcyk8L3NwYW4+PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBtdC0wXCIgW2NsYXNzLmQtYmxvY2tdPVwiZm9ybSAmYW1wOyZhbXA7ICFmb3JtLmNvbnRyb2xzW2ZpZWxkXS5wcmlzdGluZSAmYW1wOyZhbXA7IGZvcm0uY29udHJvbHNbZmllbGRdLmVycm9ycz8uWydtaW4nXVwiPlRyb3AgcGV0aXQgOiBtaW5pbXVtIHt7JGFueShtYW5hZ2VyKS5taW59fS4uLjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgbXQtMFwiIFtjbGFzcy5kLWJsb2NrXT1cImZvcm0gJmFtcDsmYW1wOyAhZm9ybS5jb250cm9sc1tmaWVsZF0ucHJpc3RpbmUgJmFtcDsmYW1wOyBmb3JtLmNvbnRyb2xzW2ZpZWxkXS5lcnJvcnM/LlsnbWF4J11cIj5Ucm9wIGdyYW5kIDogbWF4aW11bSB7eyRhbnkobWFuYWdlcikubWF4fX0uLi48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIG10LTBcIiBbY2xhc3MuZC1ibG9ja109XCJmb3JtICZhbXA7JmFtcDsgIWZvcm0uY29udHJvbHNbZmllbGRdLnByaXN0aW5lICZhbXA7JmFtcDsgZm9ybS5jb250cm9sc1tmaWVsZF0uZXJyb3JzPy5bJ3JlcXVpcmVkJ11cIj5DZSBjaGFtcCBlc3QgcmVxdWlzLi4uPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2lucHV0LmRlY2ltYWwnXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIFtmb3JtQ29udHJvbF09XCJmb3JtLmdldChmaWVsZClcIiBbbmdDbGFzc109XCJpbnB1dENsYXNzZXNcIiAoa2V5dXAuZXNjYXBlKT1cInVuc2V0RWRpdCgpXCIgW3BsYWNlaG9sZGVyXT1cInJlYWxQbGFjZWhvbGRlclwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tdGV4dFwiICpuZ0lmPVwicmVhbEhlbHBcIj57e3JlYWxIZWxwfX08c3BhbiBjbGFzcz1cIm1zLTFcIiAqbmdJZj1cInJlcXVpcmVkXCI+KHJlcXVpcyk8L3NwYW4+PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBtdC0wXCIgW2NsYXNzLmQtYmxvY2tdPVwiZm9ybSAmYW1wOyZhbXA7ICFmb3JtLmNvbnRyb2xzW2ZpZWxkXS5wcmlzdGluZSAmYW1wOyZhbXA7IGZvcm0uY29udHJvbHNbZmllbGRdLmVycm9ycz8uWydtaW4nXVwiPlRyb3AgcGV0aXQgOiBtaW5pbXVtIHt7JGFueShtYW5hZ2VyKS5taW59fS4uLjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgbXQtMFwiIFtjbGFzcy5kLWJsb2NrXT1cImZvcm0gJmFtcDsmYW1wOyAhZm9ybS5jb250cm9sc1tmaWVsZF0ucHJpc3RpbmUgJmFtcDsmYW1wOyBmb3JtLmNvbnRyb2xzW2ZpZWxkXS5lcnJvcnM/LlsnbWF4J11cIj5Ucm9wIGdyYW5kIDogbWF4aW11bSB7eyRhbnkobWFuYWdlcikubWF4fX0uLi48L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrIG10LTBcIiBbY2xhc3MuZC1ibG9ja109XCJmb3JtICZhbXA7JmFtcDsgIWZvcm0uY29udHJvbHNbZmllbGRdLnByaXN0aW5lICZhbXA7JmFtcDsgZm9ybS5jb250cm9sc1tmaWVsZF0uZXJyb3JzPy5bJ3JlcXVpcmVkJ11cIj5DZSBjaGFtcCBlc3QgcmVxdWlzLi4uPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2lucHV0LmNoZWNrYm94J1wiPlxuICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiIFtmb3JtQ29udHJvbF09XCJmb3JtLmdldChmaWVsZClcIiAoa2V5dXAuZXNjYXBlKT1cInVuc2V0RWRpdCgpXCIgKGNoYW5nZSk9XCJ1cGRhdGUoKVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tdGV4dFwiPnt7cmVhbEhlbHB9fTwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIid0ZXh0YXJlYSdcIj5cbiAgICAgIDx0ZXh0YXJlYSBbZm9ybUNvbnRyb2xdPVwiZm9ybS5nZXQoZmllbGQpXCIgKGtleXVwLmVzY2FwZSk9XCJ1bnNldEVkaXQoKVwiIFtuZ0NsYXNzXT1cImlucHV0Q2xhc3Nlc1wiIChrZXl1cC5jb250cm9sLmVudGVyKT1cInVwZGF0ZSgpXCIgW3BsYWNlaG9sZGVyXT1cInJlYWxQbGFjZWhvbGRlclwiPjwvdGV4dGFyZWE+XG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tbGluayB3LTEwMCBkaXNwZWRpdC10ZXh0LXVwZGF0ZS1idXR0b25cIiAoY2xpY2spPVwidXBkYXRlKClcIiAqbmdJZj1cIm1vZGU9PT0nZGQnXCI+PGkgY2xhc3M9XCJiaSBiaS1zYXZlXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tdGV4dFwiICpuZ0lmPVwicmVhbEhlbHBcIj57e3JlYWxIZWxwfX08c3BhbiBjbGFzcz1cIm1zLTFcIiAqbmdJZj1cInJlcXVpcmVkXCI+KHJlcXVpcyk8L3NwYW4+PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBtdC0wXCIgW2NsYXNzLmQtYmxvY2tdPVwiZm9ybSAmYW1wOyZhbXA7ICFmb3JtLmNvbnRyb2xzW2ZpZWxkXS5wcmlzdGluZSAmYW1wOyZhbXA7IGZvcm0uY29udHJvbHNbZmllbGRdLmVycm9ycz8uWydtaW5sZW5ndGgnXVwiPlRyb3AgY291cnQgOiB7eyRhbnkobWFuYWdlcikubWluTGVuZ3RofX0gY2FyYWN0w6hyZXMgbWluaW11bS4uLjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgbXQtMFwiIFtjbGFzcy5kLWJsb2NrXT1cImZvcm0gJmFtcDsmYW1wOyAhZm9ybS5jb250cm9sc1tmaWVsZF0ucHJpc3RpbmUgJmFtcDsmYW1wOyBmb3JtLmNvbnRyb2xzW2ZpZWxkXS5lcnJvcnM/LlsnbWF4bGVuZ3RoJ11cIj5Ucm9wIGxvbmcgOiB7eyRhbnkobWFuYWdlcikubWF4TGVuZ3RofX0gY2FyYWN0w6hyZXMgbWF4aW11bS4uLjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgbXQtMFwiIFtjbGFzcy5kLWJsb2NrXT1cImZvcm0gJmFtcDsmYW1wOyAhZm9ybS5jb250cm9sc1tmaWVsZF0ucHJpc3RpbmUgJmFtcDsmYW1wOyBmb3JtLmNvbnRyb2xzW2ZpZWxkXS5lcnJvcnM/LlsncGF0dGVybiddXCI+Rm9ybWF0IGludmFsaWRlLi4uPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBtdC0wXCIgW2NsYXNzLmQtYmxvY2tdPVwiZm9ybSAmYW1wOyZhbXA7ICFmb3JtLmNvbnRyb2xzW2ZpZWxkXS5wcmlzdGluZSAmYW1wOyZhbXA7IGZvcm0uY29udHJvbHNbZmllbGRdLmVycm9ycz8uWydyZXF1aXJlZCddXCI+Q2UgY2hhbXAgZXN0IHJlcXVpcy4uLjwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidma3NlbGVjdCdcIj5cbiAgICAgIDxkYXRhLWZrc2VsZWN0IFtjb2xsZWN0aW9uXT1cImNvbGxlY3Rpb25cIiBbZmlsdGVyXT1cImZpbHRlclwiIFtkaXNwbGF5XT1cImRpc3BsYXlcIiAoc2VsZWN0ZWQpPVwic2VsZWN0ZWRSZWZJdGVtKCRldmVudClcIiBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIiAoY2FuY2VsbGVkKT1cInVuc2V0RWRpdCgpXCIgKGNsZWFyZWQpPVwic2VsZWN0ZWRSZWZJdGVtKG51bGwpXCI+PC9kYXRhLWZrc2VsZWN0PlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidtMm1zZWxlY3QnXCI+XG4gICAgICA8ZGF0YS1tMm1zZWxlY3QgW2NvbGxlY3Rpb25dPVwiY29sbGVjdGlvblwiIFtmaWx0ZXJdPVwiZmlsdGVyXCIgKGNoYW5nZWQpPVwidXBkYXRlKClcIiBbZm9ybUNvbnRyb2xdPVwiZm9ybS5nZXQoZmllbGQpXCIgKGRldGFpbHNDaGFuZ2VkKT1cIm9uTTJNVmFsdWVzQ2hhbmdlcygkZXZlbnQpXCIgW21vZGVsXT1cIm1vZGVsXCIgW2ZpZWxkXT1cImZpZWxkXCIgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCI+PC9kYXRhLW0ybXNlbGVjdD5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInc2VsZWN0J1wiPlxuICAgICAgPHNlbGVjdCBbZm9ybUNvbnRyb2xdPVwiZm9ybS5nZXQoZmllbGQpXCIgKGtleXVwLmVzY2FwZSk9XCJ1bnNldEVkaXQoKVwiIChjaGFuZ2UpPVwidXBkYXRlKClcIiBbbmdDbGFzc109XCJpbnB1dENsYXNzZXNcIj5cbiAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgYyBvZiByZWFsQ2hvaWNlc1wiIFtuZ1ZhbHVlXT1cImMudmFsdWUhPT11bmRlZmluZWQgPyBjLnZhbHVlIDogY1wiPnt7Yy5kZXNjID8gYy5kZXNjIDogY319PC9vcHRpb24+XG4gICAgICA8L3NlbGVjdD5cbiAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXRleHRcIj57e3JlYWxIZWxwfX08L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuPCEtLSBEaXNwL2VkaXQgdG9nZ2xlci0tPlxuPG5nLXRlbXBsYXRlICNkaXNwZWRpdFRwbD5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFlZGl0XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImRpc3BUcGxcIj48L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJlZGl0XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImZnXCI+XG4gICAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZnXCIgKHN1Ym1pdCk9XCJ1cGRhdGUoKVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZWRpdFRwbDsgY29udGV4dDoge2Zvcm06IGZnfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9mb3JtPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG48IS0tIERpc3BFZGl0IG5vZm9ybS0tPlxuPG5nLXRlbXBsYXRlICNkaXNwZWRpdEZvcm1UcGw+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCIhZWRpdFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJkaXNwVHBsXCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiZWRpdFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmb3JtXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZWRpdFRwbDsgY29udGV4dDoge2Zvcm06IGZvcm19XCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cbjwhLS0gRGQgZGlzcGxheS0tPlxuPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1vZGU9PT0nZGQnXCI+XG4gIDxkdCBbY2xhc3MucmVxdWlyZWRdPVwicmVxdWlyZWRcIiAqbmdJZj1cIiFoaWRlTGFiZWxcIj48c3BhbiBjbGFzcz1cImVkaXRhYmxlXCIgKGNsaWNrKT1cInRvZ2dsZUVkaXQoKVwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRpdGxlVHBsXCI+PC9uZy1jb250YWluZXI+PC9zcGFuPjxzcGFuIGNsYXNzPVwicG9pbnRlciBmbG9hdC1lbmRcIiAoY2xpY2spPVwic2V0RGVmYXVsdCgpXCIgKm5nSWY9XCJyZWFsRGVmYXVsdCE9PSB1bmRlZmluZWQgJmFtcDsmYW1wOyBlZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS10cmFzaCBtcy0yXCI+PC9pPjwvc3Bhbj48L2R0PlxuICA8ZGQgW2NsYXNzLm1iLTBdPVwiaGlkZUxhYmVsXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImRpc3BlZGl0VHBsXCI+PC9uZy1jb250YWluZXI+XG4gIDwvZGQ+XG48L25nLWNvbnRhaW5lcj5cbjwhLS0gSW5saW5lIGRpc3BsYXktLT5cbjxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlPT09J2lubGluZSdcIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFoaWRlTGFiZWxcIj48c3BhbiBjbGFzcz1cInBvaW50ZXIgZmxvYXQtZW5kXCIgKGNsaWNrKT1cInNldERlZmF1bHQoKVwiICpuZ0lmPVwicmVhbERlZmF1bHQhPT0gdW5kZWZpbmVkICZhbXA7JmFtcDsgZWRpdFwiPjxpIGNsYXNzPVwiYmkgYmktdHJhc2ggbXMtMlwiPjwvaT48L3NwYW4+XG4gICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJyZXF1aXJlZFwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRpdGxlVHBsXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9sYWJlbD5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJkaXNwZWRpdFRwbFwiPjwvbmctY29udGFpbmVyPlxuPC9uZy1jb250YWluZXI+XG48IS0tIEZvcm0gZGlzcGxheS0tPlxuPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1vZGU9PT0nZm9ybSdcIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFoaWRlTGFiZWxcIj48c3BhbiBjbGFzcz1cInBvaW50ZXIgZmxvYXQtZW5kXCIgKGNsaWNrKT1cInNldERlZmF1bHQoKVwiICpuZ0lmPVwicmVhbERlZmF1bHQhPT0gdW5kZWZpbmVkICZhbXA7JmFtcDsgZWRpdFwiPjxpIGNsYXNzPVwiYmkgYmktdHJhc2ggbXMtMlwiPjwvaT48L3NwYW4+XG4gICAgPGxhYmVsIFtjbGFzcy5yZXF1aXJlZF09XCJyZXF1aXJlZFwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRpdGxlVHBsXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9sYWJlbD5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJkaXNwZWRpdEZvcm1UcGxcIj48L25nLWNvbnRhaW5lcj5cbjwvbmctY29udGFpbmVyPiJdfQ==
|