mis-crystal-design-system 18.1.7-signal-16-test → 18.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/async-search-dropdown/async-dropdown.component.d.ts +44 -3
  2. package/daterangepicker_v2/tz-drp-container/tz-drp-container.component.d.ts +9 -2
  3. package/esm2022/async-search-dropdown/async-dropdown.component.mjs +147 -37
  4. package/esm2022/datepicker_v2/tz-dp-container/tz-dp-container.component.mjs +35 -22
  5. package/esm2022/daterangepicker_v2/tz-daterangepicker.directive.mjs +6 -3
  6. package/esm2022/daterangepicker_v2/tz-drp-container/tz-drp-container.component.mjs +270 -187
  7. package/esm2022/dynamic-form/dynamic-form.component.mjs +30 -21
  8. package/esm2022/loader/loader.component.mjs +12 -6
  9. package/esm2022/slider/slider.component.mjs +2 -2
  10. package/esm2022/table/sort-icons.directive.mjs +24 -5
  11. package/esm2022/table/table.component.mjs +200 -93
  12. package/esm2022/table/table.module.mjs +7 -5
  13. package/esm2022/timepicker/timepicker.component.mjs +41 -14
  14. package/esm2022/timerangepicker/timerangepicker.component.mjs +73 -23
  15. package/fesm2022/mis-crystal-design-system-async-search-dropdown.mjs +146 -36
  16. package/fesm2022/mis-crystal-design-system-async-search-dropdown.mjs.map +1 -1
  17. package/fesm2022/mis-crystal-design-system-datepicker_v2.mjs +34 -21
  18. package/fesm2022/mis-crystal-design-system-datepicker_v2.mjs.map +1 -1
  19. package/fesm2022/mis-crystal-design-system-daterangepicker_v2.mjs +274 -188
  20. package/fesm2022/mis-crystal-design-system-daterangepicker_v2.mjs.map +1 -1
  21. package/fesm2022/mis-crystal-design-system-dynamic-form.mjs +29 -20
  22. package/fesm2022/mis-crystal-design-system-dynamic-form.mjs.map +1 -1
  23. package/fesm2022/mis-crystal-design-system-loader.mjs +11 -5
  24. package/fesm2022/mis-crystal-design-system-loader.mjs.map +1 -1
  25. package/fesm2022/mis-crystal-design-system-slider.mjs +2 -2
  26. package/fesm2022/mis-crystal-design-system-slider.mjs.map +1 -1
  27. package/fesm2022/mis-crystal-design-system-table.mjs +227 -99
  28. package/fesm2022/mis-crystal-design-system-table.mjs.map +1 -1
  29. package/fesm2022/mis-crystal-design-system-timepicker.mjs +40 -13
  30. package/fesm2022/mis-crystal-design-system-timepicker.mjs.map +1 -1
  31. package/fesm2022/mis-crystal-design-system-timerangepicker.mjs +72 -22
  32. package/fesm2022/mis-crystal-design-system-timerangepicker.mjs.map +1 -1
  33. package/loader/loader.component.d.ts +7 -1
  34. package/package.json +18 -18
  35. package/table/table.component.d.ts +16 -4
  36. package/table/table.module.d.ts +2 -1
  37. package/timepicker/timepicker.component.d.ts +3 -1
  38. package/timerangepicker/timerangepicker.component.d.ts +5 -1
@@ -1,4 +1,4 @@
1
- import { Component, input, output, signal, computed } from "@angular/core";
1
+ import { Component, input, output, signal, computed, effect, untracked } from "@angular/core";
2
2
  import dayjs from 'dayjs';
3
3
  import timezone from 'dayjs/plugin/timezone';
4
4
  import utc from 'dayjs/plugin/utc';
@@ -44,6 +44,8 @@ export class TimeRangePickerComponent {
44
44
  this.gap = input('1rem');
45
45
  this.disableStartTime = input(false);
46
46
  this.disableEndTime = input(false);
47
+ this.fontSize = input("14px");
48
+ this.disableUserInput = input(false);
47
49
  // --- Output Signal ---
48
50
  this.timeRangeEmitter = output();
49
51
  // --- Internal Writable Signals ---
@@ -53,13 +55,55 @@ export class TimeRangePickerComponent {
53
55
  this.triggerChange = signal(true);
54
56
  this._firstIntervals = signal({ start: 0, end: 0 });
55
57
  this._isInitializing = false;
58
+ this._previousStartDateEpoch = null;
59
+ this._previousEndDateEpoch = null;
56
60
  // --- Computed Signals (Derived State) ---
57
61
  this.firstIntervals = computed(() => this._firstIntervals()); // A public computed signal to access the writable one
58
- // Simple constructor - no effects here
62
+ // Effect to watch for changes in startDateEpoch and endDateEpoch
63
+ effect(() => {
64
+ // ONLY track these two signals - this is the only line that creates dependencies
65
+ const currentStartDate = this.startDateEpoch();
66
+ const currentEndDate = this.endDateEpoch();
67
+ // Use untracked() for everything else to prevent infinite loops
68
+ untracked(() => {
69
+ // Skip if component is initializing
70
+ if (this._isInitializing) {
71
+ return;
72
+ }
73
+ // Skip if component hasn't been initialized yet
74
+ if (!this.startTime() || !this.endTime()) {
75
+ return;
76
+ }
77
+ // Skip if dates haven't actually changed (prevents initial double-run)
78
+ if (this._previousStartDateEpoch === currentStartDate &&
79
+ this._previousEndDateEpoch === currentEndDate) {
80
+ return;
81
+ }
82
+ // Update previous values
83
+ this._previousStartDateEpoch = currentStartDate;
84
+ this._previousEndDateEpoch = currentEndDate;
85
+ // Reinitialize and emit when date inputs change
86
+ this.initializeComponent();
87
+ // Emit the updated time range
88
+ const validity = this.checkTimeValidity(this.startTime().time.trim(), this.startDateEpoch()) &&
89
+ this.checkTimeValidity(this.endTime().time.trim(), this.endDateEpoch());
90
+ this.rangeValidation(validity);
91
+ this.emitTimeRange({
92
+ valid: validity && this.rangeValidity(),
93
+ startTime: this.startTime().time,
94
+ endTime: this.endTime().time,
95
+ startEpoch: dayjs.tz(`${this.getStartDate()} ${this.startTime().time}`, `DD-MM-YYYY ${this.getTimeFormat()}`, this.timezone()).valueOf(),
96
+ endEpoch: dayjs.tz(`${this.getEndDate()} ${this.endTime().time}`, `DD-MM-YYYY ${this.getTimeFormat()}`, this.timezone()).valueOf()
97
+ });
98
+ });
99
+ }, { allowSignalWrites: true });
59
100
  }
60
101
  ngOnInit() {
61
102
  // Initialize the component once
62
103
  this.initializeComponent();
104
+ // Store initial values to prevent effect from running on first load
105
+ this._previousStartDateEpoch = this.startDateEpoch();
106
+ this._previousEndDateEpoch = this.endDateEpoch();
63
107
  }
64
108
  initializeComponent() {
65
109
  this._isInitializing = true;
@@ -151,15 +195,16 @@ export class TimeRangePickerComponent {
151
195
  // Calculate start time epoch for comparison
152
196
  const startTimeEpoch = dayjs.tz(`${this.getStartDate()} ${this.startTime().time}`, `DD-MM-YYYY ${this.getTimeFormat()}`, this.timezone()).valueOf();
153
197
  const endTimeEpoch = dayjs.tz(`${this.getEndDate()} ${this.endTime().time}`, `DD-MM-YYYY ${this.getTimeFormat()}`, this.timezone()).valueOf();
154
- // Auto-adjust end time if start time >= end time (for both same and different dates)
155
- if (startTimeEpoch >= endTimeEpoch) {
198
+ // Auto-adjust end time if start time > end time (for both same and different dates)
199
+ // This ensures end time is always after start time
200
+ if (startTimeEpoch > endTimeEpoch) {
156
201
  // Calculate new end time as start time + interval
157
202
  let newEndTimeEpoch = dayjs.tz(startTimeEpoch, this.timezone()).add(this.interval(), "m").valueOf();
158
203
  // If same date, check if the new end time would go beyond end of day
159
204
  if (this.getStartDate() === this.getEndDate()) {
160
205
  const endOfDay = dayjs.tz(this.startDateEpoch(), this.timezone()).endOf("d").valueOf();
161
206
  if (newEndTimeEpoch > endOfDay) {
162
- // NEW: Set end time to 11:59 PM (end of day) when start time is last interval
207
+ // Set end time to 11:59 PM (end of day) when start time is last interval
163
208
  newEndTimeEpoch = endOfDay;
164
209
  }
165
210
  }
@@ -174,26 +219,37 @@ export class TimeRangePickerComponent {
174
219
  start: this._firstIntervals().start,
175
220
  end: newEndTimeEpoch
176
221
  });
222
+ // Trigger change to force end timepicker to update its display with the new end time
223
+ // This is necessary when we reset the end time due to conflict
224
+ this.triggerChange.update(value => !value);
177
225
  }
178
- // NEW: Update end timepicker's firstInterval when both timepickers are on the same day
179
- // BUT only if there was a conflict (start >= end) or if we need to adjust for end of day
226
+ // Update end timepicker's firstInterval when both timepickers are on the same day
227
+ // ALWAYS update to ensure dropdown starts from next interval after start time
228
+ // This fixes the bug where selecting an earlier start time doesn't update end picker intervals
229
+ // NOTE: We only update firstInterval (dropdown options), NOT the selected end time value
230
+ // The timepicker component now handles firstInterval changes separately and won't reset chosenTime
180
231
  if (this.getStartDate() === this.getEndDate()) {
181
- // Only update firstInterval if there was a conflict or if we're at end of day
182
- if (startTimeEpoch >= endTimeEpoch) {
232
+ // Only update firstInterval if there's no conflict (start < end)
233
+ // If there's a conflict, it's already handled above and firstInterval was updated there
234
+ if (startTimeEpoch < endTimeEpoch) {
183
235
  // Calculate the next interval after the selected start time
184
236
  let nextIntervalAfterStart = dayjs.tz(startTimeEpoch, this.timezone()).add(this.interval(), "m").valueOf();
185
- // NEW: If next interval would go beyond end of day, use end of day instead
237
+ // If next interval would go beyond end of day, use end of day instead
186
238
  const endOfDay = dayjs.tz(this.startDateEpoch(), this.timezone()).endOf("d").valueOf();
187
239
  if (nextIntervalAfterStart > endOfDay) {
188
240
  nextIntervalAfterStart = endOfDay;
189
241
  }
190
242
  // Update the firstIntervals to make end timepicker dropdown start from next interval after start time
243
+ // This ensures users can always select times between the new start time and the current end time
244
+ // The timepicker component will update the dropdown but preserve the selected end time value
191
245
  this._firstIntervals.set({
192
246
  start: this._firstIntervals().start,
193
247
  end: nextIntervalAfterStart
194
248
  });
249
+ // NOTE: We don't call triggerChange here because we only want to update the dropdown,
250
+ // not reset the selected end time. The timepicker's separate effect for firstInterval
251
+ // will handle updating the dropdown without resetting chosenTime.
195
252
  }
196
- // If start < end, don't update firstIntervals - let the end timepicker keep its current dropdown
197
253
  }
198
254
  // Always validate and emit the time range
199
255
  const validity = this.checkTimeValidity(this.startTime().time.trim(), this.startDateEpoch()) &&
@@ -206,12 +262,6 @@ export class TimeRangePickerComponent {
206
262
  startEpoch: dayjs.tz(`${this.getStartDate()} ${this.startTime().time}`, `DD-MM-YYYY ${this.getTimeFormat()}`, this.timezone()).valueOf(),
207
263
  endEpoch: dayjs.tz(`${this.getEndDate()} ${this.endTime().time}`, `DD-MM-YYYY ${this.getTimeFormat()}`, this.timezone()).valueOf()
208
264
  });
209
- // FIXED: Only trigger change when there was a conflict (start >= end) that required end time update
210
- const currentStartTimeEpoch = dayjs.tz(`${this.getStartDate()} ${this.startTime().time}`, `DD-MM-YYYY ${this.getTimeFormat()}`, this.timezone()).valueOf();
211
- const currentEndTimeEpoch = dayjs.tz(`${this.getEndDate()} ${this.endTime().time}`, `DD-MM-YYYY ${this.getTimeFormat()}`, this.timezone()).valueOf();
212
- if (currentStartTimeEpoch >= currentEndTimeEpoch) {
213
- this.triggerChange.update(value => !value);
214
- }
215
265
  }
216
266
  endPickerHandler(time) {
217
267
  this.endTime.set(time);
@@ -252,7 +302,7 @@ export class TimeRangePickerComponent {
252
302
  }
253
303
  }
254
304
  static { this.ɵfac = function TimeRangePickerComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TimeRangePickerComponent)(); }; }
255
- static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TimeRangePickerComponent, selectors: [["mis-timerangepicker"]], inputs: { inputWidth: [1, "inputWidth"], dropdownWidth: [1, "dropdownWidth"], height: [1, "height"], timezone: [1, "timezone"], startDateEpoch: [1, "startDateEpoch"], endDateEpoch: [1, "endDateEpoch"], givenStartTime: [1, "givenStartTime"], givenEndTime: [1, "givenEndTime"], clockFormat: [1, "clockFormat"], interval: [1, "interval"], showTooltip: [1, "showTooltip"], direction: [1, "direction"], gap: [1, "gap"], disableStartTime: [1, "disableStartTime"], disableEndTime: [1, "disableEndTime"] }, outputs: { timeRangeEmitter: "timeRangeEmitter" }, decls: 4, vars: 29, consts: [[1, "rangepicker-container", 3, "ngStyle"], [3, "timeEmitter", "clockFormat", "interval", "dateAsEpoch", "firstInterval", "timezone", "height", "inputWidth", "dropdownWidth", "showTooltip", "givenTime", "disable"], [4, "ngIf"], [3, "timeEmitter", "clockFormat", "interval", "dateAsEpoch", "firstInterval", "rangeValidity", "timezone", "height", "inputWidth", "dropdownWidth", "showTooltip", "givenTime", "triggerChange", "disable"]], template: function TimeRangePickerComponent_Template(rf, ctx) { if (rf & 1) {
305
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TimeRangePickerComponent, selectors: [["mis-timerangepicker"]], inputs: { inputWidth: [1, "inputWidth"], dropdownWidth: [1, "dropdownWidth"], height: [1, "height"], timezone: [1, "timezone"], startDateEpoch: [1, "startDateEpoch"], endDateEpoch: [1, "endDateEpoch"], givenStartTime: [1, "givenStartTime"], givenEndTime: [1, "givenEndTime"], clockFormat: [1, "clockFormat"], interval: [1, "interval"], showTooltip: [1, "showTooltip"], direction: [1, "direction"], gap: [1, "gap"], disableStartTime: [1, "disableStartTime"], disableEndTime: [1, "disableEndTime"], fontSize: [1, "fontSize"], disableUserInput: [1, "disableUserInput"] }, outputs: { timeRangeEmitter: "timeRangeEmitter" }, decls: 4, vars: 33, consts: [[1, "rangepicker-container", 3, "ngStyle"], [3, "timeEmitter", "clockFormat", "interval", "dateAsEpoch", "firstInterval", "timezone", "height", "inputWidth", "dropdownWidth", "showTooltip", "givenTime", "disable", "disableUserInput", "fontSize"], [4, "ngIf"], [3, "timeEmitter", "clockFormat", "interval", "dateAsEpoch", "firstInterval", "rangeValidity", "timezone", "height", "inputWidth", "dropdownWidth", "showTooltip", "givenTime", "triggerChange", "disable", "disableUserInput", "fontSize"]], template: function TimeRangePickerComponent_Template(rf, ctx) { if (rf & 1) {
256
306
  i0.ɵɵelementStart(0, "div", 0)(1, "mis-timepicker", 1);
257
307
  i0.ɵɵlistener("timeEmitter", function TimeRangePickerComponent_Template_mis_timepicker_timeEmitter_1_listener($event) { return ctx.startPickerHandler($event); });
258
308
  i0.ɵɵelementEnd();
@@ -261,18 +311,18 @@ export class TimeRangePickerComponent {
261
311
  i0.ɵɵlistener("timeEmitter", function TimeRangePickerComponent_Template_mis_timepicker_timeEmitter_3_listener($event) { return ctx.endPickerHandler($event); });
262
312
  i0.ɵɵelementEnd()();
263
313
  } if (rf & 2) {
264
- i0.ɵɵproperty("ngStyle", i0.ɵɵpureFunction2(26, _c0, ctx.direction(), ctx.gap()));
314
+ i0.ɵɵproperty("ngStyle", i0.ɵɵpureFunction2(30, _c0, ctx.direction(), ctx.gap()));
265
315
  i0.ɵɵadvance();
266
- i0.ɵɵproperty("clockFormat", ctx.clockFormat())("interval", ctx.interval())("dateAsEpoch", ctx.startDateEpoch())("firstInterval", ctx.firstIntervals().start)("timezone", ctx.timezone())("height", ctx.height())("inputWidth", ctx.inputWidth())("dropdownWidth", ctx.dropdownWidth())("showTooltip", ctx.showTooltip())("givenTime", ctx.givenStartTime())("disable", ctx.disableStartTime());
316
+ i0.ɵɵproperty("clockFormat", ctx.clockFormat())("interval", ctx.interval())("dateAsEpoch", ctx.startDateEpoch())("firstInterval", ctx.firstIntervals().start)("timezone", ctx.timezone())("height", ctx.height())("inputWidth", ctx.inputWidth())("dropdownWidth", ctx.dropdownWidth())("showTooltip", ctx.showTooltip())("givenTime", ctx.givenStartTime())("disable", ctx.disableStartTime())("disableUserInput", ctx.disableUserInput())("fontSize", ctx.fontSize());
267
317
  i0.ɵɵadvance();
268
318
  i0.ɵɵproperty("ngIf", ctx.direction() === "row");
269
319
  i0.ɵɵadvance();
270
- i0.ɵɵproperty("clockFormat", ctx.clockFormat())("interval", ctx.interval())("dateAsEpoch", ctx.endDateEpoch())("firstInterval", ctx.firstIntervals().end)("rangeValidity", ctx.rangeValidity())("timezone", ctx.timezone())("height", ctx.height())("inputWidth", ctx.inputWidth())("dropdownWidth", ctx.dropdownWidth())("showTooltip", ctx.showTooltip())("givenTime", ctx.givenEndTime())("triggerChange", ctx.triggerChange())("disable", ctx.disableEndTime());
320
+ i0.ɵɵproperty("clockFormat", ctx.clockFormat())("interval", ctx.interval())("dateAsEpoch", ctx.endDateEpoch())("firstInterval", ctx.firstIntervals().end)("rangeValidity", ctx.rangeValidity())("timezone", ctx.timezone())("height", ctx.height())("inputWidth", ctx.inputWidth())("dropdownWidth", ctx.dropdownWidth())("showTooltip", ctx.showTooltip())("givenTime", ctx.givenEndTime())("triggerChange", ctx.triggerChange())("disable", ctx.disableEndTime())("disableUserInput", ctx.disableUserInput())("fontSize", ctx.fontSize());
271
321
  } }, dependencies: [i1.NgIf, i1.NgStyle, i2.TimePickerComponent], styles: [".rangepicker-container[_ngcontent-%COMP%]{display:flex;gap:1rem;align-items:center}p[_ngcontent-%COMP%]{margin:0;display:inline-flex;align-items:center}"] }); }
272
322
  }
273
323
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TimeRangePickerComponent, [{
274
324
  type: Component,
275
- args: [{ selector: "mis-timerangepicker", template: "<div class=\"rangepicker-container\" [ngStyle]=\"{'flexDirection': direction(), 'gap': gap()}\">\n <mis-timepicker\n [clockFormat]=\"clockFormat()\"\n [interval]=\"interval()\"\n [dateAsEpoch]=\"startDateEpoch()\"\n [firstInterval]=\"firstIntervals().start\"\n (timeEmitter)=\"startPickerHandler($event)\"\n [timezone]=\"timezone()\"\n [height]=\"height()\"\n [inputWidth]=\"inputWidth()\"\n [dropdownWidth]=\"dropdownWidth()\"\n [showTooltip]=\"showTooltip()\"\n [givenTime]=\"givenStartTime()\"\n [disable]=\"disableStartTime()\"\n ></mis-timepicker>\n <p *ngIf=\"direction() === 'row'\">-</p>\n <mis-timepicker\n [clockFormat]=\"clockFormat()\"\n [interval]=\"interval()\"\n [dateAsEpoch]=\"endDateEpoch()\"\n [firstInterval]=\"firstIntervals().end\"\n (timeEmitter)=\"endPickerHandler($event)\"\n [rangeValidity]=\"rangeValidity()\"\n [timezone]=\"timezone()\"\n [height]=\"height()\"\n [inputWidth]=\"inputWidth()\"\n [dropdownWidth]=\"dropdownWidth()\"\n [showTooltip]=\"showTooltip()\"\n [givenTime]=\"givenEndTime()\"\n [triggerChange]=\"triggerChange()\"\n [disable]=\"disableEndTime()\"\n ></mis-timepicker>\n</div>\n\n", styles: [".rangepicker-container{display:flex;gap:1rem;align-items:center}p{margin:0;display:inline-flex;align-items:center}\n"] }]
325
+ args: [{ selector: "mis-timerangepicker", template: "<div class=\"rangepicker-container\" [ngStyle]=\"{'flexDirection': direction(), 'gap': gap()}\">\n <mis-timepicker\n [clockFormat]=\"clockFormat()\"\n [interval]=\"interval()\"\n [dateAsEpoch]=\"startDateEpoch()\"\n [firstInterval]=\"firstIntervals().start\"\n (timeEmitter)=\"startPickerHandler($event)\"\n [timezone]=\"timezone()\"\n [height]=\"height()\"\n [inputWidth]=\"inputWidth()\"\n [dropdownWidth]=\"dropdownWidth()\"\n [showTooltip]=\"showTooltip()\"\n [givenTime]=\"givenStartTime()\"\n [disable]=\"disableStartTime()\"\n [disableUserInput]=\"disableUserInput()\"\n [fontSize]=\"fontSize()\"\n ></mis-timepicker>\n <p *ngIf=\"direction() === 'row'\">-</p>\n <mis-timepicker\n [clockFormat]=\"clockFormat()\"\n [interval]=\"interval()\"\n [dateAsEpoch]=\"endDateEpoch()\"\n [firstInterval]=\"firstIntervals().end\"\n (timeEmitter)=\"endPickerHandler($event)\"\n [rangeValidity]=\"rangeValidity()\"\n [timezone]=\"timezone()\"\n [height]=\"height()\"\n [inputWidth]=\"inputWidth()\"\n [dropdownWidth]=\"dropdownWidth()\"\n [showTooltip]=\"showTooltip()\"\n [givenTime]=\"givenEndTime()\"\n [triggerChange]=\"triggerChange()\"\n [disable]=\"disableEndTime()\"\n [disableUserInput]=\"disableUserInput()\"\n [fontSize]=\"fontSize()\"\n ></mis-timepicker>\n</div>\n\n", styles: [".rangepicker-container{display:flex;gap:1rem;align-items:center}p{margin:0;display:inline-flex;align-items:center}\n"] }]
276
326
  }], () => [], null); })();
277
327
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TimeRangePickerComponent, { className: "TimeRangePickerComponent" }); })();
278
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXJhbmdlcGlja2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL21pcy1jb21wb25lbnRzL3RpbWVyYW5nZXBpY2tlci90aW1lcmFuZ2VwaWNrZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vcHJvamVjdHMvbWlzLWNvbXBvbmVudHMvdGltZXJhbmdlcGlja2VyL3RpbWVyYW5nZXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBa0IsTUFBTSxlQUFlLENBQUM7QUFFM0YsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sUUFBUSxNQUFNLHVCQUF1QixDQUFDO0FBQzdDLE9BQU8sR0FBRyxNQUFNLGtCQUFrQixDQUFDOzs7Ozs7SUNXakMseUJBQWlDO0lBQUEsaUJBQUM7SUFBQSxpQkFBSTs7QURUeEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNsQixLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBT3ZCLE1BQU0sT0FBTyx3QkFBd0I7SUFnQ25DLDZFQUE2RTtJQUNyRSxhQUFhO1FBQ25CLE9BQU8sSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFDekQsQ0FBQztJQUVPLFlBQVk7UUFDbEIsT0FBTyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUVPLFVBQVU7UUFDaEIsT0FBTyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxZ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QSxBQURBLEFBREEsK0NBQTZCLDRCQUNOLHFDQUNTLDZDQUNRLDRCQUVqQix3QkFDSixnQ0FDUSxzQ0FDTSxrQ0FDSixtQ0FDQyxtQ0FDQTtZQUU1QixjQUEyQjtZQUEzQixnREFBMkI7WUFFN0IsY0FBNkI7WUFhN0IsQUFEQSxBQURBLEFBREEsQUFEQSxBQURBLEFBREEsQUFEQSxBQURBLEFBRkEsQUFEQSxBQURBLEFBREEsK0NBQTZCLDRCQUNOLG1DQUNPLDJDQUNRLHNDQUVMLDRCQUNWLHdCQUNKLGdDQUNRLHNDQUNNLGtDQUNKLGlDQUNELHNDQUNLLGlDQUNMOzs7aUZEaEJuQix3QkFBd0I7Y0FMcEMsU0FBUzsyQkFDRSxxQkFBcUI7O2tGQUlwQix3QkFBd0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGlucHV0LCBvdXRwdXQsIHNpZ25hbCwgY29tcHV0ZWQsIGVmZmVjdCwgT25Jbml0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IElUaW1lUmFuZ2UsIElUaW1lLCBURGlyZWN0aW9uIH0gZnJvbSBcIi4vdGltZXJhbmdlLm5hbWVzcGFjZVwiO1xuaW1wb3J0IGRheWpzIGZyb20gJ2RheWpzJztcbmltcG9ydCB0aW1lem9uZSBmcm9tICdkYXlqcy9wbHVnaW4vdGltZXpvbmUnO1xuaW1wb3J0IHV0YyBmcm9tICdkYXlqcy9wbHVnaW4vdXRjJztcblxuZGF5anMuZXh0ZW5kKHV0Yyk7XG5kYXlqcy5leHRlbmQodGltZXpvbmUpO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwibWlzLXRpbWVyYW5nZXBpY2tlclwiLFxuICB0ZW1wbGF0ZVVybDogXCIuL3RpbWVyYW5nZXBpY2tlci5jb21wb25lbnQuaHRtbFwiLCAvLyBDb3JyZWN0ZWQgZmlsZSBuYW1lXG4gIHN0eWxlVXJsczogW1wiLi90aW1lcmFuZ2VwaWNrZXIuY29tcG9uZW50LnNjc3NcIl1cbn0pXG5leHBvcnQgY2xhc3MgVGltZVJhbmdlUGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgLy8gLS0tIElucHV0IFNpZ25hbHMgKHJlYWQtb25seSkgLS0tXG4gIGlucHV0V2lkdGggPSBpbnB1dDxzdHJpbmc+KFwiMTAwcHhcIik7XG4gIGRyb3Bkb3duV2lkdGggPSBpbnB1dDxzdHJpbmcgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIGhlaWdodCA9IGlucHV0PHN0cmluZz4oXCI0NnB4XCIpO1xuICB0aW1lem9uZSA9IGlucHV0PHN0cmluZz4oXCJBc2lhL0tvbGthdGFcIik7XG4gIHN0YXJ0RGF0ZUVwb2NoID0gaW5wdXQ8bnVtYmVyPihkYXlqcy50eihkYXlqcygpLCB0aGlzLnRpbWV6b25lKCkpLnZhbHVlT2YoKSk7XG4gIGVuZERhdGVFcG9jaCA9IGlucHV0PG51bWJlcj4oZGF5anMudHooZGF5anMoKSwgdGhpcy50aW1lem9uZSgpKS52YWx1ZU9mKCkpO1xuICBnaXZlblN0YXJ0VGltZSA9IGlucHV0PG51bWJlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgZ2l2ZW5FbmRUaW1lID0gaW5wdXQ8bnVtYmVyIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBjbG9ja0Zvcm1hdCA9IGlucHV0PG51bWJlcj4oMTIpO1xuICBpbnRlcnZhbCA9IGlucHV0PG51bWJlcj4oMTUpO1xuICBzaG93VG9vbHRpcCA9IGlucHV0PGJvb2xlYW4+KHRydWUpO1xuICBkaXJlY3Rpb24gPSBpbnB1dDxURGlyZWN0aW9uPigncm93Jyk7XG4gIGdhcCA9IGlucHV0PHN0cmluZz4oJzFyZW0nKTtcbiAgZGlzYWJsZVN0YXJ0VGltZSA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcbiAgZGlzYWJsZUVuZFRpbWUgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG4gIFxuICAvLyAtLS0gT3V0cHV0IFNpZ25hbCAtLS1cbiAgdGltZVJhbmdlRW1pdHRlciA9IG91dHB1dDxJVGltZVJhbmdlPigpO1xuXG4gIC8vIC0tLSBJbnRlcm5hbCBXcml0YWJsZSBTaWduYWxzIC0tLVxuICBzdGFydFRpbWUgPSBzaWduYWw8SVRpbWUgfCBudWxsPihudWxsKTtcbiAgZW5kVGltZSA9IHNpZ25hbDxJVGltZSB8IG51bGw+KG51bGwpO1xuICByYW5nZVZhbGlkaXR5ID0gc2lnbmFsPGJvb2xlYW4+KHRydWUpO1xuICB0cmlnZ2VyQ2hhbmdlID0gc2lnbmFsPGJvb2xlYW4+KHRydWUpO1xuICBwcml2YXRlIF9maXJzdEludGVydmFscyA9IHNpZ25hbDx7IHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyIH0+KHsgc3RhcnQ6IDAsIGVuZDogMCB9KTtcbiAgcHJpdmF0ZSBfaXNJbml0aWFsaXppbmcgPSBmYWxzZTtcblxuICAvLyAtLS0gQ29tcHV0ZWQgU2lnbmFscyAoRGVyaXZlZCBTdGF0ZSkgLS0tXG4gIGZpcnN0SW50ZXJ2YWxzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5fZmlyc3RJbnRlcnZhbHMoKSk7IC8vIEEgcHVibGljIGNvbXB1dGVkIHNpZ25hbCB0byBhY2Nlc3MgdGhlIHdyaXRhYmxlIG9uZVxuICBcbiAgLy8gSGVscGVyIG1ldGhvZHMgaW5zdGVhZCBvZiBjb21wdXRlZCBzaWduYWxzIHRvIGF2b2lkIHNpZ25hbCB3cml0ZSBjb25mbGljdHNcbiAgcHJpdmF0ZSBnZXRUaW1lRm9ybWF0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY2xvY2tGb3JtYXQoKSA9PT0gMTIgPyBcImhoOm1tIGFcIiA6IFwiSEg6bW1cIjtcbiAgfVxuICBcbiAgcHJpdmF0ZSBnZXRTdGFydERhdGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZGF5anMudHoodGhpcy5zdGFydERhdGVFcG9jaCgpLCB0aGlzLnRpbWV6b25lKCkpLmZvcm1hdChcIkRELU1NLVlZWVlcIik7XG4gIH1cbiAgXG4gIHByaXZhdGUgZ2V0RW5kRGF0ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBkYXlqcy50eih0aGlzLmVuZERhdGVFcG9jaCgpLCB0aGlzLnRpbWV6b25lKCkpLmZvcm1hdChcIkRELU1NLVlZWVlcIik7XG4gIH1cbiAgXG4gIHByaXZhdGUgZ2V0Q3VyckRhdGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZGF5anMudHooZGF5anMoKSwgdGhpcy50aW1lem9uZSgpKS5mb3JtYXQoXCJERC1NTS1ZWVlZXCIpO1xuICB9XG4gIFxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBTaW1wbGUgY29uc3RydWN0b3IgLSBubyBlZmZlY3RzIGhlcmVcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIEluaXRpYWxpemUgdGhlIGNvbXBvbmVudCBvbmNlXG4gICAgdGhpcy5pbml0aWFsaXplQ29tcG9uZW50KCk7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVDb21wb25lbnQoKTogdm9pZCB7XG4gICAgdGhpcy5faXNJbml0aWFsaXppbmcgPSB0cnVlO1xuICAgIFxuICAgIHRoaXMuc2V0Rmlyc3RJbnRlcnZhbHMoKTtcbiAgICBjb25zdCBmaXJzdEludGVydmFscyA9IHRoaXMuX2ZpcnN0SW50ZXJ2YWxzKCk7XG5cbiAgICB0aGlzLnN0YXJ0VGltZS5zZXQoe1xuICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICB0aW1lOiBkYXlqcy50eihmaXJzdEludGVydmFscy5zdGFydCwgdGhpcy50aW1lem9uZSgpKS5mb3JtYXQodGhpcy5nZXRUaW1lRm9ybWF0KCkpLFxuICAgICAgZXBvY2g6IGRheWpzLnR6KGZpcnN0SW50ZXJ2YWxzLnN0YXJ0LCB0aGlzLnRpbWV6b25lKCkpLnZhbHVlT2YoKVxuICAgIH0pO1xuICAgIFxuICAgIC8vIEVuc3VyZSBlbmQgdGltZSBpcyBhbHdheXMgYWZ0ZXIgc3RhcnQgdGltZVxuICAgIGxldCBlbmRUaW1lRXBvY2ggPSBmaXJzdEludGVydmFscy5lbmQ7XG4gICAgY29uc3Qgc3RhcnRUaW1lRXBvY2ggPSBmaXJzdEludGVydmFscy5zdGFydDtcbiAgICBcbiAgICAvLyBJZiBlbmQgdGltZSBpcyBzYW1lIG9yIGJlZm9yZSBzdGFydCB0aW1lLCBhZGQgb25lIGludGVydmFsIHRvIGVuZCB0aW1lXG4gICAgaWYgKGVuZFRpbWVFcG9jaCA8PSBzdGFydFRpbWVFcG9jaCkge1xuICAgICAgZW5kVGltZUVwb2NoID0gZGF5anMudHooc3RhcnRUaW1lRXBvY2gsIHRoaXMudGltZXpvbmUoKSkuYWRkKHRoaXMuaW50ZXJ2YWwoKSwgJ20nKS52YWx1ZU9mKCk7XG4gICAgICBcbiAgICAgIC8vIFVwZGF0ZSB0aGUgZmlyc3RJbnRlcnZhbHMgdG8gcmVmbGVjdCB0aGUgYWRqdXN0ZWQgZW5kIHRpbWVcbiAgICAgIHRoaXMuX2ZpcnN0SW50ZXJ2YWxzLnNldCh7XG4gICAgICAgIHN0YXJ0OiBmaXJzdEludGVydmFscy5zdGFydCxcbiAgICAgICAgZW5kOiBlbmRUaW1lRXBvY2hcbiAgICAgIH0pO1xuICAgIH1cbiAgICBcbiAgICB0aGlzLmVuZFRpbWUuc2V0KHtcbiAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgdGltZTogZGF5anMudHooZW5kVGltZUVwb2NoLCB0aGlzLnRpbWV6b25lKCkpLmZvcm1hdCh0aGlzLmdldFRpbWVGb3JtYXQoKSksXG4gICAgICBlcG9jaDogZW5kVGltZUVwb2NoXG4gICAgfSk7XG4gICAgXG4gICAgdGhpcy5faXNJbml0aWFsaXppbmcgPSBmYWxzZTtcbiAgfVxuXG4gIC8vIGNhbGN1bGF0ZSB0aGUgZmlyc3QgaW50ZXJ2YWwgb2YgdGhlIHBpY2tlclxuICBwcml2YXRlIHNldEZpcnN0SW50ZXJ2YWxzKCk6IHZvaWQge1xuICAgIGxldCBmaXJzdEludGVydmFsRm9yU3RhcnRQaWNrZXI6IG51bWJlcjtcbiAgICBsZXQgZmlyc3RJbnRlcnZhbEZvckVuZFBpY2tlcjogbnVtYmVyO1xuXG4gICAgY29uc3QgbWludXRlcyA9IGRheWpzLnR6KGRheWpzKCksIHRoaXMudGltZXpvbmUoKSkubWludXRlKCk7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5pbnRlcnZhbCgpIC0gKG1pbnV0ZXMgJSB0aGlzLmludGVydmFsKCkpO1xuICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gZGF5anMudHooZGF5anMoKSwgdGhpcy50aW1lem9uZSgpKS52YWx1ZU9mKCk7XG5cbiAgICBpZiggdGhpcy5nZXRTdGFydERhdGUoKSA9PT0gdGhpcy5nZXRDdXJyRGF0ZSgpICl7XG4gICAgICBpZih0aGlzLmdldFN0YXJ0RGF0ZSgpID09PSB0aGlzLmdldEVuZERhdGUoKSl7XG4gICAgICAgIGlmKGN1cnJlbnRUaW1lID49IGRheWpzLnR6KHRoaXMuc3RhcnREYXRlRXBvY2goKSwgdGhpcy50aW1lem9uZSgpKS5lbmRPZihcImRcIikuc3VidHJhY3QodGhpcy5pbnRlcnZhbCgpLFwibVwiKS52YWx1ZU9mKCkpe1xuICAgICAgICAgIGZpcnN0SW50ZXJ2YWxGb3JTdGFydFBpY2tlciA9IGN1cnJlbnRUaW1lO1xuICAgICAgICAgIGZpcnN0SW50ZXJ2YWxGb3JFbmRQaWNrZXIgPSBkYXlqcy50eih0aGlzLmVuZERhdGVFcG9jaCgpLCB0aGlzLnRpbWV6b25lKCkpLmVuZE9mKFwiZFwiKS52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZmlyc3RJbnRlcnZhbEZvclN0YXJ0UGlja2VyID0gZGF5anMudHooZGF5anMoKSwgdGhpcy50aW1lem9uZSgpKS5hZGQob2Zmc2V0LCBcIm1cIikudmFsdWVPZigpO1xuICAgICAgICAgIC8vIEZvciBzYW1lIGRhdGUsIGVuZCBwaWNrZXIgc2hvdWxkIHN0YXJ0IGZyb20gYmVnaW5uaW5nIG9mIGRheSB0byBhdm9pZCB2YWxpZGF0aW9uIGlzc3Vlc1xuICAgICAgICAgIGZpcnN0SW50ZXJ2YWxGb3JFbmRQaWNrZXIgPSBkYXlqcy50eih0aGlzLmVuZERhdGVFcG9jaCgpLCB0aGlzLnRpbWV6b25lKCkpLnN0YXJ0T2YoXCJkXCIpLnZhbHVlT2YoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYoY3VycmVudFRpbWUgPj0gZGF5anMudHoodGhpcy5zdGFydERhdGVFcG9jaCgpLCB0aGlzLnRpbWV6b25lKCkpLmVuZE9mKFwiZFwiKS5zdWJ0cmFjdCh0aGlzLmludGVydmFsKCksXCJtXCIpLnZhbHVlT2YoKSl7XG4gICAgICAgICAgZmlyc3RJbnRlcnZhbEZvclN0YXJ0UGlja2VyID0gY3VycmVudFRpbWU7XG4gICAgICAgICAgZmlyc3RJbnRlcnZhbEZvckVuZFBpY2tlciA9IGRheWpzLnR6KHRoaXMuZW5kRGF0ZUVwb2NoKCksIHRoaXMudGltZXpvbmUoKSkuZW5kT2YoXCJkXCIpLnZhbHVlT2YoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaXJzdEludGVydmFsRm9yU3RhcnRQaWNrZXIgPSBkYXlqcy50eihkYXlqcygpLCB0aGlzLnRpbWV6b25lKCkpLmFkZChvZmZzZXQsIFwibVwiKS52YWx1ZU9mKCk7XG4gICAgICAgICAgZmlyc3RJbnRlcnZhbEZvckVuZFBpY2tlciA9IGRheWpzLnR6KHRoaXMuZW5kRGF0ZUVwb2NoKCksIHRoaXMudGltZXpvbmUoKSkuc3RhcnRPZihcImRcIikudmFsdWVPZigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZih0aGlzLmdldFN0YXJ0RGF0ZSgpID09PSB0aGlzLmdldEVuZERhdGUoKSl7XG4gICAgICAgIGZpcnN0SW50ZXJ2YWxGb3JTdGFydFBpY2tlciA9IGRheWpzLnR6KHRoaXMuc3RhcnREYXRlRXBvY2goKSwgdGhpcy50aW1lem9uZSgpKS5zdGFydE9mKFwiZFwiKS52YWx1ZU9mKCk7XG4gICAgICAgIGZpcnN0SW50ZXJ2YWxGb3JFbmRQaWNrZXIgPSBkYXlqcy50eih0aGlzLmVuZERhdGVFcG9jaCgpLCB0aGlzLnRpbWV6b25lKCkpLmFkZCh0aGlzLmludGVydmFsKCksIFwibVwiKS52YWx1ZU9mKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmaXJzdEludGVydmFsRm9yU3RhcnRQaWNrZXIgPSBkYXlqcy50eih0aGlzLnN0YXJ0RGF0ZUVwb2NoKCksIHRoaXMudGltZXpvbmUoKSkuc3RhcnRPZihcImRcIikudmFsdWVPZigpO1xuICAgICAgICBmaXJzdEludGVydmFsRm9yRW5kUGlja2VyID0gZGF5anMudHoodGhpcy5lbmREYXRlRXBvY2goKSwgdGhpcy50aW1lem9uZSgpKS5zdGFydE9mKFwiZFwiKS52YWx1ZU9mKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYodGhpcy5naXZlblN0YXJ0VGltZSgpKSB7XG4gICAgICBmaXJzdEludGVydmFsRm9yU3RhcnRQaWNrZXIgPSB0aGlzLmdpdmVuU3RhcnRUaW1lKCkhO1xuICAgIH1cbiAgICBcbiAgICBpZih0aGlzLmdpdmVuRW5kVGltZSgpKSB7XG4gICAgICBmaXJzdEludGVydmFsRm9yRW5kUGlja2VyID0gdGhpcy5naXZlbkVuZFRpbWUoKSE7XG4gICAgfVxuICAgICAgXG4gICAgdGhpcy5fZmlyc3RJbnRlcnZhbHMuc2V0KHsgc3RhcnQ6IGZpcnN0SW50ZXJ2YWxGb3JTdGFydFBpY2tlciwgZW5kOiBmaXJzdEludGVydmFsRm9yRW5kUGlja2VyIH0pO1xuICB9XG5cbiAgLy8gLS0tIFB1YmxpYyBNZXRob2RzIC0tLVxuICBlbWl0VGltZVJhbmdlKGRhdGE6IElUaW1lUmFuZ2UpOiB2b2lkIHtcbiAgICB0aGlzLnRpbWVSYW5nZUVtaXR0ZXIuZW1pdChkYXRhKTtcbiAgfVxuXG4gIHN0YXJ0UGlja2VySGFuZGxlcih0aW1lOiBJVGltZSk6IHZvaWQge1xuICAgIHRoaXMuc3RhcnRUaW1lLnNldCh0aW1lKTtcbiAgICB0aGlzLnJhbmdlVmFsaWRpdHkuc2V0KHRydWUpO1xuICAgIFxuICAgIC8vIERvbid0IGVtaXQgZHVyaW5nIGluaXRpYWxpemF0aW9uXG4gICAgaWYgKHRoaXMuX2lzSW5pdGlhbGl6aW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2FsY3VsYXRlIHN0YXJ0IHRpbWUgZXBvY2ggZm9yIGNvbXBhcmlzb25cbiAgICBjb25zdCBzdGFydFRpbWVFcG9jaCA9IGRheWpzLnR6KGAke3RoaXMuZ2V0U3RhcnREYXRlKCl9ICR7dGhpcy5zdGFydFRpbWUoKSEudGltZX1gLCBgREQtTU0tWVlZWSAke3RoaXMuZ2V0VGltZUZvcm1hdCgpfWAsIHRoaXMudGltZXpvbmUoKSkudmFsdWVPZigpO1xuICAgIGNvbnN0IGVuZFRpbWVFcG9jaCA9IGRheWpzLnR6KGAke3RoaXMuZ2V0RW5kRGF0ZSgpfSAke3RoaXMuZW5kVGltZSgpIS50aW1lfWAsIGBERC1NTS1ZWVlZICR7dGhpcy5nZXRUaW1lRm9ybWF0KCl9YCwgdGhpcy50aW1lem9uZSgpKS52YWx1ZU9mKCk7XG5cbiAgICAvLyBBdXRvLWFkanVzdCBlbmQgdGltZSBpZiBzdGFydCB0aW1lID49IGVuZCB0aW1lIChmb3IgYm90aCBzYW1lIGFuZCBkaWZmZXJlbnQgZGF0ZXMpXG4gICAgaWYgKHN0YXJ0VGltZUVwb2NoID49IGVuZFRpbWVFcG9jaCkge1xuICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBlbmQgdGltZSBhcyBzdGFydCB0aW1lICsgaW50ZXJ2YWxcbiAgICAgIGxldCBuZXdFbmRUaW1lRXBvY2ggPSBkYXlqcy50eihzdGFydFRpbWVFcG9jaCwgdGhpcy50aW1lem9uZSgpKS5hZGQodGhpcy5pbnRlcnZhbCgpLCBcIm1cIikudmFsdWVPZigpO1xuICAgICAgXG4gICAgICAvLyBJZiBzYW1lIGRhdGUsIGNoZWNrIGlmIHRoZSBuZXcgZW5kIHRpbWUgd291bGQgZ28gYmV5b25kIGVuZCBvZiBkYXlcbiAgICAgIGlmICh0aGlzLmdldFN0YXJ0RGF0ZSgpID09PSB0aGlzLmdldEVuZERhdGUoKSkge1xuICAgICAgICBjb25zdCBlbmRPZkRheSA9IGRheWpzLnR6KHRoaXMuc3RhcnREYXRlRXBvY2goKSwgdGhpcy50aW1lem9uZSgpKS5lbmRPZihcImRcIikudmFsdWVPZigpO1xuICAgICAgICBpZiAobmV3RW5kVGltZUVwb2NoID4gZW5kT2ZEYXkpIHtcbiAgICAgICAgICAvLyBORVc6IFNldCBlbmQgdGltZSB0byAxMTo1OSBQTSAoZW5kIG9mIGRheSkgd2hlbiBzdGFydCB0aW1lIGlzIGxhc3QgaW50ZXJ2YWxcbiAgICAgICAgICBuZXdFbmRUaW1lRXBvY2ggPSBlbmRPZkRheTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBVcGRhdGUgdGhlIGVuZCB0aW1lIHNpZ25hbFxuICAgICAgdGhpcy5lbmRUaW1lLnNldCh7XG4gICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB0aW1lOiBkYXlqcy50eihuZXdFbmRUaW1lRXBvY2gsIHRoaXMudGltZXpvbmUoKSkuZm9ybWF0KHRoaXMuZ2V0VGltZUZvcm1hdCgpKSxcbiAgICAgICAgZXBvY2g6IG5ld0VuZFRpbWVFcG9jaFxuICAgICAgfSk7XG4gICAgICBcbiAgICAgIC8vIFVwZGF0ZSB0aGUgZmlyc3RJbnRlcnZhbHMgdG8gcmVmbGVjdCB0aGUgbmV3IGVuZCB0aW1lXG4gICAgICB0aGlzLl9maXJzdEludGVydmFscy5zZXQoeyBcbiAgICAgICAgc3RhcnQ6IHRoaXMuX2ZpcnN0SW50ZXJ2YWxzKCkuc3RhcnQsIFxuICAgICAgICBlbmQ6IG5ld0VuZFRpbWVFcG9jaCBcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIE5FVzogVXBkYXRlIGVuZCB0aW1lcGlja2VyJ3MgZmlyc3RJbnRlcnZhbCB3aGVuIGJvdGggdGltZXBpY2tlcnMgYXJlIG9uIHRoZSBzYW1lIGRheVxuICAgIC8vIEJVVCBvbmx5IGlmIHRoZXJlIHdhcyBhIGNvbmZsaWN0IChzdGFydCA+PSBlbmQpIG9yIGlmIHdlIG5lZWQgdG8gYWRqdXN0IGZvciBlbmQgb2YgZGF5XG4gICAgaWYgKHRoaXMuZ2V0U3RhcnREYXRlKCkgPT09IHRoaXMuZ2V0RW5kRGF0ZSgpKSB7XG4gICAgICAvLyBPbmx5IHVwZGF0ZSBmaXJzdEludGVydmFsIGlmIHRoZXJlIHdhcyBhIGNvbmZsaWN0IG9yIGlmIHdlJ3JlIGF0IGVuZCBvZiBkYXlcbiAgICAgIGlmIChzdGFydFRpbWVFcG9jaCA+PSBlbmRUaW1lRXBvY2gpIHtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBuZXh0IGludGVydmFsIGFmdGVyIHRoZSBzZWxlY3RlZCBzdGFydCB0aW1lXG4gICAgICAgIGxldCBuZXh0SW50ZXJ2YWxBZnRlclN0YXJ0ID0gZGF5anMudHooc3RhcnRUaW1lRXBvY2gsIHRoaXMudGltZXpvbmUoKSkuYWRkKHRoaXMuaW50ZXJ2YWwoKSwgXCJtXCIpLnZhbHVlT2YoKTtcbiAgICAgICAgXG4gICAgICAgIC8vIE5FVzogSWYgbmV4dCBpbnRlcnZhbCB3b3VsZCBnbyBiZXlvbmQgZW5kIG9mIGRheSwgdXNlIGVuZCBvZiBkYXkgaW5zdGVhZFxuICAgICAgICBjb25zdCBlbmRPZkRheSA9IGRheWpzLnR6KHRoaXMuc3RhcnREYXRlRXBvY2goKSwgdGhpcy50aW1lem9uZSgpKS5lbmRPZihcImRcIikudmFsdWVPZigpO1xuICAgICAgICBpZiAobmV4dEludGVydmFsQWZ0ZXJTdGFydCA+IGVuZE9mRGF5KSB7XG4gICAgICAgICAgbmV4dEludGVydmFsQWZ0ZXJTdGFydCA9IGVuZE9mRGF5O1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvLyBVcGRhdGUgdGhlIGZpcnN0SW50ZXJ2YWxzIHRvIG1ha2UgZW5kIHRpbWVwaWNrZXIgZHJvcGRvd24gc3RhcnQgZnJvbSBuZXh0IGludGVydmFsIGFmdGVyIHN0YXJ0IHRpbWVcbiAgICAgICAgdGhpcy5fZmlyc3RJbnRlcnZhbHMuc2V0KHsgXG4gICAgICAgICAgc3RhcnQ6IHRoaXMuX2ZpcnN0SW50ZXJ2YWxzKCkuc3RhcnQsIFxuICAgICAgICAgIGVuZDogbmV4dEludGVydmFsQWZ0ZXJTdGFydCBcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyBJZiBzdGFydCA8IGVuZCwgZG9uJ3QgdXBkYXRlIGZpcnN0SW50ZXJ2YWxzIC0gbGV0IHRoZSBlbmQgdGltZXBpY2tlciBrZWVwIGl0cyBjdXJyZW50IGRyb3Bkb3duXG4gICAgfVxuXG4gICAgLy8gQWx3YXlzIHZhbGlkYXRlIGFuZCBlbWl0IHRoZSB0aW1lIHJhbmdlXG4gICAgY29uc3QgdmFsaWRpdHkgPVxuICAgICAgdGhpcy5jaGVja1RpbWVWYWxpZGl0eSh0aGlzLnN0YXJ0VGltZSgpIS50aW1lLnRyaW0oKSwgdGhpcy5zdGFydERhdGVFcG9jaCgpKSAmJlxuICAgICAgdGhpcy5jaGVja1RpbWVWYWxpZGl0eSh0aGlzLmVuZFRpbWUoKSEudGltZS50cmltKCksIHRoaXMuZW5kRGF0ZUVwb2NoKCkpO1xuXG4gICAgdGhpcy5yYW5nZVZhbGlkYXRpb24odmFsaWRpdHkpO1xuICAgIHRoaXMuZW1pdFRpbWVSYW5nZSh7XG4gICAgICB2YWxpZDogdmFsaWRpdHkgJiYgdGhpcy5yYW5nZVZhbGlkaXR5KCksXG4gICAgICBzdGFydFRpbWU6IHRoaXMuc3RhcnRUaW1lKCkhLnRpbWUsXG4gICAgICBlbmRUaW1lOiB0aGlzLmVuZFRpbWUoKSEudGltZSxcbiAgICAgIHN0YXJ0RXBvY2g6IGRheWpzLnR6KGAke3RoaXMuZ2V0U3RhcnREYXRlKCl9ICR7dGhpcy5zdGFydFRpbWUoKSEudGltZX1gLCBgREQtTU0tWVlZWSAke3RoaXMuZ2V0VGltZUZvcm1hdCgpfWAsIHRoaXMudGltZXpvbmUoKSkudmFsdWVPZigpLFxuICAgICAgZW5kRXBvY2g6IGRheWpzLnR6KGAke3RoaXMuZ2V0RW5kRGF0ZSgpfSAke3RoaXMuZW5kVGltZSgpIS50aW1lfWAsIGBERC1NTS1ZWVlZICR7dGhpcy5nZXRUaW1lRm9ybWF0KCl9YCwgdGhpcy50aW1lem9uZSgpKS52YWx1ZU9mKClcbiAgICB9KTtcblxuICAgIC8vIEZJWEVEOiBPbmx5IHRyaWdnZXIgY2hhbmdlIHdoZW4gdGhlcmUgd2FzIGEgY29uZmxpY3QgKHN0YXJ0ID49IGVuZCkgdGhhdCByZXF1aXJlZCBlbmQgdGltZSB1cGRhdGVcbiAgICBjb25zdCBjdXJyZW50U3RhcnRUaW1lRXBvY2ggPSBkYXlqcy50eihgJHt0aGlzLmdldFN0YXJ0RGF0ZSgpfSAke3RoaXMuc3RhcnRUaW1lKCkhLnRpbWV9YCwgYERELU1NLVlZWVkgJHt0aGlzLmdldFRpbWVGb3JtYXQoKX1gLCB0aGlzLnRpbWV6b25lKCkpLnZhbHVlT2YoKTtcbiAgICBjb25zdCBjdXJyZW50RW5kVGltZUVwb2NoID0gZGF5anMudHooYCR7dGhpcy5nZXRFbmREYXRlKCl9ICR7dGhpcy5lbmRUaW1lKCkhLnRpbWV9YCwgYERELU1NLVlZWVkgJHt0aGlzLmdldFRpbWVGb3JtYXQoKX1gLCB0aGlzLnRpbWV6b25lKCkpLnZhbHVlT2YoKTtcbiAgICBcbiAgICBpZiAoY3VycmVudFN0YXJ0VGltZUVwb2NoID49IGN1cnJlbnRFbmRUaW1lRXBvY2gpIHtcbiAgICAgIHRoaXMudHJpZ2dlckNoYW5nZS51cGRhdGUodmFsdWUgPT4gIXZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBlbmRQaWNrZXJIYW5kbGVyKHRpbWU6IElUaW1lKTogdm9pZCB7XG4gICAgdGhpcy5lbmRUaW1lLnNldCh0aW1lKTtcbiAgICBcbiAgICAvLyBEb24ndCBlbWl0IGR1cmluZyBpbml0aWFsaXphdGlvblxuICAgIGlmICh0aGlzLl9pc0luaXRpYWxpemluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkaXR5ID1cbiAgICAgIHRoaXMuY2hlY2tUaW1lVmFsaWRpdHkodGhpcy5zdGFydFRpbWUoKSEudGltZS50cmltKCksIHRoaXMuc3RhcnREYXRlRXBvY2goKSkgJiYgXG4gICAgICB0aGlzLmNoZWNrVGltZVZhbGlkaXR5KHRoaXMuZW5kVGltZSgpIS50aW1lLnRyaW0oKSwgdGhpcy5lbmREYXRlRXBvY2goKSk7XG5cbiAgICB0aGlzLnJhbmdlVmFsaWRhdGlvbih2YWxpZGl0eSk7XG4gICAgdGhpcy5lbWl0VGltZVJhbmdlKHtcbiAgICAgIHZhbGlkOiB2YWxpZGl0eSAmJiB0aGlzLnJhbmdlVmFsaWRpdHkoKSxcbiAgICAgIHN0YXJ0VGltZTogdGhpcy5zdGFydFRpbWUoKSEudGltZSxcbiAgICAgIGVuZFRpbWU6IHRoaXMuZW5kVGltZSgpIS50aW1lLFxuICAgICAgc3RhcnRFcG9jaDogZGF5anMudHooYCR7dGhpcy5nZXRTdGFydERhdGUoKX0gJHt0aGlzLnN0YXJ0VGltZSgpIS50aW1lfWAsIGBERC1NTS1ZWVlZICR7dGhpcy5nZXRUaW1lRm9ybWF0KCl9YCwgdGhpcy50aW1lem9uZSgpKS52YWx1ZU9mKCksXG4gICAgICBlbmRFcG9jaDogZGF5anMudHooYCR7dGhpcy5nZXRFbmREYXRlKCl9ICR7dGhpcy5lbmRUaW1lKCkhLnRpbWV9YCwgYERELU1NLVlZWVkgJHt0aGlzLmdldFRpbWVGb3JtYXQoKX1gLCB0aGlzLnRpbWV6b25lKCkpLnZhbHVlT2YoKVxuICAgIH0pO1xuICB9XG5cbiAgY2hlY2tUaW1lVmFsaWRpdHkodGltZTogc3RyaW5nLCBkYXRlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCBSRTEyID0gL14oKFswXVsxLTldfDFbMC0yXSk6KFswLTVdWzAtOV0pKCApPyhhbXxwbXxBTXxQTSkpJC9pO1xuICAgIGNvbnN0IFJFMjQgPSAvXihbMDFdWzAtOV18MlswLTNdKTpbMC01XVswLTldJC87XG4gICAgY29uc3QgUkUgPSB0aGlzLmNsb2NrRm9ybWF0KCkgPT09IDEyID8gUkUxMiA6IFJFMjQ7XG5cbiAgICBjb25zdCB0aW1lZGF5anMgPSBkYXlqcy50eihgJHtkYXlqcy50eihkYXRlLCB0aGlzLnRpbWV6b25lKCkpLmZvcm1hdChcIkRELU1NLVlZWVlcIil9ICR7dGltZX1gLCBgJ0RELU1NLVlZWVknICR7dGhpcy5nZXRUaW1lRm9ybWF0KCl9YCwgdGhpcy50aW1lem9uZSgpKTtcbiAgICBsZXQgZmxhZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgaWYgKCh0aGlzLmdpdmVuU3RhcnRUaW1lKCkgJiYgdGhpcy5naXZlbkVuZFRpbWUoKSkgfHwgKHRoaXMuZ2V0U3RhcnREYXRlKCkgIT09IHRoaXMuZ2V0RW5kRGF0ZSgpICYmIHRoaXMuZ2V0U3RhcnREYXRlKCkgIT09IHRoaXMuZ2V0Q3VyckRhdGUoKSkpIHtcbiAgICAgIGZsYWcgPSB0aW1lLm1hdGNoKFJFKSA/IHRydWUgOiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhZyA9IHRpbWUubWF0Y2goUkUpICYmIHRpbWVkYXlqcy5kaWZmKGRheWpzLnR6KGRheWpzKCksIHRoaXMudGltZXpvbmUoKSksIFwibVwiKSA+PSAwID8gdHJ1ZSA6IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gZmxhZztcbiAgfVxuXG4gIHJhbmdlVmFsaWRhdGlvbih2YWxpZGl0eTogYm9vbGVhbikge1xuICAgIGlmICh2YWxpZGl0eSAmJiB0aGlzLmdldFN0YXJ0RGF0ZSgpID09PSB0aGlzLmdldEVuZERhdGUoKSkge1xuICAgICAgY29uc3Qgc3RhcnRkYXlqcyA9IGRheWpzLnR6KHRoaXMuc3RhcnRUaW1lKCkhLnRpbWUsIHRoaXMuZ2V0VGltZUZvcm1hdCgpLCB0aGlzLnRpbWV6b25lKCkpO1xuICAgICAgY29uc3QgZW5kZGF5anMgPSBkYXlqcy50eih0aGlzLmVuZFRpbWUoKSEudGltZSwgdGhpcy5nZXRUaW1lRm9ybWF0KCksIHRoaXMudGltZXpvbmUoKSk7XG4gICAgICB0aGlzLnJhbmdlVmFsaWRpdHkuc2V0KGVuZGRheWpzLmRpZmYoc3RhcnRkYXlqcywgXCJtXCIpID49IDEpO1xuICAgIH1cbiAgfVxufVxuXG5cbiIsIjxkaXYgY2xhc3M9XCJyYW5nZXBpY2tlci1jb250YWluZXJcIiBbbmdTdHlsZV09XCJ7J2ZsZXhEaXJlY3Rpb24nOiBkaXJlY3Rpb24oKSwgJ2dhcCc6IGdhcCgpfVwiPlxuICA8bWlzLXRpbWVwaWNrZXJcbiAgICBbY2xvY2tGb3JtYXRdPVwiY2xvY2tGb3JtYXQoKVwiXG4gICAgW2ludGVydmFsXT1cImludGVydmFsKClcIlxuICAgIFtkYXRlQXNFcG9jaF09XCJzdGFydERhdGVFcG9jaCgpXCJcbiAgICBbZmlyc3RJbnRlcnZhbF09XCJmaXJzdEludGVydmFscygpLnN0YXJ0XCJcbiAgICAodGltZUVtaXR0ZXIpPVwic3RhcnRQaWNrZXJIYW5kbGVyKCRldmVudClcIlxuICAgIFt0aW1lem9uZV09XCJ0aW1lem9uZSgpXCJcbiAgICBbaGVpZ2h0XT1cImhlaWdodCgpXCJcbiAgICBbaW5wdXRXaWR0aF09XCJpbnB1dFdpZHRoKClcIlxuICAgIFtkcm9wZG93bldpZHRoXT1cImRyb3Bkb3duV2lkdGgoKVwiXG4gICAgW3Nob3dUb29sdGlwXT1cInNob3dUb29sdGlwKClcIlxuICAgIFtnaXZlblRpbWVdPVwiZ2l2ZW5TdGFydFRpbWUoKVwiXG4gICAgW2Rpc2FibGVdPVwiZGlzYWJsZVN0YXJ0VGltZSgpXCJcbiAgPjwvbWlzLXRpbWVwaWNrZXI+XG4gIDxwICpuZ0lmPVwiZGlyZWN0aW9uKCkgPT09ICdyb3cnXCI+LTwvcD5cbiAgPG1pcy10aW1lcGlja2VyXG4gICAgW2Nsb2NrRm9ybWF0XT1cImNsb2NrRm9ybWF0KClcIlxuICAgIFtpbnRlcnZhbF09XCJpbnRlcnZhbCgpXCJcbiAgICBbZGF0ZUFzRXBvY2hdPVwiZW5kRGF0ZUVwb2NoKClcIlxuICAgIFtmaXJzdEludGVydmFsXT1cImZpcnN0SW50ZXJ2YWxzKCkuZW5kXCJcbiAgICAodGltZUVtaXR0ZXIpPVwiZW5kUGlja2VySGFuZGxlcigkZXZlbnQpXCJcbiAgICBbcmFuZ2VWYWxpZGl0eV09XCJyYW5nZVZhbGlkaXR5KClcIlxuICAgIFt0aW1lem9uZV09XCJ0aW1lem9uZSgpXCJcbiAgICBbaGVpZ2h0XT1cImhlaWdodCgpXCJcbiAgICBbaW5wdXRXaWR0aF09XCJpbnB1dFdpZHRoKClcIlxuICAgIFtkcm9wZG93bldpZHRoXT1cImRyb3Bkb3duV2lkdGgoKVwiXG4gICAgW3Nob3dUb29sdGlwXT1cInNob3dUb29sdGlwKClcIlxuICAgIFtnaXZlblRpbWVdPVwiZ2l2ZW5FbmRUaW1lKClcIlxuICAgIFt0cmlnZ2VyQ2hhbmdlXT1cInRyaWdnZXJDaGFuZ2UoKVwiXG4gICAgW2Rpc2FibGVdPVwiZGlzYWJsZUVuZFRpbWUoKVwiXG4gID48L21pcy10aW1lcGlja2VyPlxuPC9kaXY+XG5cbiJdfQ==
328
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXJhbmdlcGlja2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL21pcy1jb21wb25lbnRzL3RpbWVyYW5nZXBpY2tlci90aW1lcmFuZ2VwaWNrZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vcHJvamVjdHMvbWlzLWNvbXBvbmVudHMvdGltZXJhbmdlcGlja2VyL3RpbWVyYW5nZXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBRXRHLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLFFBQVEsTUFBTSx1QkFBdUIsQ0FBQztBQUM3QyxPQUFPLEdBQUcsTUFBTSxrQkFBa0IsQ0FBQzs7Ozs7O0lDYWpDLHlCQUFpQztJQUFBLGlCQUFDO0lBQUEsaUJBQUk7O0FEWHhDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbEIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQU92QixNQUFNLE9BQU8sd0JBQXdCO0lBb0NuQyw2RUFBNkU7SUFDckUsYUFBYTtRQUNuQixPQUFPLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ3pELENBQUM7SUFFTyxZQUFZO1FBQ2xCLE9BQU8sS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQy9FLENBQUM7SUFFTyxVQUFVO1FBQ2hCLE9BQU8sS0FBSyxDQUFDLEVB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NENBQ1csNEJBQ2hCOzs7aUZEcEJkLHdCQUF3QjtjQUxwQyxTQUFTOzJCQUNFLHFCQUFxQjs7a0ZBSXBCLHdCQUF3QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgaW5wdXQsIG91dHB1dCwgc2lnbmFsLCBjb21wdXRlZCwgZWZmZWN0LCB1bnRyYWNrZWQsIE9uSW5pdCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBJVGltZVJhbmdlLCBJVGltZSwgVERpcmVjdGlvbiB9IGZyb20gXCIuL3RpbWVyYW5nZS5uYW1lc3BhY2VcIjtcbmltcG9ydCBkYXlqcyBmcm9tICdkYXlqcyc7XG5pbXBvcnQgdGltZXpvbmUgZnJvbSAnZGF5anMvcGx1Z2luL3RpbWV6b25lJztcbmltcG9ydCB1dGMgZnJvbSAnZGF5anMvcGx1Z2luL3V0Yyc7XG5cbmRheWpzLmV4dGVuZCh1dGMpO1xuZGF5anMuZXh0ZW5kKHRpbWV6b25lKTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcIm1pcy10aW1lcmFuZ2VwaWNrZXJcIixcbiAgdGVtcGxhdGVVcmw6IFwiLi90aW1lcmFuZ2VwaWNrZXIuY29tcG9uZW50Lmh0bWxcIiwgLy8gQ29ycmVjdGVkIGZpbGUgbmFtZVxuICBzdHlsZVVybHM6IFtcIi4vdGltZXJhbmdlcGlja2VyLmNvbXBvbmVudC5zY3NzXCJdXG59KVxuZXhwb3J0IGNsYXNzIFRpbWVSYW5nZVBpY2tlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8vIC0tLSBJbnB1dCBTaWduYWxzIChyZWFkLW9ubHkpIC0tLVxuICBpbnB1dFdpZHRoID0gaW5wdXQ8c3RyaW5nPihcIjEwMHB4XCIpO1xuICBkcm9wZG93bldpZHRoID0gaW5wdXQ8c3RyaW5nIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBoZWlnaHQgPSBpbnB1dDxzdHJpbmc+KFwiNDZweFwiKTtcbiAgdGltZXpvbmUgPSBpbnB1dDxzdHJpbmc+KFwiQXNpYS9Lb2xrYXRhXCIpO1xuICBzdGFydERhdGVFcG9jaCA9IGlucHV0PG51bWJlcj4oZGF5anMudHooZGF5anMoKSwgdGhpcy50aW1lem9uZSgpKS52YWx1ZU9mKCkpO1xuICBlbmREYXRlRXBvY2ggPSBpbnB1dDxudW1iZXI+KGRheWpzLnR6KGRheWpzKCksIHRoaXMudGltZXpvbmUoKSkudmFsdWVPZigpKTtcbiAgZ2l2ZW5TdGFydFRpbWUgPSBpbnB1dDxudW1iZXIgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIGdpdmVuRW5kVGltZSA9IGlucHV0PG51bWJlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgY2xvY2tGb3JtYXQgPSBpbnB1dDxudW1iZXI+KDEyKTtcbiAgaW50ZXJ2YWwgPSBpbnB1dDxudW1iZXI+KDE1KTtcbiAgc2hvd1Rvb2x0aXAgPSBpbnB1dDxib29sZWFuPih0cnVlKTtcbiAgZGlyZWN0aW9uID0gaW5wdXQ8VERpcmVjdGlvbj4oJ3JvdycpO1xuICBnYXAgPSBpbnB1dDxzdHJpbmc+KCcxcmVtJyk7XG4gIGRpc2FibGVTdGFydFRpbWUgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG4gIGRpc2FibGVFbmRUaW1lID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuICBmb250U2l6ZSA9IGlucHV0PHN0cmluZz4oXCIxNHB4XCIpO1xuICBkaXNhYmxlVXNlcklucHV0ID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gIC8vIC0tLSBPdXRwdXQgU2lnbmFsIC0tLVxuICB0aW1lUmFuZ2VFbWl0dGVyID0gb3V0cHV0PElUaW1lUmFuZ2U+KCk7XG5cbiAgLy8gLS0tIEludGVybmFsIFdyaXRhYmxlIFNpZ25hbHMgLS0tXG4gIHN0YXJ0VGltZSA9IHNpZ25hbDxJVGltZSB8IG51bGw+KG51bGwpO1xuICBlbmRUaW1lID0gc2lnbmFsPElUaW1lIHwgbnVsbD4obnVsbCk7XG4gIHJhbmdlVmFsaWRpdHkgPSBzaWduYWw8Ym9vbGVhbj4odHJ1ZSk7XG4gIHRyaWdnZXJDaGFuZ2UgPSBzaWduYWw8Ym9vbGVhbj4odHJ1ZSk7XG4gIHByaXZhdGUgX2ZpcnN0SW50ZXJ2YWxzID0gc2lnbmFsPHsgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIgfT4oeyBzdGFydDogMCwgZW5kOiAwIH0pO1xuICBwcml2YXRlIF9pc0luaXRpYWxpemluZyA9IGZhbHNlO1xuICBwcml2YXRlIF9wcmV2aW91c1N0YXJ0RGF0ZUVwb2NoOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfcHJldmlvdXNFbmREYXRlRXBvY2g6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8vIC0tLSBDb21wdXRlZCBTaWduYWxzIChEZXJpdmVkIFN0YXRlKSAtLS1cbiAgZmlyc3RJbnRlcnZhbHMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9maXJzdEludGVydmFscygpKTsgLy8gQSBwdWJsaWMgY29tcHV0ZWQgc2lnbmFsIHRvIGFjY2VzcyB0aGUgd3JpdGFibGUgb25lXG4gIFxuICAvLyBIZWxwZXIgbWV0aG9kcyBpbnN0ZWFkIG9mIGNvbXB1dGVkIHNpZ25hbHMgdG8gYXZvaWQgc2lnbmFsIHdyaXRlIGNvbmZsaWN0c1xuICBwcml2YXRlIGdldFRpbWVGb3JtYXQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jbG9ja0Zvcm1hdCgpID09PSAxMiA/IFwiaGg6bW0gYVwiIDogXCJISDptbVwiO1xuICB9XG4gIFxuICBwcml2YXRlIGdldFN0YXJ0RGF0ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBkYXlqcy50eih0aGlzLnN0YXJ0RGF0ZUVwb2NoKCksIHRoaXMudGltZXpvbmUoKSkuZm9ybWF0KFwiREQtTU0tWVlZWVwiKTtcbiAgfVxuICBcbiAgcHJpdmF0ZSBnZXRFbmREYXRlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGRheWpzLnR6KHRoaXMuZW5kRGF0ZUVwb2NoKCksIHRoaXMudGltZXpvbmUoKSkuZm9ybWF0KFwiREQtTU0tWVlZWVwiKTtcbiAgfVxuICBcbiAgcHJpdmF0ZSBnZXRDdXJyRGF0ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBkYXlqcy50eihkYXlqcygpLCB0aGlzLnRpbWV6b25lKCkpLmZvcm1hdChcIkRELU1NLVlZWVlcIik7XG4gIH1cbiAgXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIEVmZmVjdCB0byB3YXRjaCBmb3IgY2hhbmdlcyBpbiBzdGFydERhdGVFcG9jaCBhbmQgZW5kRGF0ZUVwb2NoXG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIC8vIE9OTFkgdHJhY2sgdGhlc2UgdHdvIHNpZ25hbHMgLSB0aGlzIGlzIHRoZSBvbmx5IGxpbmUgdGhhdCBjcmVhdGVzIGRlcGVuZGVuY2llc1xuICAgICAgY29uc3QgY3VycmVudFN0YXJ0RGF0ZSA9IHRoaXMuc3RhcnREYXRlRXBvY2goKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRFbmREYXRlID0gdGhpcy5lbmREYXRlRXBvY2goKTtcbiAgICAgIFxuICAgICAgLy8gVXNlIHVudHJhY2tlZCgpIGZvciBldmVyeXRoaW5nIGVsc2UgdG8gcHJldmVudCBpbmZpbml0ZSBsb29wc1xuICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgLy8gU2tpcCBpZiBjb21wb25lbnQgaXMgaW5pdGlhbGl6aW5nXG4gICAgICAgIGlmICh0aGlzLl9pc0luaXRpYWxpemluZykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gU2tpcCBpZiBjb21wb25lbnQgaGFzbid0IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gICAgICAgIGlmICghdGhpcy5zdGFydFRpbWUoKSB8fCAhdGhpcy5lbmRUaW1lKCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIC8vIFNraXAgaWYgZGF0ZXMgaGF2ZW4ndCBhY3R1YWxseSBjaGFuZ2VkIChwcmV2ZW50cyBpbml0aWFsIGRvdWJsZS1ydW4pXG4gICAgICAgIGlmICh0aGlzLl9wcmV2aW91c1N0YXJ0RGF0ZUVwb2NoID09PSBjdXJyZW50U3RhcnREYXRlICYmIFxuICAgICAgICAgICAgdGhpcy5fcHJldmlvdXNFbmREYXRlRXBvY2ggPT09IGN1cnJlbnRFbmREYXRlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvLyBVcGRhdGUgcHJldmlvdXMgdmFsdWVzXG4gICAgICAgIHRoaXMuX3ByZXZpb3VzU3RhcnREYXRlRXBvY2ggPSBjdXJyZW50U3RhcnREYXRlO1xuICAgICAgICB0aGlzLl9wcmV2aW91c0VuZERhdGVFcG9jaCA9IGN1cnJlbnRFbmREYXRlO1xuICAgICAgICBcbiAgICAgICAgLy8gUmVpbml0aWFsaXplIGFuZCBlbWl0IHdoZW4gZGF0ZSBpbnB1dHMgY2hhbmdlXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUNvbXBvbmVudCgpO1xuICAgICAgICBcbiAgICAgICAgLy8gRW1pdCB0aGUgdXBkYXRlZCB0aW1lIHJhbmdlXG4gICAgICAgIGNvbnN0IHZhbGlkaXR5ID1cbiAgICAgICAgICB0aGlzLmNoZWNrVGltZVZhbGlkaXR5KHRoaXMuc3RhcnRUaW1lKCkhLnRpbWUudHJpbSgpLCB0aGlzLnN0YXJ0RGF0ZUVwb2NoKCkpICYmXG4gICAgICAgICAgdGhpcy5jaGVja1RpbWVWYWxpZGl0eSh0aGlzLmVuZFRpbWUoKSEudGltZS50cmltKCksIHRoaXMuZW5kRGF0ZUVwb2NoKCkpO1xuXG4gICAgICAgIHRoaXMucmFuZ2VWYWxpZGF0aW9uKHZhbGlkaXR5KTtcbiAgICAgICAgdGhpcy5lbWl0VGltZVJhbmdlKHtcbiAgICAgICAgICB2YWxpZDogdmFsaWRpdHkgJiYgdGhpcy5yYW5nZVZhbGlkaXR5KCksXG4gICAgICAgICAgc3RhcnRUaW1lOiB0aGlzLnN0YXJ0VGltZSgpIS50aW1lLFxuICAgICAgICAgIGVuZFRpbWU6IHRoaXMuZW5kVGltZSgpIS50aW1lLFxuICAgICAgICAgIHN0YXJ0RXBvY2g6IGRheWpzLnR6KGAke3RoaXMuZ2V0U3RhcnREYXRlKCl9ICR7dGhpcy5zdGFydFRpbWUoKSEudGltZX1gLCBgREQtTU0tWVlZWSAke3RoaXMuZ2V0VGltZUZvcm1hdCgpfWAsIHRoaXMudGltZXpvbmUoKSkudmFsdWVPZigpLFxuICAgICAgICAgIGVuZEVwb2NoOiBkYXlqcy50eihgJHt0aGlzLmdldEVuZERhdGUoKX0gJHt0aGlzLmVuZFRpbWUoKSEudGltZX1gLCBgREQtTU0tWVlZWSAke3RoaXMuZ2V0VGltZUZvcm1hdCgpfWAsIHRoaXMudGltZXpvbmUoKSkudmFsdWVPZigpXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSwgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9KTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIEluaXRpYWxpemUgdGhlIGNvbXBvbmVudCBvbmNlXG4gICAgdGhpcy5pbml0aWFsaXplQ29tcG9uZW50KCk7XG4gICAgXG4gICAgLy8gU3RvcmUgaW5pdGlhbCB2YWx1ZXMgdG8gcHJldmVudCBlZmZlY3QgZnJvbSBydW5uaW5nIG9uIGZpcnN0IGxvYWRcbiAgICB0aGlzLl9wcmV2aW91c1N0YXJ0RGF0ZUVwb2NoID0gdGhpcy5zdGFydERhdGVFcG9jaCgpO1xuICAgIHRoaXMuX3ByZXZpb3VzRW5kRGF0ZUVwb2NoID0gdGhpcy5lbmREYXRlRXBvY2goKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUNvbXBvbmVudCgpOiB2b2lkIHtcbiAgICB0aGlzLl9pc0luaXRpYWxpemluZyA9IHRydWU7XG4gICAgXG4gICAgdGhpcy5zZXRGaXJzdEludGVydmFscygpO1xuICAgIGNvbnN0IGZpcnN0SW50ZXJ2YWxzID0gdGhpcy5fZmlyc3RJbnRlcnZhbHMoKTtcblxuICAgIHRoaXMuc3RhcnRUaW1lLnNldCh7XG4gICAgICB2YWxpZDogdHJ1ZSxcbiAgICAgIHRpbWU6IGRheWpzLnR6KGZpcnN0SW50ZXJ2YWxzLnN0YXJ0LCB0aGlzLnRpbWV6b25lKCkpLmZvcm1hdCh0aGlzLmdldFRpbWVGb3JtYXQoKSksXG4gICAgICBlcG9jaDogZGF5anMudHooZmlyc3RJbnRlcnZhbHMuc3RhcnQsIHRoaXMudGltZXpvbmUoKSkudmFsdWVPZigpXG4gICAgfSk7XG4gICAgXG4gICAgLy8gRW5zdXJlIGVuZCB0aW1lIGlzIGFsd2F5cyBhZnRlciBzdGFydCB0aW1lXG4gICAgbGV0IGVuZFRpbWVFcG9jaCA9IGZpcnN0SW50ZXJ2YWxzLmVuZDtcbiAgICBjb25zdCBzdGFydFRpbWVFcG9jaCA9IGZpcnN0SW50ZXJ2YWxzLnN0YXJ0O1xuICAgIFxuICAgIC8vIElmIGVuZCB0aW1lIGlzIHNhbWUgb3IgYmVmb3JlIHN0YXJ0IHRpbWUsIGFkZCBvbmUgaW50ZXJ2YWwgdG8gZW5kIHRpbWVcbiAgICBpZiAoZW5kVGltZUVwb2NoIDw9IHN0YXJ0VGltZUVwb2NoKSB7XG4gICAgICBlbmRUaW1lRXBvY2ggPSBkYXlqcy50eihzdGFydFRpbWVFcG9jaCwgdGhpcy50aW1lem9uZSgpKS5hZGQodGhpcy5pbnRlcnZhbCgpLCAnbScpLnZhbHVlT2YoKTtcbiAgICAgIFxuICAgICAgLy8gVXBkYXRlIHRoZSBmaXJzdEludGVydmFscyB0byByZWZsZWN0IHRoZSBhZGp1c3RlZCBlbmQgdGltZVxuICAgICAgdGhpcy5fZmlyc3RJbnRlcnZhbHMuc2V0KHtcbiAgICAgICAgc3RhcnQ6IGZpcnN0SW50ZXJ2YWxzLnN0YXJ0LFxuICAgICAgICBlbmQ6IGVuZFRpbWVFcG9jaFxuICAgICAgfSk7XG4gICAgfVxuICAgIFxuICAgIHRoaXMuZW5kVGltZS5zZXQoe1xuICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICB0aW1lOiBkYXlqcy50eihlbmRUaW1lRXBvY2gsIHRoaXMudGltZXpvbmUoKSkuZm9ybWF0KHRoaXMuZ2V0VGltZUZvcm1hdCgpKSxcbiAgICAgIGVwb2NoOiBlbmRUaW1lRXBvY2hcbiAgICB9KTtcbiAgICBcbiAgICB0aGlzLl9pc0luaXRpYWxpemluZyA9IGZhbHNlO1xuICB9XG5cbiAgLy8gY2FsY3VsYXRlIHRoZSBmaXJzdCBpbnRlcnZhbCBvZiB0aGUgcGlja2VyXG4gIHByaXZhdGUgc2V0Rmlyc3RJbnRlcnZhbHMoKTogdm9pZCB7XG4gICAgbGV0IGZpcnN0SW50ZXJ2YWxGb3JTdGFydFBpY2tlcjogbnVtYmVyO1xuICAgIGxldCBmaXJzdEludGVydmFsRm9yRW5kUGlja2VyOiBudW1iZXI7XG5cbiAgICBjb25zdCBtaW51dGVzID0gZGF5anMudHooZGF5anMoKSwgdGhpcy50aW1lem9uZSgpKS5taW51dGUoKTtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmludGVydmFsKCkgLSAobWludXRlcyAlIHRoaXMuaW50ZXJ2YWwoKSk7XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBkYXlqcy50eihkYXlqcygpLCB0aGlzLnRpbWV6b25lKCkpLnZhbHVlT2YoKTtcblxuICAgIGlmKCB0aGlzLmdldFN0YXJ0RGF0ZSgpID09PSB0aGlzLmdldEN1cnJEYXRlKCkgKXtcbiAgICAgIGlmKHRoaXMuZ2V0U3RhcnREYXRlKCkgPT09IHRoaXMuZ2V0RW5kRGF0ZSgpKXtcbiAgICAgICAgaWYoY3VycmVudFRpbWUgPj0gZGF5anMudHoodGhpcy5zdGFydERhdGVFcG9jaCgpLCB0aGlzLnRpbWV6b25lKCkpLmVuZE9mKFwiZFwiKS5zdWJ0cmFjdCh0aGlzLmludGVydmFsKCksXCJtXCIpLnZhbHVlT2YoKSl7XG4gICAgICAgICAgZmlyc3RJbnRlcnZhbEZvclN0YXJ0UGlja2VyID0gY3VycmVudFRpbWU7XG4gICAgICAgICAgZmlyc3RJbnRlcnZhbEZvckVuZFBpY2tlciA9IGRheWpzLnR6KHRoaXMuZW5kRGF0ZUVwb2NoKCksIHRoaXMudGltZXpvbmUoKSkuZW5kT2YoXCJkXCIpLnZhbHVlT2YoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaXJzdEludGVydmFsRm9yU3RhcnRQaWNrZXIgPSBkYXlqcy50eihkYXlqcygpLCB0aGlzLnRpbWV6b25lKCkpLmFkZChvZmZzZXQsIFwibVwiKS52YWx1ZU9mKCk7XG4gICAgICAgICAgLy8gRm9yIHNhbWUgZGF0ZSwgZW5kIHBpY2tlciBzaG91bGQgc3RhcnQgZnJvbSBiZWdpbm5pbmcgb2YgZGF5IHRvIGF2b2lkIHZhbGlkYXRpb24gaXNzdWVzXG4gICAgICAgICAgZmlyc3RJbnRlcnZhbEZvckVuZFBpY2tlciA9IGRheWpzLnR6KHRoaXMuZW5kRGF0ZUVwb2NoKCksIHRoaXMudGltZXpvbmUoKSkuc3RhcnRPZihcImRcIikudmFsdWVPZigpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZihjdXJyZW50VGltZSA+PSBkYXlqcy50eih0aGlzLnN0YXJ0RGF0ZUVwb2NoKCksIHRoaXMudGltZXpvbmUoKSkuZW5kT2YoXCJkXCIpLnN1YnRyYWN0KHRoaXMuaW50ZXJ2YWwoKSxcIm1cIikudmFsdWVPZigpKXtcbiAgICAgICAgICBmaXJzdEludGVydmFsRm9yU3RhcnRQaWNrZXIgPSBjdXJyZW50VGltZTtcbiAgICAgICAgICBmaXJzdEludGVydmFsRm9yRW5kUGlja2VyID0gZGF5anMudHoodGhpcy5lbmREYXRlRXBvY2goKSwgdGhpcy50aW1lem9uZSgpKS5lbmRPZihcImRcIikudmFsdWVPZigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZpcnN0SW50ZXJ2YWxGb3JTdGFydFBpY2tlciA9IGRheWpzLnR6KGRheWpzKCksIHRoaXMudGltZXpvbmUoKSkuYWRkKG9mZnNldCwgXCJtXCIpLnZhbHVlT2YoKTtcbiAgICAgICAgICBmaXJzdEludGVydmFsRm9yRW5kUGlja2VyID0gZGF5anMudHoodGhpcy5lbmREYXRlRXBvY2goKSwgdGhpcy50aW1lem9uZSgpKS5zdGFydE9mKFwiZFwiKS52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmKHRoaXMuZ2V0U3RhcnREYXRlKCkgPT09IHRoaXMuZ2V0RW5kRGF0ZSgpKXtcbiAgICAgICAgZmlyc3RJbnRlcnZhbEZvclN0YXJ0UGlja2VyID0gZGF5anMudHoodGhpcy5zdGFydERhdGVFcG9jaCgpLCB0aGlzLnRpbWV6b25lKCkpLnN0YXJ0T2YoXCJkXCIpLnZhbHVlT2YoKTtcbiAgICAgICAgZmlyc3RJbnRlcnZhbEZvckVuZFBpY2tlciA9IGRheWpzLnR6KHRoaXMuZW5kRGF0ZUVwb2NoKCksIHRoaXMudGltZXpvbmUoKSkuYWRkKHRoaXMuaW50ZXJ2YWwoKSwgXCJtXCIpLnZhbHVlT2YoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZpcnN0SW50ZXJ2YWxGb3JTdGFydFBpY2tlciA9IGRheWpzLnR6KHRoaXMuc3RhcnREYXRlRXBvY2goKSwgdGhpcy50aW1lem9uZSgpKS5zdGFydE9mKFwiZFwiKS52YWx1ZU9mKCk7XG4gICAgICAgIGZpcnN0SW50ZXJ2YWxGb3JFbmRQaWNrZXIgPSBkYXlqcy50eih0aGlzLmVuZERhdGVFcG9jaCgpLCB0aGlzLnRpbWV6b25lKCkpLnN0YXJ0T2YoXCJkXCIpLnZhbHVlT2YoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZih0aGlzLmdpdmVuU3RhcnRUaW1lKCkpIHtcbiAgICAgIGZpcnN0SW50ZXJ2YWxGb3JTdGFydFBpY2tlciA9IHRoaXMuZ2l2ZW5TdGFydFRpbWUoKSE7XG4gICAgfVxuICAgIFxuICAgIGlmKHRoaXMuZ2l2ZW5FbmRUaW1lKCkpIHtcbiAgICAgIGZpcnN0SW50ZXJ2YWxGb3JFbmRQaWNrZXIgPSB0aGlzLmdpdmVuRW5kVGltZSgpITtcbiAgICB9XG4gICAgICBcbiAgICB0aGlzLl9maXJzdEludGVydmFscy5zZXQoeyBzdGFydDogZmlyc3RJbnRlcnZhbEZvclN0YXJ0UGlja2VyLCBlbmQ6IGZpcnN0SW50ZXJ2YWxGb3JFbmRQaWNrZXIgfSk7XG4gIH1cblxuICAvLyAtLS0gUHVibGljIE1ldGhvZHMgLS0tXG4gIGVtaXRUaW1lUmFuZ2UoZGF0YTogSVRpbWVSYW5nZSk6IHZvaWQge1xuICAgIHRoaXMudGltZVJhbmdlRW1pdHRlci5lbWl0KGRhdGEpO1xuICB9XG5cbiAgc3RhcnRQaWNrZXJIYW5kbGVyKHRpbWU6IElUaW1lKTogdm9pZCB7XG4gICAgdGhpcy5zdGFydFRpbWUuc2V0KHRpbWUpO1xuICAgIHRoaXMucmFuZ2VWYWxpZGl0eS5zZXQodHJ1ZSk7XG4gICAgXG4gICAgLy8gRG9uJ3QgZW1pdCBkdXJpbmcgaW5pdGlhbGl6YXRpb25cbiAgICBpZiAodGhpcy5faXNJbml0aWFsaXppbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDYWxjdWxhdGUgc3RhcnQgdGltZSBlcG9jaCBmb3IgY29tcGFyaXNvblxuICAgIGNvbnN0IHN0YXJ0VGltZUVwb2NoID0gZGF5anMudHooYCR7dGhpcy5nZXRTdGFydERhdGUoKX0gJHt0aGlzLnN0YXJ0VGltZSgpIS50aW1lfWAsIGBERC1NTS1ZWVlZICR7dGhpcy5nZXRUaW1lRm9ybWF0KCl9YCwgdGhpcy50aW1lem9uZSgpKS52YWx1ZU9mKCk7XG4gICAgY29uc3QgZW5kVGltZUVwb2NoID0gZGF5anMudHooYCR7dGhpcy5nZXRFbmREYXRlKCl9ICR7dGhpcy5lbmRUaW1lKCkhLnRpbWV9YCwgYERELU1NLVlZWVkgJHt0aGlzLmdldFRpbWVGb3JtYXQoKX1gLCB0aGlzLnRpbWV6b25lKCkpLnZhbHVlT2YoKTtcblxuICAgIC8vIEF1dG8tYWRqdXN0IGVuZCB0aW1lIGlmIHN0YXJ0IHRpbWUgPiBlbmQgdGltZSAoZm9yIGJvdGggc2FtZSBhbmQgZGlmZmVyZW50IGRhdGVzKVxuICAgIC8vIFRoaXMgZW5zdXJlcyBlbmQgdGltZSBpcyBhbHdheXMgYWZ0ZXIgc3RhcnQgdGltZVxuICAgIGlmIChzdGFydFRpbWVFcG9jaCA+IGVuZFRpbWVFcG9jaCkge1xuICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBlbmQgdGltZSBhcyBzdGFydCB0aW1lICsgaW50ZXJ2YWxcbiAgICAgIGxldCBuZXdFbmRUaW1lRXBvY2ggPSBkYXlqcy50eihzdGFydFRpbWVFcG9jaCwgdGhpcy50aW1lem9uZSgpKS5hZGQodGhpcy5pbnRlcnZhbCgpLCBcIm1cIikudmFsdWVPZigpO1xuICAgICAgXG4gICAgICAvLyBJZiBzYW1lIGRhdGUsIGNoZWNrIGlmIHRoZSBuZXcgZW5kIHRpbWUgd291bGQgZ28gYmV5b25kIGVuZCBvZiBkYXlcbiAgICAgIGlmICh0aGlzLmdldFN0YXJ0RGF0ZSgpID09PSB0aGlzLmdldEVuZERhdGUoKSkge1xuICAgICAgICBjb25zdCBlbmRPZkRheSA9IGRheWpzLnR6KHRoaXMuc3RhcnREYXRlRXBvY2goKSwgdGhpcy50aW1lem9uZSgpKS5lbmRPZihcImRcIikudmFsdWVPZigpO1xuICAgICAgICBpZiAobmV3RW5kVGltZUVwb2NoID4gZW5kT2ZEYXkpIHtcbiAgICAgICAgICAvLyBTZXQgZW5kIHRpbWUgdG8gMTE6NTkgUE0gKGVuZCBvZiBkYXkpIHdoZW4gc3RhcnQgdGltZSBpcyBsYXN0IGludGVydmFsXG4gICAgICAgICAgbmV3RW5kVGltZUVwb2NoID0gZW5kT2ZEYXk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gVXBkYXRlIHRoZSBlbmQgdGltZSBzaWduYWxcbiAgICAgIHRoaXMuZW5kVGltZS5zZXQoe1xuICAgICAgICB2YWxpZDogdHJ1ZSxcbiAgICAgICAgdGltZTogZGF5anMudHoobmV3RW5kVGltZUVwb2NoLCB0aGlzLnRpbWV6b25lKCkpLmZvcm1hdCh0aGlzLmdldFRpbWVGb3JtYXQoKSksXG4gICAgICAgIGVwb2NoOiBuZXdFbmRUaW1lRXBvY2hcbiAgICAgIH0pO1xuICAgICAgXG4gICAgICAvLyBVcGRhdGUgdGhlIGZpcnN0SW50ZXJ2YWxzIHRvIHJlZmxlY3QgdGhlIG5ldyBlbmQgdGltZVxuICAgICAgdGhpcy5fZmlyc3RJbnRlcnZhbHMuc2V0KHsgXG4gICAgICAgIHN0YXJ0OiB0aGlzLl9maXJzdEludGVydmFscygpLnN0YXJ0LCBcbiAgICAgICAgZW5kOiBuZXdFbmRUaW1lRXBvY2ggXG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgLy8gVHJpZ2dlciBjaGFuZ2UgdG8gZm9yY2UgZW5kIHRpbWVwaWNrZXIgdG8gdXBkYXRlIGl0cyBkaXNwbGF5IHdpdGggdGhlIG5ldyBlbmQgdGltZVxuICAgICAgLy8gVGhpcyBpcyBuZWNlc3Nhcnkgd2hlbiB3ZSByZXNldCB0aGUgZW5kIHRpbWUgZHVlIHRvIGNvbmZsaWN0XG4gICAgICB0aGlzLnRyaWdnZXJDaGFuZ2UudXBkYXRlKHZhbHVlID0+ICF2YWx1ZSk7XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIGVuZCB0aW1lcGlja2VyJ3MgZmlyc3RJbnRlcnZhbCB3aGVuIGJvdGggdGltZXBpY2tlcnMgYXJlIG9uIHRoZSBzYW1lIGRheVxuICAgIC8vIEFMV0FZUyB1cGRhdGUgdG8gZW5zdXJlIGRyb3Bkb3duIHN0YXJ0cyBmcm9tIG5leHQgaW50ZXJ2YWwgYWZ0ZXIgc3RhcnQgdGltZVxuICAgIC8vIFRoaXMgZml4ZXMgdGhlIGJ1ZyB3aGVyZSBzZWxlY3RpbmcgYW4gZWFybGllciBzdGFydCB0aW1lIGRvZXNuJ3QgdXBkYXRlIGVuZCBwaWNrZXIgaW50ZXJ2YWxzXG4gICAgLy8gTk9URTogV2Ugb25seSB1cGRhdGUgZmlyc3RJbnRlcnZhbCAoZHJvcGRvd24gb3B0aW9ucyksIE5PVCB0aGUgc2VsZWN0ZWQgZW5kIHRpbWUgdmFsdWVcbiAgICAvLyBUaGUgdGltZXBpY2tlciBjb21wb25lbnQgbm93IGhhbmRsZXMgZmlyc3RJbnRlcnZhbCBjaGFuZ2VzIHNlcGFyYXRlbHkgYW5kIHdvbid0IHJlc2V0IGNob3NlblRpbWVcbiAgICBpZiAodGhpcy5nZXRTdGFydERhdGUoKSA9PT0gdGhpcy5nZXRFbmREYXRlKCkpIHtcbiAgICAgIC8vIE9ubHkgdXBkYXRlIGZpcnN0SW50ZXJ2YWwgaWYgdGhlcmUncyBubyBjb25mbGljdCAoc3RhcnQgPCBlbmQpXG4gICAgICAvLyBJZiB0aGVyZSdzIGEgY29uZmxpY3QsIGl0J3MgYWxyZWFkeSBoYW5kbGVkIGFib3ZlIGFuZCBmaXJzdEludGVydmFsIHdhcyB1cGRhdGVkIHRoZXJlXG4gICAgICBpZiAoc3RhcnRUaW1lRXBvY2ggPCBlbmRUaW1lRXBvY2gpIHtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBuZXh0IGludGVydmFsIGFmdGVyIHRoZSBzZWxlY3RlZCBzdGFydCB0aW1lXG4gICAgICAgIGxldCBuZXh0SW50ZXJ2YWxBZnRlclN0YXJ0ID0gZGF5anMudHooc3RhcnRUaW1lRXBvY2gsIHRoaXMudGltZXpvbmUoKSkuYWRkKHRoaXMuaW50ZXJ2YWwoKSwgXCJtXCIpLnZhbHVlT2YoKTtcbiAgICAgICAgXG4gICAgICAgIC8vIElmIG5leHQgaW50ZXJ2YWwgd291bGQgZ28gYmV5b25kIGVuZCBvZiBkYXksIHVzZSBlbmQgb2YgZGF5IGluc3RlYWRcbiAgICAgICAgY29uc3QgZW5kT2ZEYXkgPSBkYXlqcy50eih0aGlzLnN0YXJ0RGF0ZUVwb2NoKCksIHRoaXMudGltZXpvbmUoKSkuZW5kT2YoXCJkXCIpLnZhbHVlT2YoKTtcbiAgICAgICAgaWYgKG5leHRJbnRlcnZhbEFmdGVyU3RhcnQgPiBlbmRPZkRheSkge1xuICAgICAgICAgIG5leHRJbnRlcnZhbEFmdGVyU3RhcnQgPSBlbmRPZkRheTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gVXBkYXRlIHRoZSBmaXJzdEludGVydmFscyB0byBtYWtlIGVuZCB0aW1lcGlja2VyIGRyb3Bkb3duIHN0YXJ0IGZyb20gbmV4dCBpbnRlcnZhbCBhZnRlciBzdGFydCB0aW1lXG4gICAgICAgIC8vIFRoaXMgZW5zdXJlcyB1c2VycyBjYW4gYWx3YXlzIHNlbGVjdCB0aW1lcyBiZXR3ZWVuIHRoZSBuZXcgc3RhcnQgdGltZSBhbmQgdGhlIGN1cnJlbnQgZW5kIHRpbWVcbiAgICAgICAgLy8gVGhlIHRpbWVwaWNrZXIgY29tcG9uZW50IHdpbGwgdXBkYXRlIHRoZSBkcm9wZG93biBidXQgcHJlc2VydmUgdGhlIHNlbGVjdGVkIGVuZCB0aW1lIHZhbHVlXG4gICAgICAgIHRoaXMuX2ZpcnN0SW50ZXJ2YWxzLnNldCh7IFxuICAgICAgICAgIHN0YXJ0OiB0aGlzLl9maXJzdEludGVydmFscygpLnN0YXJ0LCBcbiAgICAgICAgICBlbmQ6IG5leHRJbnRlcnZhbEFmdGVyU3RhcnQgXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBOT1RFOiBXZSBkb24ndCBjYWxsIHRyaWdnZXJDaGFuZ2UgaGVyZSBiZWNhdXNlIHdlIG9ubHkgd2FudCB0byB1cGRhdGUgdGhlIGRyb3Bkb3duLFxuICAgICAgICAvLyBub3QgcmVzZXQgdGhlIHNlbGVjdGVkIGVuZCB0aW1lLiBUaGUgdGltZXBpY2tlcidzIHNlcGFyYXRlIGVmZmVjdCBmb3IgZmlyc3RJbnRlcnZhbFxuICAgICAgICAvLyB3aWxsIGhhbmRsZSB1cGRhdGluZyB0aGUgZHJvcGRvd24gd2l0aG91dCByZXNldHRpbmcgY2hvc2VuVGltZS5cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBbHdheXMgdmFsaWRhdGUgYW5kIGVtaXQgdGhlIHRpbWUgcmFuZ2VcbiAgICBjb25zdCB2YWxpZGl0eSA9XG4gICAgICB0aGlzLmNoZWNrVGltZVZhbGlkaXR5KHRoaXMuc3RhcnRUaW1lKCkhLnRpbWUudHJpbSgpLCB0aGlzLnN0YXJ0RGF0ZUVwb2NoKCkpICYmXG4gICAgICB0aGlzLmNoZWNrVGltZVZhbGlkaXR5KHRoaXMuZW5kVGltZSgpIS50aW1lLnRyaW0oKSwgdGhpcy5lbmREYXRlRXBvY2goKSk7XG5cbiAgICB0aGlzLnJhbmdlVmFsaWRhdGlvbih2YWxpZGl0eSk7XG4gICAgdGhpcy5lbWl0VGltZVJhbmdlKHtcbiAgICAgIHZhbGlkOiB2YWxpZGl0eSAmJiB0aGlzLnJhbmdlVmFsaWRpdHkoKSxcbiAgICAgIHN0YXJ0VGltZTogdGhpcy5zdGFydFRpbWUoKSEudGltZSxcbiAgICAgIGVuZFRpbWU6IHRoaXMuZW5kVGltZSgpIS50aW1lLFxuICAgICAgc3RhcnRFcG9jaDogZGF5anMudHooYCR7dGhpcy5nZXRTdGFydERhdGUoKX0gJHt0aGlzLnN0YXJ0VGltZSgpIS50aW1lfWAsIGBERC1NTS1ZWVlZICR7dGhpcy5nZXRUaW1lRm9ybWF0KCl9YCwgdGhpcy50aW1lem9uZSgpKS52YWx1ZU9mKCksXG4gICAgICBlbmRFcG9jaDogZGF5anMudHooYCR7dGhpcy5nZXRFbmREYXRlKCl9ICR7dGhpcy5lbmRUaW1lKCkhLnRpbWV9YCwgYERELU1NLVlZWVkgJHt0aGlzLmdldFRpbWVGb3JtYXQoKX1gLCB0aGlzLnRpbWV6b25lKCkpLnZhbHVlT2YoKVxuICAgIH0pO1xuICB9XG5cbiAgZW5kUGlja2VySGFuZGxlcih0aW1lOiBJVGltZSk6IHZvaWQge1xuICAgIHRoaXMuZW5kVGltZS5zZXQodGltZSk7XG4gICAgXG4gICAgLy8gRG9uJ3QgZW1pdCBkdXJpbmcgaW5pdGlhbGl6YXRpb25cbiAgICBpZiAodGhpcy5faXNJbml0aWFsaXppbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB2YWxpZGl0eSA9XG4gICAgICB0aGlzLmNoZWNrVGltZVZhbGlkaXR5KHRoaXMuc3RhcnRUaW1lKCkhLnRpbWUudHJpbSgpLCB0aGlzLnN0YXJ0RGF0ZUVwb2NoKCkpICYmIFxuICAgICAgdGhpcy5jaGVja1RpbWVWYWxpZGl0eSh0aGlzLmVuZFRpbWUoKSEudGltZS50cmltKCksIHRoaXMuZW5kRGF0ZUVwb2NoKCkpO1xuXG4gICAgdGhpcy5yYW5nZVZhbGlkYXRpb24odmFsaWRpdHkpO1xuICAgIHRoaXMuZW1pdFRpbWVSYW5nZSh7XG4gICAgICB2YWxpZDogdmFsaWRpdHkgJiYgdGhpcy5yYW5nZVZhbGlkaXR5KCksXG4gICAgICBzdGFydFRpbWU6IHRoaXMuc3RhcnRUaW1lKCkhLnRpbWUsXG4gICAgICBlbmRUaW1lOiB0aGlzLmVuZFRpbWUoKSEudGltZSxcbiAgICAgIHN0YXJ0RXBvY2g6IGRheWpzLnR6KGAke3RoaXMuZ2V0U3RhcnREYXRlKCl9ICR7dGhpcy5zdGFydFRpbWUoKSEudGltZX1gLCBgREQtTU0tWVlZWSAke3RoaXMuZ2V0VGltZUZvcm1hdCgpfWAsIHRoaXMudGltZXpvbmUoKSkudmFsdWVPZigpLFxuICAgICAgZW5kRXBvY2g6IGRheWpzLnR6KGAke3RoaXMuZ2V0RW5kRGF0ZSgpfSAke3RoaXMuZW5kVGltZSgpIS50aW1lfWAsIGBERC1NTS1ZWVlZICR7dGhpcy5nZXRUaW1lRm9ybWF0KCl9YCwgdGhpcy50aW1lem9uZSgpKS52YWx1ZU9mKClcbiAgICB9KTtcbiAgfVxuXG4gIGNoZWNrVGltZVZhbGlkaXR5KHRpbWU6IHN0cmluZywgZGF0ZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgUkUxMiA9IC9eKChbMF1bMS05XXwxWzAtMl0pOihbMC01XVswLTldKSggKT8oYW18cG18QU18UE0pKSQvaTtcbiAgICBjb25zdCBSRTI0ID0gL14oWzAxXVswLTldfDJbMC0zXSk6WzAtNV1bMC05XSQvO1xuICAgIGNvbnN0IFJFID0gdGhpcy5jbG9ja0Zvcm1hdCgpID09PSAxMiA/IFJFMTIgOiBSRTI0O1xuXG4gICAgY29uc3QgdGltZWRheWpzID0gZGF5anMudHooYCR7ZGF5anMudHooZGF0ZSwgdGhpcy50aW1lem9uZSgpKS5mb3JtYXQoXCJERC1NTS1ZWVlZXCIpfSAke3RpbWV9YCwgYCdERC1NTS1ZWVlZJyAke3RoaXMuZ2V0VGltZUZvcm1hdCgpfWAsIHRoaXMudGltZXpvbmUoKSk7XG4gICAgbGV0IGZsYWc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIGlmICgodGhpcy5naXZlblN0YXJ0VGltZSgpICYmIHRoaXMuZ2l2ZW5FbmRUaW1lKCkpIHx8ICh0aGlzLmdldFN0YXJ0RGF0ZSgpICE9PSB0aGlzLmdldEVuZERhdGUoKSAmJiB0aGlzLmdldFN0YXJ0RGF0ZSgpICE9PSB0aGlzLmdldEN1cnJEYXRlKCkpKSB7XG4gICAgICBmbGFnID0gdGltZS5tYXRjaChSRSkgPyB0cnVlIDogZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZsYWcgPSB0aW1lLm1hdGNoKFJFKSAmJiB0aW1lZGF5anMuZGlmZihkYXlqcy50eihkYXlqcygpLCB0aGlzLnRpbWV6b25lKCkpLCBcIm1cIikgPj0gMCA/IHRydWUgOiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGZsYWc7XG4gIH1cblxuICByYW5nZVZhbGlkYXRpb24odmFsaWRpdHk6IGJvb2xlYW4pIHtcbiAgICBpZiAodmFsaWRpdHkgJiYgdGhpcy5nZXRTdGFydERhdGUoKSA9PT0gdGhpcy5nZXRFbmREYXRlKCkpIHtcbiAgICAgIGNvbnN0IHN0YXJ0ZGF5anMgPSBkYXlqcy50eih0aGlzLnN0YXJ0VGltZSgpIS50aW1lLCB0aGlzLmdldFRpbWVGb3JtYXQoKSwgdGhpcy50aW1lem9uZSgpKTtcbiAgICAgIGNvbnN0IGVuZGRheWpzID0gZGF5anMudHoodGhpcy5lbmRUaW1lKCkhLnRpbWUsIHRoaXMuZ2V0VGltZUZvcm1hdCgpLCB0aGlzLnRpbWV6b25lKCkpO1xuICAgICAgdGhpcy5yYW5nZVZhbGlkaXR5LnNldChlbmRkYXlqcy5kaWZmKHN0YXJ0ZGF5anMsIFwibVwiKSA+PSAxKTtcbiAgICB9XG4gIH1cbn1cblxuXG4iLCI8ZGl2IGNsYXNzPVwicmFuZ2VwaWNrZXItY29udGFpbmVyXCIgW25nU3R5bGVdPVwieydmbGV4RGlyZWN0aW9uJzogZGlyZWN0aW9uKCksICdnYXAnOiBnYXAoKX1cIj5cbiAgPG1pcy10aW1lcGlja2VyXG4gICAgW2Nsb2NrRm9ybWF0XT1cImNsb2NrRm9ybWF0KClcIlxuICAgIFtpbnRlcnZhbF09XCJpbnRlcnZhbCgpXCJcbiAgICBbZGF0ZUFzRXBvY2hdPVwic3RhcnREYXRlRXBvY2goKVwiXG4gICAgW2ZpcnN0SW50ZXJ2YWxdPVwiZmlyc3RJbnRlcnZhbHMoKS5zdGFydFwiXG4gICAgKHRpbWVFbWl0dGVyKT1cInN0YXJ0UGlja2VySGFuZGxlcigkZXZlbnQpXCJcbiAgICBbdGltZXpvbmVdPVwidGltZXpvbmUoKVwiXG4gICAgW2hlaWdodF09XCJoZWlnaHQoKVwiXG4gICAgW2lucHV0V2lkdGhdPVwiaW5wdXRXaWR0aCgpXCJcbiAgICBbZHJvcGRvd25XaWR0aF09XCJkcm9wZG93bldpZHRoKClcIlxuICAgIFtzaG93VG9vbHRpcF09XCJzaG93VG9vbHRpcCgpXCJcbiAgICBbZ2l2ZW5UaW1lXT1cImdpdmVuU3RhcnRUaW1lKClcIlxuICAgIFtkaXNhYmxlXT1cImRpc2FibGVTdGFydFRpbWUoKVwiXG4gICAgW2Rpc2FibGVVc2VySW5wdXRdPVwiZGlzYWJsZVVzZXJJbnB1dCgpXCJcbiAgICBbZm9udFNpemVdPVwiZm9udFNpemUoKVwiXG4gID48L21pcy10aW1lcGlja2VyPlxuICA8cCAqbmdJZj1cImRpcmVjdGlvbigpID09PSAncm93J1wiPi08L3A+XG4gIDxtaXMtdGltZXBpY2tlclxuICAgIFtjbG9ja0Zvcm1hdF09XCJjbG9ja0Zvcm1hdCgpXCJcbiAgICBbaW50ZXJ2YWxdPVwiaW50ZXJ2YWwoKVwiXG4gICAgW2RhdGVBc0Vwb2NoXT1cImVuZERhdGVFcG9jaCgpXCJcbiAgICBbZmlyc3RJbnRlcnZhbF09XCJmaXJzdEludGVydmFscygpLmVuZFwiXG4gICAgKHRpbWVFbWl0dGVyKT1cImVuZFBpY2tlckhhbmRsZXIoJGV2ZW50KVwiXG4gICAgW3JhbmdlVmFsaWRpdHldPVwicmFuZ2VWYWxpZGl0eSgpXCJcbiAgICBbdGltZXpvbmVdPVwidGltZXpvbmUoKVwiXG4gICAgW2hlaWdodF09XCJoZWlnaHQoKVwiXG4gICAgW2lucHV0V2lkdGhdPVwiaW5wdXRXaWR0aCgpXCJcbiAgICBbZHJvcGRvd25XaWR0aF09XCJkcm9wZG93bldpZHRoKClcIlxuICAgIFtzaG93VG9vbHRpcF09XCJzaG93VG9vbHRpcCgpXCJcbiAgICBbZ2l2ZW5UaW1lXT1cImdpdmVuRW5kVGltZSgpXCJcbiAgICBbdHJpZ2dlckNoYW5nZV09XCJ0cmlnZ2VyQ2hhbmdlKClcIlxuICAgIFtkaXNhYmxlXT1cImRpc2FibGVFbmRUaW1lKClcIlxuICAgIFtkaXNhYmxlVXNlcklucHV0XT1cImRpc2FibGVVc2VySW5wdXQoKVwiXG4gICAgW2ZvbnRTaXplXT1cImZvbnRTaXplKClcIlxuICA+PC9taXMtdGltZXBpY2tlcj5cbjwvZGl2PlxuXG4iXX0=
@@ -1,11 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, signal, effect, Component, ViewChild, ContentChild, HostListener, NgModule } from '@angular/core';
2
+ import { input, output, signal, Component, ViewChild, ContentChild, HostListener, NgModule } from '@angular/core';
3
3
  import * as i3 from '@angular/forms';
4
4
  import { UntypedFormControl, ReactiveFormsModule, FormsModule } from '@angular/forms';
5
5
  import * as i1 from '@angular/cdk/overlay';
6
6
  import { ConnectionPositionPair, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
7
7
  import { TemplatePortal } from '@angular/cdk/portal';
8
- import { tap, debounceTime, distinctUntilChanged } from 'rxjs/operators';
8
+ import { tap, debounceTime, distinctUntilChanged, filter } from 'rxjs/operators';
9
9
  import { Subject, merge } from 'rxjs';
10
10
  import * as i2 from '@angular/common';
11
11
  import { CommonModule } from '@angular/common';
@@ -230,34 +230,20 @@ class AsyncDropdownComponent {
230
230
  this.error = signal(false);
231
231
  this.openPopUpOnTab = signal(false);
232
232
  this.data = signal([]);
233
- // === Effect to handle search ===
234
- this.searchEffect = effect(() => {
235
- // Merge form control changes and manual triggers
236
- merge(this.searchInput.valueChanges.pipe(tap((val) => this.searchQueryChange.emit(val)), debounceTime(this.debounceTime()), distinctUntilChanged()), this.httpStreamTrigger).subscribe((query) => {
237
- const q = query?.trim() ?? '';
238
- if (!q || q.length < this.minInputLength()) {
239
- this.closeDropdown();
240
- return;
241
- }
242
- this.loading.set(true);
243
- this.error.set(false);
244
- // Open overlay if not yet open
245
- if (!this.overlayRef?.hasAttached()) {
246
- this.openDropdown(this.dd, this.origin.nativeElement);
247
- }
248
- // Call HTTP stream
249
- this.httpStream()(q).subscribe({
250
- next: (list) => {
251
- this.loading.set(false);
252
- this.data.set(list);
253
- },
254
- error: () => {
255
- this.loading.set(false);
256
- this.error.set(true);
257
- },
258
- });
259
- });
260
- });
233
+ /**
234
+ * Tracks the last selected value to prevent dropdown from reopening when:
235
+ * - Input regains focus after selection (showing selected value)
236
+ * - Parent component re-renders and triggers change detection
237
+ * - User hasn't actually typed a new search query
238
+ *
239
+ * This is necessary because the input serves dual purposes:
240
+ * 1. Search input (user types, triggers API calls)
241
+ * 2. Display selected value (shows what was selected)
242
+ *
243
+ * Without this, setting the input value after selection would trigger
244
+ * the search subscription, causing unwanted API calls and dropdown reopening.
245
+ */
246
+ this.lastSelectedValue = signal(null);
261
247
  this.handleControlChanges = (values) => {
262
248
  values.forEach((el) => this.selectData(el, true));
263
249
  };
@@ -267,17 +253,92 @@ class AsyncDropdownComponent {
267
253
  if (this.multi() && !this.uniqueKey()) {
268
254
  throw new Error('[uniqueKey] required in multi mode.');
269
255
  }
270
- if (this.disabled())
256
+ if (this.disabled()) {
271
257
  this.searchInput.disable();
258
+ }
259
+ /**
260
+ * Search observable pipeline with RxJS operators to filter at the source.
261
+ * This declarative approach prevents unwanted searches by filtering:
262
+ * 1. Empty queries or queries below minInputLength
263
+ * 2. Queries that match the last selected value (prevents reopening after selection)
264
+ *
265
+ * Filtering at the source is preferred over checking flags in subscribe()
266
+ * because it's more declarative, testable, and follows RxJS best practices.
267
+ */
268
+ const searchObservable = this.searchInput.valueChanges.pipe(tap((val) => this.searchQueryChange.emit(val)), debounceTime(this.debounceTime()), distinctUntilChanged(),
269
+ // Filter: Only process non-empty queries that meet minInputLength requirement
270
+ filter((query) => {
271
+ const q = query?.trim() ?? '';
272
+ if (!q || q.length < this.minInputLength()) {
273
+ // Close dropdown if query is too short
274
+ this.closeDropdown();
275
+ return false;
276
+ }
277
+ return true;
278
+ }),
279
+ // Filter: Ignore queries that match the last selected value
280
+ // This prevents dropdown from reopening when input shows selected value
281
+ filter((query) => {
282
+ const q = query?.trim() ?? '';
283
+ const lastSelected = this.lastSelectedValue();
284
+ // Allow search if no previous selection OR query is different from selected value
285
+ return !lastSelected || q !== lastSelected;
286
+ }));
287
+ /**
288
+ * Subscribe to search queries and trigger HTTP stream.
289
+ * All filtering is done in the pipe chain above, so this callback
290
+ * only handles the actual search execution.
291
+ */
292
+ this.searchSubscription = merge(searchObservable, this.httpStreamTrigger)
293
+ .pipe(
294
+ // Additional filter for httpStreamTrigger (manual refresh)
295
+ filter((query) => {
296
+ const q = query?.trim() ?? '';
297
+ // For manual triggers, still respect minInputLength and lastSelectedValue
298
+ if (!q || q.length < this.minInputLength()) {
299
+ return false;
300
+ }
301
+ const lastSelected = this.lastSelectedValue();
302
+ return !lastSelected || q !== lastSelected;
303
+ }))
304
+ .subscribe((query) => {
305
+ const q = query?.trim() ?? '';
306
+ this.loading.set(true);
307
+ this.error.set(false);
308
+ // Open overlay if not yet open
309
+ if (!this.overlayRef?.hasAttached()) {
310
+ this.openDropdown(this.dd, this.origin.nativeElement);
311
+ }
312
+ // Call HTTP stream
313
+ this.httpStream()(q).subscribe({
314
+ next: (list) => {
315
+ this.loading.set(false);
316
+ this.data.set(list);
317
+ if (!this.overlayRef?.hasAttached() && list.length > 0) {
318
+ this.openDropdown(this.dd, this.origin.nativeElement);
319
+ }
320
+ },
321
+ error: () => {
322
+ this.loading.set(false);
323
+ this.error.set(true);
324
+ },
325
+ });
326
+ });
272
327
  if (this.control()?.value) {
273
328
  this.handleControlChanges(this.control().value);
274
329
  }
275
- this.control()?.valueChanges.subscribe(this.handleControlChanges);
330
+ this.controlSubscription = this.control()?.valueChanges.subscribe(this.handleControlChanges);
331
+ // Handle searchValue input changes
332
+ if (this.searchValue()) {
333
+ this.searchInput.patchValue(this.searchValue(), { emitEvent: false });
334
+ }
276
335
  }
277
336
  ngOnChanges() {
278
- if (this.searchValue()) {
279
- this.searchInput.patchValue(this.searchValue());
337
+ // Handle searchValue changes
338
+ if (this.searchValue() !== undefined) {
339
+ this.searchInput.patchValue(this.searchValue(), { emitEvent: false });
280
340
  }
341
+ // Handle disabled changes
281
342
  if (this.disabled()) {
282
343
  this.searchInput.disable();
283
344
  }
@@ -286,6 +347,9 @@ class AsyncDropdownComponent {
286
347
  }
287
348
  }
288
349
  ngOnDestroy() {
350
+ this.searchSubscription?.unsubscribe();
351
+ this.controlSubscription?.unsubscribe();
352
+ this.httpStreamTrigger.complete();
289
353
  this.overlayRef?.dispose();
290
354
  }
291
355
  // === Methods ===
@@ -317,10 +381,12 @@ class AsyncDropdownComponent {
317
381
  width: origin.clientWidth,
318
382
  });
319
383
  this.overlayRef = this.overlay.create(configs);
320
- if (this.dropdownListWidth())
384
+ if (this.dropdownListWidth()) {
321
385
  this.overlayRef.updateSize({ width: this.dropdownListWidth() });
386
+ }
322
387
  this.overlayRef.attach(new TemplatePortal(template, this.viewContainerRef));
323
388
  this.overlayRef.backdropClick().subscribe(() => this.closeDropdown());
389
+ this.opened.set(true);
324
390
  }
325
391
  closeDropdown() {
326
392
  this.opened.set(false);
@@ -337,12 +403,29 @@ class AsyncDropdownComponent {
337
403
  this.closeDropdown();
338
404
  }
339
405
  }
406
+ /**
407
+ * Handles item selection from dropdown.
408
+ *
409
+ * For single-select mode:
410
+ * - Sets input value to display selected item (standard UX pattern)
411
+ * - Stores selected value to prevent reopening dropdown on focus/change detection
412
+ * - Blurs input to prevent immediate focus-triggered searches
413
+ *
414
+ * For multi-select mode:
415
+ * - Clears input for next selection
416
+ * - Maintains focus for continuous selection
417
+ */
340
418
  selectData(item, effectedFromOutside = true) {
341
419
  if (item.disabled)
342
420
  return;
343
421
  this.itemSelected.emit(item);
344
422
  if (!this.multi()) {
345
- this.searchInput.patchValue(item[this.displayKey()], { emitEvent: false });
423
+ const selectedValue = item[this.displayKey()];
424
+ // Set input value to show selected item (standard UX - like Angular Material, etc.)
425
+ // Use emitEvent: false to prevent triggering valueChanges subscription
426
+ this.searchInput.patchValue(selectedValue, { emitEvent: false });
427
+ // Store selected value - RxJS filter will prevent reopening with same value
428
+ this.lastSelectedValue.set(selectedValue);
346
429
  this.setControlValue(item);
347
430
  }
348
431
  else {
@@ -360,6 +443,11 @@ class AsyncDropdownComponent {
360
443
  this.data.set([]);
361
444
  }
362
445
  this.closeDropdown();
446
+ // Blur input to prevent focus events from immediately triggering search
447
+ // The lastSelectedValue filter will also prevent reopening if focus occurs
448
+ if (this.inputRef?.nativeElement) {
449
+ this.inputRef.nativeElement.blur();
450
+ }
363
451
  }
364
452
  removeItem(item) {
365
453
  this.itemRemoved.emit(item);
@@ -374,12 +462,34 @@ class AsyncDropdownComponent {
374
462
  get selectedItems() {
375
463
  return Array.from(this.selections().values());
376
464
  }
465
+ /**
466
+ * Clears the input and resets selection state.
467
+ * Clearing lastSelectedValue allows new searches to proceed normally.
468
+ */
377
469
  removeInputValue() {
378
470
  this.searchInput.reset();
379
471
  this.data.set([]);
472
+ this.lastSelectedValue.set(null);
380
473
  this.clear.emit(true);
381
474
  }
475
+ /**
476
+ * Called when input receives focus.
477
+ * Only opens dropdown if:
478
+ * 1. minInputLength allows it (-1 or 0 means open on focus)
479
+ * 2. Input value doesn't match last selected value (prevents reopening after selection)
480
+ *
481
+ * This handles the case where input regains focus after selection.
482
+ * The RxJS filter in searchObservable handles valueChanges, but focus events
483
+ * need separate handling since they bypass valueChanges.
484
+ */
382
485
  defaultCall() {
486
+ const currentValue = this.searchInput.value?.trim() || '';
487
+ const lastSelected = this.lastSelectedValue();
488
+ // Don't open if value matches last selected (user hasn't typed new query)
489
+ if (lastSelected && currentValue === lastSelected) {
490
+ return;
491
+ }
492
+ // Only open on focus if minInputLength allows it
383
493
  if (this.minInputLength() === -1) {
384
494
  this.loading.set(true);
385
495
  this.httpStream()(this.searchInput.value || '').subscribe({