moment-timezone-picker
Version:
A simple angular moment timezone picker
207 lines (205 loc) • 22.4 kB
JavaScript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, ViewEncapsulation } from '@angular/core';
import * as momentZone from 'moment-timezone';
import { UntypedFormBuilder, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { DEFAULT_SELECT_CONFIG, formatZone } from './core';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@ng-select/ng-select";
export class MomentTimezonePickerComponent {
set config(conf) {
this._config = conf;
}
get config() {
return this._config;
}
constructor(fb, cdr) {
this.fb = fb;
this.cdr = cdr;
/**
* Setup section.
*/
this.getUserZone = false;
this.customPlaceholderText = 'Choose...';
this.customNotFoundText = 'No zone found';
this.clearable = false;
this.virtualScroll = true;
this.disabled = false;
this._config = DEFAULT_SELECT_CONFIG;
this.form = this.fb.group({
timezone: []
});
this.destroy$ = new Subject();
}
/**
* Lifecycle hooks
*/
ngOnChanges(changes) {
if (changes.getUserZone && changes.getUserZone.currentValue) {
this.guessUserTimezone();
}
if (changes.disabled) {
this.toggleTimezoneCtrl(changes.disabled.currentValue);
}
}
ngOnInit() {
this.timeZones = momentZone.tz.names().map((zone) => formatZone(zone));
this.setTimezoneChangeListener();
}
ngAfterViewInit() {
this.guessUserTimezone();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
/**
* Private
*/
toggleTimezoneCtrl(isDisabled) {
isDisabled
? this.form.get('timezone').disable()
: this.form.get('timezone').enable();
this.cdr.detectChanges();
}
setTimezoneChangeListener() {
this.form.get('timezone').valueChanges
.pipe(takeUntil(this.destroy$))
.subscribe(() => this.fireChanges());
}
guessUserTimezone() {
setTimeout(() => {
if (!this.getUserZone) {
console.warn('User zone guess turned off');
return;
}
const guessedZone = momentZone.tz.guess(true);
this.form.get('timezone').setValue(formatZone(guessedZone));
});
}
/**
* Propagate result to parent component.
*/
fireChanges() {
if (!this.propagateChange) {
return;
}
const timezone = this.form.get('timezone').value;
const transformedValue = this.valueTransformFN
? this.valueTransformFN(timezone)
: timezone;
this.propagateChange(transformedValue);
}
clearZone() {
this.form.get('timezone').reset();
}
validateZoneFromUpperLevels(zone) {
if (typeof zone === 'string' && zone.length > 0) {
return this.timeZones.find(z => z.nameValue === zone) ?? null;
}
if (typeof zone === 'object') {
return this.timeZones.find(z => z.nameValue === zone.nameValue) ?? null;
}
return null;
}
/**
* Access controls
*/
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched(fn) {
// not used
}
writeValue(zone) {
if (!zone) {
this.clearZone();
console.warn('Invalid zone passed');
return;
}
let _zone = this.validateZoneFromUpperLevels(zone);
if (_zone) {
this.form.get('timezone').setValue(_zone);
}
}
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.1", ngImport: i0, type: MomentTimezonePickerComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.1", type: MomentTimezonePickerComponent, selector: "ng-moment-timezone-picker", inputs: { getUserZone: "getUserZone", customPlaceholderText: "customPlaceholderText", customNotFoundText: "customNotFoundText", clearable: "clearable", virtualScroll: "virtualScroll", disabled: "disabled", valueTransformFN: "valueTransformFN", config: "config" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((() => MomentTimezonePickerComponent)),
multi: true
}
], usesOnChanges: true, ngImport: i0, template: `
<div class="wrapper" [formGroup]="form">
<ng-select [formControlName]="'timezone'"
[items]="timeZones"
[clearable]="clearable"
[virtualScroll]="virtualScroll"
[groupBy]="'group'"
bindLabel="name"
[placeholder]="customPlaceholderText"
[notFoundText]="customNotFoundText"
[appearance]="config.appearance"
[appendTo]="config.appendTo"
[clearOnBackspace]="config.clearOnBackspace"
[closeOnSelect]="config.closeOnSelect"
[dropdownPosition]="config.dropdownPosition"
[hideSelected]="config.hideSelected"
[searchable]="config.searchable">
</ng-select>
</div>
`, isInline: true, dependencies: [{ kind: "component", type: i2.NgSelectComponent, selector: "ng-select", inputs: ["bindLabel", "bindValue", "markFirst", "placeholder", "notFoundText", "typeToSearchText", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "keyDownFn", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.1", ngImport: i0, type: MomentTimezonePickerComponent, decorators: [{
type: Component,
args: [{
selector: 'ng-moment-timezone-picker',
template: `
<div class="wrapper" [formGroup]="form">
<ng-select [formControlName]="'timezone'"
[items]="timeZones"
[clearable]="clearable"
[virtualScroll]="virtualScroll"
[groupBy]="'group'"
bindLabel="name"
[placeholder]="customPlaceholderText"
[notFoundText]="customNotFoundText"
[appearance]="config.appearance"
[appendTo]="config.appendTo"
[clearOnBackspace]="config.clearOnBackspace"
[closeOnSelect]="config.closeOnSelect"
[dropdownPosition]="config.dropdownPosition"
[hideSelected]="config.hideSelected"
[searchable]="config.searchable">
</ng-select>
</div>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((() => MomentTimezonePickerComponent)),
multi: true
}
],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
}]
}], ctorParameters: () => [{ type: i1.UntypedFormBuilder }, { type: i0.ChangeDetectorRef }], propDecorators: { getUserZone: [{
type: Input
}], customPlaceholderText: [{
type: Input
}], customNotFoundText: [{
type: Input
}], clearable: [{
type: Input
}], virtualScroll: [{
type: Input
}], disabled: [{
type: Input
}], valueTransformFN: [{
type: Input
}], config: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9tZW50LXRpbWV6b25lLXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tb21lbnQtdGltZXpvbmUtcGlja2VyL3NyYy9saWIvbW9tZW50LXRpbWV6b25lLXBpY2tlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixLQUFLLEVBS0wsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sS0FBSyxVQUFVLE1BQU0saUJBQWlCLENBQUM7QUFDOUMsT0FBTyxFQUF1QixrQkFBa0IsRUFBb0IsaUJBQWlCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6QyxPQUFPLEVBQUMscUJBQXFCLEVBQUUsVUFBVSxFQUFzQixNQUFNLFFBQVEsQ0FBQzs7OztBQW1DOUUsTUFBTSxPQUFPLDZCQUE2QjtJQWF4QyxJQUNJLE1BQU0sQ0FBQyxJQUFrQjtRQUMzQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztJQUN0QixDQUFDO0lBSUQsSUFBSSxNQUFNO1FBQ1IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3RCLENBQUM7SUFZRCxZQUFvQixFQUFzQixFQUFVLEdBQXNCO1FBQXRELE9BQUUsR0FBRixFQUFFLENBQW9CO1FBQVUsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFoQzFFOztXQUVHO1FBQ00sZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFDcEIsMEJBQXFCLEdBQUcsV0FBVyxDQUFDO1FBQ3BDLHVCQUFrQixHQUFHLGVBQWUsQ0FBQztRQUNyQyxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLGtC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LENBQUMsQ0FBQztRQUNqRSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVDLENBQUM7SUFDSCxDQUFDO2lJQS9JVSw2QkFBNkI7cUhBQTdCLDZCQUE2Qiw0VEFWN0I7WUFDVDtnQkFDRSxPQUFPLEVBQUUsaUJBQWlCO2dCQUMxQixXQUFXLEVBQUUsVUFBVSxFQUFDLEdBQUcsRUFBRSxDQUFDLDZCQUE2QixFQUFDO2dCQUM1RCxLQUFLLEVBQUUsSUFBSTthQUNaO1NBQ0YsK0NBM0JTOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CVDs7MkZBV1UsNkJBQTZCO2tCQWpDekMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsMkJBQTJCO29CQUNyQyxRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JUO29CQUNELFNBQVMsRUFBRTt3QkFDVDs0QkFDRSxPQUFPLEVBQUUsaUJBQWlCOzRCQUMxQixXQUFXLEVBQUUsVUFBVSxFQUFDLEdBQUcsRUFBRSw4QkFBOEIsRUFBQzs0QkFDNUQsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7b0JBQ0QsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7b0JBQ3JDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO2lCQUNoRDt1SEFNVSxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUdGLE1BQU07c0JBRFQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBmb3J3YXJkUmVmLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgKiBhcyBtb21lbnRab25lIGZyb20gJ21vbWVudC10aW1lem9uZSc7XG5pbXBvcnQge0NvbnRyb2xWYWx1ZUFjY2Vzc29yLCBVbnR5cGVkRm9ybUJ1aWxkZXIsIFVudHlwZWRGb3JtR3JvdXAsIE5HX1ZBTFVFX0FDQ0VTU09SfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1N1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHt0YWtlVW50aWx9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7REVGQVVMVF9TRUxFQ1RfQ09ORklHLCBmb3JtYXRab25lLCBTZWxlY3RDb25maWcsIFRab25lfSBmcm9tICcuL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZy1tb21lbnQtdGltZXpvbmUtcGlja2VyJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwid3JhcHBlclwiIFtmb3JtR3JvdXBdPVwiZm9ybVwiPlxuICAgICAgPG5nLXNlbGVjdCBbZm9ybUNvbnRyb2xOYW1lXT1cIid0aW1lem9uZSdcIlxuICAgICAgICAgICAgICAgICBbaXRlbXNdPVwidGltZVpvbmVzXCJcbiAgICAgICAgICAgICAgICAgW2NsZWFyYWJsZV09XCJjbGVhcmFibGVcIlxuICAgICAgICAgICAgICAgICBbdmlydHVhbFNjcm9sbF09XCJ2aXJ0dWFsU2Nyb2xsXCJcbiAgICAgICAgICAgICAgICAgW2dyb3VwQnldPVwiJ2dyb3VwJ1wiXG4gICAgICAgICAgICAgICAgIGJpbmRMYWJlbD1cIm5hbWVcIlxuICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiY3VzdG9tUGxhY2Vob2xkZXJUZXh0XCJcbiAgICAgICAgICAgICAgICAgW25vdEZvdW5kVGV4dF09XCJjdXN0b21Ob3RGb3VuZFRleHRcIlxuXG4gICAgICAgICAgICAgICAgIFthcHBlYXJhbmNlXT1cImNvbmZpZy5hcHBlYXJhbmNlXCJcbiAgICAgICAgICAgICAgICAgW2FwcGVuZFRvXT1cImNvbmZpZy5hcHBlbmRUb1wiXG4gICAgICAgICAgICAgICAgIFtjbGVhck9uQmFja3NwYWNlXT1cImNvbmZpZy5jbGVhck9uQmFja3NwYWNlXCJcbiAgICAgICAgICAgICAgICAgW2Nsb3NlT25TZWxlY3RdPVwiY29uZmlnLmNsb3NlT25TZWxlY3RcIlxuICAgICAgICAgICAgICAgICBbZHJvcGRvd25Qb3NpdGlvbl09XCJjb25maWcuZHJvcGRvd25Qb3NpdGlvblwiXG4gICAgICAgICAgICAgICAgIFtoaWRlU2VsZWN0ZWRdPVwiY29uZmlnLmhpZGVTZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgIFtzZWFyY2hhYmxlXT1cImNvbmZpZy5zZWFyY2hhYmxlXCI+XG4gICAgICA8L25nLXNlbGVjdD5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBNb21lbnRUaW1lem9uZVBpY2tlckNvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH1cbiAgXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgTW9tZW50VGltZXpvbmVQaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzLCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG5cbiAgLyoqXG4gICAqIFNldHVwIHNlY3Rpb24uXG4gICAqL1xuICBASW5wdXQoKSBnZXRVc2VyWm9uZSA9IGZhbHNlO1xuICBASW5wdXQoKSBjdXN0b21QbGFjZWhvbGRlclRleHQgPSAnQ2hvb3NlLi4uJztcbiAgQElucHV0KCkgY3VzdG9tTm90Rm91bmRUZXh0ID0gJ05vIHpvbmUgZm91bmQnO1xuICBASW5wdXQoKSBjbGVhcmFibGUgPSBmYWxzZTtcbiAgQElucHV0KCkgdmlydHVhbFNjcm9sbCA9IHRydWU7XG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG4gIEBJbnB1dCgpIHZhbHVlVHJhbnNmb3JtRk4/OiAob2JqOiBUWm9uZSB8IG51bGwpID0+IGFueTtcblxuICBASW5wdXQoKVxuICBzZXQgY29uZmlnKGNvbmY6IFNlbGVjdENvbmZpZykge1xuICAgIHRoaXMuX2NvbmZpZyA9IGNvbmY7XG4gIH1cblxuICBwcml2YXRlIF9jb25maWc6IFNlbGVjdENvbmZpZyA9IERFRkFVTFRfU0VMRUNUX0NPTkZJRztcblxuICBnZXQgY29uZmlnKCk6IFNlbGVjdENvbmZpZyB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZztcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnRlcm5hbHMgc2VjdGlvbi5cbiAgICovXG4gIHRpbWVab25lczogQXJyYXk8VFpvbmU+O1xuICBmb3JtOiBVbnR5cGVkRm9ybUdyb3VwID0gdGhpcy5mYi5ncm91cCh7XG4gICAgdGltZXpvbmU6IFtdXG4gIH0pO1xuICBwcml2YXRlIHByb3BhZ2F0ZUNoYW5nZTogKF86IGFueSkgPT4ge307XG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZmI6IFVudHlwZWRGb3JtQnVpbGRlciwgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7XG4gIH1cblxuICAvKipcbiAgICogTGlmZWN5Y2xlIGhvb2tzXG4gICAqL1xuXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXMuZ2V0VXNlclpvbmUgJiYgY2hhbmdlcy5nZXRVc2VyWm9uZS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMuZ3Vlc3NVc2VyVGltZXpvbmUoKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXMuZGlzYWJsZWQpIHtcbiAgICAgIHRoaXMudG9nZ2xlVGltZXpvbmVDdHJsKGNoYW5nZXMuZGlzYWJsZWQuY3VycmVudFZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy50aW1lWm9uZXMgPSBtb21lbnRab25lLnR6Lm5hbWVzKCkubWFwKCh6b25lOiBzdHJpbmcpID0+IGZvcm1hdFpvbmUoem9uZSkpO1xuICAgIHRoaXMuc2V0VGltZXpvbmVDaGFuZ2VMaXN0ZW5lcigpO1xuICB9XG5cbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmd1ZXNzVXNlclRpbWV6b25lKCk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByaXZhdGVcbiAgICovXG5cbiAgcHJpdmF0ZSB0b2dnbGVUaW1lem9uZUN0cmwoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGlzRGlzYWJsZWRcbiAgICAgID8gdGhpcy5mb3JtLmdldCgndGltZXpvbmUnKS5kaXNhYmxlKClcbiAgICAgIDogdGhpcy5mb3JtLmdldCgndGltZXpvbmUnKS5lbmFibGUoKTtcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwcml2YXRlIHNldFRpbWV6b25lQ2hhbmdlTGlzdGVuZXIoKTogdm9pZCB7XG4gICAgdGhpcy5mb3JtLmdldCgndGltZXpvbmUnKS52YWx1ZUNoYW5nZXNcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5maXJlQ2hhbmdlcygpKTtcbiAgfVxuXG4gIHByaXZhdGUgZ3Vlc3NVc2VyVGltZXpvbmUoKTogdm9pZCB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAoIXRoaXMuZ2V0VXNlclpvbmUpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdVc2VyIHpvbmUgZ3Vlc3MgdHVybmVkIG9mZicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBndWVzc2VkWm9uZSA9IG1vbWVudFpvbmUudHouZ3Vlc3ModHJ1ZSk7XG4gICAgICB0aGlzLmZvcm0uZ2V0KCd0aW1lem9uZScpLnNldFZhbHVlKGZvcm1hdFpvbmUoZ3Vlc3NlZFpvbmUpKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9wYWdhdGUgcmVzdWx0IHRvIHBhcmVudCBjb21wb25lbnQuXG4gICAqL1xuICBwcml2YXRlIGZpcmVDaGFuZ2VzKCkge1xuICAgIGlmICghdGhpcy5wcm9wYWdhdGVDaGFuZ2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdGltZXpvbmUgPSB0aGlzLmZvcm0uZ2V0KCd0aW1lem9uZScpLnZhbHVlO1xuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLnZhbHVlVHJhbnNmb3JtRk5cbiAgICAgID8gdGhpcy52YWx1ZVRyYW5zZm9ybUZOKHRpbWV6b25lKVxuICAgICAgOiB0aW1lem9uZTtcbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZSh0cmFuc2Zvcm1lZFZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJab25lKCkge1xuICAgIHRoaXMuZm9ybS5nZXQoJ3RpbWV6b25lJykucmVzZXQoKTtcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVab25lRnJvbVVwcGVyTGV2ZWxzKHpvbmU6IHN0cmluZyB8IFRab25lKTogVFpvbmUgfCBudWxsIHtcbiAgICBpZiAodHlwZW9mIHpvbmUgPT09ICdzdHJpbmcnICYmIHpvbmUubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHRoaXMudGltZVpvbmVzLmZpbmQoeiA9PiB6Lm5hbWVWYWx1ZSA9PT0gem9uZSkgPz8gbnVsbDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB6b25lID09PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuIHRoaXMudGltZVpvbmVzLmZpbmQoeiA9PiB6Lm5hbWVWYWx1ZSA9PT0gem9uZS5uYW1lVmFsdWUpID8/IG51bGw7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjY2VzcyBjb250cm9sc1xuICAgKi9cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZSA9IGZuO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSk6IHZvaWQge1xuICAgIC8vIG5vdCB1c2VkXG4gIH1cblxuICB3cml0ZVZhbHVlKHpvbmU6IHN0cmluZyB8IFRab25lIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIGlmICghem9uZSkge1xuICAgICAgdGhpcy5jbGVhclpvbmUoKTtcbiAgICAgIGNvbnNvbGUud2FybignSW52YWxpZCB6b25lIHBhc3NlZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBfem9uZTogVFpvbmUgfCBudWxsID0gdGhpcy52YWxpZGF0ZVpvbmVGcm9tVXBwZXJMZXZlbHMoem9uZSk7XG4gICAgaWYgKF96b25lKSB7XG4gICAgICB0aGlzLmZvcm0uZ2V0KCd0aW1lem9uZScpLnNldFZhbHVlKF96b25lKTtcbiAgICB9XG4gIH1cblxufVxuIl19