@decaf-ts/for-angular 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/lib/assets/i18n/en.json +10 -1
  2. package/dist/lib/components/empty-state/empty-state.component.d.ts +301 -0
  3. package/dist/lib/components/fieldset/fieldset.component.d.ts +199 -0
  4. package/dist/lib/components/filter/filter.component.d.ts +505 -0
  5. package/dist/lib/components/for-angular-components.module.d.ts +20 -0
  6. package/dist/lib/components/index.d.ts +16 -0
  7. package/dist/lib/components/layout/layout.component.d.ts +133 -0
  8. package/dist/lib/components/list/constants.d.ts +29 -0
  9. package/dist/lib/components/list/list.component.d.ts +849 -0
  10. package/dist/lib/components/list-item/list-item.component.d.ts +390 -0
  11. package/dist/lib/components/pagination/constants.d.ts +7 -0
  12. package/dist/lib/components/pagination/pagination.component.d.ts +264 -0
  13. package/dist/lib/components/searchbar/searchbar.component.d.ts +407 -0
  14. package/dist/lib/directives/collapsable.directive.d.ts +8 -0
  15. package/dist/lib/directives/index.d.ts +1 -0
  16. package/dist/lib/engine/NgxBaseComponent.d.ts +541 -0
  17. package/dist/lib/engine/index.d.ts +1 -0
  18. package/dist/lib/engine/types.d.ts +44 -0
  19. package/dist/lib/esm2022/components/crud-field/crud-field.component.mjs +8 -4
  20. package/dist/lib/esm2022/components/crud-form/crud-form.component.mjs +3 -3
  21. package/dist/lib/esm2022/components/empty-state/empty-state.component.mjs +348 -0
  22. package/dist/lib/esm2022/components/fieldset/fieldset.component.mjs +225 -0
  23. package/dist/lib/esm2022/components/filter/filter.component.mjs +689 -0
  24. package/dist/lib/esm2022/components/for-angular-components.module.mjs +71 -0
  25. package/dist/lib/esm2022/components/index.mjs +20 -0
  26. package/dist/lib/esm2022/components/layout/layout.component.mjs +176 -0
  27. package/dist/lib/esm2022/components/list/constants.mjs +6 -0
  28. package/dist/lib/esm2022/components/list/list.component.mjs +1236 -0
  29. package/dist/lib/esm2022/components/list-item/list-item.component.mjs +408 -0
  30. package/dist/lib/esm2022/components/pagination/constants.mjs +2 -0
  31. package/dist/lib/esm2022/components/pagination/pagination.component.mjs +323 -0
  32. package/dist/lib/esm2022/components/searchbar/searchbar.component.mjs +493 -0
  33. package/dist/lib/esm2022/directives/collapsable.directive.mjs +28 -0
  34. package/dist/lib/esm2022/directives/index.mjs +2 -0
  35. package/dist/lib/esm2022/engine/NgxBaseComponent.mjs +540 -0
  36. package/dist/lib/esm2022/engine/NgxCrudFormField.mjs +3 -1
  37. package/dist/lib/esm2022/engine/index.mjs +2 -1
  38. package/dist/lib/esm2022/engine/types.mjs +3 -1
  39. package/dist/lib/esm2022/helpers/index.mjs +13 -0
  40. package/dist/lib/esm2022/helpers/utils.mjs +415 -0
  41. package/dist/lib/esm2022/public-apis.mjs +5 -4
  42. package/dist/lib/fesm2022/decaf-ts-for-angular.mjs +6724 -1761
  43. package/dist/lib/fesm2022/decaf-ts-for-angular.mjs.map +1 -1
  44. package/dist/lib/helpers/index.d.ts +12 -0
  45. package/dist/lib/helpers/utils.d.ts +253 -0
  46. package/dist/lib/public-apis.d.ts +4 -3
  47. package/package.json +2 -2
@@ -0,0 +1,540 @@
1
+ import { Input, Component, Inject, ViewChild, ElementRef, Output, EventEmitter, } from '@angular/core';
2
+ import { getInjectablesRegistry, getLocaleFromClassName, } from 'src/lib/helpers/utils';
3
+ import { stringToBoolean } from 'src/lib/helpers/utils';
4
+ import { Model } from '@decaf-ts/decorator-validation';
5
+ import { InternalError, OperationKeys } from '@decaf-ts/db-decorators';
6
+ import { BaseComponentProps } from './constants';
7
+ import { NgxRenderingEngine2 } from './NgxRenderingEngine2';
8
+ import { getLogger } from '../for-angular.module';
9
+ import { Repository } from '@decaf-ts/core';
10
+ import * as i0 from "@angular/core";
11
+ /**
12
+ * @description Base component class that provides common functionality for all Decaf components.
13
+ * @summary The NgxBaseComponent serves as the foundation for all Decaf UI components, providing
14
+ * shared functionality for localization, element references, and styling. This abstract class
15
+ * implements common properties and methods that are used across the component library, ensuring
16
+ * consistent behavior and reducing code duplication. Components that extend this class inherit
17
+ * its capabilities for handling translations, accessing DOM elements, and applying custom styling.
18
+ *
19
+ * @template M - The model type that this component works with
20
+ * @param {string} instance - The component instance token used for identification
21
+ * @param {string} locale - The locale to be used for translations
22
+ * @param {StringOrBoolean} translatable - Whether the component should be translated
23
+ * @param {string} className - Additional CSS classes to apply to the component
24
+ * @param {"ios" | "md" | undefined} mode - Component platform style
25
+ *
26
+ * @component NgxBaseComponent
27
+ * @example
28
+ * ```typescript
29
+ * @Component({
30
+ * selector: 'app-my-component',
31
+ * templateUrl: './my-component.component.html',
32
+ * styleUrls: ['./my-component.component.scss']
33
+ * })
34
+ * export class MyComponent extends NgxBaseComponent {
35
+ * constructor(@Inject('instanceToken') instance: string) {
36
+ * super(instance);
37
+ * }
38
+ *
39
+ * ngOnInit() {
40
+ * this.initialize();
41
+ * // Component-specific initialization
42
+ * }
43
+ * }
44
+ * ```
45
+ * @mermaid
46
+ * sequenceDiagram
47
+ * participant App as Application
48
+ * participant Comp as Component
49
+ * participant Base as NgxBaseComponent
50
+ * participant Engine as NgxRenderingEngine2
51
+ *
52
+ * App->>Comp: Create component
53
+ * Comp->>Base: super(instance)
54
+ * Base->>Base: Set componentName & componentLocale
55
+ *
56
+ * App->>Comp: Set @Input properties
57
+ * Comp->>Base: ngOnChanges(changes)
58
+ *
59
+ * alt model changed
60
+ * Base->>Base: getModel(model)
61
+ * Base->>Engine: getDecorators(model, {})
62
+ * Engine-->>Base: Return decorator metadata
63
+ * Base->>Base: Configure mapper and item
64
+ * Base->>Base: getLocale(translatable)
65
+ * else locale/translatable changed
66
+ * Base->>Base: getLocale(translatable)
67
+ * end
68
+ *
69
+ * App->>Comp: ngOnInit()
70
+ * Comp->>Base: initialize()
71
+ * Base->>Base: Set initialized flag
72
+ */
73
+ export class NgxBaseComponent {
74
+ /**
75
+ * @description Creates an instance of NgxBaseComponent.
76
+ * @summary Initializes a new instance of the base component with the provided instance token.
77
+ * This constructor sets up the fundamental properties required by all Decaf components,
78
+ * including the component name, locale settings, and logging capabilities. The instance
79
+ * token is used for component identification and locale derivation.
80
+ *
81
+ * The constructor performs the following initialization steps:
82
+ * 1. Sets the componentName from the provided instance token
83
+ * 2. Derives the componentLocale from the class name using utility functions
84
+ * 3. Initializes the logger instance for the component
85
+ *
86
+ * @param {string} instance - The component instance token used for identification
87
+ *
88
+ * @mermaid
89
+ * sequenceDiagram
90
+ * participant A as Angular
91
+ * participant C as Component
92
+ * participant B as NgxBaseComponent
93
+ * participant U as Utils
94
+ * participant L as Logger
95
+ *
96
+ * A->>C: new Component(instance)
97
+ * C->>B: super(instance)
98
+ * B->>B: Set componentName = instance
99
+ * B->>U: getLocaleFromClassName(instance)
100
+ * U-->>B: Return derived locale
101
+ * B->>B: Set componentLocale
102
+ * B->>L: getLogger(this)
103
+ * L-->>B: Return logger instance
104
+ * B->>B: Set logger
105
+ *
106
+ * @memberOf NgxBaseComponent
107
+ */
108
+ // eslint-disable-next-line @angular-eslint/prefer-inject
109
+ constructor(instance) {
110
+ this.instance = instance;
111
+ /**
112
+ * @description Dynamic properties configuration object.
113
+ * @summary Contains key-value pairs of dynamic properties that can be applied to the component
114
+ * at runtime. This flexible configuration object allows for dynamic property assignment without
115
+ * requiring explicit input bindings for every possible configuration option. Properties from
116
+ * this object are parsed and applied to the component instance through the parseProps method,
117
+ * enabling customizable component behavior based on external configuration.
118
+ *
119
+ * @type {Record<string, unknown>}
120
+ * @default {}
121
+ * @memberOf NgxBaseComponent
122
+ */
123
+ this.props = {};
124
+ /**
125
+ * @description Configuration for list item rendering
126
+ * @summary Defines how list items should be rendered in the component.
127
+ * This property holds a configuration object that specifies the tag name
128
+ * and other properties needed to render list items correctly. The tag property
129
+ * identifies which component should be used to render each item in a list.
130
+ * Additional properties can be included to customize the rendering behavior.
131
+ *
132
+ * @type {Record<string, unknown>}
133
+ * @default {tag: ""}
134
+ * @memberOf NgxBaseComponent
135
+ */
136
+ this.item = { tag: '' };
137
+ /**
138
+ * @description Primary key field name for the model.
139
+ * @summary Specifies which field in the model should be used as the primary key.
140
+ * This is typically used for identifying unique records in operations like update and delete.
141
+ *
142
+ * @type {string}
143
+ * @default 'id'
144
+ * @memberOf NgxBaseComponent
145
+ */
146
+ this.pk = 'id';
147
+ /**
148
+ * @description Available CRUD operations for this component.
149
+ * @summary Defines which CRUD operations (Create, Read, Update, Delete) are available
150
+ * for this component. This affects which operations can be performed on the data.
151
+ *
152
+ * @default [OperationKeys.READ]
153
+ * @memberOf NgxBaseComponent
154
+ */
155
+ this.operations = [OperationKeys.READ];
156
+ /**
157
+ * @description Field mapping configuration.
158
+ * @summary Defines how fields from the data model should be mapped to properties used by the component.
159
+ * This allows for flexible data binding between the model and the component's display logic.
160
+ *
161
+ * @type {Record<string, string>}
162
+ * @memberOf NgxBaseComponent
163
+ */
164
+ this.mapper = {};
165
+ /**
166
+ * @description Determines if the component should be translated.
167
+ * @summary Controls whether the component's text content should be processed for translation.
168
+ * When true, the component will attempt to translate text using the specified locale.
169
+ * When false, text is displayed as-is without translation. This property accepts either
170
+ * a boolean value or a string that can be converted to a boolean (e.g., 'true', 'false', '1', '0').
171
+ *
172
+ * @type {StringOrBoolean}
173
+ * @default false
174
+ * @memberOf NgxBaseComponent
175
+ */
176
+ this.translatable = true;
177
+ /**
178
+ * @description Additional CSS class names to apply to the component.
179
+ * @summary Allows custom CSS classes to be added to the component's root element.
180
+ * These classes are appended to any automatically generated classes based on other
181
+ * component properties. Multiple classes can be provided as a space-separated string.
182
+ * This provides a way to customize the component's appearance beyond the built-in styling options.
183
+ *
184
+ * @type {string}
185
+ * @default ""
186
+ * @memberOf NgxBaseComponent
187
+ */
188
+ this.className = '';
189
+ /**
190
+ * @description Component platform style.
191
+ * @summary Controls the visual appearance of the component based on platform design guidelines.
192
+ * The 'ios' mode follows iOS design patterns, while 'md' (Material Design) follows Android/Google
193
+ * design patterns. This property affects various visual aspects such as animations, form elements,
194
+ * and icons. Setting this property allows components to maintain platform-specific styling
195
+ * for a more native look and feel.
196
+ *
197
+ * @type {("ios" | "md" | undefined)}
198
+ * @default "md"
199
+ * @memberOf NgxBaseComponent
200
+ */
201
+ this.mode = 'md';
202
+ /**
203
+ * @description Controls whether child components should be rendered
204
+ * @summary Determines if child components should be rendered by the component.
205
+ * This can be set to a boolean value or a string that can be converted to a boolean.
206
+ * When true, child components defined in the model will be rendered. When false,
207
+ * child components will be skipped. This provides control over the rendering depth.
208
+ *
209
+ * @type {string | StringOrBoolean}
210
+ * @default true
211
+ * @memberOf NgxBaseComponent
212
+ */
213
+ this.renderChild = true;
214
+ /**
215
+ * @description Flag indicating if the component has been initialized
216
+ * @summary Tracks whether the component has completed its initialization process.
217
+ * This flag is used to prevent duplicate initialization and to determine if
218
+ * certain operations that require initialization can be performed.
219
+ *
220
+ * @type {boolean}
221
+ * @default false
222
+ */
223
+ this.initialized = false;
224
+ /**
225
+ * @description Event emitter for custom renderer events.
226
+ * @summary Emits custom events that occur within child components or the layout itself.
227
+ * This allows parent components to listen for and respond to user interactions or
228
+ * state changes within the grid layout. Events are passed up the component hierarchy
229
+ * to enable coordinated behavior across the application.
230
+ *
231
+ * @type {EventEmitter<RendererCustomEvent>}
232
+ * @memberOf NgxBaseComponent
233
+ */
234
+ this.listenEvent = new EventEmitter();
235
+ /**
236
+ * @description Reference to the rendering engine instance
237
+ * @summary Provides access to the NgxRenderingEngine2 singleton instance,
238
+ * which handles the rendering of components based on model definitions.
239
+ * This engine is used to extract decorator metadata and render child components.
240
+ *
241
+ * @type {NgxRenderingEngine2}
242
+ */
243
+ this.renderingEngine = NgxRenderingEngine2.get();
244
+ this.componentName = instance;
245
+ this.componentLocale = getLocaleFromClassName(instance);
246
+ this.logger = getLogger(this);
247
+ this.getLocale(this.translatable);
248
+ }
249
+ /**
250
+ * @description Getter for the repository instance.
251
+ * @summary Provides a connection to the data layer for retrieving and manipulating data.
252
+ * This method initializes the `_repository` property if it is not already set, ensuring
253
+ * that a single instance of the repository is used throughout the component.
254
+ *
255
+ * The repository is used to perform CRUD operations on the data model, such as fetching data,
256
+ * creating new items, updating existing items, and deleting items. It also provides methods
257
+ * for querying and filtering data based on specific criteria.
258
+ *
259
+ * @returns {DecafRepository<Model>} The initialized repository instance.
260
+ * @private
261
+ * @memberOf NgxBaseComponent
262
+ */
263
+ get repository() {
264
+ try {
265
+ if (!this._repository) {
266
+ const modelName = this.model.constructor.name;
267
+ const constructor = Model.get(modelName);
268
+ if (!constructor)
269
+ throw new InternalError('Cannot find model. was it registered with @model?');
270
+ this._repository = Repository.forModel(constructor);
271
+ this.model = new constructor();
272
+ }
273
+ }
274
+ catch (error) {
275
+ throw new InternalError(error?.message || error);
276
+ }
277
+ return this._repository;
278
+ }
279
+ /**
280
+ * @description Parses and applies properties from the props object to the component instance.
281
+ * @summary This method iterates through the properties of the provided instance object
282
+ * and applies any matching properties from the component's props configuration to the
283
+ * component instance. This allows for dynamic property assignment based on configuration
284
+ * stored in the props object, enabling flexible component customization without requiring
285
+ * explicit property binding for every possible configuration option.
286
+ *
287
+ * The method performs a safe property assignment by checking if each key from the instance
288
+ * exists in the props object before applying it. This prevents accidental property
289
+ * overwriting and ensures only intended properties are modified.
290
+ *
291
+ * @param {KeyValue} instance - The component instance object to process
292
+ * @return {void}
293
+ *
294
+ * @mermaid
295
+ * sequenceDiagram
296
+ * participant C as Component
297
+ * participant B as NgxBaseComponent
298
+ * participant P as Props Object
299
+ *
300
+ * C->>B: parseProps(instance)
301
+ * B->>B: Get Object.keys(instance)
302
+ * loop For each key in instance
303
+ * B->>P: Check if key exists in this.props
304
+ * alt Key exists in props
305
+ * B->>B: Set this[key] = this.props[key]
306
+ * else Key not in props
307
+ * Note over B: Skip this key
308
+ * end
309
+ * end
310
+ *
311
+ * @protected
312
+ * @memberOf NgxBaseComponent
313
+ */
314
+ parseProps(instance) {
315
+ Object.keys(instance).forEach((key) => {
316
+ if (Object.keys(this.props).includes(key))
317
+ this[key] = this.props[key];
318
+ });
319
+ }
320
+ /**
321
+ * @description Handles changes to component inputs
322
+ * @summary This Angular lifecycle hook is called when input properties change.
323
+ * It responds to changes in the model, locale, or translatable properties by
324
+ * updating the component's internal state accordingly. When the model changes,
325
+ * it calls getModel to process the new model and getLocale to update the locale.
326
+ * When locale or translatable properties change, it calls getLocale to update
327
+ * the translation settings.
328
+ *
329
+ * @param {SimpleChanges} changes - Object containing changed properties
330
+ * @return {void}
331
+ */
332
+ ngOnChanges(changes) {
333
+ if (changes[BaseComponentProps.MODEL]) {
334
+ const { currentValue } = changes[BaseComponentProps.MODEL];
335
+ if (currentValue)
336
+ this.getModel(currentValue);
337
+ this.getLocale(this.translatable);
338
+ }
339
+ if (changes[BaseComponentProps.INITIALIZED] ||
340
+ changes[BaseComponentProps.LOCALE] ||
341
+ changes[BaseComponentProps.TRANSLATABLE])
342
+ this.getLocale(this.translatable);
343
+ }
344
+ /**
345
+ * @description Gets the appropriate locale string based on the translatable flag and available locales.
346
+ * @summary Determines which locale string to use for translation based on the translatable flag
347
+ * and available locale settings. This method first converts the translatable parameter to a boolean
348
+ * using the stringToBoolean utility function. If translatable is false, it returns an empty string,
349
+ * indicating no translation should be performed. If translatable is true, it checks for an explicitly
350
+ * provided locale via the locale property. If no explicit locale is available, it falls back to the
351
+ * componentLocale derived from the component's class name.
352
+ *
353
+ * @param {StringOrBoolean} translatable - Whether the component should be translated
354
+ * @return {string} The locale string to use for translation, or empty string if not translatable
355
+ *
356
+ * @mermaid
357
+ * sequenceDiagram
358
+ * participant C as Component
359
+ * participant N as NgxBaseComponent
360
+ * participant S as StringUtils
361
+ *
362
+ * C->>N: getLocale(translatable)
363
+ * N->>S: stringToBoolean(translatable)
364
+ * S-->>N: Return boolean value
365
+ * N->>N: Store in this.translatable
366
+ * alt translatable is false
367
+ * N-->>C: Return empty string
368
+ * else translatable is true
369
+ * alt this.locale is defined
370
+ * N-->>C: Return this.locale
371
+ * else this.locale is not defined
372
+ * N-->>C: Return this.componentLocale
373
+ * end
374
+ * end
375
+ */
376
+ getLocale(translatable) {
377
+ this.translatable = stringToBoolean(translatable);
378
+ if (!this.translatable)
379
+ return '';
380
+ if (!this.locale)
381
+ this.locale = this.componentLocale;
382
+ return this.locale;
383
+ }
384
+ /**
385
+ * @description Gets the route for the component
386
+ * @summary Retrieves the route path for the component, generating one based on the model
387
+ * if no route is explicitly set. This method checks if a route is already defined, and if not,
388
+ * it creates a default route based on the model's constructor name. The generated route follows
389
+ * the pattern '/model/{ModelName}'. This is useful for automatic routing in CRUD operations.
390
+ *
391
+ * @return {string} The route path for the component, or empty string if no route is available
392
+ */
393
+ getRoute() {
394
+ if (!this.route && this.model instanceof Model)
395
+ this.route = `/model/${this.model?.constructor.name}`;
396
+ return this.route || '';
397
+ }
398
+ /**
399
+ * @description Resolves and sets the component's model
400
+ * @summary Processes the provided model parameter, which can be either a Model instance
401
+ * or a string identifier. If a string is provided, it attempts to resolve the actual model
402
+ * from the injectables registry. After resolving the model, it calls setModelDefinitions
403
+ * to configure the component based on the model's metadata.
404
+ *
405
+ * @param {string | Model} model - The model instance or identifier string
406
+ * @return {void}
407
+ */
408
+ getModel(model) {
409
+ if (!(model instanceof Model))
410
+ this.model = getInjectablesRegistry().get(model);
411
+ this.setModelDefinitions(this.model);
412
+ }
413
+ /**
414
+ * @description Configures component properties based on model metadata
415
+ * @summary Extracts and applies configuration from the model's decorators to set up
416
+ * the component. This method uses the rendering engine to retrieve decorator metadata
417
+ * from the model, then configures the component's mapper and item properties accordingly.
418
+ * It ensures the route is properly set and merges various properties from the model's
419
+ * metadata into the component's configuration.
420
+ *
421
+ * @param {Model} model - The model to extract configuration from
422
+ * @return {void}
423
+ */
424
+ setModelDefinitions(model) {
425
+ if (model instanceof Model) {
426
+ this.getRoute();
427
+ this.model = model;
428
+ const field = this.renderingEngine.getDecorators(this.model, {});
429
+ const { props, item, children } = field;
430
+ this.props = Object.assign(props || {}, { children: children || [] });
431
+ if (item?.props?.['mapper'])
432
+ this.mapper = item?.props['mapper'] || {};
433
+ this.item = {
434
+ tag: item?.tag || '',
435
+ ...item?.props,
436
+ ...(this.mapper ? { mapper: this.mapper } : {}),
437
+ ...{ route: item?.props?.['route'] || this.route },
438
+ };
439
+ }
440
+ }
441
+ /**
442
+ * @description Initializes the component
443
+ * @summary Performs one-time initialization of the component. This method checks if
444
+ * the component has already been initialized to prevent duplicate initialization.
445
+ * When called for the first time, it sets the initialized flag to true and logs
446
+ * an initialization message with the component name. This method is typically called
447
+ * during the component's lifecycle setup.
448
+ */
449
+ initialize() {
450
+ this.initialized = true;
451
+ }
452
+ /**
453
+ * @description Handles custom events from child components.
454
+ * @summary Receives events from child renderer components and forwards them to parent
455
+ * components through the listenEvent output. This creates an event propagation chain
456
+ * that allows events to bubble up through the component hierarchy, enabling coordinated
457
+ * responses to user interactions across the layout structure.
458
+ *
459
+ * @param {RendererCustomEvent} event - The custom event from a child component
460
+ * @return {void}
461
+ *
462
+ * @mermaid
463
+ * sequenceDiagram
464
+ * participant C as Child Component
465
+ * participant L as NgxBaseComponent
466
+ * participant P as Parent Component
467
+ *
468
+ * C->>L: Emit RendererCustomEvent
469
+ * L->>L: handleEvent(event)
470
+ * L->>P: listenEvent.emit(event)
471
+ * Note over P: Handle event in parent
472
+ *
473
+ * @memberOf NgxBaseComponent
474
+ */
475
+ handleEvent(event) {
476
+ this.listenEvent.emit(event);
477
+ }
478
+ /**
479
+ * @description Tracks items in ngFor loops for optimal change detection.
480
+ * @summary Provides a tracking function for Angular's *ngFor directive to optimize rendering
481
+ * performance. This method generates unique identifiers for list items based on their index
482
+ * and content, allowing Angular to efficiently track changes and minimize DOM manipulations
483
+ * during list updates. The tracking function is essential for maintaining component state
484
+ * and preventing unnecessary re-rendering of unchanged items.
485
+ *
486
+ * @param {number} index - The index of the item in the list
487
+ * @param {KeyValue | string | number} item - The item data to track
488
+ * @returns {string | number} A unique identifier for the item
489
+ * @memberOf NgxBaseComponent
490
+ */
491
+ trackItemFn(index, item) {
492
+ return `${index}-${item}`;
493
+ }
494
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgxBaseComponent, deps: [{ token: 'instanceToken' }], target: i0.ɵɵFactoryTarget.Component }); }
495
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NgxBaseComponent, isStandalone: true, selector: "ng-component", inputs: { rendererId: "rendererId", model: "model", props: "props", item: "item", pk: "pk", route: "route", operations: "operations", uid: "uid", mapper: "mapper", locale: "locale", translatable: "translatable", className: "className", mode: "mode", renderChild: "renderChild" }, outputs: { listenEvent: "listenEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: '', isInline: true }); }
496
+ }
497
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgxBaseComponent, decorators: [{
498
+ type: Component,
499
+ args: [{
500
+ standalone: true,
501
+ template: '',
502
+ }]
503
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
504
+ type: Inject,
505
+ args: ['instanceToken']
506
+ }] }], propDecorators: { component: [{
507
+ type: ViewChild,
508
+ args: ['component', { read: ElementRef, static: true }]
509
+ }], rendererId: [{
510
+ type: Input
511
+ }], model: [{
512
+ type: Input
513
+ }], props: [{
514
+ type: Input
515
+ }], item: [{
516
+ type: Input
517
+ }], pk: [{
518
+ type: Input
519
+ }], route: [{
520
+ type: Input
521
+ }], operations: [{
522
+ type: Input
523
+ }], uid: [{
524
+ type: Input
525
+ }], mapper: [{
526
+ type: Input
527
+ }], locale: [{
528
+ type: Input
529
+ }], translatable: [{
530
+ type: Input
531
+ }], className: [{
532
+ type: Input
533
+ }], mode: [{
534
+ type: Input
535
+ }], renderChild: [{
536
+ type: Input
537
+ }], listenEvent: [{
538
+ type: Output
539
+ }] } });
540
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTmd4QmFzZUNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZW5naW5lL05neEJhc2VDb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLEtBQUssRUFDTCxTQUFTLEVBQ1QsTUFBTSxFQUNOLFNBQVMsRUFDVCxVQUFVLEVBR1YsTUFBTSxFQUNOLFlBQVksR0FDYixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLHNCQUFzQixHQUN2QixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDdkQsT0FBTyxFQUVMLGFBQWEsRUFDYixhQUFhLEVBQ2QsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDakQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFNUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRWxELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7QUFFNUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2REc7QUFLSCxNQUFNLE9BQWdCLGdCQUFnQjtJQXNTcEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQWlDRztJQUNILHlEQUF5RDtJQUN6RCxZQUF5RCxRQUFnQjtRQUFoQixhQUFRLEdBQVIsUUFBUSxDQUFRO1FBaFF6RTs7Ozs7Ozs7Ozs7V0FXRztRQUVILFVBQUssR0FBNEIsRUFBRSxDQUFDO1FBRXBDOzs7Ozs7Ozs7OztXQVdHO1FBRUgsU0FBSSxHQUE0QixFQUFF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cG9ydCB7XG4gIElucHV0LFxuICBDb21wb25lbnQsXG4gIEluamVjdCxcbiAgVmlld0NoaWxkLFxuICBFbGVtZW50UmVmLFxuICBPbkNoYW5nZXMsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIE91dHB1dCxcbiAgRXZlbnRFbWl0dGVyLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEtleVZhbHVlLCBSZW5kZXJlckN1c3RvbUV2ZW50LCBTdHJpbmdPckJvb2xlYW4gfSBmcm9tICdzcmMvbGliL2VuZ2luZS90eXBlcyc7XG5pbXBvcnQge1xuICBnZXRJbmplY3RhYmxlc1JlZ2lzdHJ5LFxuICBnZXRMb2NhbGVGcm9tQ2xhc3NOYW1lLFxufSBmcm9tICdzcmMvbGliL2hlbHBlcnMvdXRpbHMnO1xuaW1wb3J0IHsgc3RyaW5nVG9Cb29sZWFuIH0gZnJvbSAnc3JjL2xpYi9oZWxwZXJzL3V0aWxzJztcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uJztcbmltcG9ydCB7XG4gIENydWRPcGVyYXRpb25zLFxuICBJbnRlcm5hbEVycm9yLFxuICBPcGVyYXRpb25LZXlzXG59IGZyb20gJ0BkZWNhZi10cy9kYi1kZWNvcmF0b3JzJztcbmltcG9ydCB7IEJhc2VDb21wb25lbnRQcm9wcyB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IE5neFJlbmRlcmluZ0VuZ2luZTIgfSBmcm9tICcuL05neFJlbmRlcmluZ0VuZ2luZTInO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnQGRlY2FmLXRzL2xvZ2dpbmcnO1xuaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSAnLi4vZm9yLWFuZ3VsYXIubW9kdWxlJztcbmltcG9ydCB7IERlY2FmUmVwb3NpdG9yeSB9IGZyb20gJy4uL2NvbXBvbmVudHMvbGlzdC9jb25zdGFudHMnO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSB9IGZyb20gJ0BkZWNhZi10cy9jb3JlJztcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQmFzZSBjb21wb25lbnQgY2xhc3MgdGhhdCBwcm92aWRlcyBjb21tb24gZnVuY3Rpb25hbGl0eSBmb3IgYWxsIERlY2FmIGNvbXBvbmVudHMuXG4gKiBAc3VtbWFyeSBUaGUgTmd4QmFzZUNvbXBvbmVudCBzZXJ2ZXMgYXMgdGhlIGZvdW5kYXRpb24gZm9yIGFsbCBEZWNhZiBVSSBjb21wb25lbnRzLCBwcm92aWRpbmdcbiAqIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGZvciBsb2NhbGl6YXRpb24sIGVsZW1lbnQgcmVmZXJlbmNlcywgYW5kIHN0eWxpbmcuIFRoaXMgYWJzdHJhY3QgY2xhc3NcbiAqIGltcGxlbWVudHMgY29tbW9uIHByb3BlcnRpZXMgYW5kIG1ldGhvZHMgdGhhdCBhcmUgdXNlZCBhY3Jvc3MgdGhlIGNvbXBvbmVudCBsaWJyYXJ5LCBlbnN1cmluZ1xuICogY29uc2lzdGVudCBiZWhhdmlvciBhbmQgcmVkdWNpbmcgY29kZSBkdXBsaWNhdGlvbi4gQ29tcG9uZW50cyB0aGF0IGV4dGVuZCB0aGlzIGNsYXNzIGluaGVyaXRcbiAqIGl0cyBjYXBhYmlsaXRpZXMgZm9yIGhhbmRsaW5nIHRyYW5zbGF0aW9ucywgYWNjZXNzaW5nIERPTSBlbGVtZW50cywgYW5kIGFwcGx5aW5nIGN1c3RvbSBzdHlsaW5nLlxuICpcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCB0aGlzIGNvbXBvbmVudCB3b3JrcyB3aXRoXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5zdGFuY2UgLSBUaGUgY29tcG9uZW50IGluc3RhbmNlIHRva2VuIHVzZWQgZm9yIGlkZW50aWZpY2F0aW9uXG4gKiBAcGFyYW0ge3N0cmluZ30gbG9jYWxlIC0gVGhlIGxvY2FsZSB0byBiZSB1c2VkIGZvciB0cmFuc2xhdGlvbnNcbiAqIEBwYXJhbSB7U3RyaW5nT3JCb29sZWFufSB0cmFuc2xhdGFibGUgLSBXaGV0aGVyIHRoZSBjb21wb25lbnQgc2hvdWxkIGJlIHRyYW5zbGF0ZWRcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWUgLSBBZGRpdGlvbmFsIENTUyBjbGFzc2VzIHRvIGFwcGx5IHRvIHRoZSBjb21wb25lbnRcbiAqIEBwYXJhbSB7XCJpb3NcIiB8IFwibWRcIiB8IHVuZGVmaW5lZH0gbW9kZSAtIENvbXBvbmVudCBwbGF0Zm9ybSBzdHlsZVxuICpcbiAqIEBjb21wb25lbnQgTmd4QmFzZUNvbXBvbmVudFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ2FwcC1teS1jb21wb25lbnQnLFxuICogICB0ZW1wbGF0ZVVybDogJy4vbXktY29tcG9uZW50LmNvbXBvbmVudC5odG1sJyxcbiAqICAgc3R5bGVVcmxzOiBbJy4vbXktY29tcG9uZW50LmNvbXBvbmVudC5zY3NzJ11cbiAqIH0pXG4gKiBleHBvcnQgY2xhc3MgTXlDb21wb25lbnQgZXh0ZW5kcyBOZ3hCYXNlQ29tcG9uZW50IHtcbiAqICAgY29uc3RydWN0b3IoQEluamVjdCgnaW5zdGFuY2VUb2tlbicpIGluc3RhbmNlOiBzdHJpbmcpIHtcbiAqICAgICBzdXBlcihpbnN0YW5jZSk7XG4gKiAgIH1cbiAqXG4gKiAgIG5nT25Jbml0KCkge1xuICogICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICogICAgIC8vIENvbXBvbmVudC1zcGVjaWZpYyBpbml0aWFsaXphdGlvblxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQXBwIGFzIEFwcGxpY2F0aW9uXG4gKiAgIHBhcnRpY2lwYW50IENvbXAgYXMgQ29tcG9uZW50XG4gKiAgIHBhcnRpY2lwYW50IEJhc2UgYXMgTmd4QmFzZUNvbXBvbmVudFxuICogICBwYXJ0aWNpcGFudCBFbmdpbmUgYXMgTmd4UmVuZGVyaW5nRW5naW5lMlxuICpcbiAqICAgQXBwLT4+Q29tcDogQ3JlYXRlIGNvbXBvbmVudFxuICogICBDb21wLT4+QmFzZTogc3VwZXIoaW5zdGFuY2UpXG4gKiAgIEJhc2UtPj5CYXNlOiBTZXQgY29tcG9uZW50TmFtZSAmIGNvbXBvbmVudExvY2FsZVxuICpcbiAqICAgQXBwLT4+Q29tcDogU2V0IEBJbnB1dCBwcm9wZXJ0aWVzXG4gKiAgIENvbXAtPj5CYXNlOiBuZ09uQ2hhbmdlcyhjaGFuZ2VzKVxuICpcbiAqICAgYWx0IG1vZGVsIGNoYW5nZWRcbiAqICAgICBCYXNlLT4+QmFzZTogZ2V0TW9kZWwobW9kZWwpXG4gKiAgICAgQmFzZS0+PkVuZ2luZTogZ2V0RGVjb3JhdG9ycyhtb2RlbCwge30pXG4gKiAgICAgRW5naW5lLS0+PkJhc2U6IFJldHVybiBkZWNvcmF0b3IgbWV0YWRhdGFcbiAqICAgICBCYXNlLT4+QmFzZTogQ29uZmlndXJlIG1hcHBlciBhbmQgaXRlbVxuICogICAgIEJhc2UtPj5CYXNlOiBnZXRMb2NhbGUodHJhbnNsYXRhYmxlKVxuICogICBlbHNlIGxvY2FsZS90cmFuc2xhdGFibGUgY2hhbmdlZFxuICogICAgIEJhc2UtPj5CYXNlOiBnZXRMb2NhbGUodHJhbnNsYXRhYmxlKVxuICogICBlbmRcbiAqXG4gKiAgIEFwcC0+PkNvbXA6IG5nT25Jbml0KClcbiAqICAgQ29tcC0+PkJhc2U6IGluaXRpYWxpemUoKVxuICogICBCYXNlLT4+QmFzZTogU2V0IGluaXRpYWxpemVkIGZsYWdcbiAqL1xuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHRlbXBsYXRlOiAnJyxcbn0pXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTmd4QmFzZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVmZXJlbmNlIHRvIHRoZSBjb21wb25lbnQncyBlbGVtZW50LlxuICAgKiBAc3VtbWFyeSBQcm92aWRlcyBkaXJlY3QgYWNjZXNzIHRvIHRoZSBuYXRpdmUgRE9NIGVsZW1lbnQgb2YgdGhlIGNvbXBvbmVudCB0aHJvdWdoIEFuZ3VsYXInc1xuICAgKiBWaWV3Q2hpbGQgZGVjb3JhdG9yLiBUaGlzIHJlZmVyZW5jZSBjYW4gYmUgdXNlZCB0byBtYW5pcHVsYXRlIHRoZSBET00gZWxlbWVudCBkaXJlY3RseSxcbiAgICogYXBwbHkgY3VzdG9tIHN0eWxlcywgb3IgYWNjZXNzIG5hdGl2ZSBlbGVtZW50IHByb3BlcnRpZXMgYW5kIG1ldGhvZHMuIFRoZSBlbGVtZW50IGlzXG4gICAqIGlkZW50aWZpZWQgYnkgdGhlICdjb21wb25lbnQnIHRlbXBsYXRlIHJlZmVyZW5jZSB2YXJpYWJsZS5cbiAgICpcbiAgICogQHR5cGUge0VsZW1lbnRSZWZ9XG4gICAqIEBtZW1iZXJPZiBOZ3hCYXNlQ29tcG9uZW50XG4gICAqL1xuICBAVmlld0NoaWxkKCdjb21wb25lbnQnLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogdHJ1ZSB9KVxuICBjb21wb25lbnQhOiBFbGVtZW50UmVmO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIG5hbWUgb2YgdGhlIGNvbXBvbmVudC5cbiAgICogQHN1bW1hcnkgU3RvcmVzIHRoZSBuYW1lIG9mIHRoZSBjb21wb25lbnQsIHdoaWNoIGlzIHR5cGljYWxseSBkZXJpdmVkIGZyb20gdGhlIGNsYXNzIG5hbWUuXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgdXNlZCBpbnRlcm5hbGx5IGZvciB2YXJpb3VzIHB1cnBvc2VzIHN1Y2ggYXMgbG9nZ2luZywgZGVyaXZpbmcgdGhlIGRlZmF1bHRcbiAgICogbG9jYWxlLCBhbmQgcG90ZW50aWFsbHkgZm9yIGNvbXBvbmVudCBpZGVudGlmaWNhdGlvbiBpbiBkZWJ1Z2dpbmcgb3IgZXJyb3IgcmVwb3J0aW5nLlxuICAgKlxuICAgKiBUaGUgYGNvbXBvbmVudE5hbWVgIGlzIHNldCBkdXJpbmcgdGhlIGNvbXBvbmVudCdzIGluaXRpYWxpemF0aW9uIHByb2Nlc3MgYW5kIHNob3VsZCBub3RcbiAgICogYmUgbW9kaWZpZWQgZXh0ZXJuYWxseS4gSXQncyBtYXJrZWQgYXMgcHJvdGVjdGVkIHRvIGFsbG93IGFjY2VzcyBpbiBkZXJpdmVkIGNsYXNzZXMgd2hpbGVcbiAgICogcHJldmVudGluZyBkaXJlY3QgYWNjZXNzIGZyb20gb3V0c2lkZSB0aGUgY29tcG9uZW50IGhpZXJhcmNoeS5cbiAgICpcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICogQHByb3RlY3RlZFxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBJbnNpZGUgYSBkZXJpdmVkIGNvbXBvbmVudCBjbGFzc1xuICAgKiBjb25zb2xlLmxvZyh0aGlzLmNvbXBvbmVudE5hbWUpOyAvLyBPdXRwdXRzOiBcIk15Q3VzdG9tQ29tcG9uZW50XCJcbiAgICovXG4gIGNvbXBvbmVudE5hbWUhOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIHJlbmRlcmVyLlxuICAgKiBAc3VtbWFyeSBBIHVuaXF1ZSBpZGVudGlmaWVyIHVzZWQgdG8gcmVmZXJlbmNlIHRoZSBjb21wb25lbnQncyByZW5kZXJlciBpbnN0YW5jZS5cbiAgICogVGhpcyBjYW4gYmUgdXNlZCBmb3IgdGFyZ2V0aW5nIHNwZWNpZmljIHJlbmRlcmVyIGluc3RhbmNlcyB3aGVuIG11bHRpcGxlIGNvbXBvbmVudHNcbiAgICogYXJlIHByZXNlbnQgb24gdGhlIHNhbWUgcGFnZS5cbiAgICpcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICogQG1lbWJlck9mIE5neEJhc2VDb21wb25lbnRcbiAgICovXG4gIEBJbnB1dCgpXG4gIHJlbmRlcmVySWQhOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXBvc2l0b3J5IG1vZGVsIGZvciBkYXRhIG9wZXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IFRoZSBkYXRhIG1vZGVsIHJlcG9zaXRvcnkgdGhhdCB0aGlzIGNvbXBvbmVudCB3aWxsIHVzZSBmb3IgQ1JVRCBvcGVyYXRpb25zLlxuICAgKiBUaGlzIHByb3ZpZGVzIGEgY29ubmVjdGlvbiB0byB0aGUgZGF0YSBsYXllciBmb3IgcmV0cmlldmluZyBhbmQgbWFuaXB1bGF0aW5nIGRhdGEuXG4gICAqXG4gICAqIEB0eXBlIHtNb2RlbHwgdW5kZWZpbmVkfVxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgbW9kZWwhOiAgTW9kZWwgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgcmVwb3NpdG9yeSBmb3IgaW50ZXJhY3Rpbmcgd2l0aCB0aGUgZGF0YSBtb2RlbC5cbiAgICogQHN1bW1hcnkgUHJvdmlkZXMgYSBjb25uZWN0aW9uIHRvIHRoZSBkYXRhIGxheWVyIGZvciByZXRyaWV2aW5nIGFuZCBtYW5pcHVsYXRpbmcgZGF0YS5cbiAgICogVGhpcyBpcyBhbiBpbnN0YW5jZSBvZiB0aGUgYERlY2FmUmVwb3NpdG9yeWAgY2xhc3MgZnJvbSB0aGUgYEBkZWNhZi10cy9jb3JlYCBwYWNrYWdlLFxuICAgKiB3aGljaCBpcyBpbml0aWFsaXplZCBpbiB0aGUgYHJlcG9zaXRvcnlgIGdldHRlciBtZXRob2QuXG4gICAqXG4gICAqIFRoZSByZXBvc2l0b3J5IGlzIHVzZWQgdG8gcGVyZm9ybSBDUlVEIChDcmVhdGUsIFJlYWQsIFVwZGF0ZSwgRGVsZXRlKSBvcGVyYXRpb25zIG9uIHRoZVxuICAgKiBkYXRhIG1vZGVsLCBzdWNoIGFzIGZldGNoaW5nIGRhdGEsIGNyZWF0aW5nIG5ldyBpdGVtcywgdXBkYXRpbmcgZXhpc3RpbmcgaXRlbXMsIGFuZCBkZWxldGluZ1xuICAgKiBpdGVtcy4gSXQgYWxzbyBwcm92aWRlcyBtZXRob2RzIGZvciBxdWVyeWluZyBhbmQgZmlsdGVyaW5nIGRhdGEgYmFzZWQgb24gc3BlY2lmaWMgY3JpdGVyaWEuXG4gICAqXG4gICAqIEB0eXBlIHtEZWNhZlJlcG9zaXRvcnk8TW9kZWw+fVxuICAgKiBAcHJpdmF0ZVxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgcHJvdGVjdGVkIF9yZXBvc2l0b3J5PzogRGVjYWZSZXBvc2l0b3J5PE1vZGVsPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIER5bmFtaWMgcHJvcGVydGllcyBjb25maWd1cmF0aW9uIG9iamVjdC5cbiAgICogQHN1bW1hcnkgQ29udGFpbnMga2V5LXZhbHVlIHBhaXJzIG9mIGR5bmFtaWMgcHJvcGVydGllcyB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIHRoZSBjb21wb25lbnRcbiAgICogYXQgcnVudGltZS4gVGhpcyBmbGV4aWJsZSBjb25maWd1cmF0aW9uIG9iamVjdCBhbGxvd3MgZm9yIGR5bmFtaWMgcHJvcGVydHkgYXNzaWdubWVudCB3aXRob3V0XG4gICAqIHJlcXVpcmluZyBleHBsaWNpdCBpbnB1dCBiaW5kaW5ncyBmb3IgZXZlcnkgcG9zc2libGUgY29uZmlndXJhdGlvbiBvcHRpb24uIFByb3BlcnRpZXMgZnJvbVxuICAgKiB0aGlzIG9iamVjdCBhcmUgcGFyc2VkIGFuZCBhcHBsaWVkIHRvIHRoZSBjb21wb25lbnQgaW5zdGFuY2UgdGhyb3VnaCB0aGUgcGFyc2VQcm9wcyBtZXRob2QsXG4gICAqIGVuYWJsaW5nIGN1c3RvbWl6YWJsZSBjb21wb25lbnQgYmVoYXZpb3IgYmFzZWQgb24gZXh0ZXJuYWwgY29uZmlndXJhdGlvbi5cbiAgICpcbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fVxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgcHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb25maWd1cmF0aW9uIGZvciBsaXN0IGl0ZW0gcmVuZGVyaW5nXG4gICAqIEBzdW1tYXJ5IERlZmluZXMgaG93IGxpc3QgaXRlbXMgc2hvdWxkIGJlIHJlbmRlcmVkIGluIHRoZSBjb21wb25lbnQuXG4gICAqIFRoaXMgcHJvcGVydHkgaG9sZHMgYSBjb25maWd1cmF0aW9uIG9iamVjdCB0aGF0IHNwZWNpZmllcyB0aGUgdGFnIG5hbWVcbiAgICogYW5kIG90aGVyIHByb3BlcnRpZXMgbmVlZGVkIHRvIHJlbmRlciBsaXN0IGl0ZW1zIGNvcnJlY3RseS4gVGhlIHRhZyBwcm9wZXJ0eVxuICAgKiBpZGVudGlmaWVzIHdoaWNoIGNvbXBvbmVudCBzaG91bGQgYmUgdXNlZCB0byByZW5kZXIgZWFjaCBpdGVtIGluIGEgbGlzdC5cbiAgICogQWRkaXRpb25hbCBwcm9wZXJ0aWVzIGNhbiBiZSBpbmNsdWRlZCB0byBjdXN0b21pemUgdGhlIHJlbmRlcmluZyBiZWhhdmlvci5cbiAgICpcbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fVxuICAgKiBAZGVmYXVsdCB7dGFnOiBcIlwifVxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgaXRlbTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7IHRhZzogJycgfTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByaW1hcnkga2V5IGZpZWxkIG5hbWUgZm9yIHRoZSBtb2RlbC5cbiAgICogQHN1bW1hcnkgU3BlY2lmaWVzIHdoaWNoIGZpZWxkIGluIHRoZSBtb2RlbCBzaG91bGQgYmUgdXNlZCBhcyB0aGUgcHJpbWFyeSBrZXkuXG4gICAqIFRoaXMgaXMgdHlwaWNhbGx5IHVzZWQgZm9yIGlkZW50aWZ5aW5nIHVuaXF1ZSByZWNvcmRzIGluIG9wZXJhdGlvbnMgbGlrZSB1cGRhdGUgYW5kIGRlbGV0ZS5cbiAgICpcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICogQGRlZmF1bHQgJ2lkJ1xuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgcGs6IHN0cmluZyA9ICdpZCc7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBCYXNlIHJvdXRlIGZvciBuYXZpZ2F0aW9uIHJlbGF0ZWQgdG8gdGhpcyBjb21wb25lbnQuXG4gICAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGJhc2Ugcm91dGUgcGF0aCB1c2VkIGZvciBuYXZpZ2F0aW9uIGFjdGlvbnMgcmVsYXRlZCB0byB0aGlzIGNvbXBvbmVudC5cbiAgICogVGhpcyBpcyBvZnRlbiB1c2VkIGFzIGEgcHJlZml4IGZvciBjb25zdHJ1Y3RpbmcgbmF2aWdhdGlvbiBVUkxzLlxuICAgKlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgcm91dGUhOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBdmFpbGFibGUgQ1JVRCBvcGVyYXRpb25zIGZvciB0aGlzIGNvbXBvbmVudC5cbiAgICogQHN1bW1hcnkgRGVmaW5lcyB3aGljaCBDUlVEIG9wZXJhdGlvbnMgKENyZWF0ZSwgUmVhZCwgVXBkYXRlLCBEZWxldGUpIGFyZSBhdmFpbGFibGVcbiAgICogZm9yIHRoaXMgY29tcG9uZW50LiBUaGlzIGFmZmVjdHMgd2hpY2ggb3BlcmF0aW9ucyBjYW4gYmUgcGVyZm9ybWVkIG9uIHRoZSBkYXRhLlxuICAgKlxuICAgKiBAZGVmYXVsdCBbT3BlcmF0aW9uS2V5cy5SRUFEXVxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgb3BlcmF0aW9uczogQ3J1ZE9wZXJhdGlvbnNbXSA9IFtPcGVyYXRpb25LZXlzLlJFQURdO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IHJlY29yZC5cbiAgICogQHN1bW1hcnkgQSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgcmVjb3JkIGJlaW5nIGRpc3BsYXllZCBvciBtYW5pcHVsYXRlZC5cbiAgICogVGhpcyBpcyB0eXBpY2FsbHkgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSBwcmltYXJ5IGtleSBmb3Igb3BlcmF0aW9ucyBvbiBzcGVjaWZpYyByZWNvcmRzLlxuICAgKlxuICAgKiBAdHlwZSB7c3RyaW5nIHwgbnVtYmVyfVxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgdWlkITogc3RyaW5nIHwgbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRmllbGQgbWFwcGluZyBjb25maWd1cmF0aW9uLlxuICAgKiBAc3VtbWFyeSBEZWZpbmVzIGhvdyBmaWVsZHMgZnJvbSB0aGUgZGF0YSBtb2RlbCBzaG91bGQgYmUgbWFwcGVkIHRvIHByb3BlcnRpZXMgdXNlZCBieSB0aGUgY29tcG9uZW50LlxuICAgKiBUaGlzIGFsbG93cyBmb3IgZmxleGlibGUgZGF0YSBiaW5kaW5nIGJldHdlZW4gdGhlIG1vZGVsIGFuZCB0aGUgY29tcG9uZW50J3MgZGlzcGxheSBsb2dpYy5cbiAgICpcbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsIHN0cmluZz59XG4gICAqIEBtZW1iZXJPZiBOZ3hCYXNlQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKVxuICBtYXBwZXI6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBsb2NhbGUgdG8gYmUgdXNlZCBmb3IgdHJhbnNsYXRpb25zLlxuICAgKiBAc3VtbWFyeSBTcGVjaWZpZXMgdGhlIGxvY2FsZSBpZGVudGlmaWVyIHRvIHVzZSB3aGVuIHRyYW5zbGF0aW5nIGNvbXBvbmVudCB0ZXh0LlxuICAgKiBUaGlzIGNhbiBiZSBzZXQgZXhwbGljaXRseSB2aWEgaW5wdXQgcHJvcGVydHkgdG8gb3ZlcnJpZGUgdGhlIGF1dG9tYXRpY2FsbHkgZGVyaXZlZFxuICAgKiBsb2NhbGUgZnJvbSB0aGUgY29tcG9uZW50IG5hbWUuIFRoZSBsb2NhbGUgaXMgdHlwaWNhbGx5IGEgbGFuZ3VhZ2UgY29kZSAoZS5nLiwgJ2VuJywgJ2ZyJylcbiAgICogb3IgYSBsYW5ndWFnZS1yZWdpb24gY29kZSAoZS5nLiwgJ2VuLVVTJywgJ2ZyLUNBJykgdGhhdCBkZXRlcm1pbmVzIHdoaWNoIHRyYW5zbGF0aW9uXG4gICAqIHNldCB0byB1c2UgZm9yIHRoZSBjb21wb25lbnQncyB0ZXh0IGNvbnRlbnQuXG4gICAqXG4gICAqIEB0eXBlIHtzdHJpbmd9XG4gICAqIEBtZW1iZXJPZiBOZ3hCYXNlQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKVxuICBsb2NhbGUhOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEZXRlcm1pbmVzIGlmIHRoZSBjb21wb25lbnQgc2hvdWxkIGJlIHRyYW5zbGF0ZWQuXG4gICAqIEBzdW1tYXJ5IENvbnRyb2xzIHdoZXRoZXIgdGhlIGNvbXBvbmVudCdzIHRleHQgY29udGVudCBzaG91bGQgYmUgcHJvY2Vzc2VkIGZvciB0cmFuc2xhdGlvbi5cbiAgICogV2hlbiB0cnVlLCB0aGUgY29tcG9uZW50IHdpbGwgYXR0ZW1wdCB0byB0cmFuc2xhdGUgdGV4dCB1c2luZyB0aGUgc3BlY2lmaWVkIGxvY2FsZS5cbiAgICogV2hlbiBmYWxzZSwgdGV4dCBpcyBkaXNwbGF5ZWQgYXMtaXMgd2l0aG91dCB0cmFuc2xhdGlvbi4gVGhpcyBwcm9wZXJ0eSBhY2NlcHRzIGVpdGhlclxuICAgKiBhIGJvb2xlYW4gdmFsdWUgb3IgYSBzdHJpbmcgdGhhdCBjYW4gYmUgY29udmVydGVkIHRvIGEgYm9vbGVhbiAoZS5nLiwgJ3RydWUnLCAnZmFsc2UnLCAnMScsICcwJykuXG4gICAqXG4gICAqIEB0eXBlIHtTdHJpbmdPckJvb2xlYW59XG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqIEBtZW1iZXJPZiBOZ3hCYXNlQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKVxuICB0cmFuc2xhdGFibGU6IFN0cmluZ09yQm9vbGVhbiA9IHRydWU7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRpdGlvbmFsIENTUyBjbGFzcyBuYW1lcyB0byBhcHBseSB0byB0aGUgY29tcG9uZW50LlxuICAgKiBAc3VtbWFyeSBBbGxvd3MgY3VzdG9tIENTUyBjbGFzc2VzIHRvIGJlIGFkZGVkIHRvIHRoZSBjb21wb25lbnQncyByb290IGVsZW1lbnQuXG4gICAqIFRoZXNlIGNsYXNzZXMgYXJlIGFwcGVuZGVkIHRvIGFueSBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBjbGFzc2VzIGJhc2VkIG9uIG90aGVyXG4gICAqIGNvbXBvbmVudCBwcm9wZXJ0aWVzLiBNdWx0aXBsZSBjbGFzc2VzIGNhbiBiZSBwcm92aWRlZCBhcyBhIHNwYWNlLXNlcGFyYXRlZCBzdHJpbmcuXG4gICAqIFRoaXMgcHJvdmlkZXMgYSB3YXkgdG8gY3VzdG9taXplIHRoZSBjb21wb25lbnQncyBhcHBlYXJhbmNlIGJleW9uZCB0aGUgYnVpbHQtaW4gc3R5bGluZyBvcHRpb25zLlxuICAgKlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKiBAZGVmYXVsdCBcIlwiXG4gICAqIEBtZW1iZXJPZiBOZ3hCYXNlQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKVxuICBjbGFzc05hbWU6IHN0cmluZyA9ICcnO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ29tcG9uZW50IHBsYXRmb3JtIHN0eWxlLlxuICAgKiBAc3VtbWFyeSBDb250cm9scyB0aGUgdmlzdWFsIGFwcGVhcmFuY2Ugb2YgdGhlIGNvbXBvbmVudCBiYXNlZCBvbiBwbGF0Zm9ybSBkZXNpZ24gZ3VpZGVsaW5lcy5cbiAgICogVGhlICdpb3MnIG1vZGUgZm9sbG93cyBpT1MgZGVzaWduIHBhdHRlcm5zLCB3aGlsZSAnbWQnIChNYXRlcmlhbCBEZXNpZ24pIGZvbGxvd3MgQW5kcm9pZC9Hb29nbGVcbiAgICogZGVzaWduIHBhdHRlcm5zLiBUaGlzIHByb3BlcnR5IGFmZmVjdHMgdmFyaW91cyB2aXN1YWwgYXNwZWN0cyBzdWNoIGFzIGFuaW1hdGlvbnMsIGZvcm0gZWxlbWVudHMsXG4gICAqIGFuZCBpY29ucy4gU2V0dGluZyB0aGlzIHByb3BlcnR5IGFsbG93cyBjb21wb25lbnRzIHRvIG1haW50YWluIHBsYXRmb3JtLXNwZWNpZmljIHN0eWxpbmdcbiAgICogZm9yIGEgbW9yZSBuYXRpdmUgbG9vayBhbmQgZmVlbC5cbiAgICpcbiAgICogQHR5cGUgeyhcImlvc1wiIHwgXCJtZFwiIHwgdW5kZWZpbmVkKX1cbiAgICogQGRlZmF1bHQgXCJtZFwiXG4gICAqIEBtZW1iZXJPZiBOZ3hCYXNlQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKVxuICBtb2RlOiAnaW9zJyB8ICdtZCcgfCB1bmRlZmluZWQgPSAnbWQnO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGxvY2FsZSBkZXJpdmVkIGZyb20gdGhlIGNvbXBvbmVudCdzIGNsYXNzIG5hbWUuXG4gICAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgYXV0b21hdGljYWxseSBkZXJpdmVkIGxvY2FsZSBiYXNlZCBvbiB0aGUgY29tcG9uZW50J3MgY2xhc3MgbmFtZS5cbiAgICogVGhpcyBpcyBkZXRlcm1pbmVkIGR1cmluZyBjb21wb25lbnQgaW5pdGlhbGl6YXRpb24gYW5kIHNlcnZlcyBhcyBhIGZhbGxiYWNrIHdoZW4gbm9cbiAgICogZXhwbGljaXQgbG9jYWxlIGlzIHByb3ZpZGVkIHZpYSB0aGUgbG9jYWxlIGlucHV0IHByb3BlcnR5LiBUaGUgZGVyaXZhdGlvbiBpcyBoYW5kbGVkXG4gICAqIGJ5IHRoZSBnZXRMb2NhbGVGcm9tQ2xhc3NOYW1lIHV0aWxpdHkgZnVuY3Rpb24sIHdoaWNoIGV4dHJhY3RzIGEgbG9jYWxlIGlkZW50aWZpZXJcbiAgICogZnJvbSB0aGUgY29tcG9uZW50J3MgY2xhc3MgbmFtZS5cbiAgICpcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICogQG1lbWJlck9mIE5neEJhc2VDb21wb25lbnRcbiAgICovXG4gIGNvbXBvbmVudExvY2FsZSE6IHN0cmluZztcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENvbnRyb2xzIHdoZXRoZXIgY2hpbGQgY29tcG9uZW50cyBzaG91bGQgYmUgcmVuZGVyZWRcbiAgICogQHN1bW1hcnkgRGV0ZXJtaW5lcyBpZiBjaGlsZCBjb21wb25lbnRzIHNob3VsZCBiZSByZW5kZXJlZCBieSB0aGUgY29tcG9uZW50LlxuICAgKiBUaGlzIGNhbiBiZSBzZXQgdG8gYSBib29sZWFuIHZhbHVlIG9yIGEgc3RyaW5nIHRoYXQgY2FuIGJlIGNvbnZlcnRlZCB0byBhIGJvb2xlYW4uXG4gICAqIFdoZW4gdHJ1ZSwgY2hpbGQgY29tcG9uZW50cyBkZWZpbmVkIGluIHRoZSBtb2RlbCB3aWxsIGJlIHJlbmRlcmVkLiBXaGVuIGZhbHNlLFxuICAgKiBjaGlsZCBjb21wb25lbnRzIHdpbGwgYmUgc2tpcHBlZC4gVGhpcyBwcm92aWRlcyBjb250cm9sIG92ZXIgdGhlIHJlbmRlcmluZyBkZXB0aC5cbiAgICpcbiAgICogQHR5cGUge3N0cmluZyB8IFN0cmluZ09yQm9vbGVhbn1cbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgcmVuZGVyQ2hpbGQ6IHN0cmluZyB8IFN0cmluZ09yQm9vbGVhbiA9IHRydWU7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBGbGFnIGluZGljYXRpbmcgaWYgdGhlIGNvbXBvbmVudCBoYXMgYmVlbiBpbml0aWFsaXplZFxuICAgKiBAc3VtbWFyeSBUcmFja3Mgd2hldGhlciB0aGUgY29tcG9uZW50IGhhcyBjb21wbGV0ZWQgaXRzIGluaXRpYWxpemF0aW9uIHByb2Nlc3MuXG4gICAqIFRoaXMgZmxhZyBpcyB1c2VkIHRvIHByZXZlbnQgZHVwbGljYXRlIGluaXRpYWxpemF0aW9uIGFuZCB0byBkZXRlcm1pbmUgaWZcbiAgICogY2VydGFpbiBvcGVyYXRpb25zIHRoYXQgcmVxdWlyZSBpbml0aWFsaXphdGlvbiBjYW4gYmUgcGVyZm9ybWVkLlxuICAgKlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGluaXRpYWxpemVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFdmVudCBlbWl0dGVyIGZvciBjdXN0b20gcmVuZGVyZXIgZXZlbnRzLlxuICAgKiBAc3VtbWFyeSBFbWl0cyBjdXN0b20gZXZlbnRzIHRoYXQgb2NjdXIgd2l0aGluIGNoaWxkIGNvbXBvbmVudHMgb3IgdGhlIGxheW91dCBpdHNlbGYuXG4gICAqIFRoaXMgYWxsb3dzIHBhcmVudCBjb21wb25lbnRzIHRvIGxpc3RlbiBmb3IgYW5kIHJlc3BvbmQgdG8gdXNlciBpbnRlcmFjdGlvbnMgb3JcbiAgICogc3RhdGUgY2hhbmdlcyB3aXRoaW4gdGhlIGdyaWQgbGF5b3V0LiBFdmVudHMgYXJlIHBhc3NlZCB1cCB0aGUgY29tcG9uZW50IGhpZXJhcmNoeVxuICAgKiB0byBlbmFibGUgY29vcmRpbmF0ZWQgYmVoYXZpb3IgYWNyb3NzIHRoZSBhcHBsaWNhdGlvbi5cbiAgICpcbiAgICogQHR5cGUge0V2ZW50RW1pdHRlcjxSZW5kZXJlckN1c3RvbUV2ZW50Pn1cbiAgICogQG1lbWJlck9mIE5neEJhc2VDb21wb25lbnRcbiAgICovXG4gIEBPdXRwdXQoKVxuICBsaXN0ZW5FdmVudDogRXZlbnRFbWl0dGVyPFJlbmRlcmVyQ3VzdG9tRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxSZW5kZXJlckN1c3RvbUV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVmZXJlbmNlIHRvIHRoZSByZW5kZXJpbmcgZW5naW5lIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgTmd4UmVuZGVyaW5nRW5naW5lMiBzaW5nbGV0b24gaW5zdGFuY2UsXG4gICAqIHdoaWNoIGhhbmRsZXMgdGhlIHJlbmRlcmluZyBvZiBjb21wb25lbnRzIGJhc2VkIG9uIG1vZGVsIGRlZmluaXRpb25zLlxuICAgKiBUaGlzIGVuZ2luZSBpcyB1c2VkIHRvIGV4dHJhY3QgZGVjb3JhdG9yIG1ldGFkYXRhIGFuZCByZW5kZXIgY2hpbGQgY29tcG9uZW50cy5cbiAgICpcbiAgICogQHR5cGUge05neFJlbmRlcmluZ0VuZ2luZTJ9XG4gICAqL1xuICByZW5kZXJpbmdFbmdpbmU6IE5neFJlbmRlcmluZ0VuZ2luZTIgPVxuICAgIE5neFJlbmRlcmluZ0VuZ2luZTIuZ2V0KCkgYXMgdW5rbm93biBhcyBOZ3hSZW5kZXJpbmdFbmdpbmUyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgY29tcG9uZW50LlxuICAgKiBAc3VtbWFyeSBQcm92aWRlcyBsb2dnaW5nIGNhcGFiaWxpdGllcyBmb3IgdGhlIGNvbXBvbmVudCwgYWxsb3dpbmcgZm9yIGNvbnNpc3RlbnRcbiAgICogYW5kIHN0cnVjdHVyZWQgbG9nZ2luZyBvZiBpbmZvcm1hdGlvbiwgd2FybmluZ3MsIGFuZCBlcnJvcnMuIFRoaXMgbG9nZ2VyIGlzIGluaXRpYWxpemVkXG4gICAqIGluIHRoZSBuZ09uSW5pdCBtZXRob2QgdXNpbmcgdGhlIGdldExvZ2dlciBmdW5jdGlvbiBmcm9tIHRoZSBGb3JBbmd1bGFyTW9kdWxlLlxuICAgKlxuICAgKiBUaGUgbG9nZ2VyIGlzIHVzZWQgdGhyb3VnaG91dCB0aGUgY29tcG9uZW50IHRvIHJlY29yZCBpbXBvcnRhbnQgZXZlbnRzLCBkZWJ1ZyBpbmZvcm1hdGlvbixcbiAgICogYW5kIHBvdGVudGlhbCBpc3N1ZXMuIEl0IGhlbHBzIGluIG1vbml0b3JpbmcgdGhlIGNvbXBvbmVudCdzIGJlaGF2aW9yLCB0cmFja2luZyB0aGUgZmxvd1xuICAgKiBvZiBvcGVyYXRpb25zLCBhbmQgZmFjaWxpdGF0aW5nIGVhc2llciBkZWJ1Z2dpbmcgYW5kIG1haW50ZW5hbmNlLlxuICAgKlxuICAgKiBAdHlwZSB7TG9nZ2VyfVxuICAgKiBAcHJpdmF0ZVxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgbG9nZ2VyITogTG9nZ2VyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBOZ3hCYXNlQ29tcG9uZW50LlxuICAgKiBAc3VtbWFyeSBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgYmFzZSBjb21wb25lbnQgd2l0aCB0aGUgcHJvdmlkZWQgaW5zdGFuY2UgdG9rZW4uXG4gICAqIFRoaXMgY29uc3RydWN0b3Igc2V0cyB1cCB0aGUgZnVuZGFtZW50YWwgcHJvcGVydGllcyByZXF1aXJlZCBieSBhbGwgRGVjYWYgY29tcG9uZW50cyxcbiAgICogaW5jbHVkaW5nIHRoZSBjb21wb25lbnQgbmFtZSwgbG9jYWxlIHNldHRpbmdzLCBhbmQgbG9nZ2luZyBjYXBhYmlsaXRpZXMuIFRoZSBpbnN0YW5jZVxuICAgKiB0b2tlbiBpcyB1c2VkIGZvciBjb21wb25lbnQgaWRlbnRpZmljYXRpb24gYW5kIGxvY2FsZSBkZXJpdmF0aW9uLlxuICAgKlxuICAgKiBUaGUgY29uc3RydWN0b3IgcGVyZm9ybXMgdGhlIGZvbGxvd2luZyBpbml0aWFsaXphdGlvbiBzdGVwczpcbiAgICogMS4gU2V0cyB0aGUgY29tcG9uZW50TmFtZSBmcm9tIHRoZSBwcm92aWRlZCBpbnN0YW5jZSB0b2tlblxuICAgKiAyLiBEZXJpdmVzIHRoZSBjb21wb25lbnRMb2NhbGUgZnJvbSB0aGUgY2xhc3MgbmFtZSB1c2luZyB1dGlsaXR5IGZ1bmN0aW9uc1xuICAgKiAzLiBJbml0aWFsaXplcyB0aGUgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgY29tcG9uZW50XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpbnN0YW5jZSAtIFRoZSBjb21wb25lbnQgaW5zdGFuY2UgdG9rZW4gdXNlZCBmb3IgaWRlbnRpZmljYXRpb25cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQSBhcyBBbmd1bGFyXG4gICAqICAgcGFydGljaXBhbnQgQyBhcyBDb21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBCIGFzIE5neEJhc2VDb21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBVIGFzIFV0aWxzXG4gICAqICAgcGFydGljaXBhbnQgTCBhcyBMb2dnZXJcbiAgICpcbiAgICogICBBLT4+QzogbmV3IENvbXBvbmVudChpbnN0YW5jZSlcbiAgICogICBDLT4+Qjogc3VwZXIoaW5zdGFuY2UpXG4gICAqICAgQi0+PkI6IFNldCBjb21wb25lbnROYW1lID0gaW5zdGFuY2VcbiAgICogICBCLT4+VTogZ2V0TG9jYWxlRnJvbUNsYXNzTmFtZShpbnN0YW5jZSlcbiAgICogICBVLS0+PkI6IFJldHVybiBkZXJpdmVkIGxvY2FsZVxuICAgKiAgIEItPj5COiBTZXQgY29tcG9uZW50TG9jYWxlXG4gICAqICAgQi0+Pkw6IGdldExvZ2dlcih0aGlzKVxuICAgKiAgIEwtLT4+QjogUmV0dXJuIGxvZ2dlciBpbnN0YW5jZVxuICAgKiAgIEItPj5COiBTZXQgbG9nZ2VyXG4gICAqXG4gICAqIEBtZW1iZXJPZiBOZ3hCYXNlQ29tcG9uZW50XG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L3ByZWZlci1pbmplY3RcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKEBJbmplY3QoJ2luc3RhbmNlVG9rZW4nKSBwcm90ZWN0ZWQgaW5zdGFuY2U6IHN0cmluZykge1xuICAgIHRoaXMuY29tcG9uZW50TmFtZSA9IGluc3RhbmNlO1xuICAgIHRoaXMuY29tcG9uZW50TG9jYWxlID0gZ2V0TG9jYWxlRnJvbUNsYXNzTmFtZShpbnN0YW5jZSk7XG4gICAgdGhpcy5sb2dnZXIgPSBnZXRMb2dnZXIodGhpcyk7XG4gICAgdGhpcy5nZXRMb2NhbGUodGhpcy50cmFuc2xhdGFibGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXR0ZXIgZm9yIHRoZSByZXBvc2l0b3J5IGluc3RhbmNlLlxuICAgKiBAc3VtbWFyeSBQcm92aWRlcyBhIGNvbm5lY3Rpb24gdG8gdGhlIGRhdGEgbGF5ZXIgZm9yIHJldHJpZXZpbmcgYW5kIG1hbmlwdWxhdGluZyBkYXRhLlxuICAgKiBUaGlzIG1ldGhvZCBpbml0aWFsaXplcyB0aGUgYF9yZXBvc2l0b3J5YCBwcm9wZXJ0eSBpZiBpdCBpcyBub3QgYWxyZWFkeSBzZXQsIGVuc3VyaW5nXG4gICAqIHRoYXQgYSBzaW5nbGUgaW5zdGFuY2Ugb2YgdGhlIHJlcG9zaXRvcnkgaXMgdXNlZCB0aHJvdWdob3V0IHRoZSBjb21wb25lbnQuXG4gICAqXG4gICAqIFRoZSByZXBvc2l0b3J5IGlzIHVzZWQgdG8gcGVyZm9ybSBDUlVEIG9wZXJhdGlvbnMgb24gdGhlIGRhdGEgbW9kZWwsIHN1Y2ggYXMgZmV0Y2hpbmcgZGF0YSxcbiAgICogY3JlYXRpbmcgbmV3IGl0ZW1zLCB1cGRhdGluZyBleGlzdGluZyBpdGVtcywgYW5kIGRlbGV0aW5nIGl0ZW1zLiBJdCBhbHNvIHByb3ZpZGVzIG1ldGhvZHNcbiAgICogZm9yIHF1ZXJ5aW5nIGFuZCBmaWx0ZXJpbmcgZGF0YSBiYXNlZCBvbiBzcGVjaWZpYyBjcml0ZXJpYS5cbiAgICpcbiAgICogQHJldHVybnMge0RlY2FmUmVwb3NpdG9yeTxNb2RlbD59IFRoZSBpbml0aWFsaXplZCByZXBvc2l0b3J5IGluc3RhbmNlLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAbWVtYmVyT2YgTmd4QmFzZUNvbXBvbmVudFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCByZXBvc2l0b3J5KCk6IERlY2FmUmVwb3NpdG9yeTxNb2RlbD4ge1xuICAgIHRyeSB7XG4gICAgICBpZiAoIXRoaXMuX3JlcG9zaXRvcnkpIHtcbiAgICAgICAgY29uc3QgbW9kZWxOYW1lICA9ICh0aGlzLm1vZGVsIGFzIE1vZGVsKS5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gTW9kZWwuZ2V0KG1vZGVsTmFtZSk7XG4gICAgICAgIGlmICghY29uc3RydWN0b3IpXG4gICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgICAnQ2Fubm90IGZpbmQgbW9kZWwuIHdhcyBpdCByZWdpc3RlcmVkIHdpdGggQG1vZGVsPycsXG4gICAgICAgICAgKTtcbiAgICAgICAgdGhpcy5fcmVwb3NpdG9yeSA9IFJlcG9zaXRvcnkuZm9yTW9kZWwoY29uc3RydWN0b3IpO1xuICAgICAgICB0aGlzLm1vZGVsID0gbmV3IGNvbnN0cnVjdG9yKCkgYXMgTW9kZWw7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAoZXJyb3IgYXMgRXJyb3IpPy5tZXNzYWdlIHx8IGVycm9yIGFzIHN0cmluZ1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3JlcG9zaXRvcnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyBhbmQgYXBwbGllcyBwcm9wZXJ0aWVzIGZyb20gdGhlIHByb3BzIG9iamVjdCB0byB0aGUgY29tcG9uZW50IGluc3RhbmNlLlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBpdGVyYXRlcyB0aHJvdWdoIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBwcm92aWRlZCBpbnN0YW5jZSBvYmplY3RcbiAgICogYW5kIGFwcGxpZXMgYW55IG1hdGNoaW5nIHByb3BlcnRpZXMgZnJvbSB0aGUgY29tcG9uZW50J3MgcHJvcHMgY29uZmlndXJhdGlvbiB0byB0aGVcbiAgICogY29tcG9uZW50IGluc3RhbmNlLiBUaGlzIGFsbG93cyBmb3IgZHluYW1pYyBwcm9wZXJ0eSBhc3NpZ25tZW50IGJhc2VkIG9uIGNvbmZpZ3VyYXRpb25cbiAgICogc3RvcmVkIGluIHRoZSBwcm9wcyBvYmplY3QsIGVuYWJsaW5nIGZsZXhpYmxlIGNvbXBvbmVudCBjdXN0b21pemF0aW9uIHdpdGhvdXQgcmVxdWlyaW5nXG4gICAqIGV4cGxpY2l0IHByb3BlcnR5IGJpbmRpbmcgZm9yIGV2ZXJ5IHBvc3NpYmxlIGNvbmZpZ3VyYXRpb24gb3B0aW9uLlxuICAgKlxuICAgKiBUaGUgbWV0aG9kIHBlcmZvcm1zIGEgc2FmZSBwcm9wZXJ0eSBhc3NpZ25tZW50IGJ5IGNoZWNraW5nIGlmIGVhY2gga2V5IGZyb20gdGhlIGluc3RhbmNlXG4gICAqIGV4aXN0cyBpbiB0aGUgcHJvcHMgb2JqZWN0IGJlZm9yZSBhcHBseWluZyBpdC4gVGhpcyBwcmV2ZW50cyBhY2NpZGVudGFsIHByb3BlcnR5XG4gICAqIG92ZXJ3cml0aW5nIGFuZCBlbnN1cmVzIG9ubHkgaW50ZW5kZWQgcHJvcGVydGllcyBhcmUgbW9kaWZpZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7S2V5VmFsdWV9IGluc3RhbmNlIC0gVGhlIGNvbXBvbmVudCBpbnN0YW5jZSBvYmplY3QgdG8gcHJvY2Vzc1xuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IEIgYXMgTmd4QmFzZUNvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IFAgYXMgUHJvcHMgT2JqZWN0XG4gICAqXG4gICAqICAgQy0+PkI6IHBhcnNlUHJvcHMoaW5zdGFuY2UpXG4gICAqICAgQi0+PkI6IEdldCBPYmplY3Qua2V5cyhpbnN0YW5jZSlcbiAgICogICBsb29wIEZvciBlYWNoIGtleSBpbiBpbnN0YW5jZVxuICAgKiAgICAgQi0+PlA6IENoZWNrIGlmIGtleSBleGlzdHMgaW4gdGhpcy5wcm9wc1xuICAgKiAgICAgYWx0IEtleSBleGlzdHMgaW4gcHJvcHNcbiAgICogICAgICAgQi0+PkI6IFNldCB0aGlzW2tleV0gPSB0aGlzLnByb3BzW2tleV1cbiAgICogICAgIGVsc2UgS2V5IG5vdCBpbiBwcm9wc1xuICAgKiAgICAgICBOb3RlIG92ZXIgQjogU2tpcCB0aGlzIGtleVxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQG1lbWJlck9mIE5neEJhc2VDb21wb25lbnRcbiAgICovXG4gIHByb3RlY3RlZCBwYXJzZVByb3BzKGluc3RhbmNlOiBLZXlWYWx1ZSk6IHZvaWQge1xuICAgIE9iamVjdC5rZXlzKGluc3RhbmNlKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgIGlmKE9iamVjdC5rZXlzKHRoaXMucHJvcHMpLmluY2x1ZGVzKGtleSkpXG4gICAgICAgICh0aGlzIGFzIEtleVZhbHVlKVtrZXldID0gdGhpcy5wcm9wc1trZXldO1xuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEhhbmRsZXMgY2hhbmdlcyB0byBjb21wb25lbnQgaW5wdXRzXG4gICAqIEBzdW1tYXJ5IFRoaXMgQW5ndWxhciBsaWZlY3ljbGUgaG9vayBpcyBjYWxsZWQgd2hlbiBpbnB1dCBwcm9wZXJ0aWVzIGNoYW5nZS5cbiAgICogSXQgcmVzcG9uZHMgdG8gY2hhbmdlcyBpbiB0aGUgbW9kZWwsIGxvY2FsZSwgb3IgdHJhbnNsYXRhYmxlIHByb3BlcnRpZXMgYnlcbiAgICogdXBkYXRpbmcgdGhlIGNvbXBvbmVudCdzIGludGVybmFsIHN0YXRlIGFjY29yZGluZ2x5LiBXaGVuIHRoZSBtb2RlbCBjaGFuZ2VzLFxuICAgKiBpdCBjYWxscyBnZXRNb2RlbCB0byBwcm9jZXNzIHRoZSBuZXcgbW9kZWwgYW5kIGdldExvY2FsZSB0byB1cGRhdGUgdGhlIGxvY2FsZS5cbiAgICogV2hlbiBsb2NhbGUgb3IgdHJhbnNsYXRhYmxlIHByb3BlcnRpZXMgY2hhbmdlLCBpdCBjYWxscyBnZXRMb2NhbGUgdG8gdXBkYXRlXG4gICAqIHRoZSB0cmFuc2xhdGlvbiBzZXR0aW5ncy5cbiAgICpcbiAgICogQHBhcmFtIHtTaW1wbGVDaGFuZ2VzfSBjaGFuZ2VzIC0gT2JqZWN0IGNvbnRhaW5pbmcgY2hhbmdlZCBwcm9wZXJ0aWVzXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbQmFzZUNvbXBvbmVudFByb3BzLk1PREVMXSkge1xuICAgICAgY29uc3QgeyBjdXJyZW50VmFsdWUgfSA9IGNoYW5nZXNbQmFzZUNvbXBvbmVudFByb3BzLk1PREVMXTtcbiAgICAgIGlmIChjdXJyZW50VmFsdWUpIHRoaXMuZ2V0TW9kZWwoY3VycmVudFZhbHVlKTtcbiAgICAgIHRoaXMuZ2V0TG9jYWxlKHRoaXMudHJhbnNsYXRhYmxlKTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgY2hhbmdlc1tCYXNlQ29tcG9uZW50UHJvcHMuSU5JVElBTElaRURdIHx8XG4gICAgICBjaGFuZ2VzW0Jhc2VDb21wb25lbnRQcm9wcy5MT0NBTEVdIHx8XG4gICAgICBjaGFuZ2VzW0Jhc2VDb21wb25lbnRQcm9wcy5UUkFOU0xBVEFCTEVdXG4gICAgKVxuICAgICAgdGhpcy5nZXRMb2NhbGUodGhpcy50cmFuc2xhdGFibGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIHRoZSBhcHByb3ByaWF0ZSBsb2NhbGUgc3RyaW5nIGJhc2VkIG9uIHRoZSB0cmFuc2xhdGFibGUgZmxhZyBhbmQgYXZhaWxhYmxlIGxvY2FsZXMuXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgd2hpY2ggbG9jYWxlIHN0cmluZyB0byB1c2UgZm9yIHRyYW5zbGF0aW9uIGJhc2VkIG9uIHRoZSB0cmFuc2xhdGFibGUgZmxhZ1xuICAgKiBhbmQgYXZhaWxhYmxlIGxvY2FsZSBzZXR0aW5ncy4gVGhpcyBtZXRob2QgZmlyc3QgY29udmVydHMgdGhlIHRyYW5zbGF0YWJsZSBwYXJhbWV0ZXIgdG8gYSBib29sZWFuXG4gICAqIHVzaW5nIHRoZSBzdHJpbmdUb0Jvb2xlYW4gdXRpbGl0eSBmdW5jdGlvbi4gSWYgdHJhbnNsYXRhYmxlIGlzIGZhbHNlLCBpdCByZXR1cm5zIGFuIGVtcHR5IHN0cmluZyxcbiAgICogaW5kaWNhdGluZyBubyB0cmFuc2xhdGlvbiBzaG91bGQgYmUgcGVyZm9ybWVkLiBJZiB0cmFuc2xhdGFibGUgaXMgdHJ1ZSwgaXQgY2hlY2tzIGZvciBhbiBleHBsaWNpdGx5XG4gICAqIHByb3ZpZGVkIGxvY2FsZSB2aWEgdGhlIGxvY2FsZSBwcm9wZXJ0eS4gSWYgbm8gZXhwbGljaXQgbG9jYWxlIGlzIGF2YWlsYWJsZSwgaXQgZmFsbHMgYmFjayB0byB0aGVcbiAgICogY29tcG9uZW50TG9jYWxlIGRlcml2ZWQgZnJvbSB0aGUgY29tcG9uZW50J3MgY2xhc3MgbmFtZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmdPckJvb2xlYW59IHRyYW5zbGF0YWJsZSAtIFdoZXRoZXIgdGhlIGNvbXBvbmVudCBzaG91bGQgYmUgdHJhbnNsYXRlZFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBsb2NhbGUgc3RyaW5nIHRvIHVzZSBmb3IgdHJhbnNsYXRpb24sIG9yIGVtcHR5IHN0cmluZyBpZiBub3QgdHJhbnNsYXRhYmxlXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEMgYXMgQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgTiBhcyBOZ3hCYXNlQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgUyBhcyBTdHJpbmdVdGlsc1xuICAgKlxuICAgKiAgIEMtPj5OOiBnZXRMb2NhbGUodHJhbnNsYXRhYmxlKVxuICAgKiAgIE4tPj5TOiBzdHJpbmdUb0Jvb2xlYW4odHJhbnNsYXRhYmxlKVxuICAgKiAgIFMtLT4+TjogUmV0dXJuIGJvb2xlYW4gdmFsdWVcbiAgICogICBOLT4+TjogU3RvcmUgaW4gdGhpcy50cmFuc2xhdGFibGVcbiAgICogICBhbHQgdHJhbnNsYXRhYmxlIGlzIGZhbHNlXG4gICAqICAgICBOLS0+PkM6IFJldHVybiBlbXB0eSBzdHJpbmdcbiAgICogICBlbHNlIHRyYW5zbGF0YWJsZSBpcyB0cnVlXG4gICAqICAgICBhbHQgdGhpcy5sb2NhbGUgaXMgZGVmaW5lZFxuICAgKiAgICAgICBOLS0+PkM6IFJldHVybiB0aGlzLmxvY2FsZVxuICAgKiAgICAgZWxzZSB0aGlzLmxvY2FsZSBpcyBub3QgZGVmaW5lZFxuICAgKiAgICAgICBOLS0+PkM6IFJldHVybiB0aGlzLmNvbXBvbmVudExvY2FsZVxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqL1xuICBnZXRMb2NhbGUodHJhbnNsYXRhYmxlOiBTdHJpbmdPckJvb2xlYW4pOiBzdHJpbmcge1xuICAgIHRoaXMudHJhbnNsYXRhYmxlID0gc3RyaW5nVG9Cb29sZWFuKHRyYW5zbGF0YWJsZSk7XG4gICAgaWYgKCF0aGlzLnRyYW5zbGF0YWJsZSlcbiAgICAgIHJldHVybiAnJztcbiAgICBpZiAoIXRoaXMubG9jYWxlKVxuICAgICAgdGhpcy5sb2NhbGUgPSB0aGlzLmNvbXBvbmVudExvY2FsZTtcbiAgICByZXR1cm4gdGhpcy5sb2NhbGU7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIHJvdXRlIGZvciB0aGUgY29tcG9uZW50XG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgcm91dGUgcGF0aCBmb3IgdGhlIGNvbXBvbmVudCwgZ2VuZXJhdGluZyBvbmUgYmFzZWQgb24gdGhlIG1vZGVsXG4gICAqIGlmIG5vIHJvdXRlIGlzIGV4cGxpY2l0bHkgc2V0LiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgYSByb3V0ZSBpcyBhbHJlYWR5IGRlZmluZWQsIGFuZCBpZiBub3QsXG4gICAqIGl0IGNyZWF0ZXMgYSBkZWZhdWx0IHJvdXRlIGJhc2VkIG9uIHRoZSBtb2RlbCdzIGNvbnN0cnVjdG9yIG5hbWUuIFRoZSBnZW5lcmF0ZWQgcm91dGUgZm9sbG93c1xuICAgKiB0aGUgcGF0dGVybiAnL21vZGVsL3tNb2RlbE5hbWV9Jy4gVGhpcyBpcyB1c2VmdWwgZm9yIGF1dG9tYXRpYyByb3V0aW5nIGluIENSVUQgb3BlcmF0aW9ucy5cbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgcm91dGUgcGF0aCBmb3IgdGhlIGNvbXBvbmVudCwgb3IgZW1wdHkgc3RyaW5nIGlmIG5vIHJvdXRlIGlzIGF2YWlsYWJsZVxuICAgKi9cbiAgZ2V0Um91dGUoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMucm91dGUgJiYgdGhpcy5tb2RlbCBpbnN0YW5jZW9mIE1vZGVsKVxuICAgICAgdGhpcy5yb3V0ZSA9IGAvbW9kZWwvJHt0aGlzLm1vZGVsPy5jb25zdHJ1Y3Rvci5uYW1lfWA7XG4gICAgcmV0dXJuIHRoaXMucm91dGUgfHwgJyc7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlc29sdmVzIGFuZCBzZXRzIHRoZSBjb21wb25lbnQncyBtb2RlbFxuICAgKiBAc3VtbWFyeSBQcm9jZXNzZXMgdGhlIHByb3ZpZGVkIG1vZGVsIHBhcmFtZXRlciwgd2hpY2ggY2FuIGJlIGVpdGhlciBhIE1vZGVsIGluc3RhbmNlXG4gICAqIG9yIGEgc3RyaW5nIGlkZW50aWZpZXIuIElmIGEgc3RyaW5nIGlzIHByb3ZpZGVkLCBpdCBhdHRlbXB0cyB0byByZXNvbHZlIHRoZSBhY3R1YWwgbW9kZWxcbiAgICogZnJvbSB0aGUgaW5qZWN0YWJsZXMgcmVnaXN0cnkuIEFmdGVyIHJlc29sdmluZyB0aGUgbW9kZWwsIGl0IGNhbGxzIHNldE1vZGVsRGVmaW5pdGlvbnNcbiAgICogdG8gY29uZmlndXJlIHRoZSBjb21wb25lbnQgYmFzZWQgb24gdGhlIG1vZGVsJ3MgbWV0YWRhdGEuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgTW9kZWx9IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIG9yIGlkZW50aWZpZXIgc3RyaW5nXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBnZXRNb2RlbChtb2RlbDogc3RyaW5nIHwgTW9kZWwpOiB2b2lkIHtcbiAgICBpZiAoIShtb2RlbCBpbnN0YW5jZW9mIE1vZGVsKSlcbiAgICAgIHRoaXMubW9kZWwgPSBnZXRJbmplY3RhYmxlc1JlZ2lzdHJ5KCkuZ2V0KG1vZGVsKSBhcyBNb2RlbDtcbiAgICB0aGlzLnNldE1vZGVsRGVmaW5pdGlvbnModGhpcy5tb2RlbCBhcyBNb2RlbCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENvbmZpZ3VyZXMgY29tcG9uZW50IHByb3BlcnRpZXMgYmFzZWQgb24gbW9kZWwgbWV0YWRhdGFcbiAgICogQHN1bW1hcnkgRXh0cmFjdHMgYW5kIGFwcGxpZXMgY29uZmlndXJhdGlvbiBmcm9tIHRoZSBtb2RlbCdzIGRlY29yYXRvcnMgdG8gc2V0IHVwXG4gICAqIHRoZSBjb21wb25lbnQuIFRoaXMgbWV0aG9kIHVzZXMgdGhlIHJlbmRlcmluZyBlbmdpbmUgdG8gcmV0cmlldmUgZGVjb3JhdG9yIG1ldGFkYXRhXG4gICAqIGZyb20gdGhlIG1vZGVsLCB0aGVuIGNvbmZpZ3VyZXMgdGhlIGNvbXBvbmVudCdzIG1hcHBlciBhbmQgaXRlbSBwcm9wZXJ0aWVzIGFjY29yZGluZ2x5LlxuICAgKiBJdCBlbnN1cmVzIHRoZSByb3V0ZSBpcyBwcm9wZXJseSBzZXQgYW5kIG1lcmdlcyB2YXJpb3VzIHByb3BlcnRpZXMgZnJvbSB0aGUgbW9kZWwnc1xuICAgKiBtZXRhZGF0YSBpbnRvIHRoZSBjb21wb25lbnQncyBjb25maWd1cmF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge01vZGVsfSBtb2RlbCAtIFRoZSBtb2RlbCB0byBleHRyYWN0IGNvbmZpZ3VyYXRpb24gZnJvbVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc2V0TW9kZWxEZWZpbml0aW9ucyhtb2RlbDogTW9kZWwpOiB2b2lkIHtcbiAgICBpZiAobW9kZWwgaW5zdGFuY2VvZiBNb2RlbCkge1xuICAgICAgdGhpcy5nZXRSb3V0ZSgpO1xuICAgICAgdGhpcy5tb2RlbCA9IG1vZGVsO1xuICAgICAgY29uc3QgZmllbGQgPSB0aGlzLnJlbmRlcmluZ0VuZ2luZS5nZXREZWNvcmF0b3JzKHRoaXMubW9kZWwgYXMgTW9kZWwsIHt9KTtcbiAgICAgIGNvbnN0eyBwcm9wcywgaXRlbSwgY2hpbGRyZW4gfSA9IGZpZWxkO1xuICAgICAgdGhpcy5wcm9wcyA9IE9iamVjdC5hc3NpZ24ocHJvcHMgfHwge30sIHtjaGlsZHJlbjogY2hpbGRyZW4gfHwgW119KTtcbiAgICAgIGlmKGl0ZW0/LnByb3BzPy5bJ21hcHBlciddKVxuICAgICAgICB0aGlzLm1hcHBlciA9IGl0ZW0/LnByb3BzIVsnbWFwcGVyJ10gfHwge307XG4gICAgICB0aGlzLml0ZW0gPSB7XG4gICAgICAgIHRhZzogaXRlbT8udGFnIHx8ICcnLFxuICAgICAgICAuLi5pdGVtPy5wcm9wcyxcbiAgICAgICAgLi4uKHRoaXMubWFwcGVyID8ge21hcHBlcjogdGhpcy5tYXBwZXJ9IDoge30pLFxuICAgICAgICAuLi57IHJvdXRlOiBpdGVtPy5wcm9wcz8uWydyb3V0ZSddIHx8IHRoaXMucm91dGUgfSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXplcyB0aGUgY29tcG9uZW50XG4gICAqIEBzdW1tYXJ5IFBlcmZvcm1zIG9uZS10aW1lIGluaXRpYWxpemF0aW9uIG9mIHRoZSBjb21wb25lbnQuIFRoaXMgbWV0aG9kIGNoZWNrcyBpZlxuICAgKiB0aGUgY29tcG9uZW50IGhhcyBhbHJlYWR5IGJlZW4gaW5pdGlhbGl6ZWQgdG8gcHJldmVudCBkdXBsaWNhdGUgaW5pdGlhbGl6YXRpb24uXG4gICAqIFdoZW4gY2FsbGVkIGZvciB0aGUgZmlyc3QgdGltZSwgaXQgc2V0cyB0aGUgaW5pdGlhbGl6ZWQgZmxhZyB0byB0cnVlIGFuZCBsb2dzXG4gICAqIGFuIGluaXRpYWxpemF0aW9uIG1lc3NhZ2Ugd2l0aCB0aGUgY29tcG9uZW50IG5hbWUuIFRoaXMgbWV0aG9kIGlzIHR5cGljYWxseSBjYWxsZWRcbiAgICogZHVyaW5nIHRoZSBjb21wb25lbnQncyBsaWZlY3ljbGUgc2V0dXAuXG4gICAqL1xuICBpbml0aWFsaXplKCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIGN1c3RvbSBldmVudHMgZnJvbSBjaGlsZCBjb21wb25lbnRzLlxuICAgKiBAc3VtbWFyeSBSZWNlaXZlcyBldmVudHMgZnJvbSBjaGlsZCByZW5kZXJlciBjb21wb25lbnRzIGFuZCBmb3J3YXJkcyB0aGVtIHRvIHBhcmVudFxuICAgKiBjb21wb25lbnRzIHRocm91Z2ggdGhlIGxpc3RlbkV2ZW50IG91dHB1dC4gVGhpcyBjcmVhdGVzIGFuIGV2ZW50IHByb3BhZ2F0aW9uIGNoYWluXG4gICAqIHRoYXQgYWxsb3dzIGV2ZW50cyB0byBidWJibGUgdXAgdGhyb3VnaCB0aGUgY29tcG9uZW50IGhpZXJhcmNoeSwgZW5hYmxpbmcgY29vcmRpbmF0ZWRcbiAgICogcmVzcG9uc2VzIHRvIHVzZXIgaW50ZXJhY3Rpb25zIGFjcm9zcyB0aGUgbGF5b3V0IHN0cnVjdHVyZS5cbiAgICpcbiAgICogQHBhcmFtIHtSZW5kZXJlckN1c3RvbUV2ZW50fSBldmVudCAtIFRoZSBjdXN0b20gZXZlbnQgZnJvbSBhIGNoaWxkIGNvbXBvbmVudFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENoaWxkIENvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IEwgYXMgTmd4QmFzZUNvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IFAgYXMgUGFyZW50IENvbXBvbmVudFxuICAgKlxuICAgKiAgIEMtPj5MOiBFbWl0IFJlbmRlcmVyQ3VzdG9tRXZlbnRcbiAgICogICBMLT4+TDogaGFuZGxlRXZlbnQoZXZlbnQpXG4gICAqICAgTC0+PlA6IGxpc3RlbkV2ZW50LmVtaXQoZXZlbnQpXG4gICAqICAgTm90ZSBvdmVyIFA6IEhhbmRsZSBldmVudCBpbiBwYXJlbnRcbiAgICpcbiAgICogQG1lbWJlck9mIE5neEJhc2VDb21wb25lbnRcbiAgICovXG4gIGhhbmRsZUV2ZW50KGV2ZW50OiBSZW5kZXJlckN1c3RvbUV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5saXN0ZW5FdmVudC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVHJhY2tzIGl0ZW1zIGluIG5nRm9yIGxvb3BzIGZvciBvcHRpbWFsIGNoYW5nZSBkZXRlY3Rpb24uXG4gICAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgdHJhY2tpbmcgZnVuY3Rpb24gZm9yIEFuZ3VsYXIncyAqbmdGb3IgZGlyZWN0aXZlIHRvIG9wdGltaXplIHJlbmRlcmluZ1xuICAgKiBwZXJmb3JtYW5jZS4gVGhpcyBtZXRob2QgZ2VuZXJhdGVzIHVuaXF1ZSBpZGVudGlmaWVycyBmb3IgbGlzdCBpdGVtcyBiYXNlZCBvbiB0aGVpciBpbmRleFxuICAgKiBhbmQgY29udGVudCwgYWxsb3dpbmcgQW5ndWxhciB0byBlZmZpY2llbnRseSB0cmFjayBjaGFuZ2VzIGFuZCBtaW5pbWl6ZSBET00gbWFuaXB1bGF0aW9uc1xuICAgKiBkdXJpbmcgbGlzdCB1cGRhdGVzLiBUaGUgdHJhY2tpbmcgZnVuY3Rpb24gaXMgZXNzZW50aWFsIGZvciBtYWludGFpbmluZyBjb21wb25lbnQgc3RhdGVcbiAgICogYW5kIHByZXZlbnRpbmcgdW5uZWNlc3NhcnkgcmUtcmVuZGVyaW5nIG9mIHVuY2hhbmdlZCBpdGVtcy5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gVGhlIGluZGV4IG9mIHRoZSBpdGVtIGluIHRoZSBsaXN0XG4gICAqIEBwYXJhbSB7S2V5VmFsdWUgfCBzdHJpbmcgfCBudW1iZXJ9IGl0ZW0gLSBUaGUgaXRlbSBkYXRhIHRvIHRyYWNrXG4gICAqIEByZXR1cm5zIHtzdHJpbmcgfCBudW1iZXJ9IEEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBpdGVtXG4gICAqIEBtZW1iZXJPZiBOZ3hCYXNlQ29tcG9uZW50XG4gICAqL1xuICB0cmFja0l0ZW1GbihpbmRleDogbnVtYmVyLCBpdGVtOiBLZXlWYWx1ZSB8IHN0cmluZyB8IG51bWJlcik6IHN0cmluZyB8IG51bWJlciB7XG4gICAgcmV0dXJuIGAke2luZGV4fS0ke2l0ZW19YDtcbiAgfVxufVxuIl19