ng-toggle-button
Version:
Angular toggle button switch
304 lines • 41.4 kB
JavaScript
import { Component, Input, forwardRef, Output, EventEmitter } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { CommonModule } from '@angular/common';
import * as i0 from "@angular/core";
import * as i1 from "./ng-toggle.config";
import * as i2 from "@angular/common";
const DEFAULT_COLOR_CHECKED = '#0099CC';
const DEFAULT_COLOR_UNCHECKED = '#e0e0e0';
const DEFAULT_LABEL_CHECKED = '';
const DEFAULT_LABEL_UNCHECKED = '';
const DEFAULT_SWITCH_COLOR = '#fff';
const DISABLED_COLOR = '#dbdbdb';
const DISABLED_BUTTON_COLOR = 'silver';
let nextUniqueId = 0;
export class NgToggleComponent {
constructor(config, _elementRef) {
this.config = config;
this._elementRef = _elementRef;
this.value = this.config.value || true;
this.name = this.config.name || '';
this.disabled = this.config.disabled || false;
this.height = this.config.height || 25;
this.width = this.config.width || 45;
this.margin = this.config.margin || 2;
this.fontSize = this.config.fontSize || undefined;
this.speed = this.config.speed || 300;
this.color = this.config.color;
this.switchColor = this.config.switchColor;
this.labels = this.config.labels || true;
this.fontColor = this.config.fontColor || undefined;
this.values = this.config.values || { checked: true, unchecked: false };
this.textAlign = this.config.textAlign || {
checked: 'left',
unchecked: 'right',
};
this.id = '';
this.ariaLabel = null;
this.ariaLabelledby = null;
this.cssColors = false;
this.change = new EventEmitter();
this.valueChange = new EventEmitter();
this.onChange = (_) => { };
this.onTouch = () => { };
this._uniqueId = 'ng-toggle-' + (++nextUniqueId);
this.id = this.id || this._uniqueId;
this.ariaLabel = this.ariaLabel || this.name || this.id;
}
ngOnInit() {
this.setToogle();
}
onInput(value) {
this.value = value;
this.onTouch();
this.onChange(this.value);
}
writeValue(value) {
this.value = value;
this.setToogle();
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouch = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
setToogle() {
const value = this.value;
let index = Object.values(this.values).findIndex(el => el == value);
if (index > -1)
this.toggled = Object.keys(this.values)[index] == 'checked' ? true : false;
}
ngOnChanges(changes) {
for (const propName in changes) {
const chng = changes[propName];
if (propName == 'value')
this.writeValue(chng.currentValue);
}
}
get coreStyle() {
return {
width: px(this.width),
height: px(this.height),
transition: `all ${this.speed}ms`,
backgroundColor: this.cssColors
? null
: (this.disabled ? this.colorDisabled : this.colorCurrent),
borderRadius: px(Math.round(this.height / 2))
};
}
get buttonRadius() {
const radius = this.height - this.margin * 2;
return radius > 0 ? radius : 0;
}
get distance() {
return px(this.width - this.height + this.margin);
}
get buttonStyle() {
const transition = `all ${this.speed}ms`;
const margin = px(this.margin);
const transform = this.toggled
? translate(this.distance, margin)
: translate(margin, margin);
let background = this.switchColor
? this.switchColorCurrent
: null;
background = this.disabled ? this.switchColorDisabled : background;
return {
width: px(this.buttonRadius),
height: px(this.buttonRadius),
transition,
transform,
background,
};
}
get labelStyle() {
return {
lineHeight: px(this.height),
fontSize: this.fontSize ? px(this.fontSize) : null,
color: this.fontColor ? this.fontColorCurrent : null,
width: px(this.width - this.buttonRadius - this.margin),
};
}
get labelLeftStyle() {
return {
...this.labelStyle,
textAlign: this.textAlign.checked || this.textAlign
};
}
get labelRightStyle() {
return {
...this.labelStyle,
textAlign: this.textAlign.unchecked || this.textAlign
};
}
get colorChecked() {
let { color } = this;
if (!isObject(color)) {
return color || DEFAULT_COLOR_CHECKED;
}
return get(color, 'checked', DEFAULT_COLOR_CHECKED);
}
get colorUnchecked() {
return get(this.color, 'unchecked', DEFAULT_COLOR_UNCHECKED);
}
get colorDisabled() {
return get(this.color, 'disabled', DISABLED_COLOR);
}
get colorCurrent() {
return this.toggled
? this.colorChecked
: this.colorUnchecked;
}
get labelChecked() {
return get(this.labels, 'checked', DEFAULT_LABEL_CHECKED);
}
get labelUnchecked() {
return get(this.labels, 'unchecked', DEFAULT_LABEL_UNCHECKED);
}
get switchColorChecked() {
return get(this.switchColor, 'checked', DEFAULT_SWITCH_COLOR);
}
get switchColorUnchecked() {
return get(this.switchColor, 'unchecked', DEFAULT_SWITCH_COLOR);
}
get switchColorDisabled() {
return get(this.switchColor, 'disabled', DISABLED_BUTTON_COLOR);
}
get switchColorCurrent() {
if (!isObject(this.switchColor)) {
return this.switchColor || DEFAULT_SWITCH_COLOR;
}
return this.toggled
? this.switchColorChecked
: this.switchColorUnchecked;
}
get fontColorChecked() {
return get(this.fontColor, 'checked', DEFAULT_SWITCH_COLOR);
}
get fontColorUnchecked() {
return get(this.fontColor, 'unchecked', DEFAULT_SWITCH_COLOR);
}
get fontColorDisabled() {
return get(this.fontColor, 'disabled', DEFAULT_SWITCH_COLOR);
}
get fontColorCurrent() {
if (!isObject(this.fontColor)) {
return this.fontColor || DEFAULT_SWITCH_COLOR;
}
if (this.disabled) {
return this.fontColorDisabled;
}
return this.toggled
? this.fontColorChecked
: this.fontColorUnchecked;
}
get label() {
if (this.ariaLabelledby) {
return this.ariaLabelledby;
}
return this.ariaLabel ? null : `${this._uniqueId}-label`;
}
toggle(event) {
const toggled = !this.toggled;
this.toggled = toggled;
this.value = this.getValue(toggled);
this.onTouch();
this.onChange(this.value);
this.valueChange.emit(this.value);
}
getValue(key) {
return key === true ? this.values['checked'] : this.values['unchecked'];
}
onFocus(event) {
if (!this.focused && event.relatedTarget) {
this.focused = true;
}
}
onFocusout(event) {
if (!this._elementRef.nativeElement.contains(event.relatedTarget)) {
this.focused = false;
this.onTouch();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgToggleComponent, deps: [{ token: i1.NgToggleConfig }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: NgToggleComponent, isStandalone: true, selector: "ng-toggle", inputs: { value: "value", name: "name", disabled: "disabled", height: "height", width: "width", margin: "margin", fontSize: "fontSize", speed: "speed", color: "color", switchColor: "switchColor", labels: "labels", fontColor: "fontColor", values: "values", textAlign: "textAlign", id: "id", ariaLabel: ["aria-label", "ariaLabel"], ariaLabelledby: ["aria-labelledby", "ariaLabelledby"], ariaDescribedby: ["aria-describedby", "ariaDescribedby"] }, outputs: { change: "change", valueChange: "valueChange" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgToggleComponent),
multi: true
}
], usesOnChanges: true, ngImport: i0, template: "<label class=\"ng-toggle-switch\" [for]=\"id\" [attr.id]=\"label\">\n <input\n type=\"checkbox\"\n class=\"ng-toggle-switch-input\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n (change)=\"toggle($event)\"\n (focusin)=\"onFocus($event)\"\n (focusout)=\"onFocusout($event)\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"label\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-checked]=\"toggled\"\n role=\"checkbox\"\n >\n <div\n class=\"ng-toggle-switch-core\"\n [ngClass]=\"{'ng-toggle-focused': focused}\"\n [ngStyle]=\"coreStyle\"\n >\n <div\n class=\"ng-toggle-switch-button\"\n [ngStyle]=\"buttonStyle\">\n </div>\n </div>\n <ng-container *ngIf=\"labels\">\n <span\n class=\"ng-toggle-switch-label ng-toggle-left\"\n [ngStyle]=\"labelLeftStyle\"\n *ngIf=\"toggled\"\n >\n {{labelChecked}}\n </span>\n <span\n class=\"ng-toggle-switch-label ng-toggle-right\"\n [ngStyle]=\"labelRightStyle\"\n *ngIf=\"!toggled\"\n >\n {{labelUnchecked}}\n </span>\n </ng-container>\n</label>", styles: ["label{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}.ng-toggle-switch{display:inline-block;position:relative;vertical-align:middle;-webkit-user-select:none;user-select:none;font-size:10px;cursor:pointer}.ng-toggle-switch .ng-toggle-switch-input{opacity:0;position:absolute;width:1px;height:1px}.ng-toggle-switch .ng-toggle-switch-label{position:absolute;top:0;font-weight:600;color:#fff;z-index:1;padding:0 10px;box-sizing:border-box}.ng-toggle-switch .ng-toggle-switch-label.ng-toggle-left{left:0}.ng-toggle-switch .ng-toggle-switch-label.ng-toggle-right{right:0}.ng-toggle-switch .ng-toggle-switch-core{display:block;position:relative;box-sizing:border-box;outline:0;margin:0;transition:border-color .3s,background-color .3s;-webkit-user-select:none;user-select:none}.ng-toggle-switch .ng-toggle-switch-core .ng-toggle-switch-button{display:block;position:absolute;overflow:hidden;top:0;left:0;border-radius:100%;background-color:#fff;z-index:2}.ng-toggle-switch.disabled{pointer-events:none;opacity:.6}.ng-toggle-focused{box-shadow:0 0 4px 3px #999}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgToggleComponent, decorators: [{
type: Component,
args: [{ selector: 'ng-toggle', standalone: true, imports: [CommonModule], providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgToggleComponent),
multi: true
}
], template: "<label class=\"ng-toggle-switch\" [for]=\"id\" [attr.id]=\"label\">\n <input\n type=\"checkbox\"\n class=\"ng-toggle-switch-input\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n (change)=\"toggle($event)\"\n (focusin)=\"onFocus($event)\"\n (focusout)=\"onFocusout($event)\"\n [attr.id]=\"id\"\n [attr.name]=\"name\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"label\"\n [attr.aria-describedby]=\"ariaDescribedby\"\n [attr.aria-checked]=\"toggled\"\n role=\"checkbox\"\n >\n <div\n class=\"ng-toggle-switch-core\"\n [ngClass]=\"{'ng-toggle-focused': focused}\"\n [ngStyle]=\"coreStyle\"\n >\n <div\n class=\"ng-toggle-switch-button\"\n [ngStyle]=\"buttonStyle\">\n </div>\n </div>\n <ng-container *ngIf=\"labels\">\n <span\n class=\"ng-toggle-switch-label ng-toggle-left\"\n [ngStyle]=\"labelLeftStyle\"\n *ngIf=\"toggled\"\n >\n {{labelChecked}}\n </span>\n <span\n class=\"ng-toggle-switch-label ng-toggle-right\"\n [ngStyle]=\"labelRightStyle\"\n *ngIf=\"!toggled\"\n >\n {{labelUnchecked}}\n </span>\n </ng-container>\n</label>", styles: ["label{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}.ng-toggle-switch{display:inline-block;position:relative;vertical-align:middle;-webkit-user-select:none;user-select:none;font-size:10px;cursor:pointer}.ng-toggle-switch .ng-toggle-switch-input{opacity:0;position:absolute;width:1px;height:1px}.ng-toggle-switch .ng-toggle-switch-label{position:absolute;top:0;font-weight:600;color:#fff;z-index:1;padding:0 10px;box-sizing:border-box}.ng-toggle-switch .ng-toggle-switch-label.ng-toggle-left{left:0}.ng-toggle-switch .ng-toggle-switch-label.ng-toggle-right{right:0}.ng-toggle-switch .ng-toggle-switch-core{display:block;position:relative;box-sizing:border-box;outline:0;margin:0;transition:border-color .3s,background-color .3s;-webkit-user-select:none;user-select:none}.ng-toggle-switch .ng-toggle-switch-core .ng-toggle-switch-button{display:block;position:absolute;overflow:hidden;top:0;left:0;border-radius:100%;background-color:#fff;z-index:2}.ng-toggle-switch.disabled{pointer-events:none;opacity:.6}.ng-toggle-focused{box-shadow:0 0 4px 3px #999}\n"] }]
}], ctorParameters: () => [{ type: i1.NgToggleConfig }, { type: i0.ElementRef }], propDecorators: { value: [{
type: Input
}], name: [{
type: Input
}], disabled: [{
type: Input
}], height: [{
type: Input
}], width: [{
type: Input
}], margin: [{
type: Input
}], fontSize: [{
type: Input
}], speed: [{
type: Input
}], color: [{
type: Input
}], switchColor: [{
type: Input
}], labels: [{
type: Input
}], fontColor: [{
type: Input
}], values: [{
type: Input
}], textAlign: [{
type: Input
}], id: [{
type: Input
}], ariaLabel: [{
type: Input,
args: ['aria-label']
}], ariaLabelledby: [{
type: Input,
args: ['aria-labelledby']
}], ariaDescribedby: [{
type: Input,
args: ['aria-describedby']
}], change: [{
type: Output
}], valueChange: [{
type: Output
}] } });
export const isObject = (value) => {
return typeof value === 'object';
};
export const has = (object, key) => {
return isObject(object) && object.hasOwnProperty(key);
};
export const get = (object, key, defaultValue) => {
return has(object, key) ? object[key] : defaultValue;
};
export const px = value => {
return `${value}px`;
};
export const translate = (x, y) => {
return `translate(${x}, ${y})`;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctdG9nZ2xlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXRvZ2dsZS9zcmMvbGliL25nLXRvZ2dsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy10b2dnbGUvc3JjL2xpYi9uZy10b2dnbGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQXdDLE1BQU0sZUFBZSxDQUFDO0FBQ2pJLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7QUFFL0MsTUFBTSxxQkFBcUIsR0FBRyxTQUFTLENBQUE7QUFDdkMsTUFBTSx1QkFBdUIsR0FBRyxTQUFTLENBQUE7QUFDekMsTUFBTSxxQkFBcUIsR0FBRyxFQUFFLENBQUE7QUFDaEMsTUFBTSx1QkFBdUIsR0FBRyxFQUFFLENBQUE7QUFDbEMsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUE7QUFDbkMsTUFBTSxjQUFjLEdBQUcsU0FBUyxDQUFBO0FBQ2hDLE1BQU0scUJBQXFCLEdBQUcsUUFBUSxDQUFBO0FBQ3RDLElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQztBQWdCckIsTUFBTSxPQUFPLGlCQUFpQjtJQWdDNUIsWUFDVSxNQUFzQixFQUN0QixXQUFvQztRQURwQyxXQUFNLEdBQU4sTUFBTSxDQUFnQjtRQUN0QixnQkFBVyxHQUFYLFdBQVcsQ0FBeUI7UUFoQ3JDLFVBQUssR0FBUSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUE7UUFDdEMsU0FBSSxHQUFXLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQTtRQUNyQyxhQUFRLEdBQVksSUFB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LENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsWUFBWSxFQUFFLEVBQUU7SUFDL0MsT0FBTyxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQTtBQUN0RCxDQUFDLENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSxFQUFFLEdBQUcsS0FBSyxDQUFDLEVBQUU7SUFDeEIsT0FBTyxHQUFHLEtBQUssSUFBSSxDQUFBO0FBQ3JCLENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUNoQyxPQUFPLGFBQWEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFBO0FBQ2hDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBJbnB1dCwgZm9yd2FyZFJlZiwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcywgRWxlbWVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTmdUb2dnbGVDb25maWcgfSBmcm9tICcuL25nLXRvZ2dsZS5jb25maWcnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuY29uc3QgREVGQVVMVF9DT0xPUl9DSEVDS0VEID0gJyMwMDk5Q0MnXG5jb25zdCBERUZBVUxUX0NPTE9SX1VOQ0hFQ0tFRCA9ICcjZTBlMGUwJ1xuY29uc3QgREVGQVVMVF9MQUJFTF9DSEVDS0VEID0gJydcbmNvbnN0IERFRkFVTFRfTEFCRUxfVU5DSEVDS0VEID0gJydcbmNvbnN0IERFRkFVTFRfU1dJVENIX0NPTE9SID0gJyNmZmYnXG5jb25zdCBESVNBQkxFRF9DT0xPUiA9ICcjZGJkYmRiJ1xuY29uc3QgRElTQUJMRURfQlVUVE9OX0NPTE9SID0gJ3NpbHZlcidcbmxldCBuZXh0VW5pcXVlSWQgPSAwO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZy10b2dnbGUnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgdGVtcGxhdGVVcmw6ICcuL25nLXRvZ2dsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL25nLXRvZ2dsZS5jb21wb25lbnQuc2NzcyddLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5nVG9nZ2xlQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIE5nVG9nZ2xlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoKSB2YWx1ZTogYW55ID0gdGhpcy5jb25maWcudmFsdWUgfHwgdHJ1ZVxuICBASW5wdXQoKSBuYW1lOiBzdHJpbmcgPSB0aGlzLmNvbmZpZy5uYW1lIHx8ICcnXG4gIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuID0gdGhpcy5jb25maWcuZGlzYWJsZWQgfHwgZmFsc2VcblxuICBASW5wdXQoKSBoZWlnaHQ6IG51bWJlciA9IHRoaXMuY29uZmlnLmhlaWdodCB8fCAyNVxuICBASW5wdXQoKSB3aWR0aDogbnVtYmVyID0gdGhpcy5jb25maWcud2lkdGggfHwgNDVcbiAgQElucHV0KCkgbWFyZ2luOiBudW1iZXIgPSB0aGlzLmNvbmZpZy5tYXJnaW4gfHwgMlxuICBASW5wdXQoKSBmb250U2l6ZTogbnVtYmVyID0gdGhpcy5jb25maWcuZm9udFNpemUgfHwgdW5kZWZpbmVkXG4gIEBJbnB1dCgpIHNwZWVkOiBudW1iZXIgPSB0aGlzLmNvbmZpZy5zcGVlZCB8fCAzMDBcbiAgQElucHV0KCkgY29sb3I6IHN0cmluZyB8IHRvZ2dsZUNvbmZpZyA9IHRoaXMuY29uZmlnLmNvbG9yXG4gIEBJbnB1dCgpIHN3aXRjaENvbG9yOiBzdHJpbmcgfCB0b2dnbGVDb25maWcgPSB0aGlzLmNvbmZpZy5zd2l0Y2hDb2xvclxuICBASW5wdXQoKSBsYWJlbHM6IGJvb2xlYW4gfCB0b2dnbGVDb25maWcgPSB0aGlzLmNvbmZpZy5sYWJlbHMgfHwgdHJ1ZVxuICBASW5wdXQoKSBmb250Q29sb3I6IHN0cmluZyB8IHRvZ2dsZUNvbmZpZyA9IHRoaXMuY29uZmlnLmZvbnRDb2xvciB8fCB1bmRlZmluZWRcbiAgQElucHV0KCkgdmFsdWVzOiB2YWx1ZUNvbmZpZyA9IHRoaXMuY29uZmlnLnZhbHVlcyB8fCB7Y2hlY2tlZDogdHJ1ZSwgdW5jaGVja2VkOiBmYWxzZX1cbiAgQElucHV0KCkgdGV4dEFsaWduOiBzdHJpbmcgfCB0b2dnbGVDb25maWcgPSB0aGlzLmNvbmZpZy50ZXh0QWxpZ24gfHwge1xuICAgIGNoZWNrZWQ6ICdsZWZ0JyxcbiAgICB1bmNoZWNrZWQ6ICdyaWdodCcsXG4gIH1cbiAgQElucHV0KCkgaWQ6IHN0cmluZyA9ICcnXG4gIEBJbnB1dCgnYXJpYS1sYWJlbCcpIGFyaWFMYWJlbDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgnYXJpYS1sYWJlbGxlZGJ5JykgYXJpYUxhYmVsbGVkYnk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoJ2FyaWEtZGVzY3JpYmVkYnknKSBhcmlhRGVzY3JpYmVkYnk6IHN0cmluZztcbiAgY3NzQ29sb3JzOiBib29sZWFuID0gZmFsc2VcblxuICBAT3V0cHV0KCkgY2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpXG4gIEBPdXRwdXQoKSB2YWx1ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuICB0b2dnbGVkOiBib29sZWFuXG4gIGZvY3VzZWQ6IGJvb2xlYW47XG4gIHByaXZhdGUgX3VuaXF1ZUlkOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjb25maWc6IE5nVG9nZ2xlQ29uZmlnLFxuICAgIHByaXZhdGUgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICApIHtcbiAgICB0aGlzLl91bmlxdWVJZCA9ICduZy10b2dnbGUtJysoKytuZXh0VW5pcXVlSWQpO1xuICAgIHRoaXMuaWQgPSB0aGlzLmlkIHx8IHRoaXMuX3VuaXF1ZUlkXG4gICAgdGhpcy5hcmlhTGFiZWwgPSB0aGlzLmFyaWFMYWJlbCB8fCB0aGlzLm5hbWUgfHwgdGhpcy5pZFxuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5zZXRUb29nbGUoKVxuICB9XG5cbiAgb25DaGFuZ2UgPSAoXzphbnkpID0+IHsgfVxuICBvblRvdWNoID0gKCkgPT4geyB9XG5cbiAgb25JbnB1dCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLm9uVG91Y2goKTtcbiAgICB0aGlzLm9uQ2hhbmdlKHRoaXMudmFsdWUpO1xuICB9XG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMuc2V0VG9vZ2xlKCk7XG4gIH1cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICB9XG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2ggPSBmbjtcbiAgfVxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgfVxuXG4gIHNldFRvb2dsZSgpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMudmFsdWVcbiAgICBsZXQgaW5kZXggPSBPYmplY3QudmFsdWVzKHRoaXMudmFsdWVzKS5maW5kSW5kZXgoZWwgPT4gZWwgPT0gdmFsdWUpXG4gICAgaWYoaW5kZXggPiAtMSlcbiAgICAgIHRoaXMudG9nZ2xlZCA9IE9iamVjdC5rZXlzKHRoaXMudmFsdWVzKVtpbmRleF0gPT0gJ2NoZWNrZWQnID8gdHJ1ZSA6IGZhbHNlXG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgZm9yIChjb25zdCBwcm9wTmFtZSBpbiBjaGFuZ2VzKSB7XG4gICAgICBjb25zdCBjaG5nID0gY2hhbmdlc1twcm9wTmFtZV07XG4gICAgICBpZihwcm9wTmFtZSA9PSAndmFsdWUnKVxuICAgICAgICB0aGlzLndyaXRlVmFsdWUoY2huZy5jdXJyZW50VmFsdWUpXG4gICAgfVxuICB9XG5cbiAgZ2V0IGNvcmVTdHlsZSAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdpZHRoOiBweCh0aGlzLndpZHRoKSxcbiAgICAgIGhlaWdodDogcHgodGhpcy5oZWlnaHQpLFxuICAgICAgdHJhbnNpdGlvbjogYGFsbCAke3RoaXMuc3BlZWR9bXNgLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLmNzc0NvbG9yc1xuICAgICAgICA/IG51bGxcbiAgICAgICAgOiAodGhpcy5kaXNhYmxlZCA/IHRoaXMuY29sb3JEaXNhYmxlZCA6IHRoaXMuY29sb3JDdXJyZW50KSxcbiAgICAgIGJvcmRlclJhZGl1czogcHgoTWF0aC5yb3VuZCh0aGlzLmhlaWdodCAvIDIpKVxuICAgIH1cbiAgfVxuICBnZXQgYnV0dG9uUmFkaXVzICgpIHtcbiAgICBjb25zdCByYWRpdXMgPSB0aGlzLmhlaWdodCAtIHRoaXMubWFyZ2luICogMjtcbiAgICByZXR1cm4gcmFkaXVzID4gMCA/IHJhZGl1cyA6IDA7XG4gIH1cbiAgZ2V0IGRpc3RhbmNlICgpIHtcbiAgICByZXR1cm4gcHgodGhpcy53aWR0aCAtIHRoaXMuaGVpZ2h0ICsgdGhpcy5tYXJnaW4pXG4gIH1cbiAgZ2V0IGJ1dHRvblN0eWxlICgpIHtcbiAgICBjb25zdCB0cmFuc2l0aW9uID0gYGFsbCAke3RoaXMuc3BlZWR9bXNgXG4gICAgY29uc3QgbWFyZ2luID0gcHgodGhpcy5tYXJnaW4pXG4gICAgY29uc3QgdHJhbnNmb3JtID0gdGhpcy50b2dnbGVkXG4gICAgICA/IHRyYW5zbGF0ZSh0aGlzLmRpc3RhbmNlLCBtYXJnaW4pXG4gICAgICA6IHRyYW5zbGF0ZShtYXJnaW4sIG1hcmdpbilcbiAgICBsZXQgYmFja2dyb3VuZCA9IHRoaXMuc3dpdGNoQ29sb3JcbiAgICAgID8gdGhpcy5zd2l0Y2hDb2xvckN1cnJlbnRcbiAgICAgIDogbnVsbFxuICAgIGJhY2tncm91bmQgPSB0aGlzLmRpc2FibGVkID8gdGhpcy5zd2l0Y2hDb2xvckRpc2FibGVkIDogYmFja2dyb3VuZFxuICAgIHJldHVybiB7XG4gICAgICB3aWR0aDogcHgodGhpcy5idXR0b25SYWRpdXMpLFxuICAgICAgaGVpZ2h0OiBweCh0aGlzLmJ1dHRvblJhZGl1cyksXG4gICAgICB0cmFuc2l0aW9uLFxuICAgICAgdHJhbnNmb3JtLFxuICAgICAgYmFja2dyb3VuZCxcbiAgICB9XG4gIH1cbiAgZ2V0IGxhYmVsU3R5bGUgKCkge1xuICAgIHJldHVybiB7XG4gICAgICBsaW5lSGVpZ2h0OiBweCh0aGlzLmhlaWdodCksXG4gICAgICBmb250U2l6ZTogdGhpcy5mb250U2l6ZSA/IHB4KHRoaXMuZm9udFNpemUpIDogbnVsbCxcbiAgICAgIGNvbG9yOiB0aGlzLmZvbnRDb2xvciA/IHRoaXMuZm9udENvbG9yQ3VycmVudCA6IG51bGwsXG4gICAgICB3aWR0aDogcHgodGhpcy53aWR0aCAtIHRoaXMuYnV0dG9uUmFkaXVzIC0gdGhpcy5tYXJnaW4pLFxuICAgIH1cbiAgfVxuICBnZXQgbGFiZWxMZWZ0U3R5bGUgKCkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmxhYmVsU3R5bGUsXG4gICAgICB0ZXh0QWxpZ246ICh0aGlzLnRleHRBbGlnbiBhcyB0b2dnbGVDb25maWcpLmNoZWNrZWQgfHwgdGhpcy50ZXh0QWxpZ25cbiAgICB9XG4gIH1cbiAgZ2V0IGxhYmVsUmlnaHRTdHlsZSAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMubGFiZWxTdHlsZSxcbiAgICAgIHRleHRBbGlnbjogKHRoaXMudGV4dEFsaWduIGFzIHRvZ2dsZUNvbmZpZykudW5jaGVja2VkIHx8IHRoaXMudGV4dEFsaWduXG4gICAgfVxuICB9XG5cbiAgZ2V0IGNvbG9yQ2hlY2tlZCAoKSB7XG4gICAgbGV0IHsgY29sb3IgfSA9IHRoaXNcbiAgICBpZiAoIWlzT2JqZWN0KGNvbG9yKSkge1xuICAgICAgcmV0dXJuIGNvbG9yIHx8IERFRkFVTFRfQ09MT1JfQ0hFQ0tFRFxuICAgIH1cbiAgICByZXR1cm4gZ2V0KGNvbG9yLCAnY2hlY2tlZCcsIERFRkFVTFRfQ09MT1JfQ0hFQ0tFRClcbiAgfVxuICBnZXQgY29sb3JVbmNoZWNrZWQgKCkge1xuICAgIHJldHVybiBnZXQodGhpcy5jb2xvciwgJ3VuY2hlY2tlZCcsIERFRkFVTFRfQ09MT1JfVU5DSEVDS0VEKVxuICB9XG4gIGdldCBjb2xvckRpc2FibGVkICgpIHtcbiAgICByZXR1cm4gZ2V0KHRoaXMuY29sb3IsICdkaXNhYmxlZCcsIERJU0FCTEVEX0NPTE9SKVxuICB9XG4gIGdldCBjb2xvckN1cnJlbnQgKCkge1xuICAgIHJldHVybiB0aGlzLnRvZ2dsZWRcbiAgICAgID8gdGhpcy5jb2xvckNoZWNrZWRcbiAgICAgIDogdGhpcy5jb2xvclVuY2hlY2tlZFxuICB9XG4gIGdldCBsYWJlbENoZWNrZWQgKCkge1xuICAgIHJldHVybiBnZXQodGhpcy5sYWJlbHMsICdjaGVja2VkJywgREVGQVVMVF9MQUJFTF9DSEVDS0VEKVxuICB9XG4gIGdldCBsYWJlbFVuY2hlY2tlZCAoKSB7XG4gICAgcmV0dXJuIGdldCh0aGlzLmxhYmVscywgJ3VuY2hlY2tlZCcsIERFRkFVTFRfTEFCRUxfVU5DSEVDS0VEKVxuICB9XG4gIGdldCBzd2l0Y2hDb2xvckNoZWNrZWQgKCkge1xuICAgIHJldHVybiBnZXQodGhpcy5zd2l0Y2hDb2xvciwgJ2NoZWNrZWQnLCBERUZBVUxUX1NXSVRDSF9DT0xPUilcbiAgfVxuICBnZXQgc3dpdGNoQ29sb3JVbmNoZWNrZWQgKCkge1xuICAgIHJldHVybiBnZXQodGhpcy5zd2l0Y2hDb2xvciwgJ3VuY2hlY2tlZCcsIERFRkFVTFRfU1dJVENIX0NPTE9SKVxuICB9XG4gIGdldCBzd2l0Y2hDb2xvckRpc2FibGVkKCl7XG4gICAgcmV0dXJuIGdldCh0aGlzLnN3aXRjaENvbG9yLCAnZGlzYWJsZWQnLCBESVNBQkxFRF9CVVRUT05fQ09MT1IpXG4gIH1cblxuICBnZXQgc3dpdGNoQ29sb3JDdXJyZW50ICgpIHtcbiAgICBpZiAoIWlzT2JqZWN0KHRoaXMuc3dpdGNoQ29sb3IpKSB7XG4gICAgICByZXR1cm4gdGhpcy5zd2l0Y2hDb2xvciB8fCBERUZBVUxUX1NXSVRDSF9DT0xPUlxuICAgIH1cbiAgICByZXR1cm4gdGhpcy50b2dnbGVkXG4gICAgICA/IHRoaXMuc3dpdGNoQ29sb3JDaGVja2VkXG4gICAgICA6IHRoaXMuc3dpdGNoQ29sb3JVbmNoZWNrZWRcbiAgfVxuXG4gIGdldCBmb250Q29sb3JDaGVja2VkICgpIHtcbiAgICByZXR1cm4gZ2V0KHRoaXMuZm9udENvbG9yLCAnY2hlY2tlZCcsIERFRkFVTFRfU1dJVENIX0NPTE9SKVxuICB9XG4gIGdldCBmb250Q29sb3JVbmNoZWNrZWQgKCkge1xuICAgIHJldHVybiBnZXQodGhpcy5mb250Q29sb3IsICd1bmNoZWNrZWQnLCBERUZBVUxUX1NXSVRDSF9DT0xPUilcbiAgfVxuXG4gIGdldCBmb250Q29sb3JEaXNhYmxlZCgpe1xuICAgIHJldHVybiBnZXQodGhpcy5mb250Q29sb3IsICdkaXNhYmxlZCcsIERFRkFVTFRfU1dJVENIX0NPTE9SKVxuICB9XG4gIGdldCBmb250Q29sb3JDdXJyZW50ICgpIHtcbiAgICBpZiAoIWlzT2JqZWN0KHRoaXMuZm9udENvbG9yKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZm9udENvbG9yIHx8IERFRkFVTFRfU1dJVENIX0NPTE9SXG4gICAgfVxuICAgIGlmKHRoaXMuZGlzYWJsZWQpe1xuICAgICAgcmV0dXJuIHRoaXMuZm9udENvbG9yRGlzYWJsZWRcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudG9nZ2xlZFxuICAgICAgPyB0aGlzLmZvbnRDb2xvckNoZWNrZWRcbiAgICAgIDogdGhpcy5mb250Q29sb3JVbmNoZWNrZWRcbiAgfVxuXG4gIGdldCBsYWJlbCgpIHtcbiAgICBpZiAodGhpcy5hcmlhTGFiZWxsZWRieSkge1xuICAgICAgcmV0dXJuIHRoaXMuYXJpYUxhYmVsbGVkYnk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFyaWFMYWJlbCA/IG51bGwgOiBgJHt0aGlzLl91bmlxdWVJZH0tbGFiZWxgO1xuICB9XG5cbiAgdG9nZ2xlKGV2ZW50KSB7XG4gICAgY29uc3QgdG9nZ2xlZCA9ICF0aGlzLnRvZ2dsZWQ7XG4gICAgdGhpcy50b2dnbGVkID0gdG9nZ2xlZDtcblxuICAgIHRoaXMudmFsdWUgPSB0aGlzLmdldFZhbHVlKHRvZ2dsZWQpXG4gICAgdGhpcy5vblRvdWNoKCk7XG4gICAgdGhpcy5vbkNoYW5nZSh0aGlzLnZhbHVlKTtcbiAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy52YWx1ZSlcbiAgfVxuXG4gIGdldFZhbHVlKGtleTogYm9vbGVhbikge1xuICAgIHJldHVybiBrZXkgPT09IHRydWUgPyB0aGlzLnZhbHVlc1snY2hlY2tlZCddIDogdGhpcy52YWx1ZXNbJ3VuY2hlY2tlZCddXG4gIH1cblxuICBvbkZvY3VzKGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgaWYgKCF0aGlzLmZvY3VzZWQgJiYgZXZlbnQucmVsYXRlZFRhcmdldCkge1xuICAgICAgdGhpcy5mb2N1c2VkID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBvbkZvY3Vzb3V0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgaWYgKCF0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQucmVsYXRlZFRhcmdldCBhcyBFbGVtZW50KSkge1xuICAgICAgdGhpcy5mb2N1c2VkID0gZmFsc2U7XG4gICAgICB0aGlzLm9uVG91Y2goKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGlzT2JqZWN0ID0gKHZhbHVlKSA9PiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnXG59XG5cbmV4cG9ydCBjb25zdCBoYXMgPSAob2JqZWN0LCBrZXkpID0+IHtcbiAgcmV0dXJuIGlzT2JqZWN0KG9iamVjdCkgJiYgb2JqZWN0Lmhhc093blByb3BlcnR5KGtleSlcbn1cblxuZXhwb3J0IGNvbnN0IGdldCA9IChvYmplY3QsIGtleSwgZGVmYXVsdFZhbHVlKSA9PiB7XG4gIHJldHVybiBoYXMob2JqZWN0LCBrZXkpID8gb2JqZWN0W2tleV0gOiBkZWZhdWx0VmFsdWVcbn1cblxuZXhwb3J0IGNvbnN0IHB4ID0gdmFsdWUgPT4ge1xuICByZXR1cm4gYCR7dmFsdWV9cHhgXG59XG5cbmV4cG9ydCBjb25zdCB0cmFuc2xhdGUgPSAoeCwgeSkgPT4ge1xuICByZXR1cm4gYHRyYW5zbGF0ZSgke3h9LCAke3l9KWBcbn1cblxuZXhwb3J0IHR5cGUgdG9nZ2xlQ29uZmlnID0ge1xuICBjaGVja2VkOiBzdHJpbmc7XG4gIHVuY2hlY2tlZDogc3RyaW5nO1xuICBkaXNhYmxlZD86IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIHZhbHVlQ29uZmlnID0ge1xuICBjaGVja2VkOiBhbnk7XG4gIHVuY2hlY2tlZDogYW55O1xufTtcbiIsIjxsYWJlbCBjbGFzcz1cIm5nLXRvZ2dsZS1zd2l0Y2hcIiBbZm9yXT1cImlkXCIgW2F0dHIuaWRdPVwibGFiZWxcIj5cbiAgPGlucHV0XG4gICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICBjbGFzcz1cIm5nLXRvZ2dsZS1zd2l0Y2gtaW5wdXRcIlxuICAgIFtjaGVja2VkXT1cInZhbHVlXCJcbiAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgIChjaGFuZ2UpPVwidG9nZ2xlKCRldmVudClcIlxuICAgIChmb2N1c2luKT1cIm9uRm9jdXMoJGV2ZW50KVwiXG4gICAgKGZvY3Vzb3V0KT1cIm9uRm9jdXNvdXQoJGV2ZW50KVwiXG4gICAgW2F0dHIuaWRdPVwiaWRcIlxuICAgIFthdHRyLm5hbWVdPVwibmFtZVwiXG4gICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTGFiZWxcIlxuICAgIFthdHRyLmFyaWEtbGFiZWxsZWRieV09XCJsYWJlbFwiXG4gICAgW2F0dHIuYXJpYS1kZXNjcmliZWRieV09XCJhcmlhRGVzY3JpYmVkYnlcIlxuICAgIFthdHRyLmFyaWEtY2hlY2tlZF09XCJ0b2dnbGVkXCJcbiAgICByb2xlPVwiY2hlY2tib3hcIlxuICA+XG4gIDxkaXZcbiAgICBjbGFzcz1cIm5nLXRvZ2dsZS1zd2l0Y2gtY29yZVwiXG4gICAgW25nQ2xhc3NdPVwieyduZy10b2dnbGUtZm9jdXNlZCc6IGZvY3VzZWR9XCJcbiAgICBbbmdTdHlsZV09XCJjb3JlU3R5bGVcIlxuICA+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJuZy10b2dnbGUtc3dpdGNoLWJ1dHRvblwiXG4gICAgICBbbmdTdHlsZV09XCJidXR0b25TdHlsZVwiPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxhYmVsc1wiPlxuICAgIDxzcGFuXG4gICAgICBjbGFzcz1cIm5nLXRvZ2dsZS1zd2l0Y2gtbGFiZWwgbmctdG9nZ2xlLWxlZnRcIlxuICAgICAgW25nU3R5bGVdPVwibGFiZWxMZWZ0U3R5bGVcIlxuICAgICAgKm5nSWY9XCJ0b2dnbGVkXCJcbiAgICA+XG4gICAgICB7e2xhYmVsQ2hlY2tlZH19XG4gICAgPC9zcGFuPlxuICAgIDxzcGFuXG4gICAgICBjbGFzcz1cIm5nLXRvZ2dsZS1zd2l0Y2gtbGFiZWwgbmctdG9nZ2xlLXJpZ2h0XCJcbiAgICAgIFtuZ1N0eWxlXT1cImxhYmVsUmlnaHRTdHlsZVwiXG4gICAgICAqbmdJZj1cIiF0b2dnbGVkXCJcbiAgICA+XG4gICAgICB7e2xhYmVsVW5jaGVja2VkfX1cbiAgICA8L3NwYW4+XG4gIDwvbmctY29udGFpbmVyPlxuPC9sYWJlbD4iXX0=