@xui/components
Version:
xUI Components for Angular
107 lines • 23.4 kB
JavaScript
import { booleanAttribute, ChangeDetectionStrategy, Component, computed, effect, ElementRef, input, Input, Optional, Self, signal, ViewChild } from '@angular/core';
import { FormsModule, NgControl } from '@angular/forms';
import { inNextTick } from '../utils';
import { CommonModule } from '@angular/common';
import { XuiTooltip, XuiTooltipModule } from '../tooltip';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { XuiFocusModule } from '../utils/focus.service';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "../tooltip/tooltip.directive";
import * as i3 from "@angular/cdk/drag-drop";
export class XuiSlider {
_getColor(color) {
return `x-slider-${color}`;
}
_getPercentage(absolute) {
return ((absolute - this.min()) / (this.max() - this.min())) * 100;
}
constructor(control) {
this.control = control;
this._disabled = signal(false);
this.color = input('primary');
this.secondColor = input();
this.min = input(0, { transform: (v) => Number(v) });
this.max = input(100, { transform: (v) => Number(v) });
this.step = input(1, { transform: (v) => Number(v) });
this.marks = input();
this.value = input(undefined, { transform: (v) => Number(v) });
// range = input(false, { transform: (v: string | boolean) => convertToBoolean(v) });
this.disabled = input(undefined, {
transform: booleanAttribute
});
this.tooltipDisabled = input(false, { transform: booleanAttribute });
this._value = signal(this.min());
this._tooltip = computed(() => String(this.tipFormatter ? this.tipFormatter(this._value()) : this._value()));
this.percentage = computed(() => this._getPercentage(this._value()));
this._width = computed(() => 100 - this.percentage());
this._position = computed(() => ({ x: (this.percentage() / 100) * this.hostRect.width - 5, y: 0 }));
if (this.control) {
this.control.valueAccessor = this;
}
effect(() => this.disabled() && this._disabled.set(this.disabled()), { allowSignalWrites: true });
effect(() => this.value() && this._value.set(this.value()), { allowSignalWrites: true });
effect(() => this.onChange?.(this._value()));
}
writeValue(source) {
this._value.set(source);
}
registerOnChange(onChange) {
this.onChange = onChange;
}
registerOnTouched(onTouched) {
this._onTouched = onTouched;
}
setDisabledState(isDisabled) {
this._disabled.set(isDisabled);
}
_decreaseKey() {
this._value.set(Math.min(Math.max(this._value() - this.step(), this.min()), this.max()));
}
_increaseKey() {
this._value.set(Math.min(Math.max(this._value() + this.step(), this.min()), this.max()));
}
async _move(screenX) {
if (this._disabled()) {
return;
}
const cursorOffset = 5;
const rect = this.hostRect;
const width = rect.width - 10;
const pos = Math.min(Math.max(screenX - rect.x - cursorOffset, 0), width);
const value = (pos / width) * (this.max() - this.min()); // 0 <-> max - min
const newValue = Math.round(value / this.step()) * this.step();
this._value.set(newValue + this.min());
await inNextTick();
this.tooltipRef.show();
}
get hostRect() {
return this.trackElm.nativeElement.getBoundingClientRect();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: XuiSlider, deps: [{ token: i1.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: XuiSlider, isStandalone: true, selector: "xui-slider", inputs: { tipFormatter: { classPropertyName: "tipFormatter", publicName: "tipFormatter", isSignal: false, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, secondColor: { classPropertyName: "secondColor", publicName: "secondColor", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, marks: { classPropertyName: "marks", publicName: "marks", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, tooltipDisabled: { classPropertyName: "tooltipDisabled", publicName: "tooltipDisabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "_move($event.x)", "focusout": "_onTouched?.()", "keydown.arrowLeft": "_decreaseKey()", "keydown.arrowRight": "_increaseKey()" }, properties: { "class.x-slider-disabled": "_disabled()" }, classAttribute: "x-slider" }, viewQueries: [{ propertyName: "trackElm", first: true, predicate: ["track"], descendants: true, static: true }, { propertyName: "tooltipRef", first: true, predicate: ["tooltipRef"], descendants: true }], ngImport: i0, template: "<div [class]=\"'x-slider-track ' + _getColor(color())\">\n <div [style.width.%]=\"_width()\" [class]=\"'x-slider-track-half ' + _getColor(secondColor() ?? 'none')\"></div>\n</div>\n\n<div class=\"x-slider-container\" #track>\n <div\n [tabindex]=\"_disabled() ? -1 : 0\"\n cdkDrag\n [cdkDragDisabled]=\"_disabled()\"\n [cdkDragFreeDragPosition]=\"_position()\"\n (cdkDragMoved)=\"_move($event.pointerPosition.x)\"\n class=\"x-slider-thumb\"\n xuiTooltipPosition=\"top\"\n [xuiTooltip]=\"_tooltip()\"\n [xuiTooltipDisabled]=\"tooltipDisabled()\"\n #tooltipRef=\"xuiTooltip\"\n ></div>\n\n @for (mark of marks(); track mark.value) {\n <div\n [style.left.%]=\"_getPercentage(mark.value)\"\n class=\"x-slider-mark\"\n [class]=\"mark.color ? 'x-slider-mark-' + mark.color : ''\"\n >\n <div class=\"x-slider-mark-label\">{{ mark.label }}</div>\n <div class=\"x-slider-mark-dash\"></div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: XuiTooltipModule }, { kind: "directive", type: i2.XuiTooltip, selector: "[xuiTooltip]", inputs: ["xuiTooltip", "xuiTooltipPosition", "xuiTooltipDisabled"], exportAs: ["xuiTooltip"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: XuiFocusModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: XuiSlider, decorators: [{
type: Component,
args: [{ standalone: true, imports: [CommonModule, FormsModule, XuiTooltipModule, DragDropModule, XuiFocusModule], selector: 'xui-slider', changeDetection: ChangeDetectionStrategy.OnPush, host: {
class: 'x-slider',
'[class.x-slider-disabled]': '_disabled()',
'(click)': '_move($event.x)',
'(focusout)': '_onTouched?.()',
'(keydown.arrowLeft)': '_decreaseKey()',
'(keydown.arrowRight)': '_increaseKey()'
}, template: "<div [class]=\"'x-slider-track ' + _getColor(color())\">\n <div [style.width.%]=\"_width()\" [class]=\"'x-slider-track-half ' + _getColor(secondColor() ?? 'none')\"></div>\n</div>\n\n<div class=\"x-slider-container\" #track>\n <div\n [tabindex]=\"_disabled() ? -1 : 0\"\n cdkDrag\n [cdkDragDisabled]=\"_disabled()\"\n [cdkDragFreeDragPosition]=\"_position()\"\n (cdkDragMoved)=\"_move($event.pointerPosition.x)\"\n class=\"x-slider-thumb\"\n xuiTooltipPosition=\"top\"\n [xuiTooltip]=\"_tooltip()\"\n [xuiTooltipDisabled]=\"tooltipDisabled()\"\n #tooltipRef=\"xuiTooltip\"\n ></div>\n\n @for (mark of marks(); track mark.value) {\n <div\n [style.left.%]=\"_getPercentage(mark.value)\"\n class=\"x-slider-mark\"\n [class]=\"mark.color ? 'x-slider-mark-' + mark.color : ''\"\n >\n <div class=\"x-slider-mark-label\">{{ mark.label }}</div>\n <div class=\"x-slider-mark-dash\"></div>\n </div>\n }\n</div>\n" }]
}], ctorParameters: () => [{ type: i1.NgControl, decorators: [{
type: Self
}, {
type: Optional
}] }], propDecorators: { tipFormatter: [{
type: Input
}], trackElm: [{
type: ViewChild,
args: ['track', { static: true }]
}], tooltipRef: [{
type: ViewChild,
args: ['tooltipRef']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy94dWkvc3JjL3NsaWRlci9zbGlkZXIudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzL3h1aS9zcmMvc2xpZGVyL3NsaWRlci5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFVBQVUsRUFDVixLQUFLLEVBQ0wsS0FBSyxFQUNMLFFBQVEsRUFDUixJQUFJLEVBQ0osTUFBTSxFQUNOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRXRDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzFELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7O0FBaUJ4RCxNQUFNLE9BQU8sU0FBUztJQTRCcEIsU0FBUyxDQUFDLEtBQWE7UUFDckIsT0FBTyxZQUFZLEtBQUssRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxjQUFjLENBQUMsUUFBZ0I7UUFDN0IsT0FBTyxDQUFDLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBQ3JFLENBQUM7SUFFRCxZQUF1QyxPQUFtQjtRQUFuQixZQUFPLEdB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NUUsWUFBWSxtQkFDTCx1QkFBdUIsQ0FBQyxNQUFNLFFBRXpDO3dCQUNKLEtBQUssRUFBRSxVQUFVO3dCQUNqQiwyQkFBMkIsRUFBRSxhQUFhO3dCQUMxQyxTQUFTLEVBQUUsaUJBQWlCO3dCQUM1QixZQUFZLEVBQUUsZ0JBQWdCO3dCQUM5QixxQkFBcUIsRUFBRSxnQkFBZ0I7d0JBQ3ZDLHNCQUFzQixFQUFFLGdCQUFnQjtxQkFDekM7OzBCQXNDWSxJQUFJOzswQkFBSSxRQUFRO3lDQS9CcEIsWUFBWTtzQkFBcEIsS0FBSztnQkFjd0MsUUFBUTtzQkFBckQsU0FBUzt1QkFBQyxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNILFVBQVU7c0JBQTFDLFNBQVM7dUJBQUMsWUFBWSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGJvb2xlYW5BdHRyaWJ1dGUsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIGNvbXB1dGVkLFxuICBlZmZlY3QsXG4gIEVsZW1lbnRSZWYsXG4gIGlucHV0LFxuICBJbnB1dCxcbiAgT3B0aW9uYWwsXG4gIFNlbGYsXG4gIHNpZ25hbCxcbiAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1zTW9kdWxlLCBOZ0NvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBpbk5leHRUaWNrIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHsgU2xpZGVyQ29sb3IsIFNsaWRlck1hcmsgfSBmcm9tICcuL3NsaWRlci50eXBlcyc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgWHVpVG9vbHRpcCwgWHVpVG9vbHRpcE1vZHVsZSB9IGZyb20gJy4uL3Rvb2x0aXAnO1xuaW1wb3J0IHsgRHJhZ0Ryb3BNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wJztcbmltcG9ydCB7IFh1aUZvY3VzTW9kdWxlIH0gZnJvbSAnLi4vdXRpbHMvZm9jdXMuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgWHVpVG9vbHRpcE1vZHVsZSwgRHJhZ0Ryb3BNb2R1bGUsIFh1aUZvY3VzTW9kdWxlXSxcbiAgc2VsZWN0b3I6ICd4dWktc2xpZGVyJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlVXJsOiAnc2xpZGVyLmh0bWwnLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICd4LXNsaWRlcicsXG4gICAgJ1tjbGFzcy54LXNsaWRlci1kaXNhYmxlZF0nOiAnX2Rpc2FibGVkKCknLFxuICAgICcoY2xpY2spJzogJ19tb3ZlKCRldmVudC54KScsXG4gICAgJyhmb2N1c291dCknOiAnX29uVG91Y2hlZD8uKCknLFxuICAgICcoa2V5ZG93bi5hcnJvd0xlZnQpJzogJ19kZWNyZWFzZUtleSgpJyxcbiAgICAnKGtleWRvd24uYXJyb3dSaWdodCknOiAnX2luY3JlYXNlS2V5KCknXG4gIH1cbn0pXG5leHBvcnQgY2xhc3MgWHVpU2xpZGVyIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuICBwcml2YXRlIG9uQ2hhbmdlPzogKHNvdXJjZTogbnVtYmVyKSA9PiB2b2lkO1xuICBfb25Ub3VjaGVkPzogKCkgPT4gdm9pZDtcbiAgX2Rpc2FibGVkID0gc2lnbmFsKGZhbHNlKTtcblxuICBASW5wdXQoKSB0aXBGb3JtYXR0ZXI/OiAodmFsdWU6IG51bWJlcikgPT4gc3RyaW5nO1xuICBjb2xvciA9IGlucHV0PFNsaWRlckNvbG9yPigncHJpbWFyeScpO1xuICBzZWNvbmRDb2xvciA9IGlucHV0PFNsaWRlckNvbG9yPigpO1xuICBtaW4gPSBpbnB1dCgwLCB7IHRyYW5zZm9ybTogKHY6IHN0cmluZyB8IG51bWJlcikgPT4gTnVtYmVyKHYpIH0pO1xuICBtYXggPSBpbnB1dCgxMDAsIHsgdHJhbnNmb3JtOiAodjogc3RyaW5nIHwgbnVtYmVyKSA9PiBOdW1iZXIodikgfSk7XG4gIHN0ZXAgPSBpbnB1dCgxLCB7IHRyYW5zZm9ybTogKHY6IHN0cmluZyB8IG51bWJlcikgPT4gTnVtYmVyKHYpIH0pO1xuICBtYXJrcyA9IGlucHV0PFNsaWRlck1hcmtbXT4oKTtcbiAgdmFsdWUgPSBpbnB1dDxudW1iZXIgfCB1bmRlZmluZWQsIHN0cmluZyB8IG51bWJlcj4odW5kZWZpbmVkLCB7IHRyYW5zZm9ybTogKHY6IHN0cmluZyB8IG51bWJlcikgPT4gTnVtYmVyKHYpIH0pO1xuICAvLyByYW5nZSA9IGlucHV0KGZhbHNlLCB7IHRyYW5zZm9ybTogKHY6IHN0cmluZyB8IGJvb2xlYW4pID0+IGNvbnZlcnRUb0Jvb2xlYW4odikgfSk7XG4gIGRpc2FibGVkID0gaW5wdXQ8Ym9vbGVhbiB8IHVuZGVmaW5lZCwgc3RyaW5nIHwgYm9vbGVhbj4odW5kZWZpbmVkLCB7XG4gICAgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlXG4gIH0pO1xuICB0b29sdGlwRGlzYWJsZWQgPSBpbnB1dChmYWxzZSwgeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSk7XG5cbiAgQFZpZXdDaGlsZCgndHJhY2snLCB7IHN0YXRpYzogdHJ1ZSB9KSBwcml2YXRlIHRyYWNrRWxtITogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgndG9vbHRpcFJlZicpIHByaXZhdGUgdG9vbHRpcFJlZiE6IFh1aVRvb2x0aXA7XG5cbiAgX3ZhbHVlID0gc2lnbmFsKHRoaXMubWluKCkpO1xuICBfdG9vbHRpcCA9IGNvbXB1dGVkKCgpID0+IFN0cmluZyh0aGlzLnRpcEZvcm1hdHRlciA/IHRoaXMudGlwRm9ybWF0dGVyKHRoaXMuX3ZhbHVlKCkpIDogdGhpcy5fdmFsdWUoKSkpO1xuICBwcml2YXRlIHBlcmNlbnRhZ2UgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9nZXRQZXJjZW50YWdlKHRoaXMuX3ZhbHVlKCkpKTtcbiAgX3dpZHRoID0gY29tcHV0ZWQoKCkgPT4gMTAwIC0gdGhpcy5wZXJjZW50YWdlKCkpO1xuICBfcG9zaXRpb24gPSBjb21wdXRlZCgoKSA9PiAoeyB4OiAodGhpcy5wZXJjZW50YWdlKCkgLyAxMDApICogdGhpcy5ob3N0UmVjdC53aWR0aCAtIDUsIHk6IDAgfSkpO1xuXG4gIF9nZXRDb2xvcihjb2xvcjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGB4LXNsaWRlci0ke2NvbG9yfWA7XG4gIH1cblxuICBfZ2V0UGVyY2VudGFnZShhYnNvbHV0ZTogbnVtYmVyKSB7XG4gICAgcmV0dXJuICgoYWJzb2x1dGUgLSB0aGlzLm1pbigpKSAvICh0aGlzLm1heCgpIC0gdGhpcy5taW4oKSkpICogMTAwO1xuICB9XG5cbiAgY29uc3RydWN0b3IoQFNlbGYoKSBAT3B0aW9uYWwoKSBwdWJsaWMgY29udHJvbD86IE5nQ29udHJvbCkge1xuICAgIGlmICh0aGlzLmNvbnRyb2wpIHtcbiAgICAgIHRoaXMuY29udHJvbC52YWx1ZUFjY2Vzc29yID0gdGhpcztcbiAgICB9XG5cbiAgICBlZmZlY3QoKCkgPT4gdGhpcy5kaXNhYmxlZCgpICYmIHRoaXMuX2Rpc2FibGVkLnNldCh0aGlzLmRpc2FibGVkKCkhKSwgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9KTtcbiAgICBlZmZlY3QoKCkgPT4gdGhpcy52YWx1ZSgpICYmIHRoaXMuX3ZhbHVlLnNldCh0aGlzLnZhbHVlKCkhKSwgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9KTtcbiAgICBlZmZlY3QoKCkgPT4gdGhpcy5vbkNoYW5nZT8uKHRoaXMuX3ZhbHVlKCkpKTtcbiAgfVxuXG4gIHdyaXRlVmFsdWUoc291cmNlOiBudW1iZXIpIHtcbiAgICB0aGlzLl92YWx1ZS5zZXQoc291cmNlKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2Uob25DaGFuZ2U6IChzb3VyY2U6IG51bWJlcikgPT4gdm9pZCkge1xuICAgIHRoaXMub25DaGFuZ2UgPSBvbkNoYW5nZTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKG9uVG91Y2hlZDogKCkgPT4gdm9pZCkge1xuICAgIHRoaXMuX29uVG91Y2hlZCA9IG9uVG91Y2hlZDtcbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuX2Rpc2FibGVkLnNldChpc0Rpc2FibGVkKTtcbiAgfVxuXG4gIF9kZWNyZWFzZUtleSgpIHtcbiAgICB0aGlzLl92YWx1ZS5zZXQoTWF0aC5taW4oTWF0aC5tYXgodGhpcy5fdmFsdWUoKSAtIHRoaXMuc3RlcCgpLCB0aGlzLm1pbigpKSwgdGhpcy5tYXgoKSkpO1xuICB9XG5cbiAgX2luY3JlYXNlS2V5KCkge1xuICAgIHRoaXMuX3ZhbHVlLnNldChNYXRoLm1pbihNYXRoLm1heCh0aGlzLl92YWx1ZSgpICsgdGhpcy5zdGVwKCksIHRoaXMubWluKCkpLCB0aGlzLm1heCgpKSk7XG4gIH1cblxuICBhc3luYyBfbW92ZShzY3JlZW5YOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5fZGlzYWJsZWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnNvck9mZnNldCA9IDU7XG4gICAgY29uc3QgcmVjdCA9IHRoaXMuaG9zdFJlY3Q7XG4gICAgY29uc3Qgd2lkdGggPSByZWN0LndpZHRoIC0gMTA7XG5cbiAgICBjb25zdCBwb3MgPSBNYXRoLm1pbihNYXRoLm1heChzY3JlZW5YIC0gcmVjdC54IC0gY3Vyc29yT2Zmc2V0LCAwKSwgd2lkdGgpO1xuICAgIGNvbnN0IHZhbHVlID0gKHBvcyAvIHdpZHRoKSAqICh0aGlzLm1heCgpIC0gdGhpcy5taW4oKSk7IC8vIDAgPC0+IG1heCAtIG1pblxuICAgIGNvbnN0IG5ld1ZhbHVlID0gTWF0aC5yb3VuZCh2YWx1ZSAvIHRoaXMuc3RlcCgpKSAqIHRoaXMuc3RlcCgpO1xuICAgIHRoaXMuX3ZhbHVlLnNldChuZXdWYWx1ZSArIHRoaXMubWluKCkpO1xuXG4gICAgYXdhaXQgaW5OZXh0VGljaygpO1xuICAgIHRoaXMudG9vbHRpcFJlZi5zaG93KCk7XG4gIH1cblxuICBwcml2YXRlIGdldCBob3N0UmVjdCgpIHtcbiAgICByZXR1cm4gdGhpcy50cmFja0VsbS5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIGFzIERPTVJlY3Q7XG4gIH1cbn1cbiIsIjxkaXYgW2NsYXNzXT1cIid4LXNsaWRlci10cmFjayAnICsgX2dldENvbG9yKGNvbG9yKCkpXCI+XG4gIDxkaXYgW3N0eWxlLndpZHRoLiVdPVwiX3dpZHRoKClcIiBbY2xhc3NdPVwiJ3gtc2xpZGVyLXRyYWNrLWhhbGYgJyArIF9nZXRDb2xvcihzZWNvbmRDb2xvcigpID8/ICdub25lJylcIj48L2Rpdj5cbjwvZGl2PlxuXG48ZGl2IGNsYXNzPVwieC1zbGlkZXItY29udGFpbmVyXCIgI3RyYWNrPlxuICA8ZGl2XG4gICAgW3RhYmluZGV4XT1cIl9kaXNhYmxlZCgpID8gLTEgOiAwXCJcbiAgICBjZGtEcmFnXG4gICAgW2Nka0RyYWdEaXNhYmxlZF09XCJfZGlzYWJsZWQoKVwiXG4gICAgW2Nka0RyYWdGcmVlRHJhZ1Bvc2l0aW9uXT1cIl9wb3NpdGlvbigpXCJcbiAgICAoY2RrRHJhZ01vdmVkKT1cIl9tb3ZlKCRldmVudC5wb2ludGVyUG9zaXRpb24ueClcIlxuICAgIGNsYXNzPVwieC1zbGlkZXItdGh1bWJcIlxuICAgIHh1aVRvb2x0aXBQb3NpdGlvbj1cInRvcFwiXG4gICAgW3h1aVRvb2x0aXBdPVwiX3Rvb2x0aXAoKVwiXG4gICAgW3h1aVRvb2x0aXBEaXNhYmxlZF09XCJ0b29sdGlwRGlzYWJsZWQoKVwiXG4gICAgI3Rvb2x0aXBSZWY9XCJ4dWlUb29sdGlwXCJcbiAgPjwvZGl2PlxuXG4gIEBmb3IgKG1hcmsgb2YgbWFya3MoKTsgdHJhY2sgbWFyay52YWx1ZSkge1xuICAgIDxkaXZcbiAgICAgIFtzdHlsZS5sZWZ0LiVdPVwiX2dldFBlcmNlbnRhZ2UobWFyay52YWx1ZSlcIlxuICAgICAgY2xhc3M9XCJ4LXNsaWRlci1tYXJrXCJcbiAgICAgIFtjbGFzc109XCJtYXJrLmNvbG9yID8gJ3gtc2xpZGVyLW1hcmstJyArIG1hcmsuY29sb3IgOiAnJ1wiXG4gICAgPlxuICAgICAgPGRpdiBjbGFzcz1cIngtc2xpZGVyLW1hcmstbGFiZWxcIj57eyBtYXJrLmxhYmVsIH19PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwieC1zbGlkZXItbWFyay1kYXNoXCI+PC9kaXY+XG4gICAgPC9kaXY+XG4gIH1cbjwvZGl2PlxuIl19