@natec/mef-dev-ui-kit 16.4.57 → 19.0.0-beta.1

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 (161) hide show
  1. package/fesm2022/natec-mef-dev-ui-kit.mjs +10894 -5478
  2. package/fesm2022/natec-mef-dev-ui-kit.mjs.map +1 -1
  3. package/index.d.ts +5527 -5
  4. package/index.d.ts.map +1 -0
  5. package/package.json +6 -7
  6. package/src/lib/styles/pg/_mixins.scss +2 -523
  7. package/src/lib/styles/pg/_var.scss +29 -28
  8. package/src/lib/styles/pg/modules/_buttons.scss +55 -40
  9. package/src/lib/styles/pg/modules/_form_elements.scss +5 -4
  10. package/src/lib/styles/pg/modules/_header.scss +2 -2
  11. package/src/lib/styles/pg/modules/_secondary-sidebar.scss +3 -1
  12. package/src/lib/styles/pg/modules/_select.scss +59 -60
  13. package/src/lib/styles/pg/modules/_sidebar.scss +2 -1
  14. package/src/lib/styles/pg/utils.scss +0 -3
  15. package/esm2022/lib/markup-kit/card/card/card.component.mjs +0 -116
  16. package/esm2022/lib/markup-kit/card/card-long/card-long.component.mjs +0 -169
  17. package/esm2022/lib/markup-kit/card/card-long/cart-type-colors.enum.mjs +0 -7
  18. package/esm2022/lib/markup-kit/card/card-simple/card-simple.component.mjs +0 -50
  19. package/esm2022/lib/markup-kit/card/card.module.mjs +0 -35
  20. package/esm2022/lib/markup-kit/card/index.mjs +0 -6
  21. package/esm2022/lib/markup-kit/collapse/collapse/collapse.component.mjs +0 -149
  22. package/esm2022/lib/markup-kit/collapse/collapse-set/collapse-set.component.mjs +0 -102
  23. package/esm2022/lib/markup-kit/collapse/collapse.module.mjs +0 -25
  24. package/esm2022/lib/markup-kit/collapse/index.mjs +0 -4
  25. package/esm2022/lib/markup-kit/executors/index.mjs +0 -5
  26. package/esm2022/lib/markup-kit/executors/mefdev-executor-page/mefdev-executor-page.component.mjs +0 -112
  27. package/esm2022/lib/markup-kit/executors/stage/stage.component.mjs +0 -27
  28. package/esm2022/lib/markup-kit/executors/step-executor/step-executor.component.mjs +0 -289
  29. package/esm2022/lib/markup-kit/executors/step-executor.module.mjs +0 -42
  30. package/esm2022/lib/markup-kit/modals/fill/fill.component.mjs +0 -137
  31. package/esm2022/lib/markup-kit/modals/index.mjs +0 -7
  32. package/esm2022/lib/markup-kit/modals/markup-kit.module.mjs +0 -39
  33. package/esm2022/lib/markup-kit/modals/modal-size.enum.mjs +0 -2
  34. package/esm2022/lib/markup-kit/modals/right-filter/right-filter.component.mjs +0 -48
  35. package/esm2022/lib/markup-kit/modals/slide-right/slide-right.component.mjs +0 -134
  36. package/esm2022/lib/markup-kit/modals/slide-up/slide-up.component.mjs +0 -118
  37. package/esm2022/lib/markup-kit/page-layouts/central-page/central-page.component.mjs +0 -59
  38. package/esm2022/lib/markup-kit/page-layouts/central-page-row/central-page-row.component.mjs +0 -27
  39. package/esm2022/lib/markup-kit/page-layouts/index.mjs +0 -7
  40. package/esm2022/lib/markup-kit/page-layouts/manage-page/manage-page.component.mjs +0 -73
  41. package/esm2022/lib/markup-kit/page-layouts/page-layouts.module.mjs +0 -41
  42. package/esm2022/lib/markup-kit/page-layouts/profile/profile.component.mjs +0 -137
  43. package/esm2022/lib/markup-kit/page-layouts/table-page/table-page.component.mjs +0 -42
  44. package/esm2022/lib/markup-kit/slider/index.mjs +0 -3
  45. package/esm2022/lib/markup-kit/slider/slider/slider.component.mjs +0 -120
  46. package/esm2022/lib/markup-kit/slider/slider.module.mjs +0 -28
  47. package/esm2022/lib/markup-kit/utils/datepicker/datepicker/datepicker.component.mjs +0 -607
  48. package/esm2022/lib/markup-kit/utils/datepicker/datepicker.module.mjs +0 -21
  49. package/esm2022/lib/markup-kit/utils/datepicker/index.mjs +0 -3
  50. package/esm2022/lib/markup-kit/utils/filtered-field/filtered-field-container/filtered-field-container.component.mjs +0 -72
  51. package/esm2022/lib/markup-kit/utils/filtered-field/filtered-field-item/filtered-field-item.component.mjs +0 -71
  52. package/esm2022/lib/markup-kit/utils/filtered-field/filtered-field.module.mjs +0 -29
  53. package/esm2022/lib/markup-kit/utils/filtered-field/filtered-field.service.mjs +0 -43
  54. package/esm2022/lib/markup-kit/utils/filtered-field/filtred-item.model.mjs +0 -13
  55. package/esm2022/lib/markup-kit/utils/filtered-field/index.mjs +0 -6
  56. package/esm2022/lib/markup-kit/utils/help-block/help-block.component.mjs +0 -72
  57. package/esm2022/lib/markup-kit/utils/help-block/hepl-block.module.mjs +0 -24
  58. package/esm2022/lib/markup-kit/utils/help-block/index.mjs +0 -3
  59. package/esm2022/lib/pg-components/card/card.components.mjs +0 -442
  60. package/esm2022/lib/pg-components/card/card.module.mjs +0 -24
  61. package/esm2022/lib/pg-components/card/index.mjs +0 -3
  62. package/esm2022/lib/pg-components/progress/index.mjs +0 -4
  63. package/esm2022/lib/pg-components/progress/progress.component.mjs +0 -80
  64. package/esm2022/lib/pg-components/progress/progress.config.mjs +0 -12
  65. package/esm2022/lib/pg-components/progress/progress.module.mjs +0 -22
  66. package/esm2022/lib/pg-components/select/index.mjs +0 -5
  67. package/esm2022/lib/pg-components/select/option.component.mjs +0 -93
  68. package/esm2022/lib/pg-components/select/option.pipe.mjs +0 -42
  69. package/esm2022/lib/pg-components/select/select.component.mjs +0 -782
  70. package/esm2022/lib/pg-components/select/select.module.mjs +0 -22
  71. package/esm2022/lib/pg-components/spec-flow-test/index.mjs +0 -3
  72. package/esm2022/lib/pg-components/spec-flow-test/spec-flow-test/spec-flow-test.component.mjs +0 -36
  73. package/esm2022/lib/pg-components/spec-flow-test/spec-flow-test.module.mjs +0 -25
  74. package/esm2022/lib/pg-components/switch/index.mjs +0 -3
  75. package/esm2022/lib/pg-components/switch/switch.component.mjs +0 -293
  76. package/esm2022/lib/pg-components/switch/switch.module.mjs +0 -18
  77. package/esm2022/lib/pg-components/tabs/index.mjs +0 -8
  78. package/esm2022/lib/pg-components/tabs/tab-body.component.mjs +0 -21
  79. package/esm2022/lib/pg-components/tabs/tab-label.directive.mjs +0 -45
  80. package/esm2022/lib/pg-components/tabs/tab.component.mjs +0 -102
  81. package/esm2022/lib/pg-components/tabs/tabs-ink-bar.directive.mjs +0 -81
  82. package/esm2022/lib/pg-components/tabs/tabs-nav.component.mjs +0 -298
  83. package/esm2022/lib/pg-components/tabs/tabs.module.mjs +0 -23
  84. package/esm2022/lib/pg-components/tabs/tabset.component.mjs +0 -252
  85. package/esm2022/lib/pg-components/util/convert.mjs +0 -4
  86. package/esm2022/lib/pg-components/util/request-animation.mjs +0 -26
  87. package/esm2022/natec-mef-dev-ui-kit.mjs +0 -5
  88. package/esm2022/public-api.mjs +0 -17
  89. package/lib/markup-kit/card/card/card.component.d.ts +0 -90
  90. package/lib/markup-kit/card/card-long/card-long.component.d.ts +0 -135
  91. package/lib/markup-kit/card/card-long/cart-type-colors.enum.d.ts +0 -5
  92. package/lib/markup-kit/card/card-simple/card-simple.component.d.ts +0 -37
  93. package/lib/markup-kit/card/card.module.d.ts +0 -17
  94. package/lib/markup-kit/card/index.d.ts +0 -5
  95. package/lib/markup-kit/collapse/collapse/collapse.component.d.ts +0 -74
  96. package/lib/markup-kit/collapse/collapse-set/collapse-set.component.d.ts +0 -68
  97. package/lib/markup-kit/collapse/collapse.module.d.ts +0 -14
  98. package/lib/markup-kit/collapse/index.d.ts +0 -3
  99. package/lib/markup-kit/executors/index.d.ts +0 -4
  100. package/lib/markup-kit/executors/mefdev-executor-page/mefdev-executor-page.component.d.ts +0 -84
  101. package/lib/markup-kit/executors/stage/stage.component.d.ts +0 -12
  102. package/lib/markup-kit/executors/step-executor/step-executor.component.d.ts +0 -186
  103. package/lib/markup-kit/executors/step-executor.module.d.ts +0 -12
  104. package/lib/markup-kit/modals/fill/fill.component.d.ts +0 -80
  105. package/lib/markup-kit/modals/index.d.ts +0 -6
  106. package/lib/markup-kit/modals/markup-kit.module.d.ts +0 -12
  107. package/lib/markup-kit/modals/modal-size.enum.d.ts +0 -5
  108. package/lib/markup-kit/modals/right-filter/right-filter.component.d.ts +0 -27
  109. package/lib/markup-kit/modals/slide-right/slide-right.component.d.ts +0 -76
  110. package/lib/markup-kit/modals/slide-up/slide-up.component.d.ts +0 -64
  111. package/lib/markup-kit/page-layouts/central-page/central-page.component.d.ts +0 -37
  112. package/lib/markup-kit/page-layouts/central-page-row/central-page-row.component.d.ts +0 -21
  113. package/lib/markup-kit/page-layouts/index.d.ts +0 -6
  114. package/lib/markup-kit/page-layouts/manage-page/manage-page.component.d.ts +0 -58
  115. package/lib/markup-kit/page-layouts/page-layouts.module.d.ts +0 -12
  116. package/lib/markup-kit/page-layouts/profile/profile.component.d.ts +0 -107
  117. package/lib/markup-kit/page-layouts/table-page/table-page.component.d.ts +0 -32
  118. package/lib/markup-kit/slider/index.d.ts +0 -2
  119. package/lib/markup-kit/slider/slider/slider.component.d.ts +0 -93
  120. package/lib/markup-kit/slider/slider.module.d.ts +0 -9
  121. package/lib/markup-kit/utils/datepicker/datepicker/datepicker.component.d.ts +0 -421
  122. package/lib/markup-kit/utils/datepicker/datepicker.module.d.ts +0 -10
  123. package/lib/markup-kit/utils/datepicker/index.d.ts +0 -2
  124. package/lib/markup-kit/utils/filtered-field/filtered-field-container/filtered-field-container.component.d.ts +0 -42
  125. package/lib/markup-kit/utils/filtered-field/filtered-field-item/filtered-field-item.component.d.ts +0 -56
  126. package/lib/markup-kit/utils/filtered-field/filtered-field.module.d.ts +0 -9
  127. package/lib/markup-kit/utils/filtered-field/filtered-field.service.d.ts +0 -28
  128. package/lib/markup-kit/utils/filtered-field/filtred-item.model.d.ts +0 -7
  129. package/lib/markup-kit/utils/filtered-field/index.d.ts +0 -5
  130. package/lib/markup-kit/utils/help-block/help-block.component.d.ts +0 -37
  131. package/lib/markup-kit/utils/help-block/hepl-block.module.d.ts +0 -9
  132. package/lib/markup-kit/utils/help-block/index.d.ts +0 -2
  133. package/lib/pg-components/card/card.components.d.ts +0 -241
  134. package/lib/pg-components/card/card.module.d.ts +0 -11
  135. package/lib/pg-components/card/index.d.ts +0 -2
  136. package/lib/pg-components/progress/index.d.ts +0 -3
  137. package/lib/pg-components/progress/progress.component.d.ts +0 -50
  138. package/lib/pg-components/progress/progress.config.d.ts +0 -7
  139. package/lib/pg-components/progress/progress.module.d.ts +0 -10
  140. package/lib/pg-components/select/index.d.ts +0 -4
  141. package/lib/pg-components/select/option.component.d.ts +0 -54
  142. package/lib/pg-components/select/option.pipe.d.ts +0 -8
  143. package/lib/pg-components/select/select.component.d.ts +0 -139
  144. package/lib/pg-components/select/select.module.d.ts +0 -12
  145. package/lib/pg-components/spec-flow-test/index.d.ts +0 -2
  146. package/lib/pg-components/spec-flow-test/spec-flow-test/spec-flow-test.component.d.ts +0 -22
  147. package/lib/pg-components/spec-flow-test/spec-flow-test.module.d.ts +0 -10
  148. package/lib/pg-components/switch/index.d.ts +0 -2
  149. package/lib/pg-components/switch/switch.component.d.ts +0 -185
  150. package/lib/pg-components/switch/switch.module.d.ts +0 -8
  151. package/lib/pg-components/tabs/index.d.ts +0 -7
  152. package/lib/pg-components/tabs/tab-body.component.d.ts +0 -13
  153. package/lib/pg-components/tabs/tab-label.directive.d.ts +0 -15
  154. package/lib/pg-components/tabs/tab.component.d.ts +0 -67
  155. package/lib/pg-components/tabs/tabs-ink-bar.directive.d.ts +0 -23
  156. package/lib/pg-components/tabs/tabs-nav.component.d.ts +0 -79
  157. package/lib/pg-components/tabs/tabs.module.d.ts +0 -13
  158. package/lib/pg-components/tabs/tabset.component.d.ts +0 -137
  159. package/lib/pg-components/util/convert.d.ts +0 -1
  160. package/lib/pg-components/util/request-animation.d.ts +0 -1
  161. package/public-api.d.ts +0 -15
@@ -1,607 +0,0 @@
1
- import { Component, HostListener, Input, Output, EventEmitter, } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- import * as i1 from "@angular/common";
4
- import * as i2 from "@angular/forms";
5
- import * as i3 from "../../../../pg-components/select/option.component";
6
- import * as i4 from "../../../../pg-components/select/select.component";
7
- /**
8
- * Datepicker Component for selecting dates.
9
- *
10
- * This component allows users to pick a date from a calendar interface.
11
- * It supports various configuration options such as language, date format, and date range.
12
- *
13
- * @example
14
- * <mefdev-datepicker
15
- * [labelContentText]="'Select your date'"
16
- * [lang]="'uk'"
17
- * [dateFormat]="'dd/MM/yyyy'"
18
- * [range]="{startYear: 1900, toYear: 300}"
19
- * [disabled]="false"
20
- * (dateChanged)="onDateChanged($event)"
21
- * [topOffset]="'20'"
22
- * [leftOffset]="'10'">
23
- * </mefdev-datepicker>
24
- *
25
- * <example-url>https://platform.mef.dev/ui_kit_demo/view/utils/datepicker</example-url>
26
- */
27
- export class DatepickerComponent {
28
- datePipe;
29
- elementRef;
30
- /**
31
- * A flag that checks whether a valid date has been entered and whether the entered date exists.
32
- * If the two previous conditions are not true, the datepicker will be highlighted in red
33
- */
34
- isUserDateValid = true;
35
- /**
36
- * Flag to determine if the calendar is open or closed.
37
- * Default value: false (closed).
38
- */
39
- isCalendarOpen = false;
40
- /**
41
- * The currently selected date.
42
- * Default value: Today's date.
43
- */
44
- selectedDate = new Date();
45
- /**
46
- * The formatted date for display in the input.
47
- * Default value: Formatted representation of the selected date.
48
- */
49
- formattedDate;
50
- /**
51
- * Track the edited date separately when in editing mode.
52
- * Default value: An empty string.
53
- */
54
- editedDate = '';
55
- /**
56
- * Flag to determine if the month dropdown is open or closed.
57
- * Default value: true (open).
58
- */
59
- isMonthDropdownOpen = true;
60
- /**
61
- * Flag to determine if the year dropdown is open or closed.
62
- * Default value: true (open).
63
- */
64
- isYearDropdownOpen = true;
65
- /**
66
- * The selected month (0-11).
67
- * Default value: The month of the selected date.
68
- */
69
- selectedDateMonth = this.selectedDate.getMonth();
70
- /**
71
- * The selected year.
72
- * Default value: The year of the selected date.
73
- */
74
- selectedDateYear = this.selectedDate.getFullYear();
75
- /**
76
- * An array of years for the year dropdown.
77
- * Default value: An array of years within the specified range.
78
- */
79
- years;
80
- /**
81
- * Label text for the datepicker.
82
- * Default value: 'en' (English).
83
- * @example
84
- * <mefdev-datepicker
85
- * [labelContentText] = "'Chose your date'">
86
- * </mefdev-datepicker>
87
- */
88
- labelContentText;
89
- /**
90
- * The language/locale for the datepicker.
91
- * Default value: 'en' (English).
92
- * @example
93
- * <mefdev-datepicker
94
- * [lang] = "'uk'">
95
- * </mefdev-datepicker>
96
- */
97
- lang = 'en';
98
- /**
99
- * The date format for displaying the selected date.
100
- * Default value: 'EEE MMM dd yyyy'.
101
- * @example
102
- * <mefdev-datepicker
103
- * [dateFormat]="'dd/MM/yyyy'">
104
- * </mefdev-datepicker>
105
- */
106
- dateFormat = 'EEE MMM dd yyyy';
107
- /**
108
- * The range of years available in the year dropdown.
109
- * Default value: { startYear: 1900, toYear: 300 }.
110
- * @example
111
- * <mefdev-datepicker
112
- * [range]="{startYear: 1900, toYear: 300}">
113
- * </mefdev-datepicker>
114
- */
115
- yearsRange = { startYear: 1900, toYear: 300 };
116
- /**
117
- * Whether the datepicker is disabled or not.
118
- * Default value: false (enabled).
119
- * @example
120
- * <mefdev-datepicker
121
- * [disabled]="false">
122
- * </mefdev-datepicker>
123
- */
124
- disabled = false;
125
- /**
126
- * The top offset for positioning the datepicker.
127
- * Default value: '20'.
128
- * @example
129
- * <mefdev-datepicker
130
- * [topOffset]="'20'">
131
- * </mefdev-datepicker>
132
- */
133
- topOffset = '20';
134
- /**
135
- * The left offset for positioning the datepicker.
136
- * Default value: '10'.
137
- * @example
138
- * <mefdev-datepicker
139
- * [leftOffset]="'10'">
140
- * </mefdev-datepicker>
141
- */
142
- leftOffset = '10'; //Default value
143
- /**
144
- * Event emitted when the selected date in the datepicker changes.
145
- * It emits a `Date` object representing the selected date.
146
- * @example
147
- * <mefdev-datepicker
148
- * (dateChanged)="onDateChanged($event)">
149
- * </mefdev-datepicker>
150
- */
151
- dateChanged = new EventEmitter();
152
- /**
153
- * Regular expression to validate user input for date in the format "dd/MM/yyyy".
154
- * - The day (dd) should be between 01 and 31.
155
- * - The month (MM) should be between 01 and 12.
156
- * - The year (yyyy) should be a 4-digit number.
157
- */
158
- dateRegExp = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/;
159
- /**
160
- * The string entered by the user for date input.
161
- * This variable stores the user's input as they type in the date field.
162
- */
163
- userInput = '';
164
- /**
165
- * Host listener for document click events to handle calendar interaction.
166
- * This function checks if a click event occurred within the calendar or input elements.
167
- * - If the click occurred within the calendar, no action is taken.
168
- * - If the click occurred within the input element and the component is not in editing mode,
169
- * it opens the calendar.
170
- * @param event The MouseEvent object representing the click event.
171
- */
172
- onClick(event) {
173
- const targetElement = event.target;
174
- const datepickerContainer = this.elementRef.nativeElement.querySelector('.datepicker-container');
175
- const calendar = this.elementRef.nativeElement.querySelector('.calendar');
176
- const monthDropdown = this.elementRef.nativeElement.querySelector('.monthDropdown');
177
- const yearDropdown = this.elementRef.nativeElement.querySelector('.yearDropdown');
178
- const inputElement = this.elementRef.nativeElement.querySelector('input');
179
- if (datepickerContainer && datepickerContainer.contains(calendar)) {
180
- if (calendar && calendar.contains(targetElement))
181
- return;
182
- if (this.isMonthDropdownOpen && !calendar.contains(targetElement))
183
- return;
184
- if (this.isYearDropdownOpen && !calendar.contains(targetElement))
185
- return;
186
- if ((monthDropdown && monthDropdown.contains(targetElement)) && (yearDropdown && yearDropdown.contains(targetElement))) {
187
- this.toggleMonthDropdown(event);
188
- this.toggleYearDropdown(event);
189
- }
190
- }
191
- }
192
- /**
193
- * Constructor for the DatepickerComponent class.
194
- * @param datePipe A service for formatting and parsing dates.
195
- * @param elementRef A reference to the element on which this component is attached.
196
- * It is used to access DOM elements.
197
- */
198
- constructor(datePipe, elementRef) {
199
- this.datePipe = datePipe;
200
- this.elementRef = elementRef;
201
- this.updateInputValue();
202
- }
203
- /**
204
- * Lifecycle hook called after the component is initialized.
205
- * It initializes the years for the year select dropdown.
206
- */
207
- ngOnInit() {
208
- this.initializeYears();
209
- }
210
- /**
211
- * Lifecycle hook called whenever the input properties of the component change.
212
- * It updates the input value.
213
- */
214
- ngOnChanges() {
215
- this.updateInputValue();
216
- }
217
- /**
218
- * An array of month names based on the selected language.
219
- * It provides localized month names for display in the datepicker.
220
- */
221
- get months() {
222
- return this.getMonthList(this.lang);
223
- }
224
- /**
225
- * An array of weekday names based on the selected language.
226
- * It provides localized weekday names for display in the datepicker.
227
- */
228
- get weekdays() {
229
- return this.getWeekdayList(this.lang);
230
- }
231
- /**
232
- * Initialize the list of years to be displayed in the year dropdown.
233
- * This method populates the 'years' array with a range of years based on the provided 'yearsRange' configuration.
234
- * @example
235
- * ```
236
- * // Assuming 'yearsRange' is { startYear: 1900, toYear: 300 }
237
- * // After calling initializeYears(), 'years' might contain [1900, 1901, ..., 300]
238
- * this.initializeYears();
239
- * ```
240
- */
241
- initializeYears() {
242
- this.years = Array.from({ length: this.yearsRange.toYear }, (_, index) => index + this.yearsRange.startYear);
243
- }
244
- /**
245
- * Toggle the editing mode for the date input. When enabled, the user can edit the date directly in the input field.
246
- */
247
- toggleEdit() {
248
- this.editedDate = this.formatSelectedDate(); // Store the current formatted date for editing
249
- this.isCalendarOpen = false;
250
- }
251
- /**
252
- * Get a list of month names in the specified language and format.
253
- * @param locales - An optional parameter specifying the locale or locales to use for formatting.
254
- * @param format - The format for month names, either "long" (default) or "short".
255
- * @returns An array of month names based on the provided format and locale.
256
- * ```
257
- * // Get a list of month names in the default language and long format
258
- * const months = this.getMonthList(this.lang);
259
- * ```
260
- */
261
- getMonthList(locales, format = "long") {
262
- const year = new Date().getFullYear();
263
- const monthList = [...Array(12).keys()];
264
- const formatter = new Intl.DateTimeFormat(locales, { month: format });
265
- const getMonthName = (monthIndex) => formatter.format(new Date(year, monthIndex));
266
- return monthList.map(getMonthName);
267
- }
268
- /**
269
- * Get a list of weekday names in the specified language and format.
270
- * @param locales - An optional parameter specifying the locale or locales to use for formatting.
271
- * @param format - The format for weekday names, either "short" (default) or "long".
272
- * @returns An array of weekday names based on the provided format and locale.
273
- * ```
274
- * // Get a list of weekday names in the default language and short format
275
- * const weekdays = this.getWeekdayList();
276
- * ```
277
- */
278
- getWeekdayList(locales, format = "short") {
279
- const weekdays = [...Array(7).keys()];
280
- const mondayIndex = weekdays.indexOf(0);
281
- weekdays.splice(mondayIndex, 1);
282
- weekdays.push(0);
283
- const formatter = new Intl.DateTimeFormat(locales, { weekday: format });
284
- const getWeekdayName = (weekdayIndex) => {
285
- return formatter.format(new Date(2023, 9, weekdayIndex + 1));
286
- };
287
- return weekdays.map(getWeekdayName);
288
- }
289
- /**
290
- * Save the edited date input by the user, provided it matches the specified date format.
291
- * This method checks if the entered date is in a valid format, disables the editing mode, and applies
292
- * the edited date to the 'selectedDate'. It then reformats the selected date and closes the calendar.
293
- * ```
294
- * // Save the edited date and update the selected date
295
- * this.saveEditedDate();
296
- * ```
297
- */
298
- saveEditedDate() {
299
- if (this.isDateValid(this.editedDate)) {
300
- const [day, month, year] = this.editedDate.split('/');
301
- this.selectedDate = new Date(+year, +month - 1, +day);
302
- this.formatDate();
303
- }
304
- }
305
- /**
306
- * Handle user input in the editable input field for date editing. This method captures the input value
307
- * and stores it in the 'editedDate' variable. If the input matches the valid date format, it updates
308
- * 'selectedDateMonth' and 'selectedDateYear' accordingly.
309
- * @param event - The input event containing the user's input.
310
- * ```
311
- * // Handle user input in the editable input field
312
- * this.onDateInput(event);
313
- * ```
314
- */
315
- onDateInput(event) {
316
- const inputDate = event.target.value;
317
- if (this.isDateValid(inputDate)) {
318
- this.editedDate = inputDate;
319
- const parsedDate = inputDate.split('/');
320
- this.selectedDateMonth = +parsedDate[1] - 1;
321
- this.selectedDateYear = +parsedDate[2];
322
- this.selectedDate = new Date(+parsedDate[2], +parsedDate[1] - 1, +parsedDate[0]);
323
- this.calculateFirstDayOfCalendar();
324
- }
325
- this.isUserDateValid = this.isDateValid(inputDate);
326
- }
327
- /**
328
- * Toggle the visibility of the month dropdown in the calendar interface.
329
- * This method is used to open or close the dropdown for selecting months.
330
- * @param event - The event triggering the toggle action (e.g., a click event).
331
- * ```
332
- * // Toggle the visibility of the month dropdown
333
- * this.toggleMonthDropdown(event);
334
- * ```
335
- */
336
- toggleMonthDropdown(event) {
337
- this.isMonthDropdownOpen = !this.isMonthDropdownOpen;
338
- }
339
- /**
340
- * Toggle the visibility of the year dropdown in the calendar interface.
341
- * This method is used to open or close the dropdown for selecting years.
342
- * @param event - The event triggering the toggle action (e.g., a click event).
343
- * ```
344
- * // Toggle the visibility of the year dropdown
345
- * this.toggleYearDropdown(event);
346
- * ```
347
- */
348
- toggleYearDropdown(event) {
349
- this.isYearDropdownOpen = !this.isYearDropdownOpen;
350
- }
351
- /**
352
- * Handle the change of the selected month in the calendar interface.
353
- * This method updates the input value, sets the selected date to the first day of the chosen month,
354
- * and recalculates the calendar display accordingly.
355
- * ```
356
- * // Handle the change of the selected month
357
- * this.onMonthChange();
358
- * ```
359
- */
360
- onMonthChange() {
361
- this.updateInputValue();
362
- this.selectedDate = new Date(this.selectedDateYear, this.selectedDateMonth, 1);
363
- this.formatDate();
364
- this.calculateFirstDayOfCalendar();
365
- }
366
- /**
367
- * Handle the change of the selected year in the calendar interface.
368
- * This method updates the input value, sets the selected date to the first day of the chosen year,
369
- * reformats the selected date, and recalculates the calendar display.
370
- * ```
371
- * // Handle the change of the selected year
372
- * this.onYearChange();
373
- * ```
374
- */
375
- onYearChange() {
376
- this.updateInputValue();
377
- this.selectedDate = new Date(this.selectedDateYear, this.selectedDateMonth, 1);
378
- this.formatDate();
379
- this.calculateFirstDayOfCalendar();
380
- }
381
- /**
382
- * Select a date in the calendar interface and perform necessary updates.
383
- * This method sets the selected date, formats it, closes the calendar, and emits a dateChanged event.
384
- * It also updates the selected month and year dropdown values.
385
- * @param date - The date to be selected in the calendar.
386
- */
387
- selectDate(date) {
388
- this.selectedDate = date;
389
- this.formatDate();
390
- this.isCalendarOpen = false;
391
- this.dateChanged.next(this.selectedDate);
392
- this.selectedDateMonth = this.selectedDate.getMonth();
393
- this.selectedDateYear = this.selectedDate.getFullYear();
394
- }
395
- /**
396
- * Format the selected date based on the chosen date format and language.
397
- * This method uses the Angular DatePipe to format the selected date and updates the formattedDate variable.
398
- * ```
399
- * // Format the selected date
400
- * this.formatDate();
401
- * ```
402
- */
403
- formatDate() {
404
- this.formattedDate = this.datePipe.transform(this.selectedDate, this.dateFormat) || '';
405
- }
406
- /**
407
- * Format the selected date based on the chosen date format, language, and locale.
408
- * This method uses the Angular DatePipe to format the selected date with the specified language and updates the formatted date as a string.
409
- * @returns A formatted date string.
410
- * ```
411
- * // Format the selected date with language
412
- * const formatted = this.formatSelectedDate();
413
- * ```
414
- */
415
- formatSelectedDate() {
416
- return this.datePipe.transform(this.selectedDate, this.dateFormat, this.lang) || '';
417
- }
418
- /**
419
- * Update the input value displayed in the calendar interface.
420
- * This method updates the input value to either the edited date or the formatted selected date,
421
- * depending on whether the user is in edit mode or not.
422
- * ```
423
- * // Update the input value
424
- * this.updateInputValue();
425
- * ```
426
- */
427
- updateInputValue() {
428
- this.formattedDate = this.isCalendarOpen ? this.editedDate : this.formatSelectedDate();
429
- }
430
- /**
431
- * Get an array of arrays representing the days of the current month.
432
- * Each sub-array contains the day data for a week, and each day data object includes the date and whether it belongs to the current month.
433
- * @returns An array of arrays representing the days of the current month.
434
- * ```
435
- * // Get an array of arrays representing the days of the current month
436
- * const calendar = this.calendarDays;
437
- * ```
438
- */
439
- get calendarDays() {
440
- return this.calculateFirstDayOfCalendar();
441
- }
442
- /**
443
- * Get the date of the previous month to display in empty cells of the current month.
444
- * This method returns the date of the previous month if the provided date is not in the current month.
445
- * If the provided date is in the current month, it returns the date's day as a string.
446
- * @param date - The date to evaluate.
447
- * @returns The date of the previous month or a day string.
448
- * ```
449
- * // Get the previous month's date to display in empty cells
450
- * const previousMonthDate = this.getPreviousMonthDate(new Date(2023, 8, 1));
451
- * ```
452
- */
453
- getPreviousMonthDate(date) {
454
- if (!date) {
455
- return '';
456
- }
457
- const currentDate = new Date();
458
- if (date.getMonth() === currentDate.getMonth() && date.getFullYear() === currentDate.getFullYear()) {
459
- return date.getDate().toString();
460
- }
461
- else {
462
- return this.datePipe.transform(date, 'dd');
463
- }
464
- }
465
- /**
466
- * Navigate to the previous month in the calendar interface.
467
- * This method updates the selectedDate, formats it, and recalculates the first day of the calendar.
468
- * ```
469
- * // Navigate to the previous month
470
- * this.getPreviousMonth();
471
- * ```
472
- */
473
- getPreviousMonth() {
474
- const currentMonth = this.selectedDate.getMonth();
475
- this.selectedDate = new Date(this.selectedDate.getFullYear(), currentMonth - 1, 1);
476
- this.formatDate();
477
- this.calculateFirstDayOfCalendar();
478
- }
479
- /**
480
- * Navigate to the next month in the calendar interface.
481
- * This method updates the selectedDate, formats it, and recalculates the first day of the calendar.
482
- * ```
483
- * // Navigate to the next month
484
- * this.getNextMonth();
485
- * ```
486
- */
487
- getNextMonth() {
488
- const currentMonth = this.selectedDate.getMonth();
489
- this.selectedDate = new Date(this.selectedDate.getFullYear(), currentMonth + 1, 1);
490
- this.formatDate();
491
- this.calculateFirstDayOfCalendar();
492
- }
493
- /**
494
- * Get the number of days in a given month of a specific year.
495
- * @param year - The year for which you want to determine the number of days.
496
- * @param month - The month (0-based index) for which you want to determine the number of days.
497
- * @returns The number of days in the specified month of the given year.
498
- */
499
- daysInMonth(year, month) {
500
- return new Date(year, month + 1, 0).getDate();
501
- }
502
- /**
503
- * Calculate the structure of days in a month for the calendar display.
504
- * This method generates a matrix of day data objects representing the days in the calendar.
505
- * Each day data object contains the date and whether it belongs to the current month.
506
- * @returns A matrix of day data objects for the calendar display.
507
- */
508
- calculateFirstDayOfCalendar() {
509
- const year = this.selectedDate.getFullYear();
510
- const month = this.selectedDate.getMonth();
511
- const firstDayOfMonth = new Date(year, month, 1);
512
- const firstWeekday = firstDayOfMonth.getDay();
513
- const startDay = firstWeekday === 0 ? -5 : 2 - firstWeekday;
514
- const calendarDays = [];
515
- let currentDay = startDay;
516
- for (let i = 0; i < 6; i++) {
517
- const week = [];
518
- for (let j = 0; j < 7; j++) {
519
- const day = new Date(year, month, currentDay);
520
- const dayData = {
521
- date: day,
522
- isCurrentMonth: currentDay >= 1 && currentDay <= this.daysInMonth(year, month),
523
- };
524
- week.push(dayData);
525
- currentDay++;
526
- }
527
- calendarDays.push(week);
528
- }
529
- return calendarDays;
530
- }
531
- /**
532
- * Check if a given date is the currently selected date in the calendar.
533
- * @param date - The date to check.
534
- * @returns `true` if the provided date matches the selected date, otherwise `false`.
535
- * ```
536
- * // Check if a date is selected
537
- * const isSelected = this.isDateSelected(someDate);
538
- * ```
539
- */
540
- isDateSelected(date) {
541
- return date.toDateString() === this.selectedDate.toDateString();
542
- }
543
- /**
544
- * Check if a date string is valid based on the specified date format.
545
- * It also checks whether the specified number, month is correct and whether the specified one exists among calendar years
546
- * @param inputDate - The date string to validate.
547
- * @returns `true` if the input date string is valid, otherwise `false`.
548
- * ```
549
- * // Check if a date string is valid
550
- * const isValidDate = this.isDateValid('05/25/2023');
551
- * ```
552
- */
553
- isDateValid(inputDate) {
554
- if (!this.dateRegExp.test(inputDate)) {
555
- return false;
556
- }
557
- const parts = inputDate.split('/');
558
- const day = parseInt(parts[0], 10);
559
- const month = parseInt(parts[1], 10);
560
- const year = parseInt(parts[2], 10);
561
- if (year > this.years[this.years.length - 1] || year < this.years[0]) {
562
- return false;
563
- }
564
- const daysInMonth = new Date(year, month, 0).getDate();
565
- return day <= daysInMonth;
566
- }
567
- /**
568
- * Check if a given date is today's date.
569
- * @param date - The date to check.
570
- * @returns `true` if the provided date is today's date, otherwise `false`.
571
- * ```
572
- * // Check if a date is today's date
573
- * const isToday = this.isDateToday(someDate);
574
- * ```
575
- */
576
- isDateToday(date) {
577
- const today = new Date();
578
- return date.toDateString() === today.toDateString();
579
- }
580
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DatepickerComponent, deps: [{ token: i1.DatePipe }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
581
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DatepickerComponent, selector: "mefdev-datepicker", inputs: { labelContentText: "labelContentText", lang: "lang", dateFormat: "dateFormat", yearsRange: ["range", "yearsRange"], disabled: "disabled", topOffset: "topOffset", leftOffset: "leftOffset" }, outputs: { dateChanged: "dateChanged" }, host: { listeners: { "document:click": "onClick($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"datepicker-container\" [class.disabled]=\"disabled\">\r\n\r\n <!-- Input, save & edit buttons -->\r\n <div class=\"input-container form-group\">\r\n <label *ngIf=\"labelContentText\" class=\"form-label\"> {{ labelContentText }} </label>\r\n <input\r\n [ngClass]=\"{ 'calendarNotOpened': !isCalendarOpen }\"\r\n [ngStyle]=\"{ 'border-color': isUserDateValid ? '' : 'red' }\"\r\n type=\"text\"\r\n class=\"form-control\"\r\n (input)=\"onDateInput($event)\"\r\n (click)=\"isCalendarOpen = true\"\r\n [value]=\"formattedDate\"\r\n [readOnly]=\"!isCalendarOpen\"\r\n >\r\n </div>\r\n\r\n <!-- Calendar(Dropdowns, dates) -->\r\n <div *ngIf=\"isCalendarOpen\" class=\"calendar\" #calendarContainer\r\n [style.top]=\"topOffset\"\r\n [style.left]=\"leftOffset\">\r\n <div class=\"calendar-header\">\r\n <div class=\"monthButtonContainer\">\r\n <!-- Month dropdown -->\r\n <ng-container *ngIf=\"isMonthDropdownOpen; else monthLabel\">\r\n <mefdev-select\r\n class=\"monthDropdown\"\r\n [(ngModel)]=\"selectedDateMonth\"\r\n (ngModelChange)=\"onMonthChange()\"\r\n [PlaceHolder]=\"'month'\"\r\n >\r\n <mefdev-option\r\n *ngFor=\"let month of months; let i = index\"\r\n [Value]=\"i\"\r\n [Label]=\"month\"\r\n style=\"z-index: 1\"\r\n >{{ month }}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #monthLabel>\r\n <span (click)=\"toggleMonthDropdown($event)\"></span>\r\n </ng-template>\r\n\r\n <!-- Year dropdown -->\r\n <ng-container *ngIf=\"isYearDropdownOpen; else yearLabel\">\r\n <mefdev-select\r\n class=\"yearDropdown\"\r\n [(ngModel)]=\"selectedDateYear\"\r\n (ngModelChange)=\"onYearChange()\"\r\n [PlaceHolder]=\"'year'\"\r\n >\r\n <mefdev-option\r\n *ngFor=\"let year of years\"\r\n [Label]=\"year\"\r\n [Value]=\"year\"\r\n >{{year}}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #yearLabel>\r\n <span (click)=\"toggleYearDropdown($event)\">{{ selectedDateYear }}</span>\r\n </ng-template>\r\n </div>\r\n <!-- Calendar exit button -->\r\n <div>\r\n <i class=\"fa fa-times toggleCalendarButton\" (click)=\"isCalendarOpen = false\" aria-hidden=\"true\"></i>\r\n </div>\r\n </div>\r\n\r\n <div class=\"calendar-body\">\r\n <table>\r\n <tr>\r\n <th class=\"text-center\" *ngFor=\"let weekday of weekdays\">{{ weekday }}</th>\r\n </tr>\r\n <tr *ngFor=\"let week of calendarDays\">\r\n <td *ngFor=\"let dayData of week\"\r\n (click)=\"selectDate(dayData.date)\"\r\n [ngClass]=\"{ 'selected': isDateSelected(dayData.date), 'prev-month': !dayData.isCurrentMonth }\">\r\n\r\n <span class=\"date\" [class.prev-month]=\"!dayData.isCurrentMonth\">\r\n {{ dayData.date.getDate() }}\r\n </span>\r\n </td>\r\n </tr>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".color-black{color:#000!important}.color-Dark-Gray-1{color:#373737!important}.color-Dark-Gray-2{color:#4d4d4d!important}.color-Red{color:#cf0106!important}.color-Green{color:#28b446!important}.color-Light-Gray-1{color:#929292!important}.color-Light-Gray-2{color:#eaeaea!important}.color-Light-Gray-3{color:#f3f3f3!important}.color-White{color:#fff!important}.color-Link{color:#0185cf!important}.color-dark-link{color:#50c0ff!important}.b-color-black{background-color:#000!important}.b-color-Dark-Gray-1{background-color:#373737!important}.b-color-Dark-Gray-2{background-color:#4d4d4d!important}.b-color-Red{background-color:#cf0106!important}.b-color-Green{background-color:#28b446!important}.b-color-Light-Gray-1{background-color:#929292!important}.b-color-Light-Gray-2{background-color:#eaeaea!important}.b-color-Light-Gray-3{background-color:#f3f3f3!important}.b-color-White{background-color:#fff!important}.b-color-Link{background-color:#0185cf!important}.b-color-dark-link{background-color:#50c0ff!important}.datepicker-container{position:relative;display:inline-block}.datepicker-container.disabled{pointer-events:none;opacity:.8}.input-container{position:relative;display:inline-block}.input-container input[type=text]{padding:5px 5px 5px 15px;border:1px solid #929292}.input-container .calendarNotOpened{cursor:pointer}.calendar{position:absolute;border:1px solid #929292;background-color:#eaeaea;z-index:1}.calendar .calendar-header{background-color:#fff;text-align:center;justify-content:space-between;display:flex;padding:5px 0}.calendar .calendar-header i.fa{display:flex;justify-content:center;align-items:center;width:30px;height:30px;font-size:20px;border-radius:50%;cursor:pointer;background-color:transparent;border:none;color:#cf0106}.calendar .calendar-header .monthButtonContainer{padding-left:10px;height:45px;min-width:140px;display:flex;align-items:center}.calendar .calendar-header .monthDropdown,.calendar .calendar-header .yearDropdown{height:45px;width:105px;cursor:pointer;display:inline-block;padding:6px 5px;border:1px solid #EAEAEA;border-radius:4px;background-color:#fff;color:#4d4d4d}.calendar .calendar-header .monthDropdown{margin:0 8px 0 0;width:130px}.calendar .calendar-header .monthDropdown:hover,.calendar .calendar-header .yearDropdown:hover{border-color:#f3f3f3}.calendar .calendar-body{padding:5px}.calendar .calendar-body table{width:100%}.calendar .calendar-body td{padding:10px;position:relative}.calendar .calendar-body td.selected{position:relative;color:#fff}.calendar .calendar-body td.selected:before{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);border-radius:20%;background-color:#cf0106;z-index:-1;width:30px;height:30px;color:#fff;border:1px solid #373737}.calendar .calendar-body td:hover{color:#fff;font-weight:700;background-color:#929292;border-radius:20%;cursor:pointer}.calendar .calendar-body .date{display:flex;justify-content:center}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MefDevOptionComponent, selector: "mefdev-option", inputs: ["Value", "Label", "Disabled"] }, { kind: "component", type: i4.MefDevSelectComponent, selector: "mefdev-select", inputs: ["Filter", "MaxMultiple", "FirstDefault", "AllowClear", "KeepUnListOptions", "Mode", "Multiple", "PlaceHolder", "NotFoundContent", "Size", "ShowSearch", "Tags", "Disabled", "Open"], outputs: ["SearchChange", "change", "OpenChange", "ScrollToBottom"] }] });
582
- }
583
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DatepickerComponent, decorators: [{
584
- type: Component,
585
- args: [{ selector: 'mefdev-datepicker', template: "<div class=\"datepicker-container\" [class.disabled]=\"disabled\">\r\n\r\n <!-- Input, save & edit buttons -->\r\n <div class=\"input-container form-group\">\r\n <label *ngIf=\"labelContentText\" class=\"form-label\"> {{ labelContentText }} </label>\r\n <input\r\n [ngClass]=\"{ 'calendarNotOpened': !isCalendarOpen }\"\r\n [ngStyle]=\"{ 'border-color': isUserDateValid ? '' : 'red' }\"\r\n type=\"text\"\r\n class=\"form-control\"\r\n (input)=\"onDateInput($event)\"\r\n (click)=\"isCalendarOpen = true\"\r\n [value]=\"formattedDate\"\r\n [readOnly]=\"!isCalendarOpen\"\r\n >\r\n </div>\r\n\r\n <!-- Calendar(Dropdowns, dates) -->\r\n <div *ngIf=\"isCalendarOpen\" class=\"calendar\" #calendarContainer\r\n [style.top]=\"topOffset\"\r\n [style.left]=\"leftOffset\">\r\n <div class=\"calendar-header\">\r\n <div class=\"monthButtonContainer\">\r\n <!-- Month dropdown -->\r\n <ng-container *ngIf=\"isMonthDropdownOpen; else monthLabel\">\r\n <mefdev-select\r\n class=\"monthDropdown\"\r\n [(ngModel)]=\"selectedDateMonth\"\r\n (ngModelChange)=\"onMonthChange()\"\r\n [PlaceHolder]=\"'month'\"\r\n >\r\n <mefdev-option\r\n *ngFor=\"let month of months; let i = index\"\r\n [Value]=\"i\"\r\n [Label]=\"month\"\r\n style=\"z-index: 1\"\r\n >{{ month }}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #monthLabel>\r\n <span (click)=\"toggleMonthDropdown($event)\"></span>\r\n </ng-template>\r\n\r\n <!-- Year dropdown -->\r\n <ng-container *ngIf=\"isYearDropdownOpen; else yearLabel\">\r\n <mefdev-select\r\n class=\"yearDropdown\"\r\n [(ngModel)]=\"selectedDateYear\"\r\n (ngModelChange)=\"onYearChange()\"\r\n [PlaceHolder]=\"'year'\"\r\n >\r\n <mefdev-option\r\n *ngFor=\"let year of years\"\r\n [Label]=\"year\"\r\n [Value]=\"year\"\r\n >{{year}}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #yearLabel>\r\n <span (click)=\"toggleYearDropdown($event)\">{{ selectedDateYear }}</span>\r\n </ng-template>\r\n </div>\r\n <!-- Calendar exit button -->\r\n <div>\r\n <i class=\"fa fa-times toggleCalendarButton\" (click)=\"isCalendarOpen = false\" aria-hidden=\"true\"></i>\r\n </div>\r\n </div>\r\n\r\n <div class=\"calendar-body\">\r\n <table>\r\n <tr>\r\n <th class=\"text-center\" *ngFor=\"let weekday of weekdays\">{{ weekday }}</th>\r\n </tr>\r\n <tr *ngFor=\"let week of calendarDays\">\r\n <td *ngFor=\"let dayData of week\"\r\n (click)=\"selectDate(dayData.date)\"\r\n [ngClass]=\"{ 'selected': isDateSelected(dayData.date), 'prev-month': !dayData.isCurrentMonth }\">\r\n\r\n <span class=\"date\" [class.prev-month]=\"!dayData.isCurrentMonth\">\r\n {{ dayData.date.getDate() }}\r\n </span>\r\n </td>\r\n </tr>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".color-black{color:#000!important}.color-Dark-Gray-1{color:#373737!important}.color-Dark-Gray-2{color:#4d4d4d!important}.color-Red{color:#cf0106!important}.color-Green{color:#28b446!important}.color-Light-Gray-1{color:#929292!important}.color-Light-Gray-2{color:#eaeaea!important}.color-Light-Gray-3{color:#f3f3f3!important}.color-White{color:#fff!important}.color-Link{color:#0185cf!important}.color-dark-link{color:#50c0ff!important}.b-color-black{background-color:#000!important}.b-color-Dark-Gray-1{background-color:#373737!important}.b-color-Dark-Gray-2{background-color:#4d4d4d!important}.b-color-Red{background-color:#cf0106!important}.b-color-Green{background-color:#28b446!important}.b-color-Light-Gray-1{background-color:#929292!important}.b-color-Light-Gray-2{background-color:#eaeaea!important}.b-color-Light-Gray-3{background-color:#f3f3f3!important}.b-color-White{background-color:#fff!important}.b-color-Link{background-color:#0185cf!important}.b-color-dark-link{background-color:#50c0ff!important}.datepicker-container{position:relative;display:inline-block}.datepicker-container.disabled{pointer-events:none;opacity:.8}.input-container{position:relative;display:inline-block}.input-container input[type=text]{padding:5px 5px 5px 15px;border:1px solid #929292}.input-container .calendarNotOpened{cursor:pointer}.calendar{position:absolute;border:1px solid #929292;background-color:#eaeaea;z-index:1}.calendar .calendar-header{background-color:#fff;text-align:center;justify-content:space-between;display:flex;padding:5px 0}.calendar .calendar-header i.fa{display:flex;justify-content:center;align-items:center;width:30px;height:30px;font-size:20px;border-radius:50%;cursor:pointer;background-color:transparent;border:none;color:#cf0106}.calendar .calendar-header .monthButtonContainer{padding-left:10px;height:45px;min-width:140px;display:flex;align-items:center}.calendar .calendar-header .monthDropdown,.calendar .calendar-header .yearDropdown{height:45px;width:105px;cursor:pointer;display:inline-block;padding:6px 5px;border:1px solid #EAEAEA;border-radius:4px;background-color:#fff;color:#4d4d4d}.calendar .calendar-header .monthDropdown{margin:0 8px 0 0;width:130px}.calendar .calendar-header .monthDropdown:hover,.calendar .calendar-header .yearDropdown:hover{border-color:#f3f3f3}.calendar .calendar-body{padding:5px}.calendar .calendar-body table{width:100%}.calendar .calendar-body td{padding:10px;position:relative}.calendar .calendar-body td.selected{position:relative;color:#fff}.calendar .calendar-body td.selected:before{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);border-radius:20%;background-color:#cf0106;z-index:-1;width:30px;height:30px;color:#fff;border:1px solid #373737}.calendar .calendar-body td:hover{color:#fff;font-weight:700;background-color:#929292;border-radius:20%;cursor:pointer}.calendar .calendar-body .date{display:flex;justify-content:center}\n"] }]
586
- }], ctorParameters: function () { return [{ type: i1.DatePipe }, { type: i0.ElementRef }]; }, propDecorators: { labelContentText: [{
587
- type: Input
588
- }], lang: [{
589
- type: Input
590
- }], dateFormat: [{
591
- type: Input
592
- }], yearsRange: [{
593
- type: Input,
594
- args: ['range']
595
- }], disabled: [{
596
- type: Input
597
- }], topOffset: [{
598
- type: Input
599
- }], leftOffset: [{
600
- type: Input
601
- }], dateChanged: [{
602
- type: Output
603
- }], onClick: [{
604
- type: HostListener,
605
- args: ['document:click', ['$event']]
606
- }] } });
607
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS1raXQtbGliL3NyYy9saWIvbWFya3VwLWtpdC91dGlscy9kYXRlcGlja2VyL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS1raXQtbGliL3NyYy9saWIvbWFya3VwLWtpdC91dGlscy9kYXRlcGlja2VyL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFlBQVksR0FDYixNQUFNLGVBQWUsQ0FBQzs7Ozs7O0FBR3ZCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBUUgsTUFBTSxPQUFPLG1CQUFtQjtJQThMVjtJQUE0QjtJQTVMaEQ7OztPQUdHO0lBQ0gsZUFBZSxHQUFZLElBQUksQ0FBQztJQUVoQzs7O09BR0c7SUFDSCxjQUFjLEdBQVksS0FBSyxDQUFDO0lBRWhDOzs7T0FHRztJQUNILFlBQVksR0FBUyxJQUFJLElBQUksRUFBRSxDQUFDO0lBRWhDOzs7T0FHRztJQUNILGFBQWEsQ0FBTztJQUVwQjs7O09BR0c7SUFDSCxVQUFVLEdBQVcsRUFBRSxDQUFDO0lBRXhCOzs7T0FHRztJQUNILG1CQUFtQixHQUFZLElBQUksQ0FBQztJQUVwQzs7O09BR0c7SUFDSCxrQkFBa0IsR0FBWSxJQUFJLENBQUM7SUFFbkM7OztPQUdHO0lBQ0gsaUJBQWlCLEdBQVcsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUV6RDs7O09BR0c7SUFDSCxnQkFBZ0IsR0FBVyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRTNEOzs7T0FHRztJQUNI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O3NCQUFwQixNQUFNO2dCQXlCUCxPQUFPO3NCQUROLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBJbnB1dCxcclxuICBPbkNoYW5nZXMsXHJcbiAgT25Jbml0LFxyXG4gIE91dHB1dCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERhdGVQaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuXHJcbi8qKlxyXG4gKiBEYXRlcGlja2VyIENvbXBvbmVudCBmb3Igc2VsZWN0aW5nIGRhdGVzLlxyXG4gKlxyXG4gKiBUaGlzIGNvbXBvbmVudCBhbGxvd3MgdXNlcnMgdG8gcGljayBhIGRhdGUgZnJvbSBhIGNhbGVuZGFyIGludGVyZmFjZS5cclxuICogSXQgc3VwcG9ydHMgdmFyaW91cyBjb25maWd1cmF0aW9uIG9wdGlvbnMgc3VjaCBhcyBsYW5ndWFnZSwgZGF0ZSBmb3JtYXQsIGFuZCBkYXRlIHJhbmdlLlxyXG4gKlxyXG4gKiBAZXhhbXBsZVxyXG4gKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICogICBbbGFiZWxDb250ZW50VGV4dF09XCInU2VsZWN0IHlvdXIgZGF0ZSdcIlxyXG4gKiAgIFtsYW5nXT1cIid1aydcIlxyXG4gKiAgIFtkYXRlRm9ybWF0XT1cIidkZC9NTS95eXl5J1wiXHJcbiAqICAgW3JhbmdlXT1cIntzdGFydFllYXI6IDE5MDAsIHRvWWVhcjogMzAwfVwiXHJcbiAqICAgW2Rpc2FibGVkXT1cImZhbHNlXCJcclxuICogICAoZGF0ZUNoYW5nZWQpPVwib25EYXRlQ2hhbmdlZCgkZXZlbnQpXCJcclxuICogICBbdG9wT2Zmc2V0XT1cIicyMCdcIlxyXG4gKiAgIFtsZWZ0T2Zmc2V0XT1cIicxMCdcIj5cclxuICogPC9tZWZkZXYtZGF0ZXBpY2tlcj5cclxuICpcclxuICogPGV4YW1wbGUtdXJsPmh0dHBzOi8vcGxhdGZvcm0ubWVmLmRldi91aV9raXRfZGVtby92aWV3L3V0aWxzL2RhdGVwaWNrZXI8L2V4YW1wbGUtdXJsPlxyXG4gKi9cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbWVmZGV2LWRhdGVwaWNrZXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRlcGlja2VyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9kYXRlcGlja2VyLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBEYXRlcGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgIE9uQ2hhbmdlcywgT25Jbml0IHtcclxuXHJcbiAgLyoqXHJcbiAgICogQSBmbGFnIHRoYXQgY2hlY2tzIHdoZXRoZXIgYSB2YWxpZCBkYXRlIGhhcyBiZWVuIGVudGVyZWQgYW5kIHdoZXRoZXIgdGhlIGVudGVyZWQgZGF0ZSBleGlzdHMuXHJcbiAgICogSWYgdGhlIHR3byBwcmV2aW91cyBjb25kaXRpb25zIGFyZSBub3QgdHJ1ZSwgdGhlIGRhdGVwaWNrZXIgd2lsbCBiZSBoaWdobGlnaHRlZCBpbiByZWRcclxuICAgKi9cclxuICBpc1VzZXJEYXRlVmFsaWQ6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBGbGFnIHRvIGRldGVybWluZSBpZiB0aGUgY2FsZW5kYXIgaXMgb3BlbiBvciBjbG9zZWQuXHJcbiAgICogRGVmYXVsdCB2YWx1ZTogZmFsc2UgKGNsb3NlZCkuXHJcbiAgICovXHJcbiAgaXNDYWxlbmRhck9wZW46IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGN1cnJlbnRseSBzZWxlY3RlZCBkYXRlLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6IFRvZGF5J3MgZGF0ZS5cclxuICAgKi9cclxuICBzZWxlY3RlZERhdGU6IERhdGUgPSBuZXcgRGF0ZSgpO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgZm9ybWF0dGVkIGRhdGUgZm9yIGRpc3BsYXkgaW4gdGhlIGlucHV0LlxyXG4gICAqIERlZmF1bHQgdmFsdWU6IEZvcm1hdHRlZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgc2VsZWN0ZWQgZGF0ZS5cclxuICAgKi9cclxuICBmb3JtYXR0ZWREYXRlOiBhbnkgO1xyXG5cclxuICAvKipcclxuICAgKiBUcmFjayB0aGUgZWRpdGVkIGRhdGUgc2VwYXJhdGVseSB3aGVuIGluIGVkaXRpbmcgbW9kZS5cclxuICAgKiBEZWZhdWx0IHZhbHVlOiBBbiBlbXB0eSBzdHJpbmcuXHJcbiAgICovXHJcbiAgZWRpdGVkRGF0ZTogc3RyaW5nID0gJyc7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZsYWcgdG8gZGV0ZXJtaW5lIGlmIHRoZSBtb250aCBkcm9wZG93biBpcyBvcGVuIG9yIGNsb3NlZC5cclxuICAgKiBEZWZhdWx0IHZhbHVlOiB0cnVlIChvcGVuKS5cclxuICAgKi9cclxuICBpc01vbnRoRHJvcGRvd25PcGVuOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogRmxhZyB0byBkZXRlcm1pbmUgaWYgdGhlIHllYXIgZHJvcGRvd24gaXMgb3BlbiBvciBjbG9zZWQuXHJcbiAgICogRGVmYXVsdCB2YWx1ZTogdHJ1ZSAob3BlbikuXHJcbiAgICovXHJcbiAgaXNZZWFyRHJvcGRvd25PcGVuOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIHNlbGVjdGVkIG1vbnRoICgwLTExKS5cclxuICAgKiBEZWZhdWx0IHZhbHVlOiBUaGUgbW9udGggb2YgdGhlIHNlbGVjdGVkIGRhdGUuXHJcbiAgICovXHJcbiAgc2VsZWN0ZWREYXRlTW9udGg6IG51bWJlciA9IHRoaXMuc2VsZWN0ZWREYXRlLmdldE1vbnRoKCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBzZWxlY3RlZCB5ZWFyLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6IFRoZSB5ZWFyIG9mIHRoZSBzZWxlY3RlZCBkYXRlLlxyXG4gICAqL1xyXG4gIHNlbGVjdGVkRGF0ZVllYXI6IG51bWJlciA9IHRoaXMuc2VsZWN0ZWREYXRlLmdldEZ1bGxZZWFyKCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEFuIGFycmF5IG9mIHllYXJzIGZvciB0aGUgeWVhciBkcm9wZG93bi5cclxuICAgKiBEZWZhdWx0IHZhbHVlOiBBbiBhcnJheSBvZiB5ZWFycyB3aXRoaW4gdGhlIHNwZWNpZmllZCByYW5nZS5cclxuICAgKi9cclxuICB5ZWFyczogbnVtYmVyW11cclxuXHJcbiAgLyoqXHJcbiAgICogTGFiZWwgdGV4dCBmb3IgdGhlIGRhdGVwaWNrZXIuXHJcbiAgICogRGVmYXVsdCB2YWx1ZTogJ2VuJyAoRW5nbGlzaCkuXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICAgKiAgIFtsYWJlbENvbnRlbnRUZXh0XSA9IFwiJ0Nob3NlIHlvdXIgZGF0ZSdcIj5cclxuICAgKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGxhYmVsQ29udGVudFRleHQ6IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGxhbmd1YWdlL2xvY2FsZSBmb3IgdGhlIGRhdGVwaWNrZXIuXHJcbiAgICogRGVmYXVsdCB2YWx1ZTogJ2VuJyAoRW5nbGlzaCkuXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICAgKiAgIFtsYW5nXSA9IFwiJ3VrJ1wiPlxyXG4gICAqIDwvbWVmZGV2LWRhdGVwaWNrZXI+XHJcbiAgICovXHJcbiAgQElucHV0KCkgbGFuZzogc3RyaW5nID0gJ2VuJztcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGRhdGUgZm9ybWF0IGZvciBkaXNwbGF5aW5nIHRoZSBzZWxlY3RlZCBkYXRlLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6ICdFRUUgTU1NIGRkIHl5eXknLlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogPG1lZmRldi1kYXRlcGlja2VyXHJcbiAgICogICBbZGF0ZUZvcm1hdF09XCInZGQvTU0veXl5eSdcIj5cclxuICAgKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGRhdGVGb3JtYXQ6IHN0cmluZyA9ICdFRUUgTU1NIGRkIHl5eXknO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgcmFuZ2Ugb2YgeWVhcnMgYXZhaWxhYmxlIGluIHRoZSB5ZWFyIGRyb3Bkb3duLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6IHsgc3RhcnRZZWFyOiAxOTAwLCB0b1llYXI6IDMwMCB9LlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogPG1lZmRldi1kYXRlcGlja2VyXHJcbiAgICogICBbcmFuZ2VdPVwie3N0YXJ0WWVhcjogMTkwMCwgdG9ZZWFyOiAzMDB9XCI+XHJcbiAgICogPC9tZWZkZXYtZGF0ZXBpY2tlcj5cclxuICAgKi9cclxuICBASW5wdXQoJ3JhbmdlJykgeWVhcnNSYW5nZTp7c3RhcnRZZWFyOm51bWJlciwgdG9ZZWFyOm51bWJlcn0gPSB7c3RhcnRZZWFyOjE5MDAsIHRvWWVhcjozMDB9O1xyXG5cclxuICAvKipcclxuICAgKiBXaGV0aGVyIHRoZSBkYXRlcGlja2VyIGlzIGRpc2FibGVkIG9yIG5vdC5cclxuICAgKiBEZWZhdWx0IHZhbHVlOiBmYWxzZSAoZW5hYmxlZCkuXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICAgKiAgIFtkaXNhYmxlZF09XCJmYWxzZVwiPlxyXG4gICAqIDwvbWVmZGV2LWRhdGVwaWNrZXI+XHJcbiAgICovXHJcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIHRvcCBvZmZzZXQgZm9yIHBvc2l0aW9uaW5nIHRoZSBkYXRlcGlja2VyLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6ICcyMCcuXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICAgKiAgIFt0b3BPZmZzZXRdPVwiJzIwJ1wiPlxyXG4gICAqIDwvbWVmZGV2LWRhdGVwaWNrZXI+XHJcbiAgICovXHJcbiAgQElucHV0KCkgdG9wT2Zmc2V0OiBzdHJpbmcgPSAnMjAnO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgbGVmdCBvZmZzZXQgZm9yIHBvc2l0aW9uaW5nIHRoZSBkYXRlcGlja2VyLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6ICcxMCcuXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICAgKiAgIFtsZWZ0T2Zmc2V0XT1cIicxMCdcIj5cclxuICAgKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGxlZnRPZmZzZXQ6IHN0cmluZyA9ICcxMCc7IC8vRGVmYXVsdCB2YWx1ZVxyXG5cclxuICAvKipcclxuICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIHNlbGVjdGVkIGRhdGUgaW4gdGhlIGRhdGVwaWNrZXIgY2hhbmdlcy5cclxuICAgKiBJdCBlbWl0cyBhIGBEYXRlYCBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBzZWxlY3RlZCBkYXRlLlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogPG1lZmRldi1kYXRlcGlja2VyXHJcbiAgICogICAoZGF0ZUNoYW5nZWQpPVwib25EYXRlQ2hhbmdlZCgkZXZlbnQpXCI+XHJcbiAgICogPC9tZWZkZXYtZGF0ZXBpY2tlcj5cclxuICAgKi9cclxuICBAT3V0cHV0KCkgZGF0ZUNoYW5nZWQ6IEV2ZW50RW1pdHRlcjxEYXRlPiA9IG5ldyBFdmVudEVtaXR0ZXI8RGF0ZT4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogUmVndWxhciBleHByZXNzaW9uIHRvIHZhbGlkYXRlIHVzZXIgaW5wdXQgZm9yIGRhdGUgaW4gdGhlIGZvcm1hdCBcImRkL01NL3l5eXlcIi5cclxuICAgKiAtIFRoZSBkYXkgKGRkKSBzaG91bGQgYmUgYmV0d2VlbiAwMSBhbmQgMzEuXHJcbiAgICogLSBUaGUgbW9udGggKE1NKSBzaG91bGQgYmUgYmV0d2VlbiAwMSBhbmQgMTIuXHJcbiAgICogLSBUaGUgeWVhciAoeXl5eSkgc2hvdWxkIGJlIGEgNC1kaWdpdCBudW1iZXIuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBkYXRlUmVnRXhwOiBSZWdFeHAgPSAvXigwWzEtOV18WzEyXVswLTldfDNbMDFdKVxcLygwWzEtOV18MVswLTJdKVxcL1xcZHs0fSQvO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgc3RyaW5nIGVudGVyZWQgYnkgdGhlIHVzZXIgZm9yIGRhdGUgaW5wdXQuXHJcbiAgICogVGhpcyB2YXJpYWJsZSBzdG9yZXMgdGhlIHVzZXIncyBpbnB1dCBhcyB0aGV5IHR5cGUgaW4gdGhlIGRhdGUgZmllbGQuXHJcbiAgICovXHJcbiAgdXNlcklucHV0OiBzdHJpbmcgPSAnJztcclxuXHJcbiAgLyoqXHJcbiAgICogSG9zdCBsaXN0ZW5lciBmb3IgZG9jdW1lbnQgY2xpY2sgZXZlbnRzIHRvIGhhbmRsZSBjYWxlbmRhciBpbnRlcmFjdGlvbi5cclxuICAgKiBUaGlzIGZ1bmN0aW9uIGNoZWNrcyBpZiBhIGNsaWNrIGV2ZW50IG9jY3VycmVkIHdpdGhpbiB0aGUgY2FsZW5kYXIgb3IgaW5wdXQgZWxlbWVudHMuXHJcbiAgICogLSBJZiB0aGUgY2xpY2sgb2NjdXJyZWQgd2l0aGluIHRoZSBjYWxlbmRhciwgbm8gYWN0aW9uIGlzIHRha2VuLlxyXG4gICAqIC0gSWYgdGhlIGNsaWNrIG9jY3VycmVkIHdpdGhpbiB0aGUgaW5wdXQgZWxlbWVudCBhbmQgdGhlIGNvbXBvbmVudCBpcyBub3QgaW4gZWRpdGluZyBtb2RlLFxyXG4gICAqICAgaXQgb3BlbnMgdGhlIGNhbGVuZGFyLlxyXG4gICAqIEBwYXJhbSBldmVudCBUaGUgTW91c2VFdmVudCBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjbGljayBldmVudC5cclxuICAgKi9cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXHJcbiAgb25DbGljayhldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgY29uc3QgdGFyZ2V0RWxlbWVudCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcclxuICAgIGNvbnN0IGRhdGVwaWNrZXJDb250YWluZXIgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuZGF0ZXBpY2tlci1jb250YWluZXInKTtcclxuICAgIGNvbnN0IGNhbGVuZGFyID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmNhbGVuZGFyJyk7XHJcbiAgICBjb25zdCBtb250aERyb3Bkb3duID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLm1vbnRoRHJvcGRvd24nKTtcclxuICAgIGNvbnN0IHllYXJEcm9wZG93biA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy55ZWFyRHJvcGRvd24nKTtcclxuICAgIGNvbnN0IGlucHV0RWxlbWVudCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0Jyk7XHJcblxyXG4gICAgaWYgKGRhdGVwaWNrZXJDb250YWluZXIgJiYgZGF0ZXBpY2tlckNvbnRhaW5lci5jb250YWlucyhjYWxlbmRhcikpIHtcclxuICAgICAgaWYgKGNhbGVuZGFyICYmIGNhbGVuZGFyLmNvbnRhaW5zKHRhcmdldEVsZW1lbnQpKSByZXR1cm47XHJcbiAgICAgIGlmICh0aGlzLmlzTW9udGhEcm9wZG93bk9wZW4gJiYgIWNhbGVuZGFyLmNvbnRhaW5zKHRhcmdldEVsZW1lbnQpKSByZXR1cm47XHJcbiAgICAgIGlmICh0aGlzLmlzWWVhckRyb3Bkb3duT3BlbiAmJiAhY2FsZW5kYXIuY29udGFpbnModGFyZ2V0RWxlbWVudCkpIHJldHVybjtcclxuICAgICAgaWYgKChtb250aERyb3Bkb3duICYmIG1vbnRoRHJvcGRvd24uY29udGFpbnModGFyZ2V0RWxlbWVudCkpICYmICh5ZWFyRHJvcGRvd24gJiYgeWVhckRyb3Bkb3duLmNvbnRhaW5zKHRhcmdldEVsZW1lbnQpKSkge1xyXG4gICAgICAgIHRoaXMudG9nZ2xlTW9udGhEcm9wZG93bihldmVudClcclxuICAgICAgICB0aGlzLnRvZ2dsZVllYXJEcm9wZG93bihldmVudClcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29uc3RydWN0b3IgZm9yIHRoZSBEYXRlcGlja2VyQ29tcG9uZW50IGNsYXNzLlxyXG4gICAqIEBwYXJhbSBkYXRlUGlwZSBBIHNlcnZpY2UgZm9yIGZvcm1hdHRpbmcgYW5kIHBhcnNpbmcgZGF0ZXMuXHJcbiAgICogQHBhcmFtIGVsZW1lbnRSZWYgQSByZWZlcmVuY2UgdG8gdGhlIGVsZW1lbnQgb24gd2hpY2ggdGhpcyBjb21wb25lbnQgaXMgYXR0YWNoZWQuXHJcbiAgICogSXQgaXMgdXNlZCB0byBhY2Nlc3MgRE9NIGVsZW1lbnRzLlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZGF0ZVBpcGU6IERhdGVQaXBlLCBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHtcclxuICAgIHRoaXMudXBkYXRlSW5wdXRWYWx1ZSgpXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMaWZlY3ljbGUgaG9vayBjYWxsZWQgYWZ0ZXIgdGhlIGNvbXBvbmVudCBpcyBpbml0aWFsaXplZC5cclxuICAgKiBJdCBpbml0aWFsaXplcyB0aGUgeWVhcnMgZm9yIHRoZSB5ZWFyIHNlbGVjdCBkcm9wZG93bi5cclxuICAgKi9cclxuICBuZ09uSW5pdCgpe1xyXG4gICAgdGhpcy5pbml0aWFsaXplWWVhcnMoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExpZmVjeWNsZSBob29rIGNhbGxlZCB3aGVuZXZlciB0aGUgaW5wdXQgcHJvcGVydGllcyBvZiB0aGUgY29tcG9uZW50IGNoYW5nZS5cclxuICAgKiBJdCB1cGRhdGVzIHRoZSBpbnB1dCB2YWx1ZS5cclxuICAgKi9cclxuICBuZ09uQ2hhbmdlcygpIHtcclxuICAgIHRoaXMudXBkYXRlSW5wdXRWYWx1ZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQW4gYXJyYXkgb2YgbW9udGggbmFtZXMgYmFzZWQgb24gdGhlIHNlbGVjdGVkIGxhbmd1YWdlLlxyXG4gICAqIEl0IHByb3ZpZGVzIGxvY2FsaXplZCBtb250aCBuYW1lcyBmb3IgZGlzcGxheSBpbiB0aGUgZGF0ZXBpY2tlci5cclxuICAgKi9cclxuICBwcml2YXRlIGdldCBtb250aHMoKXtcclxuICAgIHJldHVybiB0aGlzLmdldE1vbnRoTGlzdCh0aGlzLmxhbmcpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQW4gYXJyYXkgb2Ygd2Vla2RheSBuYW1lcyBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgbGFuZ3VhZ2UuXHJcbiAgICogSXQgcHJvdmlkZXMgbG9jYWxpemVkIHdlZWtkYXkgbmFtZXMgZm9yIGRpc3BsYXkgaW4gdGhlIGRhdGVwaWNrZXIuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXQgd2Vla2RheXMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5nZXRXZWVrZGF5TGlzdCh0aGlzLmxhbmcpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW5pdGlhbGl6ZSB0aGUgbGlzdCBvZiB5ZWFycyB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIHllYXIgZHJvcGRvd24uXHJcbiAgICogVGhpcyBtZXRob2QgcG9wdWxhdGVzIHRoZSAneWVhcnMnIGFycmF5IHdpdGggYSByYW5nZSBvZiB5ZWFycyBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgJ3llYXJzUmFuZ2UnIGNvbmZpZ3VyYXRpb24uXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiBgYGBcclxuICAgKiAvLyBBc3N1bWluZyAneWVhcnNSYW5nZScgaXMgeyBzdGFydFllYXI6IDE5MDAsIHRvWWVhcjogMzAwIH1cclxuICAgKiAvLyBBZnRlciBjYWxsaW5nIGluaXRpYWxpemVZZWFycygpLCAneWVhcnMnIG1pZ2h0IGNvbnRhaW4gWzE5MDAsIDE5MDEsIC4uLiwgMzAwXVxyXG4gICAqIHRoaXMuaW5pdGlhbGl6ZVllYXJzKCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpbml0aWFsaXplWWVhcnMoKSB7XHJcbiAgICB0aGlzLnllYXJzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogdGhpcy55ZWFyc1JhbmdlLnRvWWVhciB9LCAoXywgaW5kZXgpID0+IGluZGV4ICsgdGhpcy55ZWFyc1JhbmdlLnN0YXJ0WWVhcik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUb2dnbGUgdGhlIGVkaXRpbmcgbW9kZSBmb3IgdGhlIGRhdGUgaW5wdXQuIFdoZW4gZW5hYmxlZCwgdGhlIHVzZXIgY2FuIGVkaXQgdGhlIGRhdGUgZGlyZWN0bHkgaW4gdGhlIGlucHV0IGZpZWxkLlxyXG4gICAqL1xyXG4gIHRvZ2dsZUVkaXQoKSB7XHJcbiAgICB0aGlzLmVkaXRlZERhdGUgPSB0aGlzLmZvcm1hdFNlbGVjdGVkRGF0ZSgpOyAvLyBTdG9yZSB0aGUgY3VycmVudCBmb3JtYXR0ZWQgZGF0ZSBmb3IgZWRpdGluZ1xyXG4gICAgdGhpcy5pc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGEgbGlzdCBvZiBtb250aCBuYW1lcyBpbiB0aGUgc3BlY2lmaWVkIGxhbmd1YWdlIGFuZCBmb3JtYXQuXHJcbiAgICogQHBhcmFtIGxvY2FsZXMgLSBBbiBvcHRpb25hbCBwYXJhbWV0ZXIgc3BlY2lmeWluZyB0aGUgbG9jYWxlIG9yIGxvY2FsZXMgdG8gdXNlIGZvciBmb3JtYXR0aW5nLlxyXG4gICAqIEBwYXJhbSBmb3JtYXQgLSBUaGUgZm9ybWF0IGZvciBtb250aCBuYW1lcywgZWl0aGVyIFwibG9uZ1wiIChkZWZhdWx0KSBvciBcInNob3J0XCIuXHJcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgbW9udGggbmFtZXMgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGZvcm1hdCBhbmQgbG9jYWxlLlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIEdldCBhIGxpc3Qgb2YgbW9udGggbmFtZXMgaW4gdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgYW5kIGxvbmcgZm9ybWF0XHJcbiAgICogY29uc3QgbW9udGhzID0gdGhpcy5nZXRNb250aExpc3QodGhpcy5sYW5nKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIGdldE1vbnRoTGlzdCggIGxvY2FsZXM/OiBzdHJpbmcgfCBzdHJpbmdbXSwgIGZvcm1hdDogXCJsb25nXCIgfCBcInNob3J0XCIgPSBcImxvbmdcIik6IHN0cmluZ1tdIHtcclxuICAgIGNvbnN0IHllYXIgPSBuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCk7XHJcbiAgICBjb25zdCBtb250aExpc3QgPSBbLi4uQXJyYXkoMTIpLmtleXMoKV07XHJcbiAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgSW50bC5EYXRlVGltZUZvcm1hdChsb2NhbGVzLCB7ICAgIG1vbnRoOiBmb3JtYXQgIH0pO1xyXG4gICAgY29uc3QgZ2V0TW9udGhOYW1lID0gKG1vbnRoSW5kZXg6IG51bWJlcikgPT4gZm9ybWF0dGVyLmZvcm1hdChuZXcgRGF0ZSh5ZWFyLCBtb250aEluZGV4KSk7XHJcbiAgICByZXR1cm4gbW9udGhMaXN0Lm1hcChnZXRNb250aE5hbWUpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGEgbGlzdCBvZiB3ZWVrZGF5IG5hbWVzIGluIHRoZSBzcGVjaWZpZWQgbGFuZ3VhZ2UgYW5kIGZvcm1hdC5cclxuICAgKiBAcGFyYW0gbG9jYWxlcyAtIEFuIG9wdGlvbmFsIHBhcmFtZXRlciBzcGVjaWZ5aW5nIHRoZSBsb2NhbGUgb3IgbG9jYWxlcyB0byB1c2UgZm9yIGZvcm1hdHRpbmcuXHJcbiAgICogQHBhcmFtIGZvcm1hdCAtIFRoZSBmb3JtYXQgZm9yIHdlZWtkYXkgbmFtZXMsIGVpdGhlciBcInNob3J0XCIgKGRlZmF1bHQpIG9yIFwibG9uZ1wiLlxyXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHdlZWtkYXkgbmFtZXMgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGZvcm1hdCBhbmQgbG9jYWxlLlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIEdldCBhIGxpc3Qgb2Ygd2Vla2RheSBuYW1lcyBpbiB0aGUgZGVmYXVsdCBsYW5ndWFnZSBhbmQgc2hvcnQgZm9ybWF0XHJcbiAgICogY29uc3Qgd2Vla2RheXMgPSB0aGlzLmdldFdlZWtkYXlMaXN0KCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRXZWVrZGF5TGlzdChsb2NhbGVzPzogc3RyaW5nIHwgc3RyaW5nW10sIGZvcm1hdDogXCJzaG9ydFwiIHwgXCJsb25nXCIgPSBcInNob3J0XCIpOiBzdHJpbmdbXSB7XHJcbiAgICBjb25zdCB3ZWVrZGF5cyA9IFsuLi5BcnJheSg3KS5rZXlzKCldO1xyXG4gICAgY29uc3QgbW9uZGF5SW5kZXggPSB3ZWVrZGF5cy5pbmRleE9mKDApO1xyXG4gICAgd2Vla2RheXMuc3BsaWNlKG1vbmRheUluZGV4LCAxKTtcclxuICAgIHdlZWtkYXlzLnB1c2goMCk7XHJcbiAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgSW50bC5EYXRlVGltZUZvcm1hdChsb2NhbGVzLCB7IHdlZWtkYXk6IGZvcm1hdCB9KTtcclxuICAgIGNvbnN0IGdldFdlZWtkYXlOYW1lID0gKHdlZWtkYXlJbmRleDogbnVtYmVyKSA9PiB7XHJcbiAgICAgIHJldHVybiBmb3JtYXR0ZXIuZm9ybWF0KG5ldyBEYXRlKDIwMjMsIDksIHdlZWtkYXlJbmRleCArIDEpKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gd2Vla2RheXMubWFwKGdldFdlZWtkYXlOYW1lKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNhdmUgdGhlIGVkaXRlZCBkYXRlIGlucHV0IGJ5IHRoZSB1c2VyLCBwcm92aWRlZCBpdCBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgZGF0ZSBmb3JtYXQuXHJcbiAgICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSBlbnRlcmVkIGRhdGUgaXMgaW4gYSB2YWxpZCBmb3JtYXQsIGRpc2FibGVzIHRoZSBlZGl0aW5nIG1vZGUsIGFuZCBhcHBsaWVzXHJcbiAgICogdGhlIGVkaXRlZCBkYXRlIHRvIHRoZSAnc2VsZWN0ZWREYXRlJy4gSXQgdGhlbiByZWZvcm1hdHMgdGhlIHNlbGVjdGVkIGRhdGUgYW5kIGNsb3NlcyB0aGUgY2FsZW5kYXIuXHJcbiAgICogYGBgXHJcbiAgICogLy8gU2F2ZSB0aGUgZWRpdGVkIGRhdGUgYW5kIHVwZGF0ZSB0aGUgc2VsZWN0ZWQgZGF0ZVxyXG4gICAqIHRoaXMuc2F2ZUVkaXRlZERhdGUoKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIHNhdmVFZGl0ZWREYXRlKCkge1xyXG4gICAgaWYgKHRoaXMuaXNEYXRlVmFsaWQodGhpcy5lZGl0ZWREYXRlKSkge1xyXG4gICAgICBjb25zdCBbZGF5LCBtb250aCwgeWVhcl0gPSB0aGlzLmVkaXRlZERhdGUuc3BsaXQoJy8nKTtcclxuICAgICAgdGhpcy5zZWxlY3RlZERhdGUgPSBuZXcgRGF0ZSgreWVhciwgK21vbnRoIC0gMSwgK2RheSk7XHJcbiAgICAgIHRoaXMuZm9ybWF0RGF0ZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIHVzZXIgaW5wdXQgaW4gdGhlIGVkaXRhYmxlIGlucHV0IGZpZWxkIGZvciBkYXRlIGVkaXRpbmcuIFRoaXMgbWV0aG9kIGNhcHR1cmVzIHRoZSBpbnB1dCB2YWx1ZVxyXG4gICAqIGFuZCBzdG9yZXMgaXQgaW4gdGhlICdlZGl0ZWREYXRlJyB2YXJpYWJsZS4gSWYgdGhlIGlucHV0IG1hdGNoZXMgdGhlIHZhbGlkIGRhdGUgZm9ybWF0LCBpdCB1cGRhdGVzXHJcbiAgICogJ3NlbGVjdGVkRGF0ZU1vbnRoJyBhbmQgJ3NlbGVjdGVkRGF0ZVllYXInIGFjY29yZGluZ2x5LlxyXG4gICAqIEBwYXJhbSBldmVudCAtIFRoZSBpbnB1dCBldmVudCBjb250YWluaW5nIHRoZSB1c2VyJ3MgaW5wdXQuXHJcbiAgICogYGBgXHJcbiAgICogLy8gSGFuZGxlIHVzZXIgaW5wdXQgaW4gdGhlIGVkaXRhYmxlIGlucHV0IGZpZWxkXHJcbiAgICogdGhpcy5vbkRhdGVJbnB1dChldmVudCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHVibGljIG9uRGF0ZUlucHV0KGV2ZW50OiBhbnkpIHtcclxuICAgIGNvbnN0IGlucHV0RGF0ZTogc3RyaW5nID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xyXG4gICAgaWYgKHRoaXMuaXNEYXRlVmFsaWQoaW5wdXREYXRlKSkge1xyXG4gICAgICB0aGlzLmVkaXRlZERhdGUgPSBpbnB1dERhdGU7XHJcbiAgICAgIGNvbnN0IHBhcnNlZERhdGUgPSBpbnB1dERhdGUuc3BsaXQoJy8nKTtcclxuICAgICAgdGhpcy5zZWxlY3RlZERhdGVNb250aCA9ICtwYXJzZWREYXRlWzFdIC0gMTtcclxuICAgICAgdGhpcy5zZWxlY3RlZERhdGVZZWFyID0gK3BhcnNlZERhdGVbMl07XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbmV3IERhdGUoK3BhcnNlZERhdGVbMl0sICtwYXJzZWREYXRlWzFdIC0gMSwgK3BhcnNlZERhdGVbMF0pO1xyXG4gICAgICB0aGlzLmNhbGN1bGF0ZUZpcnN0RGF5T2ZDYWxlbmRhcigpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5pc1VzZXJEYXRlVmFsaWQgPSB0aGlzLmlzRGF0ZVZhbGlkKGlucHV0RGF0ZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUb2dnbGUgdGhlIHZpc2liaWxpdHkgb2YgdGhlIG1vbnRoIGRyb3Bkb3duIGluIHRoZSBjYWxlbmRhciBpbnRlcmZhY2UuXHJcbiAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBvcGVuIG9yIGNsb3NlIHRoZSBkcm9wZG93biBmb3Igc2VsZWN0aW5nIG1vbnRocy5cclxuICAgKiBAcGFyYW0gZXZlbnQgLSBUaGUgZXZlbnQgdHJpZ2dlcmluZyB0aGUgdG9nZ2xlIGFjdGlvbiAoZS5nLiwgYSBjbGljayBldmVudCkuXHJcbiAgICogYGBgXHJcbiAgICogLy8gVG9nZ2xlIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBtb250aCBkcm9wZG93blxyXG4gICAqIHRoaXMudG9nZ2xlTW9udGhEcm9wZG93bihldmVudCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB0b2dnbGVNb250aERyb3Bkb3duKGV2ZW50OiBFdmVudCkge1xyXG4gICAgdGhpcy5pc01vbnRoRHJvcGRvd25PcGVuID0gIXRoaXMuaXNNb250aERyb3Bkb3duT3BlbjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvZ2dsZSB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgeWVhciBkcm9wZG93biBpbiB0aGUgY2FsZW5kYXIgaW50ZXJmYWNlLlxyXG4gICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gb3BlbiBvciBjbG9zZSB0aGUgZHJvcGRvd24gZm9yIHNlbGVjdGluZyB5ZWFycy5cclxuICAgKiBAcGFyYW0gZXZlbnQgLSBUaGUgZXZlbnQgdHJpZ2dlcmluZyB0aGUgdG9nZ2xlIGFjdGlvbiAoZS5nLiwgYSBjbGljayBldmVudCkuXHJcbiAgICogYGBgXHJcbiAgICogLy8gVG9nZ2xlIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSB5ZWFyIGRyb3Bkb3duXHJcbiAgICogdGhpcy50b2dnbGVZZWFyRHJvcGRvd24oZXZlbnQpO1xyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIHByaXZhdGUgdG9nZ2xlWWVhckRyb3Bkb3duKGV2ZW50OiBFdmVudCkge1xyXG4gICAgdGhpcy5pc1llYXJEcm9wZG93bk9wZW4gPSAhdGhpcy5pc1llYXJEcm9wZG93bk9wZW47XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgdGhlIGNoYW5nZSBvZiB0aGUgc2VsZWN0ZWQgbW9udGggaW4gdGhlIGNhbGVuZGFyIGludGVyZmFjZS5cclxuICAgKiBUaGlzIG1ldGhvZCB1cGRhdGVzIHRoZSBpbnB1dCB2YWx1ZSwgc2V0cyB0aGUgc2VsZWN0ZWQgZGF0ZSB0byB0aGUgZmlyc3QgZGF5IG9mIHRoZSBjaG9zZW4gbW9udGgsXHJcbiAgICogYW5kIHJlY2FsY3VsYXRlcyB0aGUgY2FsZW5kYXIgZGlzcGxheSBhY2NvcmRpbmdseS5cclxuICAgKiBgYGBcclxuICAgKiAvLyBIYW5kbGUgdGhlIGNoYW5nZSBvZiB0aGUgc2VsZWN0ZWQgbW9udGhcclxuICAgKiB0aGlzLm9uTW9udGhDaGFuZ2UoKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIG9uTW9udGhDaGFuZ2UoKSB7XHJcbiAgICB0aGlzLnVwZGF0ZUlucHV0VmFsdWUoKTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbmV3IERhdGUodGhpcy5zZWxlY3RlZERhdGVZZWFyLCB0aGlzLnNlbGVjdGVkRGF0ZU1vbnRoLCAxKTtcclxuICAgIHRoaXMuZm9ybWF0RGF0ZSgpO1xyXG4gICAgdGhpcy5jYWxjdWxhdGVGaXJzdERheU9mQ2FsZW5kYXIoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZSB0aGUgY2hhbmdlIG9mIHRoZSBzZWxlY3RlZCB5ZWFyIGluIHRoZSBjYWxlbmRhciBpbnRlcmZhY2UuXHJcbiAgICogVGhpcyBtZXRob2QgdXBkYXRlcyB0aGUgaW5wdXQgdmFsdWUsIHNldHMgdGhlIHNlbGVjdGVkIGRhdGUgdG8gdGhlIGZpcnN0IGRheSBvZiB0aGUgY2hvc2VuIHllYXIsXHJcbiAgICogcmVmb3JtYXRzIHRoZSBzZWxlY3RlZCBkYXRlLCBhbmQgcmVjYWxjdWxhdGVzIHRoZSBjYWxlbmRhciBkaXNwbGF5LlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIEhhbmRsZSB0aGUgY2hhbmdlIG9mIHRoZSBzZWxlY3RlZCB5ZWFyXHJcbiAgICogdGhpcy5vblllYXJDaGFuZ2UoKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIG9uWWVhckNoYW5nZSgpIHtcclxuICAgIHRoaXMudXBkYXRlSW5wdXRWYWx1ZSgpO1xyXG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBuZXcgRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZVllYXIsIHRoaXMuc2VsZWN0ZWREYXRlTW9udGgsIDEpO1xyXG4gICAgdGhpcy5mb3JtYXREYXRlKCk7XHJcbiAgICB0aGlzLmNhbGN1bGF0ZUZpcnN0RGF5T2ZDYWxlbmRhcigpO1xyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIFNlbGVjdCBhIGRhdGUgaW4gdGhlIGNhbGVuZGFyIGludGVyZmFjZSBhbmQgcGVyZm9ybSBuZWNlc3NhcnkgdXBkYXRlcy5cclxuICAgKiBUaGlzIG1ldGhvZCBzZXRzIHRoZSBzZWxlY3RlZCBkYXRlLCBmb3JtYXRzIGl0LCBjbG9zZXMgdGhlIGNhbGVuZGFyLCBhbmQgZW1pdHMgYSBkYXRlQ2hhbmdlZCBldmVudC5cclxuICAgKiBJdCBhbHNvIHVwZGF0ZXMgdGhlIHNlbGVjdGVkIG1vbnRoIGFuZCB5ZWFyIGRyb3Bkb3duIHZhbHVlcy5cclxuICAgKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIHRvIGJlIHNlbGVjdGVkIGluIHRoZSBjYWxlbmRhci5cclxuICAgKi9cclxuICBzZWxlY3REYXRlKGRhdGU6IERhdGUpIHtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gZGF0ZTtcclxuICAgIHRoaXMuZm9ybWF0RGF0ZSgpO1xyXG4gICAgdGhpcy5pc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG4gICAgdGhpcy5kYXRlQ2hhbmdlZC5uZXh0KHRoaXMuc2VsZWN0ZWREYXRlKTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlTW9udGggPSB0aGlzLnNlbGVjdGVkRGF0ZS5nZXRNb250aCgpO1xyXG4gICAgdGhpcy5zZWxlY3RlZERhdGVZZWFyID0gdGhpcy5zZWxlY3RlZERhdGUuZ2V0RnVsbFllYXIoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSBiYXNlZCBvbiB0aGUgY2hvc2VuIGRhdGUgZm9ybWF0IGFuZCBsYW5ndWFnZS5cclxuICAgKiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBBbmd1bGFyIERhdGVQaXBlIHRvIGZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSBhbmQgdXBkYXRlcyB0aGUgZm9ybWF0dGVkRGF0ZSB2YXJpYWJsZS5cclxuICAgKiBgYGBcclxuICAgKiAvLyBGb3JtYXQgdGhlIHNlbGVjdGVkIGRhdGVcclxuICAgKiB0aGlzLmZvcm1hdERhdGUoKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIGZvcm1hdERhdGUoKSB7XHJcbiAgICB0aGlzLmZvcm1hdHRlZERhdGUgPSB0aGlzLmRhdGVQaXBlLnRyYW5zZm9ybSh0aGlzLnNlbGVjdGVkRGF0ZSwgdGhpcy5kYXRlRm9ybWF0KSB8fCAnJztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSBiYXNlZCBvbiB0aGUgY2hvc2VuIGRhdGUgZm9ybWF0LCBsYW5ndWFnZSwgYW5kIGxvY2FsZS5cclxuICAgKiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBBbmd1bGFyIERhdGVQaXBlIHRvIGZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSB3aXRoIHRoZSBzcGVjaWZpZWQgbGFuZ3VhZ2UgYW5kIHVwZGF0ZXMgdGhlIGZvcm1hdHRlZCBkYXRlIGFzIGEgc3RyaW5nLlxyXG4gICAqIEByZXR1cm5zIEEgZm9ybWF0dGVkIGRhdGUgc3RyaW5nLlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIEZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSB3aXRoIGxhbmd1YWdlXHJcbiAgICogY29uc3QgZm9ybWF0dGVkID0gdGhpcy5mb3JtYXRTZWxlY3RlZERhdGUoKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIGZvcm1hdFNlbGVjdGVkRGF0ZSgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKHRoaXMuc2VsZWN0ZWREYXRlLCB0aGlzLmRhdGVGb3JtYXQsIHRoaXMubGFuZykgfHwgJyc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVcGRhdGUgdGhlIGlucHV0IHZhbHVlIGRpc3BsYXllZCBpbiB0aGUgY2FsZW5kYXIgaW50ZXJmYWNlLlxyXG4gICAqIFRoaXMgbWV0aG9kIHVwZGF0ZXMgdGhlIGlucHV0IHZhbHVlIHRvIGVpdGhlciB0aGUgZWRpdGVkIGRhdGUgb3IgdGhlIGZvcm1hdHRlZCBzZWxlY3RlZCBkYXRlLFxyXG4gICAqIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSB1c2VyIGlzIGluIGVkaXQgbW9kZSBvciBub3QuXHJcbiAgICogYGBgXHJcbiAgICogLy8gVXBkYXRlIHRoZSBpbnB1dCB2YWx1ZVxyXG4gICAqIHRoaXMudXBkYXRlSW5wdXRWYWx1ZSgpO1xyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIHByaXZhdGUgdXBkYXRlSW5wdXRWYWx1ZSgpIHtcclxuICAgIHRoaXMuZm9ybWF0dGVkRGF0ZSA9IHRoaXMuaXNDYWxlbmRhck9wZW4gPyB0aGlzLmVkaXRlZERhdGUgOiB0aGlzLmZvcm1hdFNlbGVjdGVkRGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGFuIGFycmF5IG9mIGFycmF5cyByZXByZXNlbnRpbmcgdGhlIGRheXMgb2YgdGhlIGN1cnJlbnQgbW9udGguXHJcbiAgICogRWFjaCBzdWItYXJyYXkgY29udGFpbnMgdGhlIGRheSBkYXRhIGZvciBhIHdlZWssIGFuZCBlYWNoIGRheSBkYXRhIG9iamVjdCBpbmNsdWRlcyB0aGUgZGF0ZSBhbmQgd2hldGhlciBpdCBiZWxvbmdzIHRvIHRoZSBjdXJyZW50IG1vbnRoLlxyXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGFycmF5cyByZXByZXNlbnRpbmcgdGhlIGRheXMgb2YgdGhlIGN1cnJlbnQgbW9udGguXHJcbiAgICogYGBgXHJcbiAgICogLy8gR2V0IGFuIGFycmF5IG9mIGFycmF5cyByZXByZXNlbnRpbmcgdGhlIGRheXMgb2YgdGhlIGN1cnJlbnQgbW9udGhcclxuICAgKiBjb25zdCBjYWxlbmRhciA9IHRoaXMuY2FsZW5kYXJEYXlzO1xyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0IGNhbGVuZGFyRGF5cygpIHtcclxuICAgIHJldHVybiB0aGlzLmNhbGN1bGF0ZUZpcnN0RGF5T2ZDYWxlbmRhcigpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBkYXRlIG9mIHRoZSBwcmV2aW91cyBtb250aCB0byBkaXNwbGF5IGluIGVtcHR5IGNlbGxzIG9mIHRoZSBjdXJyZW50IG1vbnRoLlxyXG4gICAqIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGRhdGUgb2YgdGhlIHByZXZpb3VzIG1vbnRoIGlmIHRoZSBwcm92aWRlZCBkYXRlIGlzIG5vdCBpbiB0aGUgY3VycmVudCBtb250aC5cclxuICAgKiBJZiB0aGUgcHJvdmlkZWQgZGF0ZSBpcyBpbiB0aGUgY3VycmVudCBtb250aCwgaXQgcmV0dXJucyB0aGUgZGF0ZSdzIGRheSBhcyBhIHN0cmluZy5cclxuICAgKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIHRvIGV2YWx1YXRlLlxyXG4gICAqIEByZXR1cm5zIFRoZSBkYXRlIG9mIHRoZSBwcmV2aW91cyBtb250aCBvciBhIGRheSBzdHJpbmcuXHJcbiAgICogYGBgXHJcbiAgICogLy8gR2V0IHRoZSBwcmV2aW91cyBtb250aCdzIGRhdGUgdG8gZGlzcGxheSBpbiBlbXB0eSBjZWxsc1xyXG4gICAqIGNvbnN0IHByZXZpb3VzTW9udGhEYXRlID0gdGhpcy5nZXRQcmV2aW91c01vbnRoRGF0ZShuZXcgRGF0ZSgyMDIzLCA4LCAxKSk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRQcmV2aW91c01vbnRoRGF0ZShkYXRlOiBEYXRlKTogYW55IHtcclxuICAgIGlmICghZGF0ZSkge1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgICBjb25zdCBjdXJyZW50RGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICBpZiAoZGF0ZS5nZXRNb250aCgpID09PSBjdXJyZW50RGF0ZS5nZXRNb250aCgpICYmIGRhdGUuZ2V0RnVsbFllYXIoKSA9PT0gY3VycmVudERhdGUuZ2V0RnVsbFllYXIoKSkge1xyXG4gICAgICByZXR1cm4gZGF0ZS5nZXREYXRlKCkudG9TdHJpbmcoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmRhdGVQaXBlLnRyYW5zZm9ybShkYXRlLCAnZGQnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICAgKiBOYXZpZ2F0ZSB0byB0aGUgcHJldmlvdXMgbW9udGggaW4gdGhlIGNhbGVuZGFyIGludGVyZmFjZS5cclxuICAgKiBUaGlzIG1ldGhvZCB1cGRhdGVzIHRoZSBzZWxlY3RlZERhdGUsIGZvcm1hdHMgaXQsIGFuZCByZWNhbGN1bGF0ZXMgdGhlIGZpcnN0IGRheSBvZiB0aGUgY2FsZW5kYXIuXHJcbiAgICogYGBgXHJcbiAgICogLy8gTmF2aWdhdGUgdG8gdGhlIHByZXZpb3VzIG1vbnRoXHJcbiAgICogdGhpcy5nZXRQcmV2aW91c01vbnRoKCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRQcmV2aW91c01vbnRoKCkge1xyXG4gICAgY29uc3QgY3VycmVudE1vbnRoID0gdGhpcy5zZWxlY3RlZERhdGUuZ2V0TW9udGgoKTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbmV3IERhdGUodGhpcy5zZWxlY3RlZERhdGUuZ2V0RnVsbFllYXIoKSwgY3VycmVudE1vbnRoIC0gMSwgMSk7XHJcbiAgICB0aGlzLmZvcm1hdERhdGUoKTtcclxuICAgIHRoaXMuY2FsY3VsYXRlRmlyc3REYXlPZkNhbGVuZGFyKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBOYXZpZ2F0ZSB0byB0aGUgbmV4dCBtb250aCBpbiB0aGUgY2FsZW5kYXIgaW50ZXJmYWNlLlxyXG4gICAqIFRoaXMgbWV0aG9kIHVwZGF0ZXMgdGhlIHNlbGVjdGVkRGF0ZSwgZm9ybWF0cyBpdCwgYW5kIHJlY2FsY3VsYXRlcyB0aGUgZmlyc3QgZGF5IG9mIHRoZSBjYWxlbmRhci5cclxuICAgKiBgYGBcclxuICAgKiAvLyBOYXZpZ2F0ZSB0byB0aGUgbmV4dCBtb250aFxyXG4gICAqIHRoaXMuZ2V0TmV4dE1vbnRoKCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXROZXh0TW9udGgoKSB7XHJcbiAgICBjb25zdCBjdXJyZW50TW9udGggPSB0aGlzLnNlbGVjdGVkRGF0ZS5nZXRNb250aCgpO1xyXG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBuZXcgRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZS5nZXRGdWxsWWVhcigpLCBjdXJyZW50TW9udGggKyAxLCAxKTtcclxuICAgIHRoaXMuZm9ybWF0RGF0ZSgpO1xyXG4gICAgdGhpcy5jYWxjdWxhdGVGaXJzdERheU9mQ2FsZW5kYXIoKTtcclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICAgKiBHZXQgdGhlIG51bWJlciBvZiBkYXlzIGluIGEgZ2l2ZW4gbW9udGggb2YgYSBzcGVjaWZpYyB5ZWFyLlxyXG4gICAqIEBwYXJhbSB5ZWFyIC0gVGhlIHllYXIgZm9yIHdoaWNoIHlvdSB3YW50IHRvIGRldGVybWluZSB0aGUgbnVtYmVyIG9mIGRheXMuXHJcbiAgICogQHBhcmFtIG1vbnRoIC0gVGhlIG1vbnRoICgwLWJhc2VkIGluZGV4KSBmb3Igd2hpY2ggeW91IHdhbnQgdG8gZGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgZGF5cy5cclxuICAgKiBAcmV0dXJucyBUaGUgbnVtYmVyIG9mIGRheXMgaW4gdGhlIHNwZWNpZmllZCBtb250aCBvZiB0aGUgZ2l2ZW4geWVhci5cclxuICAgKi9cclxuICBwcml2YXRlIGRheXNJbk1vbnRoKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICByZXR1cm4gbmV3IERhdGUoeWVhciwgbW9udGggKyAxLCAwKS5nZXREYXRlKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDYWxjdWxhdGUgdGhlIHN0cnVjdHVyZSBvZiBkYXlzIGluIGEgbW9udGggZm9yIHRoZSBjYWxlbmRhciBkaXNwbGF5LlxyXG4gICAqIFRoaXMgbWV0aG9kIGdlbmVyYXRlcyBhIG1hdHJpeCBvZiBkYXkgZGF0YSBvYmplY3RzIHJlcHJlc2VudGluZyB0aGUgZGF5cyBpbiB0aGUgY2FsZW5kYXIuXHJcbiAgICogRWFjaCBkYXkgZGF0YSBvYmplY3QgY29udGFpbnMgdGhlIGRhdGUgYW5kIHdoZXRoZXIgaXQgYmVsb25ncyB0byB0aGUgY3VycmVudCBtb250aC5cclxuICAgKiBAcmV0dXJucyBBIG1hdHJpeCBvZiBkYXkgZGF0YSBvYmplY3RzIGZvciB0aGUgY2FsZW5kYXIgZGlzcGxheS5cclxuICAgKi9cclxuICBwcml2YXRlIGNhbGN1bGF0ZUZpcnN0RGF5T2ZDYWxlbmRhcigpIHtcclxuICAgIGNvbnN0IHllYXIgPSB0aGlzLnNlbGVjdGVkRGF0ZS5nZXRGdWxsWWVhcigpO1xyXG4gICAgY29uc3QgbW9udGggPSB0aGlzLnNlbGVjdGVkRGF0ZS5nZXRNb250aCgpO1xyXG4gICAgY29uc3QgZmlyc3REYXlPZk1vbnRoID0gbmV3IERhdGUoeWVhciwgbW9udGgsIDEpO1xyXG4gICAgY29uc3QgZmlyc3RXZWVrZGF5ID0gZmlyc3REYXlPZk1vbnRoLmdldERheSgpO1xyXG4gICAgY29uc3Qgc3RhcnREYXkgPSBmaXJzdFdlZWtkYXkgPT09IDAgPyAtNSA6IDIgLSBmaXJzdFdlZWtkYXk7XHJcbiAgICBjb25zdCBjYWxlbmRhckRheXMgPSBbXTtcclxuICAgIGxldCBjdXJyZW50RGF5ID0gc3RhcnREYXk7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDY7IGkrKykge1xyXG4gICAgICBjb25zdCB3ZWVrID0gW107XHJcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgNzsgaisrKSB7XHJcbiAgICAgICAgY29uc3QgZGF5ID0gbmV3IERhdGUoeWVhciwgbW9udGgsIGN1cnJlbnREYXkpO1xyXG4gICAgICAgIGNvbnN0IGRheURhdGEgPSB7XHJcbiAgICAgICAgICBkYXRlOiBkYXksXHJcbiAgICAgICAgICBpc0N1cnJlbnRNb250aDogY3VycmVudERheSA+PSAxICYmIGN1cnJlbnREYXkgPD0gdGhpcy5kYXlzSW5Nb250aCh5ZWFyLCBtb250aCksXHJcbiAgICAgICAgfTtcclxuICAgICAgICB3ZWVrLnB1c2goZGF5RGF0YSk7XHJcbiAgICAgICAgY3VycmVudERheSsrO1xyXG4gICAgICB9XHJcbiAgICAgIGNhbGVuZGFyRGF5cy5wdXNoKHdlZWspO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNhbGVuZGFyRGF5cztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGEgZ2l2ZW4gZGF0ZSBpcyB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGRhdGUgaW4gdGhlIGNhbGVuZGFyLlxyXG4gICAqIEBwYXJhbSBkYXRlIC0gVGhlIGRhdGUgdG8gY2hlY2suXHJcbiAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBwcm92aWRlZCBkYXRlIG1hdGNoZXMgdGhlIHNlbGVjdGVkIGRhdGUsIG90aGVyd2lzZSBgZmFsc2VgLlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIENoZWNrIGlmIGEgZGF0ZSBpcyBzZWxlY3RlZFxyXG4gICAqIGNvbnN0IGlzU2VsZWN0ZWQgPSB0aGlzLmlzRGF0ZVNlbGVjdGVkKHNvbWVEYXRlKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIGlzRGF0ZVNlbGVjdGVkKGRhdGU6IERhdGUpIHtcclxuICAgIHJldHVybiBkYXRlLnRvRGF0ZVN0cmluZygpID09PSB0aGlzLnNlbGVjdGVkRGF0ZS50b0RhdGVTdHJpbmcoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGEgZGF0ZSBzdHJpbmcgaXMgdmFsaWQgYmFzZWQgb24gdGhlIHNwZWNpZmllZCBkYXRlIGZvcm1hdC5cclxuICAgKiBJdCBhbHNvIGNoZWNrcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgbnVtYmVyLCBtb250aCBpcyBjb3JyZWN0IGFuZCB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgb25lIGV4aXN0cyBhbW9uZyBjYWxlbmRhciB5ZWFyc1xyXG4gICAqIEBwYXJhbSBpbnB1dERhdGUgLSBUaGUgZGF0ZSBzdHJpbmcgdG8gdmFsaWRhdGUuXHJcbiAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBpbnB1dCBkYXRlIHN0cmluZyBpcyB2YWxpZCwgb3RoZXJ3aXNlIGBmYWxzZWAuXHJcbiAgICogYGBgXHJcbiAgICogLy8gQ2hlY2sgaWYgYSBkYXRlIHN0cmluZyBpcyB2YWxpZFxyXG4gICAqIGNvbnN0IGlzVmFsaWREYXRlID0gdGhpcy5pc0RhdGVWYWxpZCgnMDUvMjUvMjAyMycpO1xyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaXNEYXRlVmFsaWQoaW5wdXREYXRlOiBzdHJpbmcpIHtcclxuICAgIGlmICghdGhpcy5kYXRlUmVnRXhwLnRlc3QoaW5wdXREYXRlKSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgcGFydHMgPSBpbnB1dERhdGUuc3BsaXQoJy8nKTtcclxuICAgIGNvbnN0IGRheSA9IHBhcnNlSW50KHBhcnRzWzBdLCAxMCk7XHJcbiAgICBjb25zdCBtb250aCA9IHBhcnNlSW50KHBhcnRzWzFdLCAxMCk7XHJcbiAgICBjb25zdCB5ZWFyID0gcGFyc2VJbnQocGFydHNbMl0sIDEwKTtcclxuXHJcbiAgICBpZiAoeWVhciA+IHRoaXMueWVhcnNbdGhpcy55ZWFycy5sZW5ndGggLSAxXSB8fCB5ZWFyIDwgdGhpcy55ZWFyc1swXSkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBkYXlzSW5Nb250aCA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCAwKS5nZXREYXRlKCk7XHJcbiAgICByZXR1cm4gZGF5IDw9IGRheXNJbk1vbnRoO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgYSBnaXZlbiBkYXRlIGlzIHRvZGF5J3MgZGF0ZS5cclxuICAgKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIHRvIGNoZWNrLlxyXG4gICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvdmlkZWQgZGF0ZSBpcyB0b2RheSdzIGRhdGUsIG90aGVyd2lzZSBgZmFsc2VgLlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIENoZWNrIGlmIGEgZGF0ZSBpcyB0b2RheSdzIGRhdGVcclxuICAgKiBjb25zdCBpc1RvZGF5ID0gdGhpcy5pc0RhdGVUb2RheShzb21lRGF0ZSk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpc0RhdGVUb2RheShkYXRlOiBEYXRlKSB7XHJcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XHJcbiAgICByZXR1cm4gZGF0ZS50b0RhdGVTdHJpbmcoKSA9PT0gdG9kYXkudG9EYXRlU3RyaW5nKCk7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJkYXRlcGlja2VyLWNvbnRhaW5lclwiIFtjbGFzcy5kaXNhYmxlZF09XCJkaXNhYmxlZFwiPlxyXG5cclxuICA8IS0tIElucHV0LCBzYXZlICYgZWRpdCBidXR0b25zIC0tPlxyXG4gICAgPGRpdiBjbGFzcz1cImlucHV0LWNvbnRhaW5lciBmb3JtLWdyb3VwXCI+XHJcbiAgICAgICAgPGxhYmVsICpuZ0lmPVwibGFiZWxDb250ZW50VGV4dFwiIGNsYXNzPVwiZm9ybS1sYWJlbFwiPiB7eyBsYWJlbENvbnRlbnRUZXh0IH19IDwvbGFiZWw+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7ICdjYWxlbmRhck5vdE9wZW5lZCc6ICFpc0NhbGVuZGFyT3BlbiB9XCJcclxuICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ2JvcmRlci1jb2xvcic6IGlzVXNlckRhdGVWYWxpZCA/ICcnIDogJ3JlZCcgfVwiXHJcbiAgICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXHJcbiAgICAgICAgICAoaW5wdXQpPVwib25EYXRlSW5wdXQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiaXNDYWxlbmRhck9wZW4gPSB0cnVlXCJcclxuICAgICAgICAgIFt2YWx1ZV09XCJmb3JtYXR0ZWREYXRlXCJcclxuICAgICAgICAgIFtyZWFkT25seV09XCIhaXNDYWxlbmRhck9wZW5cIlxyXG4gICAgICAgID5cclxuICAgIDwvZGl2PlxyXG5cclxuICA8IS0tIENhbGVuZGFyKERyb3Bkb3ducywgZGF0ZXMpIC0tPlxyXG4gIDxkaXYgKm5nSWY9XCJpc0NhbGVuZGFyT3BlblwiIGNsYXNzPVwiY2FsZW5kYXJcIiAjY2FsZW5kYXJDb250YWluZXJcclxuICAgICAgIFtzdHlsZS50b3BdPVwidG9wT2Zmc2V0XCJcclxuICAgICAgIFtzdHlsZS5sZWZ0XT1cImxlZnRPZmZzZXRcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJjYWxlbmRhci1oZWFkZXJcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cIm1vbnRoQnV0dG9uQ29udGFpbmVyXCI+XHJcbiAgICAgICAgPCEtLSBNb250aCBkcm9wZG93biAtLT5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNNb250aERyb3Bkb3duT3BlbjsgZWxzZSBtb250aExhYmVsXCI+XHJcbiAgICAgICAgICA8bWVmZGV2LXNlbGVjdFxyXG4gICAgICAgICAgICBjbGFzcz1cIm1vbnRoRHJvcGRvd25cIlxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlbGVjdGVkRGF0ZU1vbnRoXCJcclxuICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25Nb250aENoYW5nZSgpXCJcclxuICAgICAgICAgICAgW1BsYWNlSG9sZGVyXT1cIidtb250aCdcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8bWVmZGV2LW9wdGlvblxyXG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBtb250aCBvZiBtb250aHM7IGxldCBpID0gaW5kZXhcIlxyXG4gICAgICAgICAgICAgIFtWYWx1ZV09XCJpXCJcclxuICAgICAgICAgICAgICBbTGFiZWxdPVwibW9udGhcIlxyXG4gICAgICAgICAgICAgIHN0eWxlPVwiei1pbmRleDogMVwiXHJcbiAgICAgICAgICAgID57eyBtb250aCB9fTwvbWVmZGV2LW9wdGlvbj5cclxuICAgICAgICAgIDwvbWVmZGV2LXNlbGVjdD5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8bmctdGVtcGxhdGUgI21vbnRoTGFiZWw+XHJcbiAgICAgICAgICA8c3BhbiAoY2xpY2spPVwidG9nZ2xlTW9udGhEcm9wZG93bigkZXZlbnQpXCI+PC9zcGFuPlxyXG4gICAgICAgIDwvbmctdGVtcGxhdGU+XHJcblxyXG4gICAgICAgIDwhLS0gWWVhciBkcm9wZG93biAtLT5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNZZWFyRHJvcGRvd25PcGVuOyBlbHNlIHllYXJMYWJlbFwiPlxyXG4gICAgICAgICAgPG1lZmRldi1zZWxlY3RcclxuICAgICAgICAgICAgY2xhc3M9XCJ5ZWFyRHJvcGRvd25cIlxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlbGVjdGVkRGF0ZVllYXJcIlxyXG4gICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvblllYXJDaGFuZ2UoKVwiXHJcbiAgICAgICAgICAgIFtQbGFjZUhvbGRlcl09XCIneWVhcidcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8bWVmZGV2LW9wdGlvblxyXG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCB5ZWFyIG9mIHllYXJzXCJcclxuICAgICAgICAgICAgICBbTGFiZWxdPVwieWVhclwiXHJcbiAgICAgICAgICAgICAgW1ZhbHVlXT1cInllYXJcIlxyXG4gICAgICAgICAgICA+e3t5ZWFyfX08L21lZmRldi1vcHRpb24+XHJcbiAgICAgICAgICA8L21lZmRldi1zZWxlY3Q+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPG5nLXRlbXBsYXRlICN5ZWFyTGFiZWw+XHJcbiAgICAgICAgICA8c3BhbiAoY2xpY2spPVwidG9nZ2xlWWVhckRyb3Bkb3duKCRldmVudClcIj57eyBzZWxlY3RlZERhdGVZZWFyIH19PC9zcGFuPlxyXG4gICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8IS0tIENhbGVuZGFyIGV4aXQgYnV0dG9uIC0tPlxyXG4gICAgICA8ZGl2PlxyXG4gICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtdGltZXMgdG9nZ2xlQ2FsZW5kYXJCdXR0b25cIiAoY2xpY2spPVwiaXNDYWxlbmRhck9wZW4gPSBmYWxzZVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwiY2FsZW5kYXItYm9keVwiPlxyXG4gICAgICA8dGFibGU+XHJcbiAgICAgICAgPHRyPlxyXG4gICAgICAgICAgPHRoIGNsYXNzPVwidGV4dC1jZW50ZXJcIiAqbmdGb3I9XCJsZXQgd2Vla2RheSBvZiB3ZWVrZGF5c1wiPnt7IHdlZWtkYXkgfX08L3RoPlxyXG4gICAgICAgIDwvdHI+XHJcbiAgICAgICAgPHRyICpuZ0Zvcj1cImxldCB3ZWVrIG9mIGNhbGVuZGFyRGF5c1wiPlxyXG4gICAgICAgICAgPHRkICpuZ0Zvcj1cImxldCBkYXlEYXRhIG9mIHdlZWtcIlxyXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3REYXRlKGRheURhdGEuZGF0ZSlcIlxyXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3NlbGVjdGVkJzogaXNEYXRlU2VsZWN0ZWQoZGF5RGF0YS5kYXRlKSwgJ3ByZXYtbW9udGgnOiAhZGF5RGF0YS5pc0N1cnJlbnRNb250aCB9XCI+XHJcblxyXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRhdGVcIiBbY2xhc3MucHJldi1tb250aF09XCIhZGF5RGF0YS5pc0N1cnJlbnRNb250aFwiPlxyXG4gICAgICAgICAgICAgIHt7IGRheURhdGEuZGF0ZS5nZXREYXRlKCkgfX1cclxuICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgPC90ZD5cclxuICAgICAgICA8L3RyPlxyXG4gICAgICA8L3RhYmxlPlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG4iXX0=