angular-hijri-gregorian-date-time-picker 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1058 @@
1
+ import { Component, Input, Output, EventEmitter, HostBinding, } from '@angular/core';
2
+ import * as themesConfig from '../themes/themes.json';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/forms";
5
+ import * as i2 from "../_services/date-utilities.service";
6
+ import * as i3 from "@angular/common";
7
+ export class HijriGregorianDatepickerComponent {
8
+ constructor(formBuilder, _dateUtilsService) {
9
+ this.formBuilder = formBuilder;
10
+ this._dateUtilsService = _dateUtilsService;
11
+ /// Inputs
12
+ this.markToday = true;
13
+ this.canChangeMode = true;
14
+ this.todaysDateSection = true;
15
+ this.futureValidation = true;
16
+ this.disableYearPicker = false;
17
+ this.disableMonthPicker = false;
18
+ this.disableDayPicker = false;
19
+ this.multiple = false;
20
+ this.isRequired = false;
21
+ this.showConfirmButton = true;
22
+ this.futureValidationMessage = false;
23
+ this.arabicLayout = false;
24
+ this.mode = 'greg';
25
+ this.dir = 'ltr';
26
+ this.locale = 'en';
27
+ this.submitTextButton = 'Confirm';
28
+ this.todaysDateText = "Today's Date";
29
+ this.ummAlQuraDateText = 'Hijri Date';
30
+ this.monthSelectLabel = 'Month';
31
+ this.yearSelectLabel = 'Year';
32
+ this.theme = '';
33
+ this.pastYearsLimit = 90;
34
+ this.futureYearsLimit = 0;
35
+ this.styles = {};
36
+ // New inputs for extended functionality
37
+ this.enableTime = false; // Enable time picker (hours & minutes)
38
+ // BACKWARD COMPATIBILITY: Default to false (24-hour format)
39
+ // When true, displays 12-hour format with AM/PM toggle
40
+ this.useMeridian = false; // Enable 12-hour format with AM/PM
41
+ // BACKWARD COMPATIBILITY: Default to 'single' (existing behavior)
42
+ // 'range' enables range selection mode (first click = start, second click = end)
43
+ this.selectionMode = 'single';
44
+ /// Outputs
45
+ this.onSubmit = new EventEmitter();
46
+ this.onDaySelect = new EventEmitter();
47
+ this.onMonthChange = new EventEmitter();
48
+ this.onYearChange = new EventEmitter();
49
+ /// Variables
50
+ this.ummAlQuraMonths = [
51
+ { labelAr: 'محرم', labelEn: 'Muharram', value: 1 },
52
+ { labelAr: 'صفر', labelEn: 'Safar', value: 2 },
53
+ { labelAr: 'ربيع الأول', labelEn: 'Rabi al-Awwal', value: 3 },
54
+ { labelAr: 'ربيع الثاني', labelEn: 'Rabi al-Thani', value: 4 },
55
+ { labelAr: 'جمادى الأولى', labelEn: 'Jumada al-Awwal', value: 5 },
56
+ { labelAr: 'جمادى الآخرة', labelEn: 'Jumada al-Thani', value: 6 },
57
+ { labelAr: 'رجب', labelEn: 'Rajab', value: 7 },
58
+ { labelAr: 'شعبان', labelEn: 'Shaban', value: 8 },
59
+ { labelAr: 'رمضان', labelEn: 'Ramadan', value: 9 },
60
+ { labelAr: 'شوال', labelEn: 'Shawwal', value: 10 },
61
+ { labelAr: 'ذو القعدة', labelEn: 'Dhu al-Qadah', value: 11 },
62
+ { labelAr: 'ذو الحجة', labelEn: 'Dhu al-Hijjah', value: 12 },
63
+ ];
64
+ this.gregMonths = [
65
+ { labelAr: 'يناير', labelEn: 'January', value: 1 },
66
+ { labelAr: 'فبراير', labelEn: 'February', value: 2 },
67
+ { labelAr: 'مارس', labelEn: 'March', value: 3 },
68
+ { labelAr: 'ابريل', labelEn: 'April', value: 4 },
69
+ { labelAr: 'مايو', labelEn: 'May', value: 5 },
70
+ { labelAr: 'يونيو', labelEn: 'June', value: 6 },
71
+ { labelAr: 'يوليو', labelEn: 'July', value: 7 },
72
+ { labelAr: 'اغسطس', labelEn: 'August', value: 8 },
73
+ { labelAr: 'سبتمبر', labelEn: 'September', value: 9 },
74
+ { labelAr: 'اكتوبر', labelEn: 'October', value: 10 },
75
+ { labelAr: 'نوفمبر', labelEn: 'November', value: 11 },
76
+ { labelAr: 'ديسمبر', labelEn: 'December', value: 12 },
77
+ ];
78
+ this.weekdaysEn = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
79
+ this.weekdaysAr = ['سبت', 'جمعة', 'خميس', 'أربعاء', 'ثلاثاء', 'اثنين', 'أحد'];
80
+ // weekdaysAr = ['س', 'ج', 'خ', 'أر', 'ث', 'إث', 'أح'];
81
+ this.todaysDate = {};
82
+ this.multipleSelectedDates = [];
83
+ this.themes = [];
84
+ // Time picker variables
85
+ // BACKWARD COMPATIBILITY: selectedTime defaults to 0:0 to preserve existing behavior when enableTime=false
86
+ // When enableTime=true, this will be initialized to current system time in ngOnInit
87
+ this.selectedTime = { hour: 0, minute: 0 };
88
+ // Track if time has been initialized to avoid re-initializing at midnight
89
+ this.timeInitialized = false;
90
+ // BACKWARD COMPATIBILITY: Meridian only used when useMeridian=true
91
+ // Tracks AM/PM state for 12-hour format
92
+ this.meridian = 'AM';
93
+ // Range selection state
94
+ // BACKWARD COMPATIBILITY: These are only used when selectionMode='range'
95
+ // They do not affect single or multiple selection modes
96
+ this.rangeStart = undefined;
97
+ this.rangeEnd = undefined;
98
+ }
99
+ ngOnInit() {
100
+ this.initTheme();
101
+ this.initializeForm();
102
+ this.getTodaysDateInfo();
103
+ this.initializeYearsAndMonths();
104
+ // Initialize time from current system time or initialDate
105
+ // BACKWARD COMPATIBILITY: This only runs when enableTime=true
106
+ if (this.enableTime) {
107
+ this.initializeTime();
108
+ }
109
+ }
110
+ ngAfterViewInit() {
111
+ // Double-check time initialization after view is ready
112
+ // This handles cases where enableTime might be set after ngOnInit
113
+ if (this.enableTime && !this.timeInitialized) {
114
+ this.initializeTime();
115
+ }
116
+ }
117
+ ngOnChanges(changes) {
118
+ if (!changes['mode'].isFirstChange()) {
119
+ this.changeCalendarMode();
120
+ }
121
+ }
122
+ initTheme() {
123
+ if (this.theme != '') {
124
+ this.themes = themesConfig;
125
+ for (const themeItem of this.themes['default']) {
126
+ if (themeItem.name == this.theme) {
127
+ this.styles = themeItem.stylesConfig;
128
+ break;
129
+ }
130
+ }
131
+ }
132
+ this.fontFamilyStyle = this.styles.fontFamily;
133
+ }
134
+ /// Initialize form control for month and year select
135
+ initializeForm() {
136
+ this.periodForm = this.formBuilder.group({
137
+ year: [{ value: '', disabled: this.disableYearPicker }, []],
138
+ month: [{ value: '', disabled: this.disableMonthPicker }, []],
139
+ });
140
+ }
141
+ // Initialize years and months for calendar
142
+ initializeYearsAndMonths() {
143
+ this.years = [];
144
+ this.months = [];
145
+ // Determine the date to use for initialization (initialDate or today)
146
+ let referenceDate;
147
+ if (this.initialDate) {
148
+ const normalizedInitialDate = this._dateUtilsService.normalizeDateToString(this.initialDate);
149
+ if (normalizedInitialDate) {
150
+ if (this.mode == 'greg') {
151
+ referenceDate = normalizedInitialDate;
152
+ }
153
+ else {
154
+ const hijriDate = this._dateUtilsService.convertDate(normalizedInitialDate, true);
155
+ referenceDate = hijriDate?.uD || this.todaysDate.ummAlQura;
156
+ }
157
+ }
158
+ else {
159
+ referenceDate =
160
+ this.mode == 'greg'
161
+ ? this.todaysDate.gregorian
162
+ : this.todaysDate.ummAlQura;
163
+ }
164
+ }
165
+ else {
166
+ referenceDate =
167
+ this.mode == 'greg'
168
+ ? this.todaysDate.gregorian
169
+ : this.todaysDate.ummAlQura;
170
+ }
171
+ if (this.mode == 'greg') {
172
+ this.gregYear =
173
+ this.futureYearsLimit == 0
174
+ ? Number(referenceDate?.split('/')[2])
175
+ : Number(referenceDate?.split('/')[2]) + this.futureYearsLimit;
176
+ for (let i = 0; i < this.gregYear; i++) {
177
+ if (i < this.pastYearsLimit) {
178
+ let val = this.gregYear--;
179
+ this.years.push(val);
180
+ }
181
+ else {
182
+ break;
183
+ }
184
+ }
185
+ this.months = this.gregMonths;
186
+ }
187
+ else {
188
+ this.ummAlQuraYear =
189
+ this.futureYearsLimit == 0
190
+ ? Number(referenceDate?.split('/')[2])
191
+ : Number(referenceDate?.split('/')[2]) + this.futureYearsLimit;
192
+ for (let i = 0; i < this.ummAlQuraYear; i++) {
193
+ if (i < this.pastYearsLimit) {
194
+ let val = this.ummAlQuraYear--;
195
+ this.years.push(val);
196
+ }
197
+ else {
198
+ break;
199
+ }
200
+ }
201
+ this.months = this.ummAlQuraMonths;
202
+ }
203
+ this.years.map((year) => {
204
+ if (year == referenceDate?.split('/')[2]) {
205
+ this.periodForm.controls['year'].setValue(year);
206
+ }
207
+ });
208
+ this.months.map((month) => {
209
+ if (month.value == referenceDate?.split('/')[1]) {
210
+ this.periodForm.controls['month'].setValue(month.value);
211
+ }
212
+ });
213
+ }
214
+ /// On change event of years and months
215
+ onPeriodChange(type) {
216
+ if (type == 'year') {
217
+ this.onYearChange.emit(this.periodForm.controls['year'].value);
218
+ }
219
+ else {
220
+ this.onMonthChange.emit(this.periodForm.controls['month'].value);
221
+ }
222
+ const days = this._dateUtilsService.getMonthData('01/' +
223
+ this.periodForm.controls['month'].value +
224
+ '/' +
225
+ this.periodForm.controls['year'].value, this.mode);
226
+ this.weeks = this.generateWeeksArray(days);
227
+ }
228
+ /// Get todays(greg and umm al qura) date info
229
+ getTodaysDateInfo() {
230
+ this.todaysDate.gregorian = this._dateUtilsService.formatDate(new Date());
231
+ this.todaysDate.ummAlQura = this._dateUtilsService.convertDate(this.todaysDate.gregorian, true)?.uD;
232
+ // Use initialDate if provided, otherwise use today's date
233
+ let dateToNavigate;
234
+ if (this.initialDate) {
235
+ // Normalize initialDate to DD/MM/YYYY format
236
+ const normalizedInitialDate = this._dateUtilsService.normalizeDateToString(this.initialDate);
237
+ if (normalizedInitialDate) {
238
+ if (this.mode == 'greg') {
239
+ dateToNavigate = normalizedInitialDate;
240
+ }
241
+ else {
242
+ // Convert to Hijri for ummAlQura mode
243
+ const hijriDate = this._dateUtilsService.convertDate(normalizedInitialDate, true);
244
+ dateToNavigate = hijriDate?.uD || this.todaysDate.ummAlQura;
245
+ }
246
+ }
247
+ else {
248
+ // Invalid initialDate, fall back to today
249
+ dateToNavigate =
250
+ this.mode == 'greg'
251
+ ? this.todaysDate.gregorian
252
+ : this.todaysDate.ummAlQura;
253
+ }
254
+ }
255
+ else {
256
+ // No initialDate provided, use today
257
+ dateToNavigate =
258
+ this.mode == 'greg'
259
+ ? this.todaysDate.gregorian
260
+ : this.todaysDate.ummAlQura;
261
+ }
262
+ this.generatetMonthData(dateToNavigate);
263
+ // Highlight initialDate or initialRange if provided
264
+ if (this.selectionMode === 'range' && (this.initialRangeStart || this.initialRangeEnd)) {
265
+ this.highlightInitialRange();
266
+ }
267
+ else if (this.initialDate) {
268
+ this.highlightInitialDate();
269
+ }
270
+ }
271
+ /// Generate month days from JSON
272
+ generatetMonthData(date) {
273
+ const days = this._dateUtilsService.getMonthData(date, this.mode);
274
+ this.weeks = this.generateWeeksArray(days);
275
+ }
276
+ /// Highlight initialDate on the calendar
277
+ highlightInitialDate() {
278
+ if (!this.initialDate) {
279
+ return;
280
+ }
281
+ const normalizedInitialDate = this._dateUtilsService.normalizeDateToString(this.initialDate);
282
+ if (!normalizedInitialDate) {
283
+ return;
284
+ }
285
+ // Find the day in the weeks array that matches initialDate
286
+ for (const week of this.weeks) {
287
+ for (const day of week) {
288
+ if (day && day.gD === normalizedInitialDate) {
289
+ // Don't select if date is disabled
290
+ if (!this.isDateDisabled(day)) {
291
+ // Mark as selected without triggering events
292
+ day.selected = true;
293
+ // Set as selectedDay based on selection mode
294
+ if (this.selectionMode === 'range') {
295
+ this.rangeStart = day;
296
+ }
297
+ else if (this.multiple) {
298
+ this.multipleSelectedDates = [day];
299
+ }
300
+ else {
301
+ this.selectedDay = day;
302
+ }
303
+ // Initialize time if enableTime is active
304
+ if (this.enableTime && !this.timeInitialized) {
305
+ this.initializeTime();
306
+ }
307
+ // Attach time to the day if it's a Date object with time
308
+ if (this.enableTime && this.initialDate instanceof Date) {
309
+ day.time = {
310
+ hour: this.initialDate.getHours(),
311
+ minute: this.initialDate.getMinutes()
312
+ };
313
+ }
314
+ }
315
+ return;
316
+ }
317
+ }
318
+ }
319
+ }
320
+ /// Highlight initial range (start and end dates) on the calendar
321
+ highlightInitialRange() {
322
+ if (!this.initialRangeStart && !this.initialRangeEnd) {
323
+ return;
324
+ }
325
+ const normalizedStartDate = this.initialRangeStart
326
+ ? this._dateUtilsService.normalizeDateToString(this.initialRangeStart)
327
+ : null;
328
+ const normalizedEndDate = this.initialRangeEnd
329
+ ? this._dateUtilsService.normalizeDateToString(this.initialRangeEnd)
330
+ : null;
331
+ let startDay = null;
332
+ let endDay = null;
333
+ // Find both start and end dates in the weeks array
334
+ for (const week of this.weeks) {
335
+ for (const day of week) {
336
+ if (day && normalizedStartDate && day.gD === normalizedStartDate) {
337
+ if (!this.isDateDisabled(day)) {
338
+ startDay = day;
339
+ }
340
+ }
341
+ if (day && normalizedEndDate && day.gD === normalizedEndDate) {
342
+ if (!this.isDateDisabled(day)) {
343
+ endDay = day;
344
+ }
345
+ }
346
+ }
347
+ }
348
+ // Set range start
349
+ if (startDay) {
350
+ startDay.selected = true;
351
+ this.rangeStart = startDay;
352
+ this.selectedDay = startDay;
353
+ // Initialize and attach time to start date
354
+ if (this.enableTime) {
355
+ if (!this.timeInitialized) {
356
+ this.initializeTime();
357
+ }
358
+ if (this.initialRangeStart instanceof Date) {
359
+ startDay.time = {
360
+ hour: this.initialRangeStart.getHours(),
361
+ minute: this.initialRangeStart.getMinutes()
362
+ };
363
+ }
364
+ else {
365
+ startDay.time = { ...this.selectedTime };
366
+ }
367
+ }
368
+ }
369
+ // Set range end if provided
370
+ if (endDay && startDay) {
371
+ // Swap if end is before start
372
+ const startDate = this.parseDateString(startDay.gD);
373
+ const endDate = this.parseDateString(endDay.gD);
374
+ if (endDate && startDate && endDate < startDate) {
375
+ // Swap
376
+ this.rangeEnd = startDay;
377
+ this.rangeStart = endDay;
378
+ endDay.selected = true;
379
+ }
380
+ else {
381
+ this.rangeEnd = endDay;
382
+ }
383
+ // Attach time to end date (inherit from start)
384
+ if (this.enableTime) {
385
+ const timeToUse = this.rangeStart.time || { ...this.selectedTime };
386
+ if (this.initialRangeEnd instanceof Date) {
387
+ this.rangeEnd.time = {
388
+ hour: this.initialRangeEnd.getHours(),
389
+ minute: this.initialRangeEnd.getMinutes()
390
+ };
391
+ }
392
+ else {
393
+ this.rangeEnd.time = { ...timeToUse };
394
+ }
395
+ // Ensure start also has time
396
+ this.rangeStart.time = { ...timeToUse };
397
+ }
398
+ // Highlight the range
399
+ this.highlightRange();
400
+ this.selectedDay = this.rangeEnd;
401
+ }
402
+ }
403
+ /// Generate month weeks
404
+ generateWeeksArray(daysArray) {
405
+ const firstDayName = daysArray[0]?.dN;
406
+ const startIndex = this.weekdaysEn.indexOf(firstDayName);
407
+ const weeks = [[]];
408
+ let currentWeek = 0;
409
+ let currentDayIndex = startIndex;
410
+ daysArray?.forEach((day) => {
411
+ if (!weeks[currentWeek]) {
412
+ weeks[currentWeek] = [];
413
+ }
414
+ weeks[currentWeek][currentDayIndex] = day;
415
+ currentDayIndex++;
416
+ if (currentDayIndex === 7) {
417
+ currentDayIndex = 0;
418
+ currentWeek++;
419
+ }
420
+ });
421
+ weeks.forEach((week) => {
422
+ while (week.length < 7) {
423
+ week.push({});
424
+ }
425
+ });
426
+ return weeks;
427
+ }
428
+ /// Change calendar mode 'greg' or 'ummAlQura'
429
+ changeCalendarMode() {
430
+ this.mode = this.mode == 'greg' ? 'ummAlQura' : 'greg';
431
+ this.initializeYearsAndMonths();
432
+ this.generatetMonthData('01/' +
433
+ this.periodForm.controls['month'].value +
434
+ '/' +
435
+ this.periodForm.controls['year'].value);
436
+ }
437
+ /// On day clicked handler
438
+ onDayClicked(day) {
439
+ if (day && day?.gD) {
440
+ // Check if day is disabled by min/max constraints
441
+ if (this.isDateDisabled(day)) {
442
+ return; // Don't allow selection of disabled dates
443
+ }
444
+ if (this.futureValidation) {
445
+ if (this.checkFutureValidation(day)) {
446
+ this.futureValidationMessage = true;
447
+ }
448
+ else {
449
+ this.futureValidationMessage = false;
450
+ this.markDaySelected(day);
451
+ }
452
+ }
453
+ else {
454
+ this.markDaySelected(day);
455
+ }
456
+ }
457
+ }
458
+ /// Mark day as selected
459
+ markDaySelected(dayInfo) {
460
+ // BACKWARD COMPATIBILITY: Range selection only when selectionMode='range'
461
+ if (this.selectionMode === 'range') {
462
+ this.handleRangeSelection(dayInfo);
463
+ return;
464
+ }
465
+ // BACKWARD COMPATIBILITY: Original behavior for single/multiple selection
466
+ if (dayInfo.selected) {
467
+ dayInfo.selected = false;
468
+ this.multipleSelectedDates = this.multipleSelectedDates.filter((day) => day !== dayInfo);
469
+ if (!this.multiple) {
470
+ this.selectedDay = undefined;
471
+ }
472
+ }
473
+ else {
474
+ if (!this.multiple) {
475
+ this.weeks.forEach((week) => {
476
+ week.forEach((day) => {
477
+ day.selected = false;
478
+ });
479
+ });
480
+ dayInfo.selected = true;
481
+ this.selectedDay = dayInfo;
482
+ this.multipleSelectedDates = [dayInfo];
483
+ // Attach current time if enableTime is active
484
+ if (this.enableTime) {
485
+ // Ensure time is initialized before attaching
486
+ if (!this.timeInitialized) {
487
+ this.initializeTime();
488
+ }
489
+ dayInfo.time = { ...this.selectedTime };
490
+ }
491
+ this.onDaySelect.emit(dayInfo);
492
+ }
493
+ else {
494
+ dayInfo.selected = true;
495
+ // Attach current time if enableTime is active
496
+ if (this.enableTime) {
497
+ // Ensure time is initialized before attaching
498
+ if (!this.timeInitialized) {
499
+ this.initializeTime();
500
+ }
501
+ dayInfo.time = { ...this.selectedTime };
502
+ }
503
+ this.onDaySelect.emit(dayInfo);
504
+ if (!this.multipleSelectedDates.includes(dayInfo)) {
505
+ this.multipleSelectedDates.push(dayInfo);
506
+ }
507
+ }
508
+ }
509
+ }
510
+ /**
511
+ * Handle range selection logic
512
+ * BACKWARD COMPATIBILITY: Only called when selectionMode='range'
513
+ *
514
+ * Range selection lifecycle:
515
+ * 1. First click → Sets rangeStart
516
+ * 2. Second click → Sets rangeEnd, highlights range
517
+ * 3. Third click → Resets range, starts new selection
518
+ */
519
+ handleRangeSelection(dayInfo) {
520
+ // First click or resetting range
521
+ if (!this.rangeStart || (this.rangeStart && this.rangeEnd)) {
522
+ this.resetRange();
523
+ this.rangeStart = dayInfo;
524
+ dayInfo.selected = true;
525
+ this.selectedDay = dayInfo;
526
+ // Attach current time if enableTime is active
527
+ if (this.enableTime) {
528
+ // Ensure selectedTime is initialized
529
+ // If time hasn't been initialized yet, initialize it now
530
+ if (!this.timeInitialized) {
531
+ this.initializeTime();
532
+ }
533
+ dayInfo.time = { ...this.selectedTime };
534
+ }
535
+ this.onDaySelect.emit({ start: dayInfo, end: null });
536
+ }
537
+ // Second click - complete the range
538
+ else if (this.rangeStart && !this.rangeEnd) {
539
+ const startDate = this.parseDateString(this.rangeStart.gD);
540
+ const endDate = this.parseDateString(dayInfo.gD);
541
+ // Swap if end is before start
542
+ if (endDate && startDate && endDate < startDate) {
543
+ this.rangeEnd = this.rangeStart;
544
+ this.rangeStart = dayInfo;
545
+ }
546
+ else {
547
+ this.rangeEnd = dayInfo;
548
+ }
549
+ // Attach time if enableTime is active
550
+ // IMPORTANT: Range end inherits time from range start (not current selectedTime)
551
+ if (this.enableTime) {
552
+ // Use rangeStart's time if it exists, otherwise use current selectedTime
553
+ const timeToUse = this.rangeStart.time || { ...this.selectedTime };
554
+ this.rangeStart.time = { ...timeToUse };
555
+ this.rangeEnd.time = { ...timeToUse };
556
+ }
557
+ this.highlightRange();
558
+ this.selectedDay = this.rangeEnd;
559
+ this.onDaySelect.emit({ start: this.rangeStart, end: this.rangeEnd });
560
+ }
561
+ }
562
+ /// On confirm button clicked
563
+ onConfirmClicked() {
564
+ // BACKWARD COMPATIBILITY: Range selection output when selectionMode='range'
565
+ if (this.selectionMode === 'range') {
566
+ if (this.rangeStart && this.rangeEnd) {
567
+ // Collect all dates in range
568
+ const rangeDates = [];
569
+ this.weeks.forEach((week) => {
570
+ week.forEach((day) => {
571
+ if (day && day.gD && (this.isInRange(day) || this.isRangeStart(day) || this.isRangeEnd(day))) {
572
+ // Attach current time if enableTime is active
573
+ if (this.enableTime && !day.time) {
574
+ day.time = { ...this.selectedTime };
575
+ }
576
+ rangeDates.push(day);
577
+ }
578
+ });
579
+ });
580
+ this.onSubmit.emit({
581
+ start: this.rangeStart,
582
+ end: this.rangeEnd,
583
+ dates: rangeDates
584
+ });
585
+ }
586
+ else {
587
+ // Incomplete range
588
+ this.onSubmit.emit({ start: this.rangeStart, end: null, dates: [] });
589
+ }
590
+ return;
591
+ }
592
+ // BACKWARD COMPATIBILITY: Original behavior for multiple/single selection
593
+ if (this.multiple) {
594
+ // For multiple dates, attach time to each if enableTime is active
595
+ if (this.enableTime) {
596
+ this.multipleSelectedDates.forEach((day) => {
597
+ if (!day.time) {
598
+ day.time = { ...this.selectedTime };
599
+ }
600
+ });
601
+ }
602
+ this.onSubmit.emit(this.multipleSelectedDates);
603
+ }
604
+ else {
605
+ // For single date, attach time if enableTime is active
606
+ if (this.enableTime && this.selectedDay) {
607
+ this.selectedDay.time = { ...this.selectedTime };
608
+ }
609
+ this.onSubmit.emit(this.selectedDay);
610
+ }
611
+ }
612
+ /// Check if date from future
613
+ checkFutureValidation(day) {
614
+ if (this._dateUtilsService.checkPastOrFuture(day?.gD, new Date()) == 'Future') {
615
+ return true;
616
+ }
617
+ }
618
+ /// Check if passed day is today or not
619
+ checkTodaysDate(day) {
620
+ return (this.todaysDate?.gregorian == day?.gD ||
621
+ this.todaysDate?.ummAlQura == day?.uD);
622
+ }
623
+ /**
624
+ * Check if a day is disabled based on min/max date constraints
625
+ * Works for both Gregorian and Hijri modes
626
+ */
627
+ isDateDisabled(day) {
628
+ if (!day || !day.gD)
629
+ return true;
630
+ // Normalize min/max dates to Gregorian DD/MM/YYYY format
631
+ const minDateStr = this.minDate
632
+ ? this._dateUtilsService.normalizeDateToString(this.minDate)
633
+ : null;
634
+ const maxDateStr = this.maxDate
635
+ ? this._dateUtilsService.normalizeDateToString(this.maxDate)
636
+ : null;
637
+ // Check if the day's Gregorian date is within range
638
+ return !this._dateUtilsService.isDateInRange(day.gD, minDateStr, maxDateStr);
639
+ }
640
+ /**
641
+ * Initialize time from current system time or initialDate
642
+ * BACKWARD COMPATIBILITY: Only called when enableTime=true
643
+ *
644
+ * Priority:
645
+ * 1. If initialDate has time, use that
646
+ * 2. If selectedDay has time, use that
647
+ * 3. Otherwise, use current system time
648
+ */
649
+ initializeTime() {
650
+ let timeSet = false;
651
+ // Check if initialDate has time information
652
+ if (this.initialDate && this.initialDate instanceof Date) {
653
+ this.selectedTime = {
654
+ hour: this.initialDate.getHours(),
655
+ minute: this.initialDate.getMinutes(),
656
+ };
657
+ timeSet = true;
658
+ }
659
+ // If no time from initialDate, use current system time
660
+ if (!timeSet) {
661
+ const now = new Date();
662
+ this.selectedTime = {
663
+ hour: now.getHours(),
664
+ minute: now.getMinutes(),
665
+ };
666
+ }
667
+ // Mark that time has been initialized
668
+ this.timeInitialized = true;
669
+ // BACKWARD COMPATIBILITY: Only set meridian when useMeridian=true
670
+ if (this.useMeridian) {
671
+ this.meridian = this.selectedTime.hour >= 12 ? 'PM' : 'AM';
672
+ }
673
+ }
674
+ /**
675
+ * Increment hour value with wraparound (0-23)
676
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
677
+ */
678
+ incrementHour() {
679
+ this.selectedTime.hour = (this.selectedTime.hour + 1) % 24;
680
+ this.updateSelectedDayTime();
681
+ }
682
+ /**
683
+ * Decrement hour value with wraparound (0-23)
684
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
685
+ */
686
+ decrementHour() {
687
+ this.selectedTime.hour = (this.selectedTime.hour - 1 + 24) % 24;
688
+ this.updateSelectedDayTime();
689
+ }
690
+ /**
691
+ * Increment minute value with wraparound (0-59)
692
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
693
+ */
694
+ incrementMinute() {
695
+ this.selectedTime.minute = (this.selectedTime.minute + 1) % 60;
696
+ this.updateSelectedDayTime();
697
+ }
698
+ /**
699
+ * Decrement minute value with wraparound (0-59)
700
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
701
+ */
702
+ decrementMinute() {
703
+ this.selectedTime.minute = (this.selectedTime.minute - 1 + 60) % 60;
704
+ this.updateSelectedDayTime();
705
+ }
706
+ /**
707
+ * Handle keyboard input for hours
708
+ * Validates and clamps to 0-23 range
709
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
710
+ */
711
+ onHourInputChange(event) {
712
+ let value = parseInt(event.target.value, 10);
713
+ if (isNaN(value) || value < 0) {
714
+ value = 0;
715
+ }
716
+ else if (value > 23) {
717
+ value = 23;
718
+ }
719
+ this.selectedTime.hour = value;
720
+ event.target.value = value;
721
+ this.updateSelectedDayTime();
722
+ }
723
+ /**
724
+ * Handle keyboard input for minutes
725
+ * Validates and clamps to 0-59 range
726
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
727
+ */
728
+ onMinuteInputChange(event) {
729
+ let value = parseInt(event.target.value, 10);
730
+ if (isNaN(value) || value < 0) {
731
+ value = 0;
732
+ }
733
+ else if (value > 59) {
734
+ value = 59;
735
+ }
736
+ this.selectedTime.minute = value;
737
+ event.target.value = value;
738
+ this.updateSelectedDayTime();
739
+ }
740
+ /**
741
+ * Handle keyboard arrow keys for hour/minute input
742
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
743
+ */
744
+ onTimeKeydown(event, type) {
745
+ if (event.key === 'ArrowUp') {
746
+ event.preventDefault();
747
+ if (type === 'hour') {
748
+ this.incrementHour();
749
+ }
750
+ else {
751
+ this.incrementMinute();
752
+ }
753
+ }
754
+ else if (event.key === 'ArrowDown') {
755
+ event.preventDefault();
756
+ if (type === 'hour') {
757
+ this.decrementHour();
758
+ }
759
+ else {
760
+ this.decrementMinute();
761
+ }
762
+ }
763
+ }
764
+ /**
765
+ * Update the selected day's time property when time changes
766
+ * BACKWARD COMPATIBILITY: Only called when enableTime=true
767
+ */
768
+ updateSelectedDayTime() {
769
+ if (this.selectedDay) {
770
+ this.selectedDay.time = { ...this.selectedTime };
771
+ }
772
+ }
773
+ /**
774
+ * Get display hour for 12-hour format
775
+ * BACKWARD COMPATIBILITY: Only used when useMeridian=true
776
+ *
777
+ * Conversion:
778
+ * - 0 (midnight) → 12 AM
779
+ * - 1-11 (AM) → 1-11 AM
780
+ * - 12 (noon) → 12 PM
781
+ * - 13-23 (PM) → 1-11 PM
782
+ *
783
+ * IMPORTANT: Hour 0 is NEVER displayed as 0, always as 12
784
+ */
785
+ getDisplayHour() {
786
+ if (!this.useMeridian) {
787
+ return this.selectedTime.hour;
788
+ }
789
+ const hour = this.selectedTime.hour;
790
+ // Midnight (0) → 12
791
+ if (hour === 0) {
792
+ return 12;
793
+ }
794
+ // 1-12 → 1-12 (no change)
795
+ else if (hour <= 12) {
796
+ return hour;
797
+ }
798
+ // 13-23 → 1-11 (subtract 12)
799
+ else {
800
+ return hour - 12;
801
+ }
802
+ }
803
+ /**
804
+ * Toggle AM/PM meridian
805
+ * BACKWARD COMPATIBILITY: Only available when useMeridian=true
806
+ *
807
+ * When toggling:
808
+ * - Adds or subtracts 12 hours
809
+ * - Maintains internal 24-hour format
810
+ */
811
+ toggleMeridian() {
812
+ if (this.meridian === 'AM') {
813
+ this.meridian = 'PM';
814
+ // Add 12 hours if not already in PM range
815
+ if (this.selectedTime.hour < 12) {
816
+ this.selectedTime.hour += 12;
817
+ }
818
+ }
819
+ else {
820
+ this.meridian = 'AM';
821
+ // Subtract 12 hours if in PM range
822
+ if (this.selectedTime.hour >= 12) {
823
+ this.selectedTime.hour -= 12;
824
+ }
825
+ }
826
+ this.updateSelectedDayTime();
827
+ }
828
+ /**
829
+ * Increment hour in 12-hour mode
830
+ * BACKWARD COMPATIBILITY: Only used when useMeridian=true
831
+ */
832
+ incrementHour12() {
833
+ let displayHour = this.getDisplayHour();
834
+ displayHour = (displayHour % 12) + 1; // 1-12 cycle
835
+ // Convert back to 24-hour format
836
+ if (this.meridian === 'AM') {
837
+ this.selectedTime.hour = displayHour === 12 ? 0 : displayHour;
838
+ }
839
+ else {
840
+ this.selectedTime.hour = displayHour === 12 ? 12 : displayHour + 12;
841
+ }
842
+ this.updateSelectedDayTime();
843
+ }
844
+ /**
845
+ * Decrement hour in 12-hour mode
846
+ * BACKWARD COMPATIBILITY: Only used when useMeridian=true
847
+ */
848
+ decrementHour12() {
849
+ let displayHour = this.getDisplayHour();
850
+ displayHour = displayHour === 1 ? 12 : displayHour - 1; // 1-12 cycle
851
+ // Convert back to 24-hour format
852
+ if (this.meridian === 'AM') {
853
+ this.selectedTime.hour = displayHour === 12 ? 0 : displayHour;
854
+ }
855
+ else {
856
+ this.selectedTime.hour = displayHour === 12 ? 12 : displayHour + 12;
857
+ }
858
+ this.updateSelectedDayTime();
859
+ }
860
+ /**
861
+ * Handle 12-hour input change
862
+ * BACKWARD COMPATIBILITY: Only used when useMeridian=true
863
+ *
864
+ * IMPORTANT: Input must be 1-12, never 0
865
+ * - User types 0 → converted to 12
866
+ * - User types > 12 → clamped to 12
867
+ */
868
+ onHour12InputChange(event) {
869
+ let value = parseInt(event.target.value, 10);
870
+ // Validate 1-12 range (0 is not allowed in 12-hour format)
871
+ if (isNaN(value) || value < 1 || value === 0) {
872
+ value = 12; // Default to 12 if invalid or 0
873
+ }
874
+ else if (value > 12) {
875
+ value = 12;
876
+ }
877
+ // Convert to 24-hour format
878
+ if (this.meridian === 'AM') {
879
+ this.selectedTime.hour = value === 12 ? 0 : value;
880
+ }
881
+ else {
882
+ this.selectedTime.hour = value === 12 ? 12 : value + 12;
883
+ }
884
+ event.target.value = value;
885
+ this.updateSelectedDayTime();
886
+ }
887
+ /**
888
+ * Check if a date is within the current range
889
+ * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
890
+ */
891
+ isInRange(day) {
892
+ if (this.selectionMode !== 'range' || !this.rangeStart || !this.rangeEnd || !day?.gD) {
893
+ return false;
894
+ }
895
+ const dayDate = this.parseDateString(day.gD);
896
+ const startDate = this.parseDateString(this.rangeStart.gD);
897
+ const endDate = this.parseDateString(this.rangeEnd.gD);
898
+ if (!dayDate || !startDate || !endDate) {
899
+ return false;
900
+ }
901
+ return dayDate >= startDate && dayDate <= endDate;
902
+ }
903
+ /**
904
+ * Check if a date is the range start
905
+ * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
906
+ */
907
+ isRangeStart(day) {
908
+ return this.selectionMode === 'range' &&
909
+ this.rangeStart?.gD === day?.gD;
910
+ }
911
+ /**
912
+ * Check if a date is the range end
913
+ * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
914
+ */
915
+ isRangeEnd(day) {
916
+ return this.selectionMode === 'range' &&
917
+ this.rangeEnd?.gD === day?.gD;
918
+ }
919
+ /**
920
+ * Reset range selection
921
+ * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
922
+ */
923
+ resetRange() {
924
+ if (this.selectionMode !== 'range') {
925
+ return;
926
+ }
927
+ // Clear range highlighting
928
+ this.weeks.forEach((week) => {
929
+ week.forEach((day) => {
930
+ if (day && day.gD) {
931
+ day.selected = false;
932
+ }
933
+ });
934
+ });
935
+ this.rangeStart = undefined;
936
+ this.rangeEnd = undefined;
937
+ this.selectedDay = undefined;
938
+ }
939
+ /**
940
+ * Parse date string (DD/MM/YYYY) to Date object
941
+ * Helper for range comparison
942
+ */
943
+ parseDateString(dateStr) {
944
+ if (!dateStr)
945
+ return null;
946
+ const parts = dateStr.split('/');
947
+ if (parts.length !== 3)
948
+ return null;
949
+ const day = parseInt(parts[0], 10);
950
+ const month = parseInt(parts[1], 10) - 1; // Month is 0-indexed
951
+ const year = parseInt(parts[2], 10);
952
+ return new Date(year, month, day);
953
+ }
954
+ /**
955
+ * Highlight all dates in range
956
+ * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
957
+ */
958
+ highlightRange() {
959
+ if (this.selectionMode !== 'range' || !this.rangeStart || !this.rangeEnd) {
960
+ return;
961
+ }
962
+ this.weeks.forEach((week) => {
963
+ week.forEach((day) => {
964
+ if (day && day.gD) {
965
+ day.selected = this.isInRange(day) ||
966
+ this.isRangeStart(day) ||
967
+ this.isRangeEnd(day);
968
+ }
969
+ });
970
+ });
971
+ }
972
+ }
973
+ HijriGregorianDatepickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HijriGregorianDatepickerComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: i2.DateUtilitiesService }], target: i0.ɵɵFactoryTarget.Component });
974
+ HijriGregorianDatepickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: HijriGregorianDatepickerComponent, selector: "hijri-gregorian-datepicker", inputs: { markToday: "markToday", canChangeMode: "canChangeMode", todaysDateSection: "todaysDateSection", futureValidation: "futureValidation", disableYearPicker: "disableYearPicker", disableMonthPicker: "disableMonthPicker", disableDayPicker: "disableDayPicker", multiple: "multiple", isRequired: "isRequired", showConfirmButton: "showConfirmButton", futureValidationMessage: "futureValidationMessage", arabicLayout: "arabicLayout", mode: "mode", dir: "dir", locale: "locale", submitTextButton: "submitTextButton", todaysDateText: "todaysDateText", ummAlQuraDateText: "ummAlQuraDateText", monthSelectLabel: "monthSelectLabel", yearSelectLabel: "yearSelectLabel", futureValidationMessageEn: "futureValidationMessageEn", futureValidationMessageAr: "futureValidationMessageAr", theme: "theme", pastYearsLimit: "pastYearsLimit", futureYearsLimit: "futureYearsLimit", styles: "styles", enableTime: "enableTime", minDate: "minDate", maxDate: "maxDate", initialDate: "initialDate", initialRangeStart: "initialRangeStart", initialRangeEnd: "initialRangeEnd", useMeridian: "useMeridian", selectionMode: "selectionMode" }, outputs: { onSubmit: "onSubmit", onDaySelect: "onDaySelect", onMonthChange: "onMonthChange", onYearChange: "onYearChange" }, host: { properties: { "style.font-family": "this.fontFamilyStyle" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar-container\" [dir]=\"dir\" [attr.lang]=\"locale\">\n <div\n class=\"toggle-section\"\n [dir]=\"dir\"\n *ngIf=\"canChangeMode\"\n [ngStyle]=\"{ color: styles.primaryColor }\"\n >\n <span> {{ ummAlQuraDateText }} </span>\n <label class=\"switch\">\n <input\n type=\"checkbox\"\n [disabled]=\"!canChangeMode\"\n [checked]=\"mode === 'ummAlQura'\"\n (change)=\"changeCalendarMode()\"\n #calendarCheckbox\n />\n <span\n class=\"slider\"\n [ngStyle]=\"\n calendarCheckbox.checked\n ? { 'background-color': styles.primaryColor }\n : { 'background-color': styles.backgroundColor }\n \"\n ></span>\n </label>\n </div>\n\n <div\n class=\"todays-date-section\"\n *ngIf=\"todaysDateSection\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n color: styles.primaryColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <div\n class=\"text-info\"\n [ngClass]=\"{\n order: dir == 'rtl'\n }\"\n >\n <p>{{ todaysDateText }}</p>\n </div>\n\n <div\n class=\"data\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n 'background-color': styles.todaysDateBgColor,\n color: styles.todaysDateTextColor\n }\"\n >\n <p *ngIf=\"mode == 'ummAlQura'\">\n <!-- {{todaysDate.ummAlQura}} -->\n {{\n locale == \"ar\"\n ? _dateUtilsService.convertDateNumerals(todaysDate.ummAlQura, \"ar\")\n : todaysDate.ummAlQura\n }}\n </p>\n <p *ngIf=\"mode == 'greg'\">\n {{\n locale == \"ar\"\n ? _dateUtilsService.convertDateNumerals(todaysDate.gregorian, \"ar\")\n : todaysDate.gregorian\n }}\n </p>\n </div>\n </div>\n\n <div class=\"period-container\">\n <form [formGroup]=\"periodForm\" class=\"period-form\">\n <div\n class=\"select-item\"\n [ngClass]=\"{\n order: dir == 'ltr'\n }\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <label *ngIf=\"!periodForm.controls['year'].value\">{{\n yearSelectLabel\n }}</label>\n\n <select\n formControlName=\"year\"\n class=\"{{ 'icon-' + dir }}\"\n placeholder=\"\u0627\u0644\u0633\u0646\u0629\"\n (change)=\"onPeriodChange('year')\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n color: styles.primaryColor,\n 'font-family': styles.fontFamily\n }\"\n >\n <option *ngFor=\"let year of years\" [ngValue]=\"year\">\n {{ locale == \"ar\" ? _dateUtilsService.parseEnglish(year) : year }}\n </option>\n </select>\n </div>\n\n <div\n class=\"select-item\"\n [ngClass]=\"{\n order: dir == 'rtl'\n }\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <label *ngIf=\"!periodForm.controls['month'].value\">{{\n monthSelectLabel\n }}</label>\n <select\n class=\"{{ 'icon-' + dir }}\"\n formControlName=\"month\"\n (change)=\"onPeriodChange('month')\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n color: styles.primaryColor,\n 'font-family': styles.fontFamily\n }\"\n >\n <option *ngFor=\"let month of months\" [ngValue]=\"month.value\">\n {{ locale == \"ar\" ? month?.labelAr : month?.labelEn }}\n </option>\n </select>\n </div>\n </form>\n </div>\n\n <div\n class=\"calendar-layout\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <div class=\"week-days\">\n <div\n class=\"week-day\"\n [ngStyle]=\"{ color: styles.dayNameColor }\"\n *ngFor=\"let date of locale == 'ar' ? weekdaysAr : weekdaysEn\"\n >\n {{ date }}\n </div>\n </div>\n\n <div [dir]=\"dir\">\n <div class=\"week\" *ngFor=\"let week of weeks\">\n <div\n class=\"day\"\n *ngFor=\"let day of week\"\n (click)=\"disableDayPicker == false ? onDayClicked(day) : ''\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n color: styles.dayColor\n }\"\n >\n <div\n id=\"greg-day\"\n [ngClass]=\"{\n 'todays-date': checkTodaysDate(day),\n 'selected-date': day?.selected == true\n }\"\n [ngStyle]=\"{\n border:\n markToday && checkTodaysDate(day)\n ? '1px solid ' + styles.secondaryColor\n : '',\n 'background-color':\n day?.selected == true ? styles.secondaryColor : '',\n color:\n (day?.selected == true ? styles.todaysDateTextColor : '') ||\n (checkFutureValidation(day) && futureValidation\n ? styles.disabledDayColor\n : '') ||\n (isDateDisabled(day) ? styles.disabledDayColor : ''),\n opacity: isDateDisabled(day) ? '0.4' : '1',\n cursor: isDateDisabled(day) ? 'not-allowed' : 'pointer'\n }\"\n >\n <span *ngIf=\"mode == 'greg'\">{{\n locale == \"ar\"\n ? _dateUtilsService.parseEnglish(\n day?.gD?.split(\"/\")[0] | number\n )\n : (day?.gD?.split(\"/\")[0] | number)\n }}</span>\n\n <span id=\"ummAlQura-day\" *ngIf=\"mode == 'ummAlQura'\">{{\n locale == \"ar\"\n ? _dateUtilsService.parseEnglish(\n day?.uD?.split(\"/\")[0] | number\n )\n : (day?.uD?.split(\"/\")[0] | number)\n }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"future-validation\" dir=\"auto\" *ngIf=\"futureValidationMessage\">\n <span *ngIf=\"locale == 'ar'\">\n {{ futureValidationMessageAr }}\n </span>\n <span *ngIf=\"locale == 'en'\">\n {{ futureValidationMessageEn }}\n </span>\n </div>\n\n <!-- Time Picker Section -->\n <!-- BACKWARD COMPATIBILITY: This section only renders when enableTime=true -->\n <div class=\"time-picker-section\" *ngIf=\"enableTime\" [dir]=\"'ltr'\">\n <div class=\"time-picker-wrapper\">\n <!-- Hour Input with Arrows -->\n <div class=\"time-input-container\">\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-up\"\n (click)=\"useMeridian ? incrementHour12() : incrementHour()\"\n tabindex=\"-1\"\n aria-label=\"Increment hour\"\n >\n <i class=\"ri-arrow-drop-up-line\"></i>\n </button>\n <input\n type=\"number\"\n class=\"time-field\"\n [value]=\"getDisplayHour().toString().padStart(2, '0')\"\n (input)=\"\n useMeridian\n ? onHour12InputChange($event)\n : onHourInputChange($event)\n \"\n (keydown)=\"onTimeKeydown($event, 'hour')\"\n [min]=\"useMeridian ? 1 : 0\"\n [max]=\"useMeridian ? 12 : 23\"\n aria-label=\"Hour\"\n />\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-down\"\n (click)=\"useMeridian ? decrementHour12() : decrementHour()\"\n tabindex=\"-1\"\n aria-label=\"Decrement hour\"\n >\n <i class=\"ri-arrow-drop-down-line\"></i>\n </button>\n </div>\n\n <!-- Colon Separator -->\n <span class=\"time-colon\">:</span>\n\n <!-- Minute Input with Arrows -->\n <div class=\"time-input-container\">\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-up\"\n (click)=\"incrementMinute()\"\n tabindex=\"-1\"\n aria-label=\"Increment minute\"\n >\n <i class=\"ri-arrow-drop-up-line\"></i>\n </button>\n <input\n type=\"number\"\n class=\"time-field\"\n [value]=\"selectedTime.minute.toString().padStart(2, '0')\"\n (input)=\"onMinuteInputChange($event)\"\n (keydown)=\"onTimeKeydown($event, 'minute')\"\n min=\"0\"\n max=\"59\"\n aria-label=\"Minute\"\n />\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-down\"\n (click)=\"decrementMinute()\"\n tabindex=\"-1\"\n aria-label=\"Decrement minute\"\n >\n <i class=\"ri-arrow-drop-down-line\"></i>\n </button>\n </div>\n\n <!-- AM/PM Button Group (only when useMeridian=true) -->\n <!-- BACKWARD COMPATIBILITY: This only renders when useMeridian=true -->\n <div class=\"meridian-toggle-group\" *ngIf=\"useMeridian\">\n <button\n type=\"button\"\n class=\"meridian-btn\"\n [class.active]=\"meridian === 'AM'\"\n (click)=\"meridian !== 'AM' && toggleMeridian()\"\n aria-label=\"Select AM\"\n >\n AM\n </button>\n <button\n type=\"button\"\n class=\"meridian-btn\"\n [class.active]=\"meridian === 'PM'\"\n (click)=\"meridian !== 'PM' && toggleMeridian()\"\n aria-label=\"Select PM\"\n >\n PM\n </button>\n </div>\n </div>\n </div>\n\n <div>\n <button\n type=\"button\"\n class=\"confirm-btn\"\n [disabled]=\"\n isRequired &&\n ((!selectedDay && !multiple) ||\n (!multipleSelectedDates.length && multiple))\n \"\n (click)=\"onConfirmClicked()\"\n *ngIf=\"showConfirmButton\"\n [ngStyle]=\"{\n 'background-color': styles.secondaryColor,\n color: styles.confirmBtnTextColor,\n 'font-family': styles.fontFamily,\n 'border-radius': styles.borderRadius\n }\"\n >\n {{ submitTextButton }}\n </button>\n </div>\n</div>\n", styles: [".calendar-container{margin:auto;display:block;border-radius:20px;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-weight:400}.calendar-container[dir=rtl],.calendar-container[lang=ar]{font-family:Zain,Arabic Typesetting,Tahoma,sans-serif;font-weight:300;letter-spacing:0;line-height:1.7}.calendar-container .todays-date-section{border-radius:4px;margin-top:12px;display:flex;align-items:center;justify-content:space-between;padding-left:10px;padding-right:10px}.calendar-container .todays-date-section .text-info{display:flex;align-items:center}.calendar-container .todays-date-section .text-info p{font-size:17px;font-weight:500;letter-spacing:.02em}[dir=rtl] .calendar-container .todays-date-section .text-info p,[lang=ar] .calendar-container .todays-date-section .text-info p{font-weight:400;letter-spacing:0}[dir=rtl] .calendar-container .todays-date-section .data p,[lang=ar] .calendar-container .todays-date-section .data p{font-weight:300}.calendar-container .todays-date-section .data{border-radius:8px}.calendar-container .todays-date-section .data p{font-size:14px;font-weight:400;margin:5px 10px}.calendar-container .period-container{display:flex;justify-content:space-between;margin-top:8px}.calendar-container .period-container .period-form{width:100%;display:flex;justify-content:space-between}.calendar-container .period-container .period-form .select-item{width:42.5%;border-radius:4px;height:50px;padding-left:10px;padding-right:10px}.calendar-container .period-container .period-form label{margin-right:10px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-container .period-container .period-form label,[lang=ar] .calendar-container .period-container .period-form label{font-weight:400}.calendar-container .period-container .period-form select{width:100%;height:50px;border:none;font-size:16px;font-weight:500;display:block;margin:auto;background:url(\"data:image/svg+xml;utf8,<svg viewBox='0 0 140 140' width='15' height='15' xmlns='http://www.w3.org/2000/svg'><g><path d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' fill='black'/></g></svg>\") no-repeat 95% 50%;-webkit-appearance:none;appearance:none;cursor:pointer}.calendar-container .period-container .period-form select option,.calendar-container [dir=rtl] .period-container select{font-weight:400}.calendar-container [dir=rtl] .period-container select option{font-weight:300}.icon-ltr{background-position:right}.icon-rtl{background-position:left!important}select:focus{outline:none}.calendar-layout{border-radius:4px;margin:8px auto auto;display:block;padding-bottom:5px}.calendar-layout .week-days{text-align:center;margin-top:5px;display:flex;justify-content:space-evenly}.calendar-layout .week-days .week-day{display:inline-block;width:13%;text-align:center;padding:15px 0 10px;font-weight:600;font-size:13px;text-transform:uppercase;letter-spacing:.05em}[dir=rtl] .calendar-layout .week-days{flex-direction:row-reverse!important}[dir=rtl] .calendar-layout .week-days .week-day{font-weight:700;letter-spacing:0;text-transform:none;font-size:14px}.calendar-layout .week{text-align:center;display:flex;justify-content:space-evenly}.calendar-layout .day{display:inline-flex;width:13%;height:5.5vh;justify-content:center;align-items:center;cursor:pointer;font-weight:500;transition:all .2s ease;border-radius:4px}.calendar-layout .day:hover:not(.disabled-day){transform:scale(1.05)}[dir=rtl] .calendar-layout .day{font-weight:400}.calendar-layout #greg-day{position:relative;min-width:20px}.calendar-layout #greg-day span{font-size:14px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #greg-day span,[lang=ar] .calendar-layout #greg-day span{font-weight:400}.calendar-layout #ummAlQura-day{font-size:11px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #ummAlQura-day,[lang=ar] .calendar-layout #ummAlQura-day{font-weight:400}.calendar-layout .todays-date,.calendar-layout .selected-date{padding:10px;border-radius:5px}.confirm-btn{height:50px;width:100%;border:none;font-size:16px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;margin:8px auto 0;box-shadow:none!important;cursor:pointer;transition:all .2s ease;border-radius:8px}.confirm-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 12px #00000026!important}.confirm-btn:disabled{opacity:.5;cursor:not-allowed}[dir=rtl] .confirm-btn{font-weight:700;letter-spacing:0;text-transform:none;font-size:17px}.toggle-section{display:flex;align-items:center;justify-content:space-between}.toggle-section label{text-align:right;font-size:19px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .toggle-section label,[lang=ar] .toggle-section label{font-weight:400}.toggle-section .switch{position:relative;display:inline-block;width:50px;height:24px}.toggle-section .switch input{opacity:0;width:0;height:0}.toggle-section .slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s;border-radius:24px}.toggle-section .slider:before{content:\"\";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background-color:#fff;transition:.4s;border-radius:50%}.toggle-section input:checked+.slider:before{transform:translate(26px)}.order{order:1}.future-validation{text-align:center;color:#eb445a;margin-top:8px;font-size:13px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .future-validation,[lang=ar] .future-validation{font-weight:400;line-height:1.8}.time-picker-section{padding:10px;background:transparent;border-radius:0;font-family:Poppins,sans-serif}.time-picker-section .time-picker-wrapper{display:flex;align-items:center;justify-content:center;gap:8px}.time-picker-section .time-picker-wrapper .time-input-container{position:relative;display:inline-flex;flex-direction:column;align-items:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{width:100%;height:20px;border:1px solid #ddd;background:#ffffff;color:#5b479c;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease;padding:0;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow i{font-size:20px;line-height:1;pointer-events:none;opacity:.7;transition:opacity .2s ease;display:flex;align-items:center;justify-content:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:hover i{opacity:1}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:active{background:#e9ecef}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:focus{outline:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-up{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-down{border-radius:0 0 4px 4px;border-top:none}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:25px;border:1px solid #ddd;border-top:none;border-bottom:none;background:#ffffff;font-size:18px;font-weight:600;color:#333;text-align:center;padding:0;margin:0;transition:all .2s ease;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;-webkit-appearance:textfield;appearance:textfield}[dir=rtl] .time-picker-section .time-picker-wrapper .time-input-container .time-field,[lang=ar] .time-picker-section .time-picker-wrapper .time-input-container .time-field{font-weight:700}.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-outer-spin-button,.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-inner-spin-button{-webkit-appearance:none;appearance:none;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-field:focus{outline:none;box-shadow:0 0 0 2px #5b479c1a;z-index:1}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px;font-weight:600;color:#5b479c;padding:0 4px;-webkit-user-select:none;user-select:none;line-height:1;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .time-colon,[lang=ar] .time-picker-section .time-picker-wrapper .time-colon{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group{display:flex;flex-direction:column;gap:0;margin-left:8px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:25px;border:1px solid #ddd;background:#ffffff;color:#666;font-size:13px;font-weight:600;text-align:center;padding:0;cursor:pointer;transition:all .2s ease;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn,[lang=ar] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:first-child{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:last-child{border-radius:0 0 4px 4px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:hover:not(.active){background:#f8f9fa;border-color:#00ace4;color:#00ace4}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:active{transform:scale(.98)}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:focus{outline:none;border-color:#00ace4;box-shadow:0 0 0 2px #00ace41a;z-index:1}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn.active{background:rgb(0,77,97);border-color:#004d61;color:#fff;cursor:default}@media (max-width: 480px){.time-picker-section{padding:12px}.time-picker-section .time-picker-wrapper{gap:6px}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{height:18px}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:36px;font-size:20px}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px}.time-picker-section .time-picker-wrapper .meridian-toggle-group{margin-left:6px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:27px;font-size:12px}}\n"], dependencies: [{ kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }] });
975
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HijriGregorianDatepickerComponent, decorators: [{
976
+ type: Component,
977
+ args: [{ selector: 'hijri-gregorian-datepicker', template: "<div class=\"calendar-container\" [dir]=\"dir\" [attr.lang]=\"locale\">\n <div\n class=\"toggle-section\"\n [dir]=\"dir\"\n *ngIf=\"canChangeMode\"\n [ngStyle]=\"{ color: styles.primaryColor }\"\n >\n <span> {{ ummAlQuraDateText }} </span>\n <label class=\"switch\">\n <input\n type=\"checkbox\"\n [disabled]=\"!canChangeMode\"\n [checked]=\"mode === 'ummAlQura'\"\n (change)=\"changeCalendarMode()\"\n #calendarCheckbox\n />\n <span\n class=\"slider\"\n [ngStyle]=\"\n calendarCheckbox.checked\n ? { 'background-color': styles.primaryColor }\n : { 'background-color': styles.backgroundColor }\n \"\n ></span>\n </label>\n </div>\n\n <div\n class=\"todays-date-section\"\n *ngIf=\"todaysDateSection\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n color: styles.primaryColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <div\n class=\"text-info\"\n [ngClass]=\"{\n order: dir == 'rtl'\n }\"\n >\n <p>{{ todaysDateText }}</p>\n </div>\n\n <div\n class=\"data\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n 'background-color': styles.todaysDateBgColor,\n color: styles.todaysDateTextColor\n }\"\n >\n <p *ngIf=\"mode == 'ummAlQura'\">\n <!-- {{todaysDate.ummAlQura}} -->\n {{\n locale == \"ar\"\n ? _dateUtilsService.convertDateNumerals(todaysDate.ummAlQura, \"ar\")\n : todaysDate.ummAlQura\n }}\n </p>\n <p *ngIf=\"mode == 'greg'\">\n {{\n locale == \"ar\"\n ? _dateUtilsService.convertDateNumerals(todaysDate.gregorian, \"ar\")\n : todaysDate.gregorian\n }}\n </p>\n </div>\n </div>\n\n <div class=\"period-container\">\n <form [formGroup]=\"periodForm\" class=\"period-form\">\n <div\n class=\"select-item\"\n [ngClass]=\"{\n order: dir == 'ltr'\n }\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <label *ngIf=\"!periodForm.controls['year'].value\">{{\n yearSelectLabel\n }}</label>\n\n <select\n formControlName=\"year\"\n class=\"{{ 'icon-' + dir }}\"\n placeholder=\"\u0627\u0644\u0633\u0646\u0629\"\n (change)=\"onPeriodChange('year')\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n color: styles.primaryColor,\n 'font-family': styles.fontFamily\n }\"\n >\n <option *ngFor=\"let year of years\" [ngValue]=\"year\">\n {{ locale == \"ar\" ? _dateUtilsService.parseEnglish(year) : year }}\n </option>\n </select>\n </div>\n\n <div\n class=\"select-item\"\n [ngClass]=\"{\n order: dir == 'rtl'\n }\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <label *ngIf=\"!periodForm.controls['month'].value\">{{\n monthSelectLabel\n }}</label>\n <select\n class=\"{{ 'icon-' + dir }}\"\n formControlName=\"month\"\n (change)=\"onPeriodChange('month')\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n color: styles.primaryColor,\n 'font-family': styles.fontFamily\n }\"\n >\n <option *ngFor=\"let month of months\" [ngValue]=\"month.value\">\n {{ locale == \"ar\" ? month?.labelAr : month?.labelEn }}\n </option>\n </select>\n </div>\n </form>\n </div>\n\n <div\n class=\"calendar-layout\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <div class=\"week-days\">\n <div\n class=\"week-day\"\n [ngStyle]=\"{ color: styles.dayNameColor }\"\n *ngFor=\"let date of locale == 'ar' ? weekdaysAr : weekdaysEn\"\n >\n {{ date }}\n </div>\n </div>\n\n <div [dir]=\"dir\">\n <div class=\"week\" *ngFor=\"let week of weeks\">\n <div\n class=\"day\"\n *ngFor=\"let day of week\"\n (click)=\"disableDayPicker == false ? onDayClicked(day) : ''\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n color: styles.dayColor\n }\"\n >\n <div\n id=\"greg-day\"\n [ngClass]=\"{\n 'todays-date': checkTodaysDate(day),\n 'selected-date': day?.selected == true\n }\"\n [ngStyle]=\"{\n border:\n markToday && checkTodaysDate(day)\n ? '1px solid ' + styles.secondaryColor\n : '',\n 'background-color':\n day?.selected == true ? styles.secondaryColor : '',\n color:\n (day?.selected == true ? styles.todaysDateTextColor : '') ||\n (checkFutureValidation(day) && futureValidation\n ? styles.disabledDayColor\n : '') ||\n (isDateDisabled(day) ? styles.disabledDayColor : ''),\n opacity: isDateDisabled(day) ? '0.4' : '1',\n cursor: isDateDisabled(day) ? 'not-allowed' : 'pointer'\n }\"\n >\n <span *ngIf=\"mode == 'greg'\">{{\n locale == \"ar\"\n ? _dateUtilsService.parseEnglish(\n day?.gD?.split(\"/\")[0] | number\n )\n : (day?.gD?.split(\"/\")[0] | number)\n }}</span>\n\n <span id=\"ummAlQura-day\" *ngIf=\"mode == 'ummAlQura'\">{{\n locale == \"ar\"\n ? _dateUtilsService.parseEnglish(\n day?.uD?.split(\"/\")[0] | number\n )\n : (day?.uD?.split(\"/\")[0] | number)\n }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"future-validation\" dir=\"auto\" *ngIf=\"futureValidationMessage\">\n <span *ngIf=\"locale == 'ar'\">\n {{ futureValidationMessageAr }}\n </span>\n <span *ngIf=\"locale == 'en'\">\n {{ futureValidationMessageEn }}\n </span>\n </div>\n\n <!-- Time Picker Section -->\n <!-- BACKWARD COMPATIBILITY: This section only renders when enableTime=true -->\n <div class=\"time-picker-section\" *ngIf=\"enableTime\" [dir]=\"'ltr'\">\n <div class=\"time-picker-wrapper\">\n <!-- Hour Input with Arrows -->\n <div class=\"time-input-container\">\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-up\"\n (click)=\"useMeridian ? incrementHour12() : incrementHour()\"\n tabindex=\"-1\"\n aria-label=\"Increment hour\"\n >\n <i class=\"ri-arrow-drop-up-line\"></i>\n </button>\n <input\n type=\"number\"\n class=\"time-field\"\n [value]=\"getDisplayHour().toString().padStart(2, '0')\"\n (input)=\"\n useMeridian\n ? onHour12InputChange($event)\n : onHourInputChange($event)\n \"\n (keydown)=\"onTimeKeydown($event, 'hour')\"\n [min]=\"useMeridian ? 1 : 0\"\n [max]=\"useMeridian ? 12 : 23\"\n aria-label=\"Hour\"\n />\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-down\"\n (click)=\"useMeridian ? decrementHour12() : decrementHour()\"\n tabindex=\"-1\"\n aria-label=\"Decrement hour\"\n >\n <i class=\"ri-arrow-drop-down-line\"></i>\n </button>\n </div>\n\n <!-- Colon Separator -->\n <span class=\"time-colon\">:</span>\n\n <!-- Minute Input with Arrows -->\n <div class=\"time-input-container\">\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-up\"\n (click)=\"incrementMinute()\"\n tabindex=\"-1\"\n aria-label=\"Increment minute\"\n >\n <i class=\"ri-arrow-drop-up-line\"></i>\n </button>\n <input\n type=\"number\"\n class=\"time-field\"\n [value]=\"selectedTime.minute.toString().padStart(2, '0')\"\n (input)=\"onMinuteInputChange($event)\"\n (keydown)=\"onTimeKeydown($event, 'minute')\"\n min=\"0\"\n max=\"59\"\n aria-label=\"Minute\"\n />\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-down\"\n (click)=\"decrementMinute()\"\n tabindex=\"-1\"\n aria-label=\"Decrement minute\"\n >\n <i class=\"ri-arrow-drop-down-line\"></i>\n </button>\n </div>\n\n <!-- AM/PM Button Group (only when useMeridian=true) -->\n <!-- BACKWARD COMPATIBILITY: This only renders when useMeridian=true -->\n <div class=\"meridian-toggle-group\" *ngIf=\"useMeridian\">\n <button\n type=\"button\"\n class=\"meridian-btn\"\n [class.active]=\"meridian === 'AM'\"\n (click)=\"meridian !== 'AM' && toggleMeridian()\"\n aria-label=\"Select AM\"\n >\n AM\n </button>\n <button\n type=\"button\"\n class=\"meridian-btn\"\n [class.active]=\"meridian === 'PM'\"\n (click)=\"meridian !== 'PM' && toggleMeridian()\"\n aria-label=\"Select PM\"\n >\n PM\n </button>\n </div>\n </div>\n </div>\n\n <div>\n <button\n type=\"button\"\n class=\"confirm-btn\"\n [disabled]=\"\n isRequired &&\n ((!selectedDay && !multiple) ||\n (!multipleSelectedDates.length && multiple))\n \"\n (click)=\"onConfirmClicked()\"\n *ngIf=\"showConfirmButton\"\n [ngStyle]=\"{\n 'background-color': styles.secondaryColor,\n color: styles.confirmBtnTextColor,\n 'font-family': styles.fontFamily,\n 'border-radius': styles.borderRadius\n }\"\n >\n {{ submitTextButton }}\n </button>\n </div>\n</div>\n", styles: [".calendar-container{margin:auto;display:block;border-radius:20px;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-weight:400}.calendar-container[dir=rtl],.calendar-container[lang=ar]{font-family:Zain,Arabic Typesetting,Tahoma,sans-serif;font-weight:300;letter-spacing:0;line-height:1.7}.calendar-container .todays-date-section{border-radius:4px;margin-top:12px;display:flex;align-items:center;justify-content:space-between;padding-left:10px;padding-right:10px}.calendar-container .todays-date-section .text-info{display:flex;align-items:center}.calendar-container .todays-date-section .text-info p{font-size:17px;font-weight:500;letter-spacing:.02em}[dir=rtl] .calendar-container .todays-date-section .text-info p,[lang=ar] .calendar-container .todays-date-section .text-info p{font-weight:400;letter-spacing:0}[dir=rtl] .calendar-container .todays-date-section .data p,[lang=ar] .calendar-container .todays-date-section .data p{font-weight:300}.calendar-container .todays-date-section .data{border-radius:8px}.calendar-container .todays-date-section .data p{font-size:14px;font-weight:400;margin:5px 10px}.calendar-container .period-container{display:flex;justify-content:space-between;margin-top:8px}.calendar-container .period-container .period-form{width:100%;display:flex;justify-content:space-between}.calendar-container .period-container .period-form .select-item{width:42.5%;border-radius:4px;height:50px;padding-left:10px;padding-right:10px}.calendar-container .period-container .period-form label{margin-right:10px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-container .period-container .period-form label,[lang=ar] .calendar-container .period-container .period-form label{font-weight:400}.calendar-container .period-container .period-form select{width:100%;height:50px;border:none;font-size:16px;font-weight:500;display:block;margin:auto;background:url(\"data:image/svg+xml;utf8,<svg viewBox='0 0 140 140' width='15' height='15' xmlns='http://www.w3.org/2000/svg'><g><path d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' fill='black'/></g></svg>\") no-repeat 95% 50%;-webkit-appearance:none;appearance:none;cursor:pointer}.calendar-container .period-container .period-form select option,.calendar-container [dir=rtl] .period-container select{font-weight:400}.calendar-container [dir=rtl] .period-container select option{font-weight:300}.icon-ltr{background-position:right}.icon-rtl{background-position:left!important}select:focus{outline:none}.calendar-layout{border-radius:4px;margin:8px auto auto;display:block;padding-bottom:5px}.calendar-layout .week-days{text-align:center;margin-top:5px;display:flex;justify-content:space-evenly}.calendar-layout .week-days .week-day{display:inline-block;width:13%;text-align:center;padding:15px 0 10px;font-weight:600;font-size:13px;text-transform:uppercase;letter-spacing:.05em}[dir=rtl] .calendar-layout .week-days{flex-direction:row-reverse!important}[dir=rtl] .calendar-layout .week-days .week-day{font-weight:700;letter-spacing:0;text-transform:none;font-size:14px}.calendar-layout .week{text-align:center;display:flex;justify-content:space-evenly}.calendar-layout .day{display:inline-flex;width:13%;height:5.5vh;justify-content:center;align-items:center;cursor:pointer;font-weight:500;transition:all .2s ease;border-radius:4px}.calendar-layout .day:hover:not(.disabled-day){transform:scale(1.05)}[dir=rtl] .calendar-layout .day{font-weight:400}.calendar-layout #greg-day{position:relative;min-width:20px}.calendar-layout #greg-day span{font-size:14px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #greg-day span,[lang=ar] .calendar-layout #greg-day span{font-weight:400}.calendar-layout #ummAlQura-day{font-size:11px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #ummAlQura-day,[lang=ar] .calendar-layout #ummAlQura-day{font-weight:400}.calendar-layout .todays-date,.calendar-layout .selected-date{padding:10px;border-radius:5px}.confirm-btn{height:50px;width:100%;border:none;font-size:16px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;margin:8px auto 0;box-shadow:none!important;cursor:pointer;transition:all .2s ease;border-radius:8px}.confirm-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 12px #00000026!important}.confirm-btn:disabled{opacity:.5;cursor:not-allowed}[dir=rtl] .confirm-btn{font-weight:700;letter-spacing:0;text-transform:none;font-size:17px}.toggle-section{display:flex;align-items:center;justify-content:space-between}.toggle-section label{text-align:right;font-size:19px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .toggle-section label,[lang=ar] .toggle-section label{font-weight:400}.toggle-section .switch{position:relative;display:inline-block;width:50px;height:24px}.toggle-section .switch input{opacity:0;width:0;height:0}.toggle-section .slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s;border-radius:24px}.toggle-section .slider:before{content:\"\";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background-color:#fff;transition:.4s;border-radius:50%}.toggle-section input:checked+.slider:before{transform:translate(26px)}.order{order:1}.future-validation{text-align:center;color:#eb445a;margin-top:8px;font-size:13px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .future-validation,[lang=ar] .future-validation{font-weight:400;line-height:1.8}.time-picker-section{padding:10px;background:transparent;border-radius:0;font-family:Poppins,sans-serif}.time-picker-section .time-picker-wrapper{display:flex;align-items:center;justify-content:center;gap:8px}.time-picker-section .time-picker-wrapper .time-input-container{position:relative;display:inline-flex;flex-direction:column;align-items:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{width:100%;height:20px;border:1px solid #ddd;background:#ffffff;color:#5b479c;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease;padding:0;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow i{font-size:20px;line-height:1;pointer-events:none;opacity:.7;transition:opacity .2s ease;display:flex;align-items:center;justify-content:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:hover i{opacity:1}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:active{background:#e9ecef}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:focus{outline:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-up{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-down{border-radius:0 0 4px 4px;border-top:none}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:25px;border:1px solid #ddd;border-top:none;border-bottom:none;background:#ffffff;font-size:18px;font-weight:600;color:#333;text-align:center;padding:0;margin:0;transition:all .2s ease;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;-webkit-appearance:textfield;appearance:textfield}[dir=rtl] .time-picker-section .time-picker-wrapper .time-input-container .time-field,[lang=ar] .time-picker-section .time-picker-wrapper .time-input-container .time-field{font-weight:700}.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-outer-spin-button,.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-inner-spin-button{-webkit-appearance:none;appearance:none;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-field:focus{outline:none;box-shadow:0 0 0 2px #5b479c1a;z-index:1}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px;font-weight:600;color:#5b479c;padding:0 4px;-webkit-user-select:none;user-select:none;line-height:1;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .time-colon,[lang=ar] .time-picker-section .time-picker-wrapper .time-colon{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group{display:flex;flex-direction:column;gap:0;margin-left:8px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:25px;border:1px solid #ddd;background:#ffffff;color:#666;font-size:13px;font-weight:600;text-align:center;padding:0;cursor:pointer;transition:all .2s ease;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn,[lang=ar] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:first-child{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:last-child{border-radius:0 0 4px 4px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:hover:not(.active){background:#f8f9fa;border-color:#00ace4;color:#00ace4}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:active{transform:scale(.98)}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:focus{outline:none;border-color:#00ace4;box-shadow:0 0 0 2px #00ace41a;z-index:1}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn.active{background:rgb(0,77,97);border-color:#004d61;color:#fff;cursor:default}@media (max-width: 480px){.time-picker-section{padding:12px}.time-picker-section .time-picker-wrapper{gap:6px}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{height:18px}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:36px;font-size:20px}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px}.time-picker-section .time-picker-wrapper .meridian-toggle-group{margin-left:6px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:27px;font-size:12px}}\n"] }]
978
+ }], ctorParameters: function () { return [{ type: i1.UntypedFormBuilder }, { type: i2.DateUtilitiesService }]; }, propDecorators: { markToday: [{
979
+ type: Input
980
+ }], canChangeMode: [{
981
+ type: Input
982
+ }], todaysDateSection: [{
983
+ type: Input
984
+ }], futureValidation: [{
985
+ type: Input
986
+ }], disableYearPicker: [{
987
+ type: Input
988
+ }], disableMonthPicker: [{
989
+ type: Input
990
+ }], disableDayPicker: [{
991
+ type: Input
992
+ }], multiple: [{
993
+ type: Input
994
+ }], isRequired: [{
995
+ type: Input
996
+ }], showConfirmButton: [{
997
+ type: Input
998
+ }], futureValidationMessage: [{
999
+ type: Input
1000
+ }], arabicLayout: [{
1001
+ type: Input
1002
+ }], mode: [{
1003
+ type: Input
1004
+ }], dir: [{
1005
+ type: Input
1006
+ }], locale: [{
1007
+ type: Input
1008
+ }], submitTextButton: [{
1009
+ type: Input
1010
+ }], todaysDateText: [{
1011
+ type: Input
1012
+ }], ummAlQuraDateText: [{
1013
+ type: Input
1014
+ }], monthSelectLabel: [{
1015
+ type: Input
1016
+ }], yearSelectLabel: [{
1017
+ type: Input
1018
+ }], futureValidationMessageEn: [{
1019
+ type: Input
1020
+ }], futureValidationMessageAr: [{
1021
+ type: Input
1022
+ }], theme: [{
1023
+ type: Input
1024
+ }], pastYearsLimit: [{
1025
+ type: Input
1026
+ }], futureYearsLimit: [{
1027
+ type: Input
1028
+ }], styles: [{
1029
+ type: Input
1030
+ }], enableTime: [{
1031
+ type: Input
1032
+ }], minDate: [{
1033
+ type: Input
1034
+ }], maxDate: [{
1035
+ type: Input
1036
+ }], initialDate: [{
1037
+ type: Input
1038
+ }], initialRangeStart: [{
1039
+ type: Input
1040
+ }], initialRangeEnd: [{
1041
+ type: Input
1042
+ }], useMeridian: [{
1043
+ type: Input
1044
+ }], selectionMode: [{
1045
+ type: Input
1046
+ }], onSubmit: [{
1047
+ type: Output
1048
+ }], onDaySelect: [{
1049
+ type: Output
1050
+ }], onMonthChange: [{
1051
+ type: Output
1052
+ }], onYearChange: [{
1053
+ type: Output
1054
+ }], fontFamilyStyle: [{
1055
+ type: HostBinding,
1056
+ args: ['style.font-family']
1057
+ }] } });
1058
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGlqcmktZ3JlZ29yaWFuLWRhdGVwaWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvaGlqcmktZ3JlZ29yaWFuLWRhdGVwaWNrZXIvc3JjL2xpYi9oaWpyaS1ncmVnb3JpYW4tZGF0ZXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9oaWpyaS1ncmVnb3JpYW4tZGF0ZXBpY2tlci9zcmMvbGliL2hpanJpLWdyZWdvcmlhbi1kYXRlcGlja2VyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUVMLE1BQU0sRUFDTixZQUFZLEVBQ1osV0FBVyxHQUlaLE1BQU0sZUFBZSxDQUFDO0FBS3ZCLE9BQU8sS0FBSyxZQUFZLE1BQU0sdUJBQXVCLENBQUM7Ozs7O0FBTXRELE1BQU0sT0FBTyxpQ0FBaUM7SUFpSDVDLFlBQ1MsV0FBK0IsRUFDL0IsaUJBQXVDO1FBRHZDLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQUMvQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQXNCO1FBbEhoRCxVQUFVO1FBQ0QsY0FBUyxHQUFZLElBQUksQ0FBQztRQUMxQixrQkFBYSxHQUFZLElBQUksQ0FBQztRQUM5QixzQkFBaUIsR0FBWSxJQUFJLENBQUM7UUFDbEMscUJBQWdCLEdBQVksSUFBSSxDQUFDO1FBQ2pDLHNCQUFpQixHQUFZLEtBQUssQ0FBQztRQUNuQyx1QkFBa0IsR0FBWSxLQUFLLENBQUM7UUFDcEMscUJBQWdCLEdBQVksS0FBSyxDQUFDO1FBQ2xDLGFBQVEsR0FBWSxLQUFLLENBQUM7UUFDMUIsZUFBVSxHQUFZLEtBQUssQ0FBQztRQUM1QixzQkFBaUIsR0FBWSxJQUFJLENBQUM7UUFDbEMsNEJBQXVCLEdBQVksS0FBSyxDQUFDO1FBQ3pDLGlCQUFZLEdBQVksS0FBSyxDQUFDO1FBQzlCLFNBQUksR0FB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R0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBSUcsV0FBVztzQkFBbkIsS0FBSztnQkFJRyxhQUFhO3NCQUFyQixLQUFLO2dCQUVJLFFBQVE7c0JBQWpCLE1BQU07Z0JBQ0csV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLFlBQVk7c0JBQXJCLE1BQU07Z0JBOEQyQixlQUFlO3NCQUFoRCxXQUFXO3VCQUFDLG1CQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RCaW5kaW5nLFxuICBPbkNoYW5nZXMsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIEFmdGVyVmlld0luaXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVW50eXBlZEZvcm1CdWlsZGVyLCBVbnR5cGVkRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgc3R5bGVzQ29uZmlnIH0gZnJvbSAnLi4vX2ludGVyZmFjZXMvc3R5bGVzLWNvbmZpZy5tb2RlbCc7XG5pbXBvcnQgeyBEYXRlVXRpbGl0aWVzU2VydmljZSB9IGZyb20gJy4uL19zZXJ2aWNlcy9kYXRlLXV0aWxpdGllcy5zZXJ2aWNlJztcbmltcG9ydCB7IFRvZGF5RGF0ZSwgRGF5SW5mbyB9IGZyb20gJy4uL19pbnRlcmZhY2VzL2NhbGVuZGFyLW1vZGVsJztcbmltcG9ydCAqIGFzIHRoZW1lc0NvbmZpZyBmcm9tICcuLi90aGVtZXMvdGhlbWVzLmpzb24nO1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnaGlqcmktZ3JlZ29yaWFuLWRhdGVwaWNrZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vaGlqcmktZ3JlZ29yaWFuLWRhdGVwaWNrZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9oaWpyaS1ncmVnb3JpYW4tZGF0ZXBpY2tlci5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBIaWpyaUdyZWdvcmlhbkRhdGVwaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCB7XG4gIC8vLyBJbnB1dHNcbiAgQElucHV0KCkgbWFya1RvZGF5OiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgY2FuQ2hhbmdlTW9kZTogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIHRvZGF5c0RhdGVTZWN0aW9uOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgZnV0dXJlVmFsaWRhdGlvbjogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGRpc2FibGVZZWFyUGlja2VyOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGRpc2FibGVNb250aFBpY2tlcjogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBkaXNhYmxlRGF5UGlja2VyOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIG11bHRpcGxlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGlzUmVxdWlyZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgc2hvd0NvbmZpcm1CdXR0b246IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBmdXR1cmVWYWxpZGF0aW9uTWVzc2FnZTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBhcmFiaWNMYXlvdXQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbW9kZTogc3RyaW5nID0gJ2dyZWcnO1xuICBASW5wdXQoKSBkaXI6IHN0cmluZyA9ICdsdHInO1xuICBASW5wdXQoKSBsb2NhbGU6IHN0cmluZyA9ICdlbic7XG4gIEBJbnB1dCgpIHN1Ym1pdFRleHRCdXR0b246IHN0cmluZyA9ICdDb25maXJtJztcbiAgQElucHV0KCkgdG9kYXlzRGF0ZVRleHQ6IHN0cmluZyA9IFwiVG9kYXkncyBEYXRlXCI7XG4gIEBJbnB1dCgpIHVtbUFsUXVyYURhdGVUZXh0OiBzdHJpbmcgPSAnSGlqcmkgRGF0ZSc7XG4gIEBJbnB1dCgpIG1vbnRoU2VsZWN0TGFiZWw6IHN0cmluZyA9ICdNb250aCc7XG4gIEBJbnB1dCgpIHllYXJTZWxlY3RMYWJlbDogc3RyaW5nID0gJ1llYXInO1xuICBASW5wdXQoKSBmdXR1cmVWYWxpZGF0aW9uTWVzc2FnZUVuOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGZ1dHVyZVZhbGlkYXRpb25NZXNzYWdlQXI6IHN0cmluZztcbiAgQElucHV0KCkgdGhlbWU/OiBzdHJpbmcgPSAnJztcbiAgQElucHV0KCkgcGFzdFllYXJzTGltaXQ6IG51bWJlciA9IDkwO1xuICBASW5wdXQoKSBmdXR1cmVZZWFyc0xpbWl0OiBudW1iZXIgPSAwO1xuICBASW5wdXQoKSBzdHlsZXM/OiBzdHlsZXNDb25maWcgPSB7fTtcblxuICAvLyBOZXcgaW5wdXRzIGZvciBleHRlbmRlZCBmdW5jdGlvbmFsaXR5XG4gIEBJbnB1dCgpIGVuYWJsZVRpbWU6IGJvb2xlYW4gPSBmYWxzZTsgLy8gRW5hYmxlIHRpbWUgcGlja2VyIChob3VycyAmIG1pbnV0ZXMpXG4gIEBJbnB1dCgpIG1pbkRhdGU/OiBEYXRlIHwgc3RyaW5nOyAvLyBNaW5pbXVtIGFsbG93ZWQgZGF0ZSAoR3JlZ29yaWFuIERhdGUgb3IgREQvTU0vWVlZWSBzdHJpbmcpXG4gIEBJbnB1dCgpIG1heERhdGU/OiBEYXRlIHwgc3RyaW5nOyAvLyBNYXhpbXVtIGFsbG93ZWQgZGF0ZSAoR3JlZ29yaWFuIERhdGUgb3IgREQvTU0vWVlZWSBzdHJpbmcpXG4gIEBJbnB1dCgpIGluaXRpYWxEYXRlPzogRGF0ZSB8IHN0cmluZzsgLy8gSW5pdGlhbCBkYXRlIHRvIG5hdmlnYXRlIHRvIHdoZW4gcGlja2VyIG9wZW5zXG4gIFxuICAvLyBSYW5nZSBzZWxlY3Rpb24gaW5pdGlhbCBkYXRlc1xuICBASW5wdXQoKSBpbml0aWFsUmFuZ2VTdGFydD86IERhdGUgfCBzdHJpbmc7IC8vIEluaXRpYWwgc3RhcnQgZGF0ZSBmb3IgcmFuZ2Ugc2VsZWN0aW9uXG4gIEBJbnB1dCgpIGluaXRpYWxSYW5nZUVuZD86IERhdGUgfCBzdHJpbmc7IC8vIEluaXRpYWwgZW5kIGRhdGUgZm9yIHJhbmdlIHNlbGVjdGlvblxuICBcbiAgLy8gQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogRGVmYXVsdCB0byBmYWxzZSAoMjQtaG91ciBmb3JtYXQpXG4gIC8vIFdoZW4gdHJ1ZSwgZGlzcGxheXMgMTItaG91ciBmb3JtYXQgd2l0aCBBTS9QTSB0b2dnbGVcbiAgQElucHV0KCkgdXNlTWVyaWRpYW46IGJvb2xlYW4gPSBmYWxzZTsgLy8gRW5hYmxlIDEyLWhvdXIgZm9ybWF0IHdpdGggQU0vUE1cbiAgXG4gIC8vIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IERlZmF1bHQgdG8gJ3NpbmdsZScgKGV4aXN0aW5nIGJlaGF2aW9yKVxuICAvLyAncmFuZ2UnIGVuYWJsZXMgcmFuZ2Ugc2VsZWN0aW9uIG1vZGUgKGZpcnN0IGNsaWNrID0gc3RhcnQsIHNlY29uZCBjbGljayA9IGVuZClcbiAgQElucHV0KCkgc2VsZWN0aW9uTW9kZTogJ3NpbmdsZScgfCAncmFuZ2UnID0gJ3NpbmdsZSc7XG4gIC8vLyBPdXRwdXRzXG4gIEBPdXRwdXQoKSBvblN1Ym1pdCA9IG5ldyBFdmVudEVtaXR0ZXI8b2JqZWN0PigpO1xuICBAT3V0cHV0KCkgb25EYXlTZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPG9iamVjdD4oKTtcbiAgQE91dHB1dCgpIG9uTW9udGhDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG9iamVjdD4oKTtcbiAgQE91dHB1dCgpIG9uWWVhckNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8b2JqZWN0PigpO1xuICAvLy8gVmFyaWFibGVzXG4gIHVtbUFsUXVyYU1vbnRocyA9IFtcbiAgICB7IGxhYmVsQXI6ICfZhdit2LHZhScsIGxhYmVsRW46ICdNdWhhcnJhbScsIHZhbHVlOiAxIH0sXG4gICAgeyBsYWJlbEFyOiAn2LXZgdixJywgbGFiZWxFbjogJ1NhZmFyJywgdmFsdWU6IDIgfSxcbiAgICB7IGxhYmVsQXI6ICfYsdio2YrYuSDYp9mE2KPZiNmEJywgbGFiZWxFbjogJ1JhYmkgYWwtQXd3YWwnLCB2YWx1ZTogMyB9LFxuICAgIHsgbGFiZWxBcjogJ9ix2KjZiti5INin2YTYq9in2YbZiicsIGxhYmVsRW46ICdSYWJpIGFsLVRoYW5pJywgdmFsdWU6IDQgfSxcbiAgICB7IGxhYmVsQXI6ICfYrNmF2KfYr9mJINin2YTYo9mI2YTZiScsIGxhYmVsRW46ICdKdW1hZGEgYWwtQXd3YWwnLCB2YWx1ZTogNSB9LFxuICAgIHsgbGFiZWxBcjogJ9is2YXYp9iv2Ykg2KfZhNii2K7YsdipJywgbGFiZWxFbjogJ0p1bWFkYSBhbC1UaGFuaScsIHZhbHVlOiA2IH0sXG4gICAgeyBsYWJlbEFyOiAn2LHYrNioJywgbGFiZWxFbjogJ1JhamFiJywgdmFsdWU6IDcgfSxcbiAgICB7IGxhYmVsQXI6ICfYtNi52KjYp9mGJywgbGFiZWxFbjogJ1NoYWJhbicsIHZhbHVlOiA4IH0sXG4gICAgeyBsYWJlbEFyOiAn2LHZhdi22KfZhicsIGxhYmVsRW46ICdSYW1hZGFuJywgdmFsdWU6IDkgfSxcbiAgICB7IGxhYmVsQXI6ICfYtNmI2KfZhCcsIGxhYmVsRW46ICdTaGF3d2FsJywgdmFsdWU6IDEwIH0sXG4gICAgeyBsYWJlbEFyOiAn2LDZiCDYp9mE2YLYudiv2KknLCBsYWJlbEVuOiAnRGh1IGFsLVFhZGFoJywgdmFsdWU6IDExIH0sXG4gICAgeyBsYWJlbEFyOiAn2LDZiCDYp9mE2K3YrNipJywgbGFiZWxFbjogJ0RodSBhbC1IaWpqYWgnLCB2YWx1ZTogMTIgfSxcbiAgXTtcbiAgZ3JlZ01vbnRocyA9IFtcbiAgICB7IGxhYmVsQXI6ICfZitmG2KfZitixJywgbGFiZWxFbjogJ0phbnVhcnknLCB2YWx1ZTogMSB9LFxuICAgIHsgbGFiZWxBcjogJ9mB2KjYsdin2YrYsScsIGxhYmVsRW46ICdGZWJydWFyeScsIHZhbHVlOiAyIH0sXG4gICAgeyBsYWJlbEFyOiAn2YXYp9ix2LMnLCBsYWJlbEVuOiAnTWFyY2gnLCB2YWx1ZTogMyB9LFxuICAgIHsgbGFiZWxBcjogJ9in2KjYsdmK2YQnLCBsYWJlbEVuOiAnQXByaWwnLCB2YWx1ZTogNCB9LFxuICAgIHsgbGFiZWxBcjogJ9mF2KfZitmIJywgbGFiZWxFbjogJ01heScsIHZhbHVlOiA1IH0sXG4gICAgeyBsYWJlbEFyOiAn2YrZiNmG2YrZiCcsIGxhYmVsRW46ICdKdW5lJywgdmFsdWU6IDYgfSxcbiAgICB7IGxhYmVsQXI6ICfZitmI2YTZitmIJywgbGFiZWxFbjogJ0p1bHknLCB2YWx1ZTogNyB9LFxuICAgIHsgbGFiZWxBcjogJ9in2LrYs9i32LMnLCBsYWJlbEVuOiAnQXVndXN0JywgdmFsdWU6IDggfSxcbiAgICB7IGxhYmVsQXI6ICfYs9io2KrZhdio2LEnLCBsYWJlbEVuOiAnU2VwdGVtYmVyJywgdmFsdWU6IDkgfSxcbiAgICB7IGxhYmVsQXI6ICfYp9mD2KrZiNio2LEnLCBsYWJlbEVuOiAnT2N0b2JlcicsIHZhbHVlOiAxMCB9LFxuICAgIHsgbGFiZWxBcjogJ9mG2YjZgdmF2KjYsScsIGxhYmVsRW46ICdOb3ZlbWJlcicsIHZhbHVlOiAxMSB9LFxuICAgIHsgbGFiZWxBcjogJ9iv2YrYs9mF2KjYsScsIGxhYmVsRW46ICdEZWNlbWJlcicsIHZhbHVlOiAxMiB9LFxuICBdO1xuICB1bW1BbFF1cmFZZWFyOiBudW1iZXI7XG4gIGdyZWdZZWFyOiBudW1iZXI7XG4gIHllYXJzOiBhbnlbXTtcbiAgd2Vla3M6IGFueVtdO1xuICBtb250aHM6IGFueVtdO1xuICB3ZWVrZGF5c0VuID0gWydTdW4nLCAnTW9uJywgJ1R1ZScsICdXZWQnLCAnVGh1JywgJ0ZyaScsICdTYXQnXTtcbiAgd2Vla2RheXNBciA9IFsn2LPYqNiqJywgJ9is2YXYudipJywgJ9iu2YXZitizJywgJ9ij2LHYqNi52KfYoScsICfYq9mE2KfYq9in2KEnLCAn2KfYq9mG2YrZhicsICfYo9it2K8nXTtcbiAgLy8gd2Vla2RheXNBciA9IFsn2LMnLCAn2KwnLCAn2K4nLCAn2KPYsScsICfYqycsICfYpdirJywgJ9ij2K0nXTtcbiAgdG9kYXlzRGF0ZTogVG9kYXlEYXRlID0ge307XG4gIHNlbGVjdGVkRGF5OiBEYXlJbmZvO1xuICBwZXJpb2RGb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xuICBtdWx0aXBsZVNlbGVjdGVkRGF0ZXMgPSBbXSBhcyBEYXlJbmZvW107XG4gIHRoZW1lcyA9IFtdIGFzIGFueTtcblxuICAvLyBUaW1lIHBpY2tlciB2YXJpYWJsZXNcbiAgLy8gQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogc2VsZWN0ZWRUaW1lIGRlZmF1bHRzIHRvIDA6MCB0byBwcmVzZXJ2ZSBleGlzdGluZyBiZWhhdmlvciB3aGVuIGVuYWJsZVRpbWU9ZmFsc2VcbiAgLy8gV2hlbiBlbmFibGVUaW1lPXRydWUsIHRoaXMgd2lsbCBiZSBpbml0aWFsaXplZCB0byBjdXJyZW50IHN5c3RlbSB0aW1lIGluIG5nT25Jbml0XG4gIHNlbGVjdGVkVGltZTogeyBob3VyOiBudW1iZXI7IG1pbnV0ZTogbnVtYmVyIH0gPSB7IGhvdXI6IDAsIG1pbnV0ZTogMCB9O1xuICBcbiAgLy8gVHJhY2sgaWYgdGltZSBoYXMgYmVlbiBpbml0aWFsaXplZCB0byBhdm9pZCByZS1pbml0aWFsaXppbmcgYXQgbWlkbmlnaHRcbiAgcHJpdmF0ZSB0aW1lSW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgXG4gIC8vIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IE1lcmlkaWFuIG9ubHkgdXNlZCB3aGVuIHVzZU1lcmlkaWFuPXRydWVcbiAgLy8gVHJhY2tzIEFNL1BNIHN0YXRlIGZvciAxMi1ob3VyIGZvcm1hdFxuICBtZXJpZGlhbjogJ0FNJyB8ICdQTScgPSAnQU0nO1xuICBcbiAgLy8gUmFuZ2Ugc2VsZWN0aW9uIHN0YXRlXG4gIC8vIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IFRoZXNlIGFyZSBvbmx5IHVzZWQgd2hlbiBzZWxlY3Rpb25Nb2RlPSdyYW5nZSdcbiAgLy8gVGhleSBkbyBub3QgYWZmZWN0IHNpbmdsZSBvciBtdWx0aXBsZSBzZWxlY3Rpb24gbW9kZXNcbiAgcmFuZ2VTdGFydD86IERheUluZm8gPSB1bmRlZmluZWQ7XG4gIHJhbmdlRW5kPzogRGF5SW5mbyA9IHVuZGVmaW5lZDtcblxuICBASG9zdEJpbmRpbmcoJ3N0eWxlLmZvbnQtZmFtaWx5JykgZm9udEZhbWlseVN0eWxlOiBzdHJpbmc7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyLFxuICAgIHB1YmxpYyBfZGF0ZVV0aWxzU2VydmljZTogRGF0ZVV0aWxpdGllc1NlcnZpY2VcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdFRoZW1lKCk7XG4gICAgdGhpcy5pbml0aWFsaXplRm9ybSgpO1xuICAgIHRoaXMuZ2V0VG9kYXlzRGF0ZUluZm8oKTtcbiAgICB0aGlzLmluaXRpYWxpemVZZWFyc0FuZE1vbnRocygpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSB0aW1lIGZyb20gY3VycmVudCBzeXN0ZW0gdGltZSBvciBpbml0aWFsRGF0ZVxuICAgIC8vIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IFRoaXMgb25seSBydW5zIHdoZW4gZW5hYmxlVGltZT10cnVlXG4gICAgaWYgKHRoaXMuZW5hYmxlVGltZSkge1xuICAgICAgdGhpcy5pbml0aWFsaXplVGltZSgpO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAvLyBEb3VibGUtY2hlY2sgdGltZSBpbml0aWFsaXphdGlvbiBhZnRlciB2aWV3IGlzIHJlYWR5XG4gICAgLy8gVGhpcyBoYW5kbGVzIGNhc2VzIHdoZXJlIGVuYWJsZVRpbWUgbWlnaHQgYmUgc2V0IGFmdGVyIG5nT25Jbml0XG4gICAgaWYgKHRoaXMuZW5hYmxlVGltZSAmJiAhdGhpcy50aW1lSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZVRpbWUoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgaWYgKCFjaGFuZ2VzWydtb2RlJ10uaXNGaXJzdENoYW5nZSgpKSB7XG4gICAgICB0aGlzLmNoYW5nZUNhbGVuZGFyTW9kZSgpO1xuICAgIH1cbiAgfVxuXG4gIGluaXRUaGVtZSgpIHtcbiAgICBpZiAodGhpcy50aGVtZSAhPSAnJykge1xuICAgICAgdGhpcy50aGVtZXMgPSB0aGVtZXNDb25maWc7XG4gICAgICBmb3IgKGNvbnN0IHRoZW1lSXRlbSBvZiB0aGlzLnRoZW1lc1snZGVmYXVsdCddKSB7XG4gICAgICAgIGlmICh0aGVtZUl0ZW0ubmFtZSA9PSB0aGlzLnRoZW1lKSB7XG4gICAgICAgICAgdGhpcy5zdHlsZXMgPSB0aGVtZUl0ZW0uc3R5bGVzQ29uZmlnO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuZm9udEZhbWlseVN0eWxlID0gdGhpcy5zdHlsZXMuZm9udEZhbWlseTtcbiAgfVxuXG4gIC8vLyBJbml0aWFsaXplIGZvcm0gY29udHJvbCBmb3IgbW9udGggYW5kIHllYXIgc2VsZWN0XG4gIGluaXRpYWxpemVGb3JtKCkge1xuICAgIHRoaXMucGVyaW9kRm9ybSA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgeWVhcjogW3sgdmFsdWU6ICcnLCBkaXNhYmxlZDogdGhpcy5kaXNhYmxlWWVhclBpY2tlciB9LCBbXV0sXG4gICAgICBtb250aDogW3sgdmFsdWU6ICcnLCBkaXNhYmxlZDogdGhpcy5kaXNhYmxlTW9udGhQaWNrZXIgfSwgW11dLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gSW5pdGlhbGl6ZSB5ZWFycyBhbmQgbW9udGhzIGZvciBjYWxlbmRhclxuICBpbml0aWFsaXplWWVhcnNBbmRNb250aHMoKSB7XG4gICAgdGhpcy55ZWFycyA9IFtdO1xuICAgIHRoaXMubW9udGhzID0gW107XG5cbiAgICAvLyBEZXRlcm1pbmUgdGhlIGRhdGUgdG8gdXNlIGZvciBpbml0aWFsaXphdGlvbiAoaW5pdGlhbERhdGUgb3IgdG9kYXkpXG4gICAgbGV0IHJlZmVyZW5jZURhdGU6IHN0cmluZztcbiAgICBpZiAodGhpcy5pbml0aWFsRGF0ZSkge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZEluaXRpYWxEYXRlID1cbiAgICAgICAgdGhpcy5fZGF0ZVV0aWxzU2VydmljZS5ub3JtYWxpemVEYXRlVG9TdHJpbmcodGhpcy5pbml0aWFsRGF0ZSk7XG4gICAgICBpZiAobm9ybWFsaXplZEluaXRpYWxEYXRlKSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGUgPT0gJ2dyZWcnKSB7XG4gICAgICAgICAgcmVmZXJlbmNlRGF0ZSA9IG5vcm1hbGl6ZWRJbml0aWFsRGF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBoaWpyaURhdGUgPSB0aGlzLl9kYXRlVXRpbHNTZXJ2aWNlLmNvbnZlcnREYXRlKFxuICAgICAgICAgICAgbm9ybWFsaXplZEluaXRpYWxEYXRlLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmVmZXJlbmNlRGF0ZSA9IGhpanJpRGF0ZT8udUQgfHwgdGhpcy50b2RheXNEYXRlLnVtbUFsUXVyYTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVmZXJlbmNlRGF0ZSA9XG4gICAgICAgICAgdGhpcy5tb2RlID09ICdncmVnJ1xuICAgICAgICAgICAgPyB0aGlzLnRvZGF5c0RhdGUuZ3JlZ29yaWFuXG4gICAgICAgICAgICA6IHRoaXMudG9kYXlzRGF0ZS51bW1BbFF1cmE7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZmVyZW5jZURhdGUgPVxuICAgICAgICB0aGlzLm1vZGUgPT0gJ2dyZWcnXG4gICAgICAgICAgPyB0aGlzLnRvZGF5c0RhdGUuZ3JlZ29yaWFuXG4gICAgICAgICAgOiB0aGlzLnRvZGF5c0RhdGUudW1tQWxRdXJhO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1vZGUgPT0gJ2dyZWcnKSB7XG4gICAgICB0aGlzLmdyZWdZZWFyID1cbiAgICAgICAgdGhpcy5mdXR1cmVZZWFyc0xpbWl0ID09IDBcbiAgICAgICAgICA/IE51bWJlcihyZWZlcmVuY2VEYXRlPy5zcGxpdCgnLycpWzJdKVxuICAgICAgICAgIDogTnVtYmVyKHJlZmVyZW5jZURhdGU/LnNwbGl0KCcvJylbMl0pICsgdGhpcy5mdXR1cmVZZWFyc0xpbWl0O1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmdyZWdZZWFyOyBpKyspIHtcbiAgICAgICAgaWYgKGkgPCB0aGlzLnBhc3RZZWFyc0xpbWl0KSB7XG4gICAgICAgICAgbGV0IHZhbCA9IHRoaXMuZ3JlZ1llYXItLTtcbiAgICAgICAgICB0aGlzLnllYXJzLnB1c2godmFsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5tb250aHMgPSB0aGlzLmdyZWdNb250aHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudW1tQWxRdXJhWWVhciA9XG4gICAgICAgIHRoaXMuZnV0dXJlWWVhcnNMaW1pdCA9PSAwXG4gICAgICAgICAgPyBOdW1iZXIocmVmZXJlbmNlRGF0ZT8uc3BsaXQoJy8nKVsyXSlcbiAgICAgICAgICA6IE51bWJlcihyZWZlcmVuY2VEYXRlPy5zcGxpdCgnLycpWzJdKSArIHRoaXMuZnV0dXJlWWVhcnNMaW1pdDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy51bW1BbFF1cmFZZWFyOyBpKyspIHtcbiAgICAgICAgaWYgKGkgPCB0aGlzLnBhc3RZZWFyc0xpbWl0KSB7XG4gICAgICAgICAgbGV0IHZhbCA9IHRoaXMudW1tQWxRdXJhWWVhci0tO1xuICAgICAgICAgIHRoaXMueWVhcnMucHVzaCh2YWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLm1vbnRocyA9IHRoaXMudW1tQWxRdXJhTW9udGhzO1xuICAgIH1cbiAgICB0aGlzLnllYXJzLm1hcCgoeWVhcjogYW55KSA9PiB7XG4gICAgICBpZiAoeWVhciA9PSByZWZlcmVuY2VEYXRlPy5zcGxpdCgnLycpWzJdKSB7XG4gICAgICAgIHRoaXMucGVyaW9kRm9ybS5jb250cm9sc1sneWVhciddLnNldFZhbHVlKHllYXIpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMubW9udGhzLm1hcCgobW9udGg6IGFueSkgPT4ge1xuICAgICAgaWYgKG1vbnRoLnZhbHVlID09IHJlZmVyZW5jZURhdGU/LnNwbGl0KCcvJylbMV0pIHtcbiAgICAgICAgdGhpcy5wZXJpb2RGb3JtLmNvbnRyb2xzWydtb250aCddLnNldFZhbHVlKG1vbnRoLnZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vLyBPbiBjaGFuZ2UgZXZlbnQgb2YgeWVhcnMgYW5kIG1vbnRoc1xuICBvblBlcmlvZENoYW5nZSh0eXBlOiBzdHJpbmcpIHtcbiAgICBpZiAodHlwZSA9PSAneWVhcicpIHtcbiAgICAgIHRoaXMub25ZZWFyQ2hhbmdlLmVtaXQodGhpcy5wZXJpb2RGb3JtLmNvbnRyb2xzWyd5ZWFyJ10udmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9uTW9udGhDaGFuZ2UuZW1pdCh0aGlzLnBlcmlvZEZvcm0uY29udHJvbHNbJ21vbnRoJ10udmFsdWUpO1xuICAgIH1cbiAgICBjb25zdCBkYXlzID0gdGhpcy5fZGF0ZVV0aWxzU2VydmljZS5nZXRNb250aERhdGEoXG4gICAgICAnMDEvJyArXG4gICAgICAgIHRoaXMucGVyaW9kRm9ybS5jb250cm9sc1snbW9udGgnXS52YWx1ZSArXG4gICAgICAgICcvJyArXG4gICAgICAgIHRoaXMucGVyaW9kRm9ybS5jb250cm9sc1sneWVhciddLnZhbHVlLFxuICAgICAgdGhpcy5tb2RlXG4gICAgKTtcbiAgICB0aGlzLndlZWtzID0gdGhpcy5nZW5lcmF0ZVdlZWtzQXJyYXkoZGF5cyk7XG4gIH1cblxuICAvLy8gR2V0IHRvZGF5cyhncmVnIGFuZCB1bW0gYWwgcXVyYSkgZGF0ZSBpbmZvXG4gIGdldFRvZGF5c0RhdGVJbmZvKCkge1xuICAgIHRoaXMudG9kYXlzRGF0ZS5ncmVnb3JpYW4gPSB0aGlzLl9kYXRlVXRpbHNTZXJ2aWNlLmZvcm1hdERhdGUobmV3IERhdGUoKSk7XG4gICAgdGhpcy50b2RheXNEYXRlLnVtbUFsUXVyYSA9IHRoaXMuX2RhdGVVdGlsc1NlcnZpY2UuY29udmVydERhdGUoXG4gICAgICB0aGlzLnRvZGF5c0RhdGUuZ3JlZ29yaWFuLFxuICAgICAgdHJ1ZVxuICAgICk/LnVEO1xuXG4gICAgLy8gVXNlIGluaXRpYWxEYXRlIGlmIHByb3ZpZGVkLCBvdGhlcndpc2UgdXNlIHRvZGF5J3MgZGF0ZVxuICAgIGxldCBkYXRlVG9OYXZpZ2F0ZTogc3RyaW5nO1xuXG4gICAgaWYgKHRoaXMuaW5pdGlhbERhdGUpIHtcbiAgICAgIC8vIE5vcm1hbGl6ZSBpbml0aWFsRGF0ZSB0byBERC9NTS9ZWVlZIGZvcm1hdFxuICAgICAgY29uc3Qgbm9ybWFsaXplZEluaXRpYWxEYXRlID1cbiAgICAgICAgdGhpcy5fZGF0ZVV0aWxzU2VydmljZS5ub3JtYWxpemVEYXRlVG9TdHJpbmcodGhpcy5pbml0aWFsRGF0ZSk7XG5cbiAgICAgIGlmIChub3JtYWxpemVkSW5pdGlhbERhdGUpIHtcbiAgICAgICAgaWYgKHRoaXMubW9kZSA9PSAnZ3JlZycpIHtcbiAgICAgICAgICBkYXRlVG9OYXZpZ2F0ZSA9IG5vcm1hbGl6ZWRJbml0aWFsRGF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBDb252ZXJ0IHRvIEhpanJpIGZvciB1bW1BbFF1cmEgbW9kZVxuICAgICAgICAgIGNvbnN0IGhpanJpRGF0ZSA9IHRoaXMuX2RhdGVVdGlsc1NlcnZpY2UuY29udmVydERhdGUoXG4gICAgICAgICAgICBub3JtYWxpemVkSW5pdGlhbERhdGUsXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgICAgKTtcbiAgICAgICAgICBkYXRlVG9OYXZpZ2F0ZSA9IGhpanJpRGF0ZT8udUQgfHwgdGhpcy50b2RheXNEYXRlLnVtbUFsUXVyYTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSW52YWxpZCBpbml0aWFsRGF0ZSwgZmFsbCBiYWNrIHRvIHRvZGF5XG4gICAgICAgIGRhdGVUb05hdmlnYXRlID1cbiAgICAgICAgICB0aGlzLm1vZGUgPT0gJ2dyZWcnXG4gICAgICAgICAgICA/IHRoaXMudG9kYXlzRGF0ZS5ncmVnb3JpYW5cbiAgICAgICAgICAgIDogdGhpcy50b2RheXNEYXRlLnVtbUFsUXVyYTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm8gaW5pdGlhbERhdGUgcHJvdmlkZWQsIHVzZSB0b2RheVxuICAgICAgZGF0ZVRvTmF2aWdhdGUgPVxuICAgICAgICB0aGlzLm1vZGUgPT0gJ2dyZWcnXG4gICAgICAgICAgPyB0aGlzLnRvZGF5c0RhdGUuZ3JlZ29yaWFuXG4gICAgICAgICAgOiB0aGlzLnRvZGF5c0RhdGUudW1tQWxRdXJhO1xuICAgIH1cblxuICAgIHRoaXMuZ2VuZXJhdGV0TW9udGhEYXRhKGRhdGVUb05hdmlnYXRlKTtcbiAgICBcbiAgICAvLyBIaWdobGlnaHQgaW5pdGlhbERhdGUgb3IgaW5pdGlhbFJhbmdlIGlmIHByb3ZpZGVkXG4gICAgaWYgKHRoaXMuc2VsZWN0aW9uTW9kZSA9PT0gJ3JhbmdlJyAmJiAodGhpcy5pbml0aWFsUmFuZ2VTdGFydCB8fCB0aGlzLmluaXRpYWxSYW5nZUVuZCkpIHtcbiAgICAgIHRoaXMuaGlnaGxpZ2h0SW5pdGlhbFJhbmdlKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmluaXRpYWxEYXRlKSB7XG4gICAgICB0aGlzLmhpZ2hsaWdodEluaXRpYWxEYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8vIEdlbmVyYXRlIG1vbnRoIGRheXMgZnJvbSBKU09OXG4gIGdlbmVyYXRldE1vbnRoRGF0YShkYXRlOiBzdHJpbmcpIHtcbiAgICBjb25zdCBkYXlzID0gdGhpcy5fZGF0ZVV0aWxzU2VydmljZS5nZXRNb250aERhdGEoZGF0ZSwgdGhpcy5tb2RlKTtcbiAgICB0aGlzLndlZWtzID0gdGhpcy5nZW5lcmF0ZVdlZWtzQXJyYXkoZGF5cyk7XG4gIH1cblxuICAvLy8gSGlnaGxpZ2h0IGluaXRpYWxEYXRlIG9uIHRoZSBjYWxlbmRhclxuICBwcml2YXRlIGhpZ2hsaWdodEluaXRpYWxEYXRlKCkge1xuICAgIGlmICghdGhpcy5pbml0aWFsRGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5vcm1hbGl6ZWRJbml0aWFsRGF0ZSA9XG4gICAgICB0aGlzLl9kYXRlVXRpbHNTZXJ2aWNlLm5vcm1hbGl6ZURhdGVUb1N0cmluZyh0aGlzLmluaXRpYWxEYXRlKTtcblxuICAgIGlmICghbm9ybWFsaXplZEluaXRpYWxEYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRmluZCB0aGUgZGF5IGluIHRoZSB3ZWVrcyBhcnJheSB0aGF0IG1hdGNoZXMgaW5pdGlhbERhdGVcbiAgICBmb3IgKGNvbnN0IHdlZWsgb2YgdGhpcy53ZWVrcykge1xuICAgICAgZm9yIChjb25zdCBkYXkgb2Ygd2Vlaykge1xuICAgICAgICBpZiAoZGF5ICYmIGRheS5nRCA9PT0gbm9ybWFsaXplZEluaXRpYWxEYXRlKSB7XG4gICAgICAgICAgLy8gRG9uJ3Qgc2VsZWN0IGlmIGRhdGUgaXMgZGlzYWJsZWRcbiAgICAgICAgICBpZiAoIXRoaXMuaXNEYXRlRGlzYWJsZWQoZGF5KSkge1xuICAgICAgICAgICAgLy8gTWFyayBhcyBzZWxlY3RlZCB3aXRob3V0IHRyaWdnZXJpbmcgZXZlbnRzXG4gICAgICAgICAgICBkYXkuc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAvLyBTZXQgYXMgc2VsZWN0ZWREYXkgYmFzZWQgb24gc2VsZWN0aW9uIG1vZGVcbiAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGlvbk1vZGUgPT09ICdyYW5nZScpIHtcbiAgICAgICAgICAgICAgdGhpcy5yYW5nZVN0YXJ0ID0gZGF5O1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLm11bHRpcGxlKSB7XG4gICAgICAgICAgICAgIHRoaXMubXVsdGlwbGVTZWxlY3RlZERhdGVzID0gW2RheV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gZGF5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgICAgICAvLyBJbml0aWFsaXplIHRpbWUgaWYgZW5hYmxlVGltZSBpcyBhY3RpdmVcbiAgICAgICAgICAgIGlmICh0aGlzLmVuYWJsZVRpbWUgJiYgIXRoaXMudGltZUluaXRpYWxpemVkKSB7XG4gICAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZVRpbWUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gQXR0YWNoIHRpbWUgdG8gdGhlIGRheSBpZiBpdCdzIGEgRGF0ZSBvYmplY3Qgd2l0aCB0aW1lXG4gICAgICAgICAgICBpZiAodGhpcy5lbmFibGVUaW1lICYmIHRoaXMuaW5pdGlhbERhdGUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICAgIGRheS50aW1lID0ge1xuICAgICAgICAgICAgICAgIGhvdXI6IHRoaXMuaW5pdGlhbERhdGUuZ2V0SG91cnMoKSxcbiAgICAgICAgICAgICAgICBtaW51dGU6IHRoaXMuaW5pdGlhbERhdGUuZ2V0TWludXRlcygpXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vLyBIaWdobGlnaHQgaW5pdGlhbCByYW5nZSAoc3RhcnQgYW5kIGVuZCBkYXRlcykgb24gdGhlIGNhbGVuZGFyXG4gIHByaXZhdGUgaGlnaGxpZ2h0SW5pdGlhbFJhbmdlKCkge1xuICAgIGlmICghdGhpcy5pbml0aWFsUmFuZ2VTdGFydCAmJiAhdGhpcy5pbml0aWFsUmFuZ2VFbmQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBub3JtYWxpemVkU3RhcnREYXRlID0gdGhpcy5pbml0aWFsUmFuZ2VTdGFydFxuICAgICAgPyB0aGlzLl9kYXRlVXRpbHNTZXJ2aWNlLm5vcm1hbGl6ZURhdGVUb1N0cmluZyh0aGlzLmluaXRpYWxSYW5nZVN0YXJ0KVxuICAgICAgOiBudWxsO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRFbmREYXRlID0gdGhpcy5pbml0aWFsUmFuZ2VFbmRcbiAgICAgID8gdGhpcy5fZGF0ZVV0aWxzU2VydmljZS5ub3JtYWxpemVEYXRlVG9TdHJpbmcodGhpcy5pbml0aWFsUmFuZ2VFbmQpXG4gICAgICA6IG51bGw7XG5cbiAgICBsZXQgc3RhcnREYXk6IERheUluZm8gfCBudWxsID0gbnVsbDtcbiAgICBsZXQgZW5kRGF5OiBEYXlJbmZvIHwgbnVsbCA9IG51bGw7XG5cbiAgICAvLyBGaW5kIGJvdGggc3RhcnQgYW5kIGVuZCBkYXRlcyBpbiB0aGUgd2Vla3MgYXJyYXlcbiAgICBmb3IgKGNvbnN0IHdlZWsgb2YgdGhpcy53ZWVrcykge1xuICAgICAgZm9yIChjb25zdCBkYXkgb2Ygd2Vlaykge1xuICAgICAgICBpZiAoZGF5ICYmIG5vcm1hbGl6ZWRTdGFydERhdGUgJiYgZGF5LmdEID09PSBub3JtYWxpemVkU3RhcnREYXRlKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLmlzRGF0ZURpc2FibGVkKGRheSkpIHtcbiAgICAgICAgICAgIHN0YXJ0RGF5ID0gZGF5O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF5ICYmIG5vcm1hbGl6ZWRFbmREYXRlICYmIGRheS5nRCA9PT0gbm9ybWFsaXplZEVuZERhdGUpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuaXNEYXRlRGlzYWJsZWQoZGF5KSkge1xuICAgICAgICAgICAgZW5kRGF5ID0gZGF5O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNldCByYW5nZSBzdGFydFxuICAgIGlmIChzdGFydERheSkge1xuICAgICAgc3RhcnREYXkuc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgdGhpcy5yYW5nZVN0YXJ0ID0gc3RhcnREYXk7XG4gICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gc3RhcnREYXk7XG4gICAgICBcbiAgICAgIC8vIEluaXRpYWxpemUgYW5kIGF0dGFjaCB0aW1lIHRvIHN0YXJ0IGRhdGVcbiAgICAgIGlmICh0aGlzLmVuYWJsZVRpbWUpIHtcbiAgICAgICAgaWYgKCF0aGlzLnRpbWVJbml0aWFsaXplZCkge1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZVRpbWUoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5pbml0aWFsUmFuZ2VTdGFydCBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgICBzdGFydERheS50aW1lID0ge1xuICAgICAgICAgICAgaG91cjogdGhpcy5pbml0aWFsUmFuZ2VTdGFydC5nZXRIb3VycygpLFxuICAgICAgICAgICAgbWludXRlOiB0aGlzLmluaXRpYWxSYW5nZVN0YXJ0LmdldE1pbnV0ZXMoKVxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RhcnREYXkudGltZSA9IHsgLi4udGhpcy5zZWxlY3RlZFRpbWUgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNldCByYW5nZSBlbmQgaWYgcHJvdmlkZWRcbiAgICBpZiAoZW5kRGF5ICYmIHN0YXJ0RGF5KSB7XG4gICAgICAvLyBTd2FwIGlmIGVuZCBpcyBiZWZvcmUgc3RhcnRcbiAgICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IHRoaXMucGFyc2VEYXRlU3RyaW5nKHN0YXJ0RGF5LmdEKTtcbiAgICAgIGNvbnN0IGVuZERhdGUgPSB0aGlzLnBhcnNlRGF0ZVN0cmluZyhlbmREYXkuZ0QpO1xuICAgICAgXG4gICAgICBpZiAoZW5kRGF0ZSAmJiBzdGFydERhdGUgJiYgZW5kRGF0ZSA8IHN0YXJ0RGF0ZSkge1xuICAgICAgICAvLyBTd2FwXG4gICAgICAgIHRoaXMucmFuZ2VFbmQgPSBzdGFydERheTtcbiAgICAgICAgdGhpcy5yYW5nZVN0YXJ0ID0gZW5kRGF5O1xuICAgICAgICBlbmREYXkuc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yYW5nZUVuZCA9IGVuZERheTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gQXR0YWNoIHRpbWUgdG8gZW5kIGRhdGUgKGluaGVyaXQgZnJvbSBzdGFydClcbiAgICAgIGlmICh0aGlzLmVuYWJsZVRpbWUpIHtcbiAgICAgICAgY29uc3QgdGltZVRvVXNlID0gdGhpcy5yYW5nZVN0YXJ0LnRpbWUgfHwgeyAuLi50aGlzLnNlbGVjdGVkVGltZSB9O1xuICAgICAgICBpZiAodGhpcy5pbml0aWFsUmFuZ2VFbmQgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgdGhpcy5yYW5nZUVuZC50aW1lID0ge1xuICAgICAgICAgICAgaG91cjogdGhpcy5pbml0aWFsUmFuZ2VFbmQuZ2V0SG91cnMoKSxcbiAgICAgICAgICAgIG1pbnV0ZTogdGhpcy5pbml0aWFsUmFuZ2VFbmQuZ2V0TWludXRlcygpXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnJhbmdlRW5kLnRpbWUgPSB7IC4uLnRpbWVUb1VzZSB9O1xuICAgICAgICB9XG4gICAgICAgIC8vIEVuc3VyZSBzdGFydCBhbHNvIGhhcyB0aW1lXG4gICAgICAgIHRoaXMucmFuZ2VTdGFydC50aW1lID0geyAuLi50aW1lVG9Vc2UgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gSGlnaGxpZ2h0IHRoZSByYW5nZVxuICAgICAgdGhpcy5oaWdobGlnaHRSYW5nZSgpO1xuICAgICAgdGhpcy5zZWxlY3RlZERheSA9IHRoaXMucmFuZ2VFbmQ7XG4gICAgfVxuICB9XG5cbiAgLy8vIEdlbmVyYXRlIG1vbnRoIHdlZWtzXG4gIGdlbmVyYXRlV2Vla3NBcnJheShkYXlzQXJyYXk6IGFueSkge1xuICAgIGNvbnN0IGZpcnN0RGF5TmFtZSA9IGRheXNBcnJheVswXT8uZE47XG4gICAgY29uc3Qgc3RhcnRJbmRleCA9IHRoaXMud2Vla2RheXNFbi5pbmRleE9mKGZpcnN0RGF5TmFtZSk7XG4gICAgY29uc3Qgd2Vla3MgPSBbW11dIGFzIGFueTtcbiAgICBsZXQgY3VycmVudFdlZWsgPSAwO1xuICAgIGxldCBjdXJyZW50RGF5SW5kZXggPSBzdGFydEluZGV4O1xuXG4gICAgZGF5c0FycmF5Py5mb3JFYWNoKChkYXk6IGFueSkgPT4ge1xuICAgICAgaWYgKCF3ZWVrc1tjdXJyZW50V2Vla10pIHtcbiAgICAgICAgd2Vla3NbY3VycmVudFdlZWtdID0gW107XG4gICAgICB9XG5cbiAgICAgIHdlZWtzW2N1cnJlbnRXZWVrXVtjdXJyZW50RGF5SW5kZXhdID0gZGF5O1xuICAgICAgY3VycmVudERheUluZGV4Kys7XG5cbiAgICAgIGlmIChjdXJyZW50RGF5SW5kZXggPT09IDcpIHtcbiAgICAgICAgY3VycmVudERheUluZGV4ID0gMDtcbiAgICAgICAgY3VycmVudFdlZWsrKztcbiAgICAgIH1cbiAgICB9KTtcbiAgICB3ZWVrcy5mb3JFYWNoKCh3ZWVrOiBhbnkpID0+IHtcbiAgICAgIHdoaWxlICh3ZWVrLmxlbmd0aCA8IDcpIHtcbiAgICAgICAgd2Vlay5wdXNoKHt9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gd2Vla3M7XG4gIH1cblxuICAvLy8gQ2hhbmdlIGNhbGVuZGFyIG1vZGUgJ2dyZWcnIG9yICd1bW1BbFF1cmEnXG4gIGNoYW5nZUNhbGVuZGFyTW9kZSgpIHtcbiAgICB0aGlzLm1vZGUgPSB0aGlzLm1vZGUgPT0gJ2dyZWcnID8gJ3VtbUFsUXVyYScgOiAnZ3JlZyc7XG4gICAgdGhpcy5pbml0aWFsaXplWWVhcnNBbmRNb250aHMoKTtcbiAgICB0aGlzLmdlbmVyYXRldE1vbnRoRGF0YShcbiAgICAgICcwMS8nICtcbiAgICAgICAgdGhpcy5wZXJpb2RGb3JtLmNvbnRyb2xzWydtb250aCddLnZhbHVlICtcbiAgICAgICAgJy8nICtcbiAgICAgICAgdGhpcy5wZXJpb2RGb3JtLmNvbnRyb2xzWyd5ZWFyJ10udmFsdWVcbiAgICApO1xuICB9XG5cbiAgLy8vIE9uIGRheSBjbGlja2VkIGhhbmRsZXJcbiAgb25EYXlDbGlja2VkKGRheTogRGF5SW5mbykge1xuICAgIGlmIChkYXkgJiYgZGF5Py5nRCkge1xuICAgICAgLy8gQ2hlY2sgaWYgZGF5IGlzIGRpc2FibGVkIGJ5IG1pbi9tYXggY29uc3RyYWludHNcbiAgICAgIGlmICh0aGlzLmlzRGF0ZURpc2FibGVkKGRheSkpIHtcbiAgICAgICAgcmV0dXJuOyAvLyBEb24ndCBhbGxvdyBzZWxlY3Rpb24gb2YgZGlzYWJsZWQgZGF0ZXNcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuZnV0dXJlVmFsaWRhdGlvbikge1xuICAgICAgICBpZiAodGhpcy5jaGVja0Z1dHVyZVZhbGlkYXRpb24oZGF5KSkge1xuICAgICAgICAgIHRoaXMuZnV0dXJlVmFsaWRhdGlvbk1lc3NhZ2UgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuZnV0dXJlVmFsaWRhdGlvbk1lc3NhZ2UgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLm1hcmtEYXlTZWxlY3RlZChkYXkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm1hcmtEYXlTZWxlY3RlZChkYXkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vLyBNYXJrIGRheSBhcyBzZWxlY3RlZFxuICBtYXJrRGF5U2VsZWN0ZWQoZGF5SW5mbzogRGF5SW5mbykge1xuICAgIC8vIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IFJhbmdlIHNlbGVjdGlvbiBvbmx5IHdoZW4gc2VsZWN0aW9uTW9kZT0ncmFuZ2UnXG4gICAgaWYgKHRoaXMuc2VsZWN0aW9uTW9kZSA9PT0gJ3JhbmdlJykge1xuICAgICAgdGhpcy5oYW5kbGVSYW5nZVNlbGVjdGlvbihkYXlJbmZvKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgXG4gICAgLy8gQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT3JpZ2luYWwgYmVoYXZpb3IgZm9yIHNpbmdsZS9tdWx0aXBsZSBzZWxlY3Rpb25cbiAgICBpZiAoZGF5SW5mby5zZWxlY3RlZCkge1xuICAgICAgZGF5SW5mby5zZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5tdWx0aXBsZVNlbGVjdGVkRGF0ZXMgPSB0aGlzLm11bHRpcGxlU2VsZWN0ZWREYXRlcy5maWx0ZXIoXG4gICAgICAgIChkYXkpID0+IGRheSAhPT0gZGF5SW5mb1xuICAgICAgKTtcbiAgICAgIGlmICghdGhpcy5tdWx0aXBsZSkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMubXVsdGlwbGUpIHtcbiAgICAgICAgdGhpcy53ZWVrcy5mb3JFYWNoKCh3ZWVrOiBhbnkpID0+IHtcbiAgICAgICAgICB3ZWVrLmZvckVhY2goKGRheTogRGF5SW5mbykgPT4ge1xuICAgICAgICAgICAgZGF5LnNlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRheUluZm8uc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gZGF5SW5mbztcbiAgICAgICAgdGhpcy5tdWx0aXBsZVNlbGVjdGVkRGF0ZXMgPSBbZGF5SW5mb107XG5cbiAgICAgICAgLy8gQXR0YWNoIGN1cnJlbnQgdGltZSBpZiBlbmFibGVUaW1lIGlzIGFjdGl2ZVxuICAgICAgICBpZiAodGhpcy5lbmFibGVUaW1lKSB7XG4gICAgICAgICAgLy8gRW5zdXJlIHRpbWUgaXMgaW5pdGlhbGl6ZWQgYmVmb3JlIGF0dGFjaGluZ1xuICAgICAgICAgIGlmICghdGhpcy50aW1lSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZVRpbWUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGF5SW5mby50aW1lID0geyAuLi50aGlzLnNlbGVjdGVkVGltZSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vbkRheVNlbGVjdC5lbWl0KGRheUluZm8pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGF5SW5mby5zZWxlY3RlZCA9IHRydWU7XG5cbiAgICAgICAgLy8gQXR0YWNoIGN1cnJlbnQgdGltZSBpZiBlbmFibGVUaW1lIGlzIGFjdGl2ZVxuICAgICAgICBpZiAodGhpcy5lbmFibGVUaW1lKSB7XG4gICAgICAgICAgLy8gRW5zdXJlIHRpbWUgaXMgaW5pdGlhbGl6ZWQgYmVmb3JlIGF0dGFjaGluZ1xuICAgICAgICAgIGlmICghdGhpcy50aW1lSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZVRpbWUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGF5SW5mby50aW1lID0geyAuLi50aGlzLnNlbGVjdGVkVGltZSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vbkRheVNlbGVjdC5lbWl0KGRheUluZm8pO1xuICAgICAgICBpZiAoIXRoaXMubXVsdGlwbGVTZWxlY3RlZERhdGVzLmluY2x1ZGVzKGRheUluZm8pKSB7XG4gICAgICAgICAgdGhpcy5tdWx0aXBsZVNlbGVjdGVkRGF0ZXMucHVzaChkYXlJbmZvKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgcmFuZ2Ugc2VsZWN0aW9uIGxvZ2ljXG4gICAqIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IE9ubHkgY2FsbGVkIHdoZW4gc2VsZWN0aW9uTW9kZT0ncmFuZ2UnXG4gICAqIFxuICAgKiBSYW5nZSBzZWxlY3Rpb24gbGlmZWN5Y2xlOlxuICAgKiAxLiBGaXJzdCBjbGljayDihpIgU2V0cyByYW5nZVN0YXJ0XG4gICAqIDIuIFNlY29uZCBjbGljayDihpIgU2V0cyByYW5nZUVuZCwgaGlnaGxpZ2h0cyByYW5nZVxuICAgKiAzLiBUaGlyZCBjbGljayDihpIgUmVzZXRzIHJhbmdlLCBzdGFydHMgbmV3IHNlbGVjdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVSYW5nZVNlbGVjdGlvbihkYXlJbmZvOiBEYXlJbmZvKTogdm9pZCB7XG4gICAgLy8gRmlyc3QgY2xpY2sgb3IgcmVzZXR0aW5nIHJhbmdlXG4gICAgaWYgKCF0aGlzLnJhbmdlU3RhcnQgfHwgKHRoaXMucmFuZ2VTdGFydCAmJiB0aGlzLnJhbmdlRW5kKSkge1xuICAgICAgdGhpcy5yZXNldFJhbmdlKCk7XG4gICAgICB0aGlzLnJhbmdlU3RhcnQgPSBkYXlJbmZvO1xuICAgICAgZGF5SW5mby5zZWxlY3RlZCA9IHRydWU7XG4gICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gZGF5SW5mbztcbiAgICAgIFxuICAgICAgLy8gQXR0YWNoIGN1cnJlbnQgdGltZSBpZiBlbmFibGVUaW1lIGlzIGFjdGl2ZVxuICAgICAgaWYgKHRoaXMuZW5hYmxlVGltZSkge1xuICAgICAgICAvLyBFbnN1cmUgc2VsZWN0ZWRUaW1lIGlzIGluaXRpYWxpemVkXG4gICAgICAgIC8vIElmIHRpbWUgaGFzbid0IGJlZW4gaW5pdGlhbGl6ZWQgeWV0LCBpbml0aWFsaXplIGl0IG5vd1xuICAgICAgICBpZiAoIXRoaXMudGltZUluaXRpYWxpemVkKSB7XG4gICAgICAgICAgdGhpcy5pbml0aWFsaXplVGltZSgpO1xuICAgICAgICB9XG4gICAgICAgIGRheUluZm8udGltZSA9IHsgLi4udGhpcy5zZWxlY3RlZFRpbWUgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgdGhpcy5vbkRheVNlbGVjdC5lbWl0KHsgc3RhcnQ6IGRheUluZm8sIGVuZDogbnVsbCB9KTtcbiAgICB9XG4gICAgLy8gU2Vjb25kIGNsaWNrIC0gY29tcGxldGUgdGhlIHJhbmdlXG4gICAgZWxzZSBpZiAodGhpcy5yYW5nZVN0YXJ0ICYmICF0aGlzLnJhbmdlRW5kKSB7XG4gICAgICBjb25zdCBzdGFydERhdGUgPSB0aGlzLnBhcnNlRGF0ZVN0cmluZyh0aGlzLnJhbmdlU3RhcnQuZ0QpO1xuICAgICAgY29uc3QgZW5kRGF0ZSA9IHRoaXMucGFyc2VEYXRlU3RyaW5nKGRheUluZm8uZ0QpO1xuICAgICAgXG4gICAgICAvLyBTd2FwIGlmIGVuZCBpcyBiZWZvcmUgc3RhcnRcbiAgICAgIGlmIChlbmREYXRlICYmIHN0YXJ0RGF0ZSAmJiBlbmREYXRlIDwgc3RhcnREYXRlKSB7XG4gICAgICAgIHRoaXMucmFuZ2VFbmQgPSB0aGlzLnJhbmdlU3RhcnQ7XG4gICAgICAgIHRoaXMucmFuZ2VTdGFydCA9IGRheUluZm87XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJhbmdlRW5kID0gZGF5SW5mbztcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gQXR0YWNoIHRpbWUgaWYgZW5hYmxlVGltZSBpcyBhY3RpdmVcbiAgICAgIC8vIElNUE9SVEFOVDogUmFuZ2UgZW5kIGluaGVyaXRzIHRpbWUgZnJvbSByYW5nZSBzdGFydCAobm90IGN1cnJlbnQgc2VsZWN0ZWRUaW1lKVxuICAgICAgaWYgKHRoaXMuZW5hYmxlVGltZSkge1xuICAgICAgICAvLyBVc2UgcmFuZ2VTdGFydCdzIHRpbWUgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgdXNlIGN1cnJlbnQgc2VsZWN0ZWRUaW1lXG4gICAgICAgIGNvbnN0IHRpbWVUb1VzZSA9IHRoaXMucmFuZ2VTdGFydC50aW1lIHx8IHsgLi4udGhpcy5zZWxlY3RlZFRpbWUgfTtcbiAgICAgICAgdGhpcy5yYW5nZVN0YXJ0LnRpbWUgPSB7IC4uLnRpbWVUb1VzZSB9O1xuICAgICAgICB0aGlzLnJhbmdlRW5kLnRpbWUgPSB7IC4uLnRpbWVUb1VzZSB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICB0aGlzLmhpZ2hsaWdodFJhbmdlKCk7XG4gICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gdGhpcy5yYW5nZUVuZDtcbiAgICAgIFxuICAgICAgdGhpcy5vbkRheVNlbGVjdC5lbWl0KHsgc3RhcnQ6IHRoaXMucmFuZ2VTdGFydCwgZW5kOiB0aGlzLnJhbmdlRW5kIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8vLyBPbiBjb25maXJtIGJ1dHRvbiBjbGlja2VkXG4gIG9uQ29uZmlybUNsaWNrZWQoKSB7XG4gICAgLy8gQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogUmFuZ2Ugc2VsZWN0aW9uIG91dHB1dCB3aGVuIHNlbGVjdGlvbk1vZGU9J3JhbmdlJ1xuICAgIGlmICh0aGlzLnNlbGVjdGlvbk1vZGUgPT09ICdyYW5nZScpIHtcbiAgICAgIGlmICh0aGlzLnJhbmdlU3RhcnQgJiYgdGhpcy5yYW5nZUVuZCkge1xuICAgICAgICAvLyBDb2xsZWN0IGFsbCBkYXRlcyBpbiByYW5nZVxuICAgICAgICBjb25zdCByYW5nZURhdGVzOiBEYXlJbmZvW10gPSBbXTtcbiAgICAgICAgdGhpcy53ZWVrcy5mb3JFYWNoKCh3ZWVrOiBhbnkpID0+IHtcbiAgICAgICAgICB3ZWVrLmZvckVhY2goKGRheTogRGF5SW5mbykgPT4ge1xuICAgICAgICAgICAgaWYgKGRheSAmJiBkYXkuZ0QgJiYgKHRoaXMuaXNJblJhbmdlKGRheSkgfHwgdGhpcy5pc1JhbmdlU3RhcnQoZGF5KSB8fCB0aGlzLmlzUmFuZ2VFbmQoZGF5KSkpIHtcbiAgICAgICAgICAgICAgLy8gQXR0YWNoIGN1cnJlbnQgdGltZSBpZiBlbmFibGVUaW1lIGlzIGFjdGl2ZVxuICAgICAgICAgICAgICBpZiAodGhpcy5lbmFibGVUaW1lICYmICFkYXkudGltZSkge1xuICAgICAgICAgICAgICAgIGRheS50aW1lID0geyAuLi50aGlzLnNlbGVjdGVkVGltZSB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJhbmdlRGF0ZXMucHVzaChkYXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIHRoaXMub25TdWJtaXQuZW1pdCh7IFxuICAgICAgICAgIHN0YXJ0OiB0aGlzLnJhbmdlU3RhcnQsIFxuICAgICAgICAgIGVuZDogdGhpcy5yYW5nZUVuZCxcbiAgICAgICAgICBkYXRlczogcmFuZ2VEYXRlcyBcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJbmNvbXBsZXRlIHJhbmdlXG4gICAgICAgIHRoaXMub25TdWJtaXQuZW1pdCh7IHN0YXJ0OiB0aGlzLnJhbmdlU3RhcnQsIGVuZDogbnVsbCwgZGF0ZXM6IFtdIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBcbiAgICAvLyBCQUNLV0FSRCBDT01QQVRJQklMSVRZOiBPcmlnaW5hbCBiZWhhdmlvciBmb3IgbXVsdGlwbGUvc2luZ2xlIHNlbGVjdGlvblxuICAgIGlmICh0aGlzLm11bHRpcGxlKSB7XG4gICAgICAvLyBGb3IgbXVsdGlwbGUgZGF0ZXMsIGF0dGFjaCB0aW1lIHRvIGVhY2ggaWYgZW5hYmxlVGltZSBpcyBhY3RpdmVcbiAgICAgIGlmICh0aGlzLmVuYWJsZVRpbWUpIHtcbiAgICAgICAgdGhpcy5tdWx0aXBsZVNlbGVjdGVkRGF0ZXMuZm9yRWFjaCgoZGF5KSA9PiB7XG4gICAgICAgICAgaWYgKCFkYXkudGltZSkge1xuICAgICAgICAgICAgZGF5LnRpbWUgPSB7IC4uLnRoaXMuc2VsZWN0ZWRUaW1lIH07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHRoaXMub25TdWJtaXQuZW1pdCh0aGlzLm11bHRpcGxlU2VsZWN0ZWREYXRlcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZvciBzaW5nbGUgZGF0ZSwgYXR0YWNoIHRpbWUgaWYgZW5hYmxlVGltZSBpcyBhY3RpdmVcbiAgICAgIGlmICh0aGlzLmVuYWJsZVRpbWUgJiYgdGhpcy5zZWxlY3RlZERheSkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkRGF5LnRpbWUgPSB7IC4uLnRoaXMuc2VsZWN0ZWRUaW1lIH07XG4gICAgICB9XG4gICAgICB0aGlzLm9uU3VibWl0LmVtaXQodGhpcy5zZWxlY3RlZERheSk7XG4gICAgfVxuICB9XG5cbiAgLy8vIENoZWNrIGlmIGRhdGUgZnJvbSBmdXR1cmVcbiAgY2hlY2tGdXR1cmVWYWxpZGF0aW9uKGRheTogRGF5SW5mbykge1xuICAgIGlmIChcbiAgICAgIHRoaXMuX2RhdGVVdGlsc1NlcnZpY2UuY2hlY2tQYXN0T3JGdXR1cmUoZGF5Py5nRCwgbmV3IERhdGUoKSkgPT0gJ0Z1dHVyZSdcbiAgICApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8vLyBDaGVjayBpZiBwYXNzZWQgZGF5IGlzIHRvZGF5IG9yIG5vdFxuICBjaGVja1RvZGF5c0RhdGUoZGF5OiBEYXlJbmZvKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMudG9kYXlzRGF0ZT8uZ3JlZ29yaWFuID09IGRheT8uZ0QgfHxcbiAgICAgIHRoaXMudG9kYXlzRGF0ZT8udW1tQWxRdXJhID09IGRheT8udURcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgZGF5IGlzIGRpc2FibGVkIGJhc2VkIG9uIG1pbi9tYXggZGF0ZSBjb25zdHJhaW50c1xuICAgKiBXb3JrcyBmb3IgYm90aCBHcmVnb3JpYW4gYW5kIEhpanJpIG1vZGVzXG4gICAqL1xuICBpc0RhdGVEaXNhYmxlZChkYXk6IERheUluZm8pOiBib29sZWFuIHtcbiAgICBpZiAoIWRheSB8fCAhZGF5LmdEKSByZXR1cm4gdHJ1ZTtcblxuICAgIC8vIE5vcm1hbGl6ZSBtaW4vbWF4IGRhdGVzIHRvIEdyZWdvcmlhbiBERC9NTS9ZWVlZIGZvcm1hdFxuICAgIGNvbnN0IG1pbkRhdGVTdHIgPSB0aGlzLm1pbkRhdGVcbiAgICAgID8gdGhpcy5fZGF0ZVV0aWxzU2VydmljZS5ub3JtYWxpemVEYXRlVG9TdHJpbmcodGhpcy5taW5EYXRlKVxuICAgICAgOiBudWxsO1xuICAgIGNvbnN0IG1heERhdGVTdHIgPSB0aGlzLm1heERhdGVcbiAgICAgID8gdGhpcy5fZGF0ZVV0aWxzU2VydmljZS5ub3JtYWxpemVEYXRlVG9TdHJpbmcodGhpcy5tYXhEYXRlKVxuICAgICAgOiBudWxsO1xuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIGRheSdzIEdyZWdvcmlhbiBkYXRlIGlzIHdpdGhpbiByYW5nZVxuICAgIHJldHVybiAhdGhpcy5fZGF0ZVV0aWxzU2VydmljZS5pc0RhdGVJblJhbmdlKFxuICAgICAgZGF5LmdELFxuICAgICAgbWluRGF0ZVN0cixcbiAgICAgIG1heERhdGVTdHJcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGltZSBmcm9tIGN1cnJlbnQgc3lzdGVtIHRpbWUgb3IgaW5pdGlhbERhdGVcbiAgICogQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT25seSBjYWxsZWQgd2hlbiBlbmFibGVUaW1lPXRydWVcbiAgICpcbiAgICogUHJpb3JpdHk6XG4gICAqIDEuIElmIGluaXRpYWxEYXRlIGhhcyB0aW1lLCB1c2UgdGhhdFxuICAgKiAyLiBJZiBzZWxlY3RlZERheSBoYXMgdGltZSwgdXNlIHRoYXRcbiAgICogMy4gT3RoZXJ3aXNlLCB1c2UgY3VycmVudCBzeXN0ZW0gdGltZVxuICAgKi9cbiAgaW5pdGlhbGl6ZVRpbWUoKTogdm9pZCB7XG4gICAgbGV0IHRpbWVTZXQgPSBmYWxzZTtcblxuICAgIC8vIENoZWNrIGlmIGluaXRpYWxEYXRlIGhhcyB0aW1lIGluZm9ybWF0aW9uXG4gICAgaWYgKHRoaXMuaW5pdGlhbERhdGUgJiYgdGhpcy5pbml0aWFsRGF0ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRUaW1lID0ge1xuICAgICAgICBob3VyOiB0aGlzLmluaXRpYWxEYXRlLmdldEhvdXJzKCksXG4gICAgICAgIG1pbnV0ZTogdGhpcy5pbml0aWFsRGF0ZS5nZXRNaW51dGVzKCksXG4gICAgICB9O1xuICAgICAgdGltZVNldCA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gSWYgbm8gdGltZSBmcm9tIGluaXRpYWxEYXRlLCB1c2UgY3VycmVudCBzeXN0ZW0gdGltZVxuICAgIGlmICghdGltZVNldCkge1xuICAgICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRUaW1lID0ge1xuICAgICAgICBob3VyOiBub3cuZ2V0SG91cnMoKSxcbiAgICAgICAgbWludXRlOiBub3cuZ2V0TWludXRlcygpLFxuICAgICAgfTtcbiAgICB9XG4gICAgXG4gICAgLy8gTWFyayB0aGF0IHRpbWUgaGFzIGJlZW4gaW5pdGlhbGl6ZWRcbiAgICB0aGlzLnRpbWVJbml0aWFsaXplZCA9IHRydWU7XG4gICAgXG4gICAgLy8gQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT25seSBzZXQgbWVyaWRpYW4gd2hlbiB1c2VNZXJpZGlhbj10cnVlXG4gICAgaWYgKHRoaXMudXNlTWVyaWRpYW4pIHtcbiAgICAgIHRoaXMubWVyaWRpYW4gPSB0aGlzLnNlbGVjdGVkVGltZS5ob3VyID49IDEyID8gJ1BNJyA6ICdBTSc7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluY3JlbWVudCBob3VyIHZhbHVlIHdpdGggd3JhcGFyb3VuZCAoMC0yMylcbiAgICogQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT25seSBhdmFpbGFibGUgd2hlbiBlbmFibGVUaW1lPXRydWVcbiAgICovXG4gIGluY3JlbWVudEhvdXIoKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZFRpbWUuaG91ciA9ICh0aGlzLnNlbGVjdGVkVGltZS5ob3VyICsgMSkgJSAyNDtcbiAgICB0aGlzLnVwZGF0ZVNlbGVjdGVkRGF5VGltZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY3JlbWVudCBob3VyIHZhbHVlIHdpdGggd3JhcGFyb3VuZCAoMC0yMylcbiAgICogQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT25seSBhdmFpbGFibGUgd2hlbiBlbmFibGVUaW1lPXRydWVcbiAgICovXG4gIGRlY3JlbWVudEhvdXIoKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZFRpbWUuaG91ciA9ICh0aGlzLnNlbGVjdGVkVGltZS5ob3VyIC0gMSArIDI0KSAlIDI0O1xuICAgIHRoaXMudXBkYXRlU2VsZWN0ZWREYXlUaW1lKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5jcmVtZW50IG1pbnV0ZSB2YWx1ZSB3aXRoIHdyYXBhcm91bmQgKDAtNTkpXG4gICAqIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IE9ubHkgYXZhaWxhYmxlIHdoZW4gZW5hYmxlVGltZT10cnVlXG4gICAqL1xuICBpbmNyZW1lbnRNaW51dGUoKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZFRpbWUubWludXRlID0gKHRoaXMuc2VsZWN0ZWRUaW1lLm1pbnV0ZSArIDEpICUgNjA7XG4gICAgdGhpcy51cGRhdGVTZWxlY3RlZERheVRpbWUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNyZW1lbnQgbWludXRlIHZhbHVlIHdpdGggd3JhcGFyb3VuZCAoMC01OSlcbiAgICogQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT25seSBhdmFpbGFibGUgd2hlbiBlbmFibGVUaW1lPXRydWVcbiAgICovXG4gIGRlY3JlbWVudE1pbnV0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkVGltZS5taW51dGUgPSAodGhpcy5zZWxlY3RlZFRpbWUubWludXRlIC0gMSArIDYwKSAlIDYwO1xuICAgIHRoaXMudXBkYXRlU2VsZWN0ZWREYXlUaW1lKCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIGtleWJvYXJkIGlucHV0IGZvciBob3Vyc1xuICAgKiBWYWxpZGF0ZXMgYW5kIGNsYW1wcyB0byAwLTIzIHJhbmdlXG4gICAqIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IE9ubHkgYXZhaWxhYmxlIHdoZW4gZW5hYmxlVGltZT10cnVlXG4gICAqL1xuICBvbkhvdXJJbnB1dENoYW5nZShldmVudDogYW55KTogdm9pZCB7XG4gICAgbGV0IHZhbHVlID0gcGFyc2VJbnQoZXZlbnQudGFyZ2V0LnZhbHVlLCAxMCk7XG5cbiAgICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlIDwgMCkge1xuICAgICAgdmFsdWUgPSAwO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgPiAyMykge1xuICAgICAgdmFsdWUgPSAyMztcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkVGltZS5ob3VyID0gdmFsdWU7XG4gICAgZXZlbnQudGFyZ2V0LnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy51cGRhdGVTZWxlY3RlZERheVRpbWUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUga2V5Ym9hcmQgaW5wdXQgZm9yIG1pbnV0ZXNcbiAgICogVmFsaWRhdGVzIGFuZCBjbGFtcHMgdG8gMC01OSByYW5nZVxuICAgKiBCQUNLV0FSRCBDT01QQVRJQklMSVRZOiBPbmx5IGF2YWlsYWJsZSB3aGVuIGVuYWJsZVRpbWU9dHJ1ZVxuICAgKi9cbiAgb25NaW51dGVJbnB1dENoYW5nZShldmVudDogYW55KTogdm9pZCB7XG4gICAgbGV0IHZhbHVlID0gcGFyc2VJbnQoZXZlbnQudGFyZ2V0LnZhbHVlLCAxMCk7XG5cbiAgICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlIDwgMCkge1xuICAgICAgdmFsdWUgPSAwO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgPiA1OSkge1xuICAgICAgdmFsdWUgPSA1OTtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkVGltZS5taW51dGUgPSB2YWx1ZTtcbiAgICBldmVudC50YXJnZXQudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLnVwZGF0ZVNlbGVjdGVkRGF5VGltZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBrZXlib2FyZCBhcnJvdyBrZXlzIGZvciBob3VyL21pbnV0ZSBpbnB1dFxuICAgKiBCQUNLV0FSRCBDT01QQVRJQklMSVRZOiBPbmx5IGF2YWlsYWJsZSB3aGVuIGVuYWJsZVRpbWU9dHJ1ZVxuICAgKi9cbiAgb25UaW1lS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCwgdHlwZTogJ2hvdXInIHwgJ21pbnV0ZScpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dVcCcpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAodHlwZSA9PT0gJ2hvdXInKSB7XG4gICAgICAgIHRoaXMuaW5jcmVtZW50SG91cigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pbmNyZW1lbnRNaW51dGUoKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gJ0Fycm93RG93bicpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAodHlwZSA9PT0gJ2hvdXInKSB7XG4gICAgICAgIHRoaXMuZGVjcmVtZW50SG91cigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kZWNyZW1lbnRNaW51dGUoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRoZSBzZWxlY3RlZCBkYXkncyB0aW1lIHByb3BlcnR5IHdoZW4gdGltZSBjaGFuZ2VzXG4gICAqIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IE9ubHkgY2FsbGVkIHdoZW4gZW5hYmxlVGltZT10cnVlXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZVNlbGVjdGVkRGF5VGltZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZERheSkge1xuICAgICAgdGhpcy5zZWxlY3RlZERheS50aW1lID0geyAuLi50aGlzLnNlbGVjdGVkVGltZSB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZGlzcGxheSBob3VyIGZvciAxMi1ob3VyIGZvcm1hdFxuICAgKiBCQUNLV0FSRCBDT01QQVRJQklMSVRZOiBPbmx5IHVzZWQgd2hlbiB1c2VNZXJpZGlhbj10cnVlXG4gICAqIFxuICAgKiBDb252ZXJzaW9uOlxuICAgKiAtIDAgKG1pZG5pZ2h0KSDihpIgMTIgQU1cbiAgICogLSAxLTExIChBTSkg4oaSIDEtMTEgQU1cbiAgICogLSAxMiAobm9vbikg4oaSIDEyIFBNXG4gICAqIC0gMTMtMjMgKFBNKSDihpIgMS0xMSBQTVxuICAgKiBcbiAgICogSU1QT1JUQU5UOiBIb3VyIDAgaXMgTkVWRVIgZGlzcGxheWVkIGFzIDAsIGFsd2F5cyBhcyAxMlxuICAgKi9cbiAgZ2V0RGlzcGxheUhvdXIoKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMudXNlTWVyaWRpYW4pIHtcbiAgICAgIHJldHVybiB0aGlzLnNlbGVjdGVkVGltZS5ob3VyO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBob3VyID0gdGhpcy5zZWxlY3RlZFRpbWUuaG91cjtcbiAgICBcbiAgICAvLyBNaWRuaWdodCAoMCkg4oaSIDEyXG4gICAgaWYgKGhvdXIgPT09IDApIHtcbiAgICAgIHJldHVybiAxMjtcbiAgICB9XG4gICAgLy8gMS0xMiDihpIgMS0xMiAobm8gY2hhbmdlKVxuICAgIGVsc2UgaWYgKGhvdXIgPD0gMTIpIHtcbiAgICAgIHJldHVybiBob3VyO1xuICAgIH1cbiAgICAvLyAxMy0yMyDihpIgMS0xMSAoc3VidHJhY3QgMTIpXG4gICAgZWxzZSB7XG4gICAgICByZXR1cm4gaG91ciAtIDEyO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGUgQU0vUE0gbWVyaWRpYW5cbiAgICogQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT25seSBhdmFpbGFibGUgd2hlbiB1c2VNZXJpZGlhbj10cnVlXG4gICAqIFxuICAgKiBXaGVuIHRvZ2dsaW5nOlxuICAgKiAtIEFkZHMgb3Igc3VidHJhY3RzIDEyIGhvdXJzXG4gICAqIC0gTWFpbnRhaW5zIGludGVybmFsIDI0LWhvdXIgZm9ybWF0XG4gICAqL1xuICB0b2dnbGVNZXJpZGlhbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tZXJpZGlhbiA9PT0gJ0FNJykge1xuICAgICAgdGhpcy5tZXJpZGlhbiA9ICdQTSc7XG4gICAgICAvLyBBZGQgMTIgaG91cnMgaWYgbm90IGFscmVhZHkgaW4gUE0gcmFuZ2VcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkVGltZS5ob3VyIDwgMTIpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRpbWUuaG91ciArPSAxMjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tZXJpZGlhbiA9ICdBTSc7XG4gICAgICAvLyBTdWJ0cmFjdCAxMiBob3VycyBpZiBpbiBQTSByYW5nZVxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRUaW1lLmhvdXIgPj0gMTIpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRpbWUuaG91ciAtPSAxMjtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy51cGRhdGVTZWxlY3RlZERheVRpbWUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbmNyZW1lbnQgaG91ciBpbiAxMi1ob3VyIG1vZGVcbiAgICogQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT25seSB1c2VkIHdoZW4gdXNlTWVyaWRpYW49dHJ1ZVxuICAgKi9cbiAgaW5jcmVtZW50SG91cjEyKCk6IHZvaWQge1xuICAgIGxldCBkaXNwbGF5SG91ciA9IHRoaXMuZ2V0RGlzcGxheUhvdXIoKTtcbiAgICBkaXNwbGF5SG91ciA9IChkaXNwbGF5SG91ciAlIDEyKSArIDE7IC8vIDEtMTIgY3ljbGVcbiAgICBcbiAgICAvLyBDb252ZXJ0IGJhY2sgdG8gMjQtaG91ciBmb3JtYXRcbiAgICBpZiAodGhpcy5tZXJpZGlhbiA9PT0gJ0FNJykge1xuICAgICAgdGhpcy5zZWxlY3RlZFRpbWUuaG91ciA9IGRpc3BsYXlIb3VyID09PSAxMiA/IDAgOiBkaXNwbGF5SG91cjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RlZFRpbWUuaG91ciA9IGRpc3BsYXlIb3VyID09PSAxMiA/IDEyIDogZGlzcGxheUhvdXIgKyAxMjtcbiAgICB9XG4gICAgXG4gICAgdGhpcy51cGRhdGVTZWxlY3RlZERheVRpbWUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNyZW1lbnQgaG91ciBpbiAxMi1ob3VyIG1vZGVcbiAgICogQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT25seSB1c2VkIHdoZW4gdXNlTWVyaWRpYW49dHJ1ZVxuICAgKi9cbiAgZGVjcmVtZW50SG91cjEyKCk6IHZvaWQge1xuICAgIGxldCBkaXNwbGF5SG91ciA9IHRoaXMuZ2V0RGlzcGxheUhvdXIoKTtcbiAgICBkaXNwbGF5SG91ciA9IGRpc3BsYXlIb3VyID09PSAxID8gMTIgOiBkaXNwbGF5SG91ciAtIDE7IC8vIDEtMTIgY3ljbGVcbiAgICBcbiAgICAvLyBDb252ZXJ0IGJhY2sgdG8gMjQtaG91ciBmb3JtYXRcbiAgICBpZiAodGhpcy5tZXJpZGlhbiA9PT0gJ0FNJykge1xuICAgICAgdGhpcy5zZWxlY3RlZFRpbWUuaG91ciA9IGRpc3BsYXlIb3VyID09PSAxMiA/IDAgOiBkaXNwbGF5SG91cjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RlZFRpbWUuaG91ciA9IGRpc3BsYXlIb3VyID09PSAxMiA/IDEyIDogZGlzcGxheUhvdXIgKyAxMjtcbiAgICB9XG4gICAgXG4gICAgdGhpcy51cGRhdGVTZWxlY3RlZERheVRpbWUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgMTItaG91ciBpbnB1dCBjaGFuZ2VcbiAgICogQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT25seSB1c2VkIHdoZW4gdXNlTWVyaWRpYW49dHJ1ZVxuICAgKiBcbiAgICogSU1QT1JUQU5UOiBJbnB1dCBtdXN0IGJlIDEtMTIsIG5ldmVyIDBcbiAgICogLSBVc2VyIHR5cGVzIDAg4oaSIGNvbnZlcnRlZCB0byAxMlxuICAgKiAtIFVzZXIgdHlwZXMgPiAxMiDihpIgY2xhbXBlZCB0byAxMlxuICAgKi9cbiAgb25Ib3VyMTJJbnB1dENoYW5nZShldmVudDogYW55KTogdm9pZCB7XG4gICAgbGV0IHZhbHVlID0gcGFyc2VJbnQoZXZlbnQudGFyZ2V0LnZhbHVlLCAxMCk7XG4gICAgXG4gICAgLy8gVmFsaWRhdGUgMS0xMiByYW5nZSAoMCBpcyBub3QgYWxsb3dlZCBpbiAxMi1ob3VyIGZvcm1hdClcbiAgICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlIDwgMSB8fCB2YWx1ZSA9PT0gMCkge1xuICAgICAgdmFsdWUgPSAxMjsgLy8gRGVmYXVsdCB0byAxMiBpZiBpbnZhbGlkIG9yIDBcbiAgICB9IGVsc2UgaWYgKHZhbHVlID4gMTIpIHtcbiAgICAgIHZhbHVlID0gMTI7XG4gICAgfVxuICAgIFxuICAgIC8vIENvbnZlcnQgdG8gMjQtaG91ciBmb3JtYXRcbiAgICBpZiAodGhpcy5tZXJpZGlhbiA9PT0gJ0FNJykge1xuICAgICAgdGhpcy5zZWxlY3RlZFRpbWUuaG91ciA9IHZhbHVlID09PSAxMiA/IDAgOiB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RlZFRpbWUuaG91ciA9IHZhbHVlID09PSAxMiA/IDEyIDogdmFsdWUgKyAxMjtcbiAgICB9XG4gICAgXG4gICAgZXZlbnQudGFyZ2V0LnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy51cGRhdGVTZWxlY3RlZERheVRpbWUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIGRhdGUgaXMgd2l0aGluIHRoZSBjdXJyZW50IHJhbmdlXG4gICAqIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IE9ubHkgdXNlZCB3aGVuIHNlbGVjdGlvbk1vZGU9J3JhbmdlJ1xuICAgKi9cbiAgaXNJblJhbmdlKGRheTogRGF5SW5mbyk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnNlbGVjdGlvbk1vZGUgIT09ICdyYW5nZScgfHwgIXRoaXMucmFuZ2VTdGFydCB8fCAhdGhpcy5yYW5nZUVuZCB8fCAhZGF5Py5nRCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBkYXlEYXRlID0gdGhpcy5wYXJzZURhdGVTdHJpbmcoZGF5LmdEKTtcbiAgICBjb25zdCBzdGFydERhdGUgPSB0aGlzLnBhcnNlRGF0ZVN0cmluZyh0aGlzLnJhbmdlU3RhcnQuZ0QpO1xuICAgIGNvbnN0IGVuZERhdGUgPSB0aGlzLnBhcnNlRGF0ZVN0cmluZyh0aGlzLnJhbmdlRW5kLmdEKTtcbiAgICBcbiAgICBpZiAoIWRheURhdGUgfHwgIXN0YXJ0RGF0ZSB8fCAhZW5kRGF0ZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gZGF5RGF0ZSA+PSBzdGFydERhdGUgJiYgZGF5RGF0ZSA8PSBlbmREYXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgZGF0ZSBpcyB0aGUgcmFuZ2Ugc3RhcnRcbiAgICogQkFDS1dBUkQgQ09NUEFUSUJJTElUWTogT25seSB1c2VkIHdoZW4gc2VsZWN0aW9uTW9kZT0ncmFuZ2UnXG4gICAqL1xuICBpc1JhbmdlU3RhcnQoZGF5OiBEYXlJbmZvKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uTW9kZSA9PT0gJ3JhbmdlJyAmJiBcbiAgICAgICAgICAgdGhpcy5yYW5nZVN0YXJ0Py5nRCA9PT0gZGF5Py5nRDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIGRhdGUgaXMgdGhlIHJhbmdlIGVuZFxuICAgKiBCQUNLV0FSRCBDT01QQVRJQklMSVRZOiBPbmx5IHVzZWQgd2hlbiBzZWxlY3Rpb25Nb2RlPSdyYW5nZSdcbiAgICovXG4gIGlzUmFuZ2VFbmQoZGF5OiBEYXlJbmZvKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uTW9kZSA9PT0gJ3JhbmdlJyAmJiBcbiAgICAgICAgICAgdGhpcy5yYW5nZUVuZD8uZ0QgPT09IGRheT8uZ0Q7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgcmFuZ2Ugc2VsZWN0aW9uXG4gICAqIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IE9ubHkgdXNlZCB3aGVuIHNlbGVjdGlvbk1vZGU9J3JhbmdlJ1xuICAgKi9cbiAgcHJpdmF0ZSByZXNldFJhbmdlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlbGVjdGlvbk1vZGUgIT09ICdyYW5nZScpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2xlYXIgcmFuZ2UgaGlnaGxpZ2h0aW5nXG4gICAgdGhpcy53ZWVrcy5mb3JFYWNoKCh3ZWVrOiBhbnkpID0+IHtcbiAgICAgIHdlZWsuZm9yRWFjaCgoZGF5OiBEYXlJbmZvKSA9PiB7XG4gICAgICAgIGlmIChkYXkgJiYgZGF5LmdEKSB7XG4gICAgICAgICAgZGF5LnNlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIFxuICAgIHRoaXMucmFuZ2VTdGFydCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJhbmdlRW5kID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuc2VsZWN0ZWREYXkgPSB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgZGF0ZSBzdHJpbmcgKEREL01NL1lZWVkpIHRvIERhdGUgb2JqZWN0XG4gICAqIEhlbHBlciBmb3IgcmFuZ2UgY29tcGFyaXNvblxuICAgKi9cbiAgcHJpdmF0ZSBwYXJzZURhdGVTdHJpbmcoZGF0ZVN0cjogc3RyaW5nKTogRGF0ZSB8IG51bGwge1xuICAgIGlmICghZGF0ZVN0cikgcmV0dXJuIG51bGw7XG4gICAgXG4gICAgY29uc3QgcGFydHMgPSBkYXRlU3RyLnNwbGl0KCcvJyk7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gMykgcmV0dXJuIG51bGw7XG4gICAgXG4gICAgY29uc3QgZGF5ID0gcGFyc2VJbnQocGFydHNbMF0sIDEwKTtcbiAgICBjb25zdCBtb250aCA9IHBhcnNlSW50KHBhcnRzWzFdLCAxMCkgLSAxOyAvLyBNb250aCBpcyAwLWluZGV4ZWRcbiAgICBjb25zdCB5ZWFyID0gcGFyc2VJbnQocGFydHNbMl0sIDEwKTtcbiAgICBcbiAgICByZXR1cm4gbmV3IERhdGUoeWVhciwgbW9udGgsIGRheSk7XG4gIH1cblxuICAvKipcbiAgICogSGlnaGxpZ2h0IGFsbCBkYXRlcyBpbiByYW5nZVxuICAgKiBCQUNLV0FSRCBDT01QQVRJQklMSVRZOiBPbmx5IHVzZWQgd2hlbiBzZWxlY3Rpb25Nb2RlPSdyYW5nZSdcbiAgICovXG4gIHByaXZhdGUgaGlnaGxpZ2h0UmFuZ2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VsZWN0aW9uTW9kZSAhPT0gJ3JhbmdlJyB8fCAhdGhpcy5yYW5nZVN0YXJ0IHx8ICF0aGlzLnJhbmdlRW5kKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFxuICAgIHRoaXMud2Vla3MuZm9yRWFjaCgod2VlazogYW55KSA9PiB7XG4gICAgICB3ZWVrLmZvckVhY2goKGRheTogRGF5SW5mbykgPT4ge1xuICAgICAgICBpZiAoZGF5ICYmIGRheS5nRCkge1xuICAgICAgICAgIGRheS5zZWxlY3RlZCA9IHRoaXMuaXNJblJhbmdlKGRheSkgfHwgXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUmFuZ2VTdGFydChkYXkpIHx8IFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc1JhbmdlRW5kKGRheSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiY2FsZW5kYXItY29udGFpbmVyXCIgW2Rpcl09XCJkaXJcIiBbYXR0ci5sYW5nXT1cImxvY2FsZVwiPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJ0b2dnbGUtc2VjdGlvblwiXG4gICAgW2Rpcl09XCJkaXJcIlxuICAgICpuZ0lmPVwiY2FuQ2hhbmdlTW9kZVwiXG4gICAgW25nU3R5bGVdPVwieyBjb2xvcjogc3R5bGVzLnByaW1hcnlDb2xvciB9XCJcbiAgPlxuICAgIDxzcGFuPiB7eyB1bW1BbFF1cmFEYXRlVGV4dCB9fSA8L3NwYW4+XG4gICAgPGxhYmVsIGNsYXNzPVwic3dpdGNoXCI+XG4gICAgICA8aW5wdXRcbiAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgW2Rpc2FibGVkXT1cIiFjYW5DaGFuZ2VNb2RlXCJcbiAgICAgICAgW2NoZWNrZWRdPVwibW9kZSA9PT0gJ3VtbUFsUXVyYSdcIlxuICAgICAgICAoY2hhbmdlKT1cImNoYW5nZUNhbGVuZGFyTW9kZSgpXCJcbiAgICAgICAgI2NhbGVuZGFyQ2hlY2tib3hcbiAgICAgIC8+XG4gICAgICA8c3BhblxuICAgICAgICBjbGFzcz1cInNsaWRlclwiXG4gICAgICAgIFtuZ1N0eWxlXT1cIlxuICAgICAgICAgIGNhbGVuZGFyQ2hlY2tib3guY2hlY2tlZFxuICAgICAgICAgICAgPyB7ICdiYWNrZ3JvdW5kLWNvbG9yJzogc3R5bGVzLnByaW1hcnlDb2xvciB9XG4gICAgICAgICAgICA6IHsgJ2JhY2tncm91bmQtY29sb3InOiBzdHlsZXMuYmFja2dyb3VuZENvbG9yIH1cbiAgICAgICAgXCJcbiAgICAgID48L3NwYW4+XG4gICAgPC9sYWJlbD5cbiAgPC9kaXY+XG5cbiAgPGRpdlxuICAgIGNsYXNzPVwidG9kYXlzLWRhdGUtc2VjdGlvblwiXG4gICAgKm5nSWY9XCJ0b2RheXNEYXRlU2VjdGlvblwiXG4gICAgW25nU3R5bGVdPVwie1xuICAgICAgJ2JhY2tncm91bmQtY29sb3InOiBzdHlsZXMuYmFja2dyb3VuZENvbG9yLFxuICAgICAgY29sb3I6IHN0eWxlcy5wcmltYXJ5Q29sb3IsXG4gICAgICAnYm9yZGVyLXJhZGl1cyc6IHN0eWxlcy5ib3JkZXJSYWRpdXNcbiAgICB9XCJcbiAgPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwidGV4dC1pbmZvXCJcbiAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgb3JkZXI6IGRpciA9PSAncnRsJ1xuICAgICAgfVwiXG4gICAgPlxuICAgICAgPHA+e3sgdG9kYXlzRGF0ZVRleHQgfX08L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImRhdGFcIlxuICAgICAgW2Rpcl09XCJkaXJcIlxuICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAnYmFja2dyb3VuZC1jb2xvcic6IHN0eWxlcy50b2RheXNEYXRlQmdDb2xvcixcbiAgICAgICAgY29sb3I6IHN0eWxlcy50b2RheXNEYXRlVGV4dENvbG9yXG4gICAgICB9XCJcbiAgICA+XG4gICAgICA8cCAqbmdJZj1cIm1vZGUgPT0gJ3VtbUFsUXVyYSdcIj5cbiAgICAgICAgPCEtLSB7e3RvZGF5c0RhdGUudW1tQWxRdXJhfX0gLS0+XG4gICAgICAgIHt7XG4gICAgICAgICAgbG9jYWxlID09IFwiYXJcIlxuICAgICAgICAgICAgPyBfZGF0ZVV0aWxzU2VydmljZS5jb252ZXJ0RGF0ZU51bWVyYWxzKHRvZGF5c0RhdGUudW1tQWxRdXJhLCBcImFyXCIpXG4gICAgICAgICAgICA6IHRvZGF5c0RhdGUudW1tQWxRdXJhXG4gICAgICAgIH19XG4gICAgICA8L3A+XG4gICAgICA8cCAqbmdJZj1cIm1vZGUgPT0gJ2dyZWcnXCI+XG4gICAgICAgIHt7XG4gICAgICAgICAgbG9jYWxlID09IFwiYXJcIlxuICAgICAgICAgICAgPyBfZGF0ZVV0aWxzU2VydmljZS5jb252ZXJ0RGF0ZU51bWVyYWxzKHRvZGF5c0RhdGUuZ3JlZ29yaWFuLCBcImFyXCIpXG4gICAgICAgICAgICA6IHRvZGF5c0RhdGUuZ3JlZ29yaWFuXG4gICAgICAgIH19XG4gICAgICA8L3A+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJwZXJpb2QtY29udGFpbmVyXCI+XG4gICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJwZXJpb2RGb3JtXCIgY2xhc3M9XCJwZXJpb2QtZm9ybVwiPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cInNlbGVjdC1pdGVtXCJcbiAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgIG9yZGVyOiBkaXIgPT0gJ2x0cidcbiAgICAgICAgfVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAnYmFja2dyb3VuZC1jb2xvcic6IHN0eWxlcy5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgJ2JvcmRlci1yYWRpdXMnOiBzdHlsZXMuYm9yZGVyUmFkaXVzXG4gICAgICAgIH1cIlxuICAgICAgPlxuICAgICAgICA8bGFiZWwgKm5nSWY9XCIhcGVyaW9kRm9ybS5jb250cm9sc1sneWVhciddLnZhbHVlXCI+e3tcbiAgICAgICAgICB5ZWFyU2VsZWN0TGFiZWxcbiAgICAgICAgfX08L2xhYmVsPlxuXG4gICAgICAgIDxzZWxlY3RcbiAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJ5ZWFyXCJcbiAgICAgICAgICBjbGFzcz1cInt7ICdpY29uLScgKyBkaXIgfX1cIlxuICAgICAgICAgIHBsYWNlaG9sZGVyPVwi2KfZhNiz2YbYqVwiXG4gICAgICAgICAgKGNoYW5nZSk9XCJvblBlcmlvZENoYW5nZSgneWVhcicpXCJcbiAgICAgICAgICBbZGlyXT1cImRpclwiXG4gICAgICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAgICAgY29sb3I6IHN0eWxlcy5wcmltYXJ5Q29sb3IsXG4gICAgICAgICAgICAnZm9udC1mYW1pbHknOiBzdHlsZXMuZm9udEZhbWlseVxuICAgICAgICAgIH1cIlxuICAgICAgICA+XG4gICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgeWVhciBvZiB5ZWFyc1wiIFtuZ1ZhbHVlXT1cInllYXJcIj5cbiAgICAgICAgICAgIHt7IGxvY2FsZSA9PSBcImFyXCIgPyBfZGF0ZVV0aWxzU2VydmljZS5wYXJzZUVuZ2xpc2goeWVhcikgOiB5ZWFyIH19XG4gICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgIDwvc2VsZWN0PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJzZWxlY3QtaXRlbVwiXG4gICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICBvcmRlcjogZGlyID09ICdydGwnXG4gICAgICAgIH1cIlxuICAgICAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAgICAgJ2JhY2tncm91bmQtY29sb3InOiBzdHlsZXMuYmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgICdib3JkZXItcmFkaXVzJzogc3R5bGVzLmJvcmRlclJhZGl1c1xuICAgICAgICB9XCJcbiAgICAgID5cbiAgICAgICAgPGxhYmVsICpuZ0lmPVwiIXBlcmlvZEZvcm0uY29udHJvbHNbJ21vbnRoJ10udmFsdWVcIj57e1xuICAgICAgICAgIG1vbnRoU2VsZWN0TGFiZWxcbiAgICAgICAgfX08L2xhYmVsPlxuICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgY2xhc3M9XCJ7eyAnaWNvbi0nICsgZGlyIH19XCJcbiAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJtb250aFwiXG4gICAgICAgICAgKGNoYW5nZSk9XCJvblBlcmlvZENoYW5nZSgnbW9udGgnKVwiXG4gICAgICAgICAgW2Rpcl09XCJkaXJcIlxuICAgICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAgIGNvbG9yOiBzdHlsZXMucHJpbWFyeUNvbG9yLFxuICAgICAgICAgICAgJ2ZvbnQtZmFtaWx5Jzogc3R5bGVzLmZvbnRGYW1pbHlcbiAgICAgICAgICB9XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG1vbnRoIG9mIG1vbnRoc1wiIFtuZ1ZhbHVlXT1cIm1vbnRoLnZhbHVlXCI+XG4gICAgICAgICAgICB7eyBsb2NhbGUgPT0gXCJhclwiID8gbW9udGg/LmxhYmVsQXIgOiBtb250aD8ubGFiZWxFbiB9fVxuICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICA8L3NlbGVjdD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZm9ybT5cbiAgPC9kaXY+XG5cbiAgPGRpdlxuICAgIGNsYXNzPVwiY2FsZW5kYXItbGF5b3V0XCJcbiAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAnYmFja2dyb3VuZC1jb2xvcic6IHN0eWxlcy5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAnYm9yZGVyLXJhZGl1cyc6IHN0eWxlcy5ib3JkZXJSYWRpdXNcbiAgICB9XCJcbiAgPlxuICAgIDxkaXYgY2xhc3M9XCJ3ZWVrLWRheXNcIj5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJ3ZWVrLWRheVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cInsgY29sb3I6IHN0eWxlcy5kYXlOYW1lQ29sb3IgfVwiXG4gICAgICAgICpuZ0Zvcj1cImxldCBkYXRlIG9mIGxvY2FsZSA9PSAnYXInID8gd2Vla2RheXNBciA6IHdlZWtkYXlzRW5cIlxuICAgICAgPlxuICAgICAgICB7eyBkYXRlIH19XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgW2Rpcl09XCJkaXJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ3ZWVrXCIgKm5nRm9yPVwibGV0IHdlZWsgb2Ygd2Vla3NcIj5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiZGF5XCJcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgZGF5IG9mIHdlZWtcIlxuICAgICAgICAgIChjbGljayk9XCJkaXNhYmxlRGF5UGlja2VyID09IGZhbHNlID8gb25EYXlDbGlja2VkKGRheSkgOiAnJ1wiXG4gICAgICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAgICAgJ2JhY2tncm91bmQtY29sb3InOiBzdHlsZXMuYmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgICAgY29sb3I6IHN0eWxlcy5kYXlDb2xvclxuICAgICAgICAgIH1cIlxuICAgICAgICA+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgaWQ9XCJncmVnLWRheVwiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICd0b2RheXMtZGF0ZSc6IGNoZWNrVG9kYXlzRGF0ZShkYXkpLFxuICAgICAgICAgICAgICAnc2VsZWN0ZWQtZGF0ZSc6IGRheT8uc2VsZWN0ZWQgPT0gdHJ1ZVxuICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAgICAgICAgIGJvcmRlcjpcbiAgICAgICAgICAgICAgICBtYXJrVG9kYXkgJiYgY2hlY2tUb2RheXNEYXRlKGRheSlcbiAgICAgICAgICAgICAgICAgID8gJzFweCBzb2xpZCAnICsgc3R5bGVzLnNlY29uZGFyeUNvbG9yXG4gICAgICAgICAgICAgICAgICA6ICcnLFxuICAgICAgICAgICAgICAnYmFja2dyb3VuZC1jb2xvcic6XG4gICAgICAgICAgICAgICAgZGF5Py5zZWxlY3RlZCA9PSB0cnVlID8gc3R5bGVzLnNlY29uZGFyeUNvbG9yIDogJycsXG4gICAgICAgICAgICAgIGNvbG9yOlxuICAgICAgICAgICAgICAgIChkYXk/LnNlbGVjdGVkID09IHRydWUgPyBzdHlsZXMudG9kYXlzRGF0ZVRleHRDb2xvciA6ICcnKSB8fFxuICAgICAgICAgICAgICAgIChjaGVja0Z1dHVyZVZhbGlkYXRpb24oZGF5KSAmJiBmdXR1cmVWYWxpZGF0aW9uXG4gICAgICAgICAgICAgICAgICA/IHN0eWxlcy5kaXNhYmxlZERheUNvbG9yXG4gICAgICAgICAgICAgICAgICA6ICcnKSB8fFxuICAgICAgICAgICAgICAgIChpc0RhdGVEaXNhYmxlZChkYXkpID8gc3R5bGVzLmRpc2FibGVkRGF5Q29sb3IgOiAnJyksXG4gICAgICAgICAgICAgIG9wYWNpdHk6IGlzRGF0ZURpc2FibGVkKGRheSkgPyAnMC40JyA6ICcxJyxcbiAgICAgICAgICAgICAgY3Vyc29yOiBpc0RhdGVEaXNhYmxlZChkYXkpID8gJ25vdC1hbGxvd2VkJyA6ICdwb2ludGVyJ1xuICAgICAgICAgICAgfVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJtb2RlID09ICdncmVnJ1wiPnt7XG4gICAgICAgICAgICAgIGxvY2FsZSA9PSBcImFyXCJcbiAgICAgICAgICAgICAgICA/IF9kYXRlVXRpbHNTZXJ2aWNlLnBhcnNlRW5nbGlzaChcbiAgICAgICAgICAgICAgICAgICAgZGF5Py5nRD8uc3BsaXQoXCIvXCIpWzBdIHwgbnVtYmVyXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgOiAoZGF5Py5nRD8uc3BsaXQoXCIvXCIpWzBdIHwgbnVtYmVyKVxuICAgICAgICAgICAgfX08L3NwYW4+XG5cbiAgICAgICAgICAgIDxzcGFuIGlkPVwidW1tQWxRdXJhLWRheVwiICpuZ0lmPVwibW9kZSA9PSAndW1tQWxRdXJhJ1wiPnt7XG4gICAgICAgICAgICAgIGxvY2FsZSA9PSBcImFyXCJcbiAgICAgICAgICAgICAgICA/IF9kYXRlVXRpbHNTZXJ2aWNlLnBhcnNlRW5nbGlzaChcbiAgICAgICAgICAgICAgICAgICAgZGF5Py51RD8uc3BsaXQoXCIvXCIpWzBdIHwgbnVtYmVyXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgOiAoZGF5Py51RD8uc3BsaXQoXCIvXCIpWzBdIHwgbnVtYmVyKVxuICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZnV0dXJlLXZhbGlkYXRpb25cIiBkaXI9XCJhdXRvXCIgKm5nSWY9XCJmdXR1cmVWYWxpZGF0aW9uTWVzc2FnZVwiPlxuICAgIDxzcGFuICpuZ0lmPVwibG9jYWxlID09ICdhcidcIj5cbiAgICAgIHt7IGZ1dHVyZVZhbGlkYXRpb25NZXNzYWdlQXIgfX1cbiAgICA8L3NwYW4+XG4gICAgPHNwYW4gKm5nSWY9XCJsb2NhbGUgPT0gJ2VuJ1wiPlxuICAgICAge3sgZnV0dXJlVmFsaWRhdGlvbk1lc3NhZ2VFbiB9fVxuICAgIDwvc3Bhbj5cbiAgPC9kaXY+XG5cbiAgPCEtLSBUaW1lIFBpY2tlciBTZWN0aW9uIC0tPlxuICA8IS0tIEJBQ0tXQVJEIENPTVBBVElCSUxJVFk6IFRoaXMgc2VjdGlvbiBvbmx5IHJlbmRlcnMgd2hlbiBlbmFibGVUaW1lPXRydWUgLS0+XG4gIDxkaXYgY2xhc3M9XCJ0aW1lLXBpY2tlci1zZWN0aW9uXCIgKm5nSWY9XCJlbmFibGVUaW1lXCIgW2Rpcl09XCInbHRyJ1wiPlxuICAgIDxkaXYgY2xhc3M9XCJ0aW1lLXBpY2tlci13cmFwcGVyXCI+XG4gICAgICA8IS0tIEhvdXIgSW5wdXQgd2l0aCBBcnJvd3MgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwidGltZS1pbnB1dC1jb250YWluZXJcIj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwidGltZS1hcnJvdyB0aW1lLWFycm93LXVwXCJcbiAgICAgICAgICAoY2xpY2spPVwidXNlTWVyaWRpYW4gPyBpbmNyZW1lbnRIb3VyMTIoKSA6IGluY3JlbWVudEhvdXIoKVwiXG4gICAgICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIkluY3JlbWVudCBob3VyXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxpIGNsYXNzPVwicmktYXJyb3ctZHJvcC11cC1saW5lXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgY2xhc3M9XCJ0aW1lLWZpZWxkXCJcbiAgICAgICAgICBbdmFsdWVdPVwiZ2V0RGlzcGxheUhvdXIoKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJylcIlxuICAgICAgICAgIChpbnB1dCk9XCJcbiAgICAgICAgICAgIHVzZU1lcmlkaWFuXG4gICAgICAgICAgICAgID8gb25Ib3VyMTJJbnB1dENoYW5nZSgkZXZlbnQpXG4gICAgICAgICAgICAgIDogb25Ib3VySW5wdXRDaGFuZ2UoJGV2ZW50KVxuICAgICAgICAgIFwiXG4gICAgICAgICAgKGtleWRvd24pPVwib25UaW1lS2V5ZG93bigkZXZlbnQsICdob3VyJylcIlxuICAgICAgICAgIFttaW5dPVwidXNlTWVyaWRpYW4gPyAxIDogMFwiXG4gICAgICAgICAgW21heF09XCJ1c2VNZXJpZGlhbiA/IDEyIDogMjNcIlxuICAgICAgICAgIGFyaWEtbGFiZWw9XCJIb3VyXCJcbiAgICAgICAgLz5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwidGltZS1hcnJvdyB0aW1lLWFycm93LWRvd25cIlxuICAgICAgICAgIChjbGljayk9XCJ1c2VNZXJpZGlhbiA/IGRlY3JlbWVudEhvdXIxMigpIDogZGVjcmVtZW50SG91cigpXCJcbiAgICAgICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiRGVjcmVtZW50IGhvdXJcIlxuICAgICAgICA+XG4gICAgICAgICAgPGkgY2xhc3M9XCJyaS1hcnJvdy1kcm9wLWRvd24tbGluZVwiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBDb2xvbiBTZXBhcmF0b3IgLS0+XG4gICAgICA8c3BhbiBjbGFzcz1cInRpbWUtY29sb25cIj46PC9zcGFuPlxuXG4gICAgICA8IS0tIE1pbnV0ZSBJbnB1dCB3aXRoIEFycm93cyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0aW1lLWlucHV0LWNvbnRhaW5lclwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJ0aW1lLWFycm93IHRpbWUtYXJyb3ctdXBcIlxuICAgICAgICAgIChjbGljayk9XCJpbmNyZW1lbnRNaW51dGUoKVwiXG4gICAgICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIkluY3JlbWVudCBtaW51dGVcIlxuICAgICAgICA+XG4gICAgICAgICAgPGkgY2xhc3M9XCJyaS1hcnJvdy1kcm9wLXVwLWxpbmVcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICBjbGFzcz1cInRpbWUtZmllbGRcIlxuICAgICAgICAgIFt2YWx1ZV09XCJzZWxlY3RlZFRpbWUubWludXRlLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKVwiXG4gICAgICAgICAgKGlucHV0KT1cIm9uTWludXRlSW5wdXRDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgKGtleWRvd24pPVwib25UaW1lS2V5ZG93bigkZXZlbnQsICdtaW51dGUnKVwiXG4gICAgICAgICAgbWluPVwiMFwiXG4gICAgICAgICAgbWF4PVwiNTlcIlxuICAgICAgICAgIGFyaWEtbGFiZWw9XCJNaW51dGVcIlxuICAgICAgICAvPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJ0aW1lLWFycm93IHRpbWUtYXJyb3ctZG93blwiXG4gICAgICAgICAgKGNsaWNrKT1cImRlY3JlbWVudE1pbnV0ZSgpXCJcbiAgICAgICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiRGVjcmVtZW50IG1pbnV0ZVwiXG4gICAgICAgID5cbiAgICAgICAgICA8aSBjbGFzcz1cInJpLWFycm93LWRyb3AtZG93bi1saW5lXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEFNL1BNIEJ1dHRvbiBHcm91cCAob25seSB3aGVuIHVzZU1lcmlkaWFuPXRydWUpIC0tPlxuICAgICAgPCEtLSBCQUNLV0FSRCBDT01QQVRJQklMSVRZOiBUaGlzIG9ubHkgcmVuZGVycyB3aGVuIHVzZU1lcmlkaWFuPXRydWUgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVyaWRpYW4tdG9nZ2xlLWdyb3VwXCIgKm5nSWY9XCJ1c2VNZXJpZGlhblwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJtZXJpZGlhbi1idG5cIlxuICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwibWVyaWRpYW4gPT09ICdBTSdcIlxuICAgICAgICAgIChjbGljayk9XCJtZXJpZGlhbiAhPT0gJ0FNJyAmJiB0b2dnbGVNZXJpZGlhbigpXCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiU2VsZWN0IEFNXCJcbiAgICAgICAgPlxuICAgICAgICAgIEFNXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJtZXJpZGlhbi1idG5cIlxuICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwibWVyaWRpYW4gPT09ICdQTSdcIlxuICAgICAgICAgIChjbGljayk9XCJtZXJpZGlhbiAhPT0gJ1BNJyAmJiB0b2dnbGVNZXJpZGlhbigpXCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiU2VsZWN0IFBNXCJcbiAgICAgICAgPlxuICAgICAgICAgIFBNXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxkaXY+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBjbGFzcz1cImNvbmZpcm0tYnRuXCJcbiAgICAgIFtkaXNhYmxlZF09XCJcbiAgICAgICAgaXNSZXF1aXJlZCAmJlxuICAgICAgICAoKCFzZWxlY3RlZERheSAmJiAhbXVsdGlwbGUpIHx8XG4gICAgICAgICAgKCFtdWx0aXBsZVNlbGVjdGVkRGF0ZXMubGVuZ3RoICYmIG11bHRpcGxlKSlcbiAgICAgIFwiXG4gICAgICAoY2xpY2spPVwib25Db25maXJtQ2xpY2tlZCgpXCJcbiAgICAgICpuZ0lmPVwic2hvd0NvbmZpcm1CdXR0b25cIlxuICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAnYmFja2dyb3VuZC1jb2xvcic6IHN0eWxlcy5zZWNvbmRhcnlDb2xvcixcbiAgICAgICAgY29sb3I6IHN0eWxlcy5jb25maXJtQnRuVGV4dENvbG9yLFxuICAgICAgICAnZm9udC1mYW1pbHknOiBzdHlsZXMuZm9udEZhbWlseSxcbiAgICAgICAgJ2JvcmRlci1yYWRpdXMnOiBzdHlsZXMuYm9yZGVyUmFkaXVzXG4gICAgICB9XCJcbiAgICA+XG4gICAgICB7eyBzdWJtaXRUZXh0QnV0dG9uIH19XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=