@decaf-ts/for-angular 0.0.25 → 0.0.26

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