UNPKG

ngx-colours

Version:

A beautiful color picker for angular that let you choose from a color palette, using sliders (Hue, Lightness, Alpha sliders) or through text input(hex, rgba, hsla)

361 lines 71.1 kB
import { Component, ViewChild, HostListener, HostBinding, } from "@angular/core";
import { trigger, transition, query, style, stagger, animate, keyframes, } from "@angular/animations";
import { ColorFormats } from "../../enums/formats";
import { defaultColors } from "../../helpers/default-colors";
import { formats } from "../../helpers/formats";
import { Hsva } from "../../clases/formats";
import { NgxColor } from "../../clases/color";
import * as i0 from "@angular/core";
import * as i1 from "../../services/converter.service";
import * as i2 from "../color-picker/color-picker.component";
import * as i3 from "@angular/common";
export class PanelComponent {
    constructor(service, cdr) {
        this.service = service;
        this.cdr = cdr;
        this.color = "#000000";
        this.previewColor = "#000000";
        this.hsva = new Hsva(0, 1, 1, 1);
        this.colorsAnimationEffect = "popup";
        this.palette = defaultColors;
        this.variants = [];
        this.colorFormats = formats;
        this.format = ColorFormats.HEX;
        this.canChangeFormat = true;
        this.menu = 1;
        this.showEyeDropper = false;
        this.hideColorPicker = false;
        this.hideTextInput = false;
        this.colorPickerControls = "default";
    }
    click(event) {
        if (this.isOutside(event)) {
            this.emitClose("cancel");
        }
    }
    onScroll() {
        this.onScreenMovement();
    }
    onResize() {
        this.onScreenMovement();
    }
    ngOnInit() {
        this.setPosition();
        this.hsva = this.service.stringToHsva(this.color);
        this.indexSeleccionado = this.findIndexSelectedColor(this.palette);
    }
    ngAfterViewInit() {
        this.setPositionY();
    }
    onScreenMovement() {
        this.setPosition();
        this.setPositionY();
        if (!this.panelRef.nativeElement.style.transition) {
            this.panelRef.nativeElement.style.transition = "transform 0.5s ease-out";
        }
    }
    findIndexSelectedColor(colors) {
        let resultIndex = undefined;
        if (this.color) {
            for (let i = 0; i < colors.length; i++) {
                const color = colors[i];
                if (typeof color == "string") {
                    if (this.service.stringToFormat(this.color, ColorFormats.HEX) ==
                        this.service.stringToFormat(color, ColorFormats.HEX)) {
                        resultIndex = i;
                    }
                }
                else {
                    if (this.findIndexSelectedColor(color.variants) != undefined) {
                        resultIndex = i;
                    }
                }
            }
        }
        return resultIndex;
    }
    iniciate(triggerInstance, triggerElementRef, color, palette, animation, format, hideTextInput, hideColorPicker, acceptLabel, cancelLabel, colorPickerControls, position) {
        // @ts-ignore
        this.showEyeDropper = !!window.EyeDropper;
        this.colorPickerControls = colorPickerControls;
        this.triggerInstance = triggerInstance;
        this.TriggerBBox = triggerElementRef;
        this.color = color;
        this.hideColorPicker = hideColorPicker;
        this.hideTextInput = hideTextInput;
        this.acceptLabel = acceptLabel;
        this.cancelLabel = cancelLabel;
        if (format) {
            if (formats.includes(format)) {
                this.format = formats.indexOf(format.toLowerCase());
                this.canChangeFormat = false;
                if (this.service.getFormatByString(this.color) != format.toLowerCase()) {
                    this.setColor(this.service.stringToHsva(this.color));
                }
            }
            else {
                console.error("Format provided is invalid, using HEX");
                this.format = ColorFormats.HEX;
            }
        }
        else {
            this.format = formats.indexOf(this.service.getFormatByString(this.color));
        }
        this.previewColor = this.color;
        this.palette = palette ?? defaultColors;
        this.colorsAnimationEffect = animation;
        if (position == "top") {
            let TriggerBBox = this.TriggerBBox.nativeElement.getBoundingClientRect();
            this.positionString =
                "transform: translateY(calc( -100% - " + TriggerBBox.height + "px ))";
        }
    }
    setPosition() {
        if (this.TriggerBBox) {
            var viewportOffset = this.TriggerBBox.nativeElement.getBoundingClientRect();
            this.top = viewportOffset.top + viewportOffset.height;
            this.left =
                viewportOffset.left + 250 > window.innerWidth
                    ? viewportOffset.right - 250
                    : viewportOffset.left;
        }
    }
    setPositionY() {
        var triggerBBox = this.TriggerBBox.nativeElement.getBoundingClientRect();
        var panelBBox = this.panelRef.nativeElement.getBoundingClientRect();
        var panelHeight = panelBBox.height;
        //Check for space above the trigger
        if (0 > panelBBox.top - 5) {
            this.positionString = "";
        }
        //Check for space below the trigger
        if (panelHeight > window.innerHeight - (panelBBox.top - 5)) {
            //there is no space, move panel over the trigger
            this.positionString =
                "transform: translateY(calc( -100% - " + triggerBBox.height + "px ));";
        }
        this.cdr.detectChanges();
    }
    hasVariant(color) {
        if (!this.previewColor) {
            return false;
        }
        return (typeof color != "string" &&
            color.variants.some((v) => v.toUpperCase() == this.previewColor.toUpperCase()));
    }
    isSelected(color) {
        if (!this.previewColor) {
            return false;
        }
        return (typeof color == "string" &&
            color.toUpperCase() == this.previewColor.toUpperCase());
    }
    getBackgroundColor(color) {
        if (typeof color == "string") {
            return { background: color };
        }
        else {
            return { background: color?.preview };
        }
    }
    onAlphaChange(event) {
        this.palette = this.ChangeAlphaOnPalette(event, this.palette);
    }
    ChangeAlphaOnPalette(alpha, colors) {
        var result = [];
        for (let i = 0; i < colors.length; i++) {
            const color = colors[i];
            if (typeof color == "string") {
                let newColor = this.service.stringToHsva(color);
                newColor.onAlphaChange(alpha);
                result.push(this.service.toFormat(newColor, this.format));
            }
            else {
                let newColor = new NgxColor();
                let newColorPreview = this.service.stringToHsva(color.preview);
                newColorPreview.onAlphaChange(alpha);
                newColor.preview = this.service.toFormat(newColorPreview, this.format);
                newColor.variants = this.ChangeAlphaOnPalette(alpha, color.variants);
                result.push(newColor);
            }
        }
        return result;
    }
    /**
     * Change color from default colors
     * @param string color
     */
    changeColor(color) {
        this.setColor(this.service.stringToHsva(color));
        // this.triggerInstance.onChange();
        this.emitClose("accept");
    }
    onChangeColorPicker(event) {
        this.temporalColor = event;
        this.color = this.service.toFormat(event, this.format);
        // this.setColor(event);
        this.triggerInstance.sliderChange(this.service.toFormat(event, this.format));
    }
    changeColorManual(color) {
        this.previewColor = color;
        this.color = color;
        this.hsva = this.service.stringToHsva(color);
        this.triggerInstance.setColor(this.color);
        // this.triggerInstance.onChange();
    }
    openEyeDropper() {
        // @ts-ignore
        if (!window.EyeDropper) {
            return;
        }
        // @ts-ignore
        const eyeDropper = new EyeDropper();
        eyeDropper.open().then(result => {
            const color = result.sRGBHex;
            this.changeColor(color);
        }).catch(e => { });
    }
    setColor(value) {
        this.hsva = value;
        this.color = this.service.toFormat(value, this.format);
        this.setPreviewColor(value);
        this.triggerInstance.setColor(this.color);
    }
    setPreviewColor(value) {
        this.previewColor = this.service.hsvaToRgba(value).toString();
    }
    onChange() {
        // this.triggerInstance.onChange();
    }
    onColorClick(color) {
        if (typeof color == "string") {
            this.changeColor(color);
        }
        else {
            this.variants = color.variants;
            this.menu = 2;
        }
    }
    addColor() {
        this.menu = 3;
        this.backupColor = this.color;
        this.color = "#FF0000";
        this.temporalColor = this.service.stringToHsva(this.color);
    }
    nextFormat() {
        if (this.canChangeFormat) {
            this.format = (this.format + 1) % this.colorFormats.length;
            this.setColor(this.hsva);
        }
    }
    emitClose(status) {
        if (this.menu == 3) {
            if (status == "cancel") {
            }
            else if (status == "accept") {
                this.setColor(this.temporalColor);
            }
        }
        this.triggerInstance.close();
    }
    onClickBack() {
        if (this.menu == 3) {
            this.color = this.backupColor;
            this.hsva = this.service.stringToHsva(this.color);
        }
        this.indexSeleccionado = this.findIndexSelectedColor(this.palette);
        this.menu = 1;
    }
    isOutside(event) {
        return event.target.classList.contains("ngx-colors-overlay");
    }
}
PanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: PanelComponent, deps: [{ token: i1.ConverterService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
PanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.0", type: PanelComponent, selector: "ngx-colors-panel", host: { listeners: { "document:mousedown": "click($event)", "document:scroll": "onScroll()", "window:resize": "onResize()" }, properties: { "style.top.px": "this.top", "style.left.px": "this.left" } }, viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["dialog"], descendants: true }], ngImport: i0, template: "<div class=\"opened\" [style]=\"positionString\" #dialog>\n  <ng-container *ngIf=\"menu == 1\">\n    <div class=\"colors\" [@colorsAnimation]=\"colorsAnimationEffect\">\n\n      <div *ngIf=\"showEyeDropper\" class=\"circle button eyedropper\" (click)=\"openEyeDropper()\">\n        <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"#222222\"><path d=\"M17.542 13.147l-7.455-6.667 1.334-1.49c.822.736 2.087.666 2.822-.159l3.503-3.831c.593-.663 1.414-1 2.238-1 1.666 0 3.016 1.358 3.016 2.996 0 .723-.271 1.435-.78 2.005l-3.503 3.83c-.735.824-.666 2.087.158 2.825l-1.333 1.491zm-4.314-1.175l-7.791 8.65c-.314.352-1.322.323-1.853.557.172-.554.048-1.538.362-1.89l7.791-8.651-1.491-1.333-7.9 8.794c-1.277 1.423-.171 2.261-1.149 4.052-.135.244-.197.48-.197.698 0 .661.54 1.151 1.141 1.151.241 0 .492-.079.724-.256 1.733-1.332 2.644-.184 3.954-1.647l7.9-8.792-1.491-1.333z\"/></svg>\n      </div>\n\n      <ng-container *ngFor=\"let color of palette; let i = index\">\n        <div class=\"circle wrapper color\">\n          <div\n            (click)=\"onColorClick(color)\"\n            class=\"circle color circle-border\"\n            [ngStyle]=\"getBackgroundColor(color)\"\n          >\n            <div *ngIf=\"i == this.indexSeleccionado\" class=\"selected\"></div>\n          </div>\n        </div>\n      </ng-container>\n      <div\n        style=\"background: rgb(245 245 245); position: relative\"\n        (click)=\"addColor()\"\n        *ngIf=\"!hideColorPicker && this.colorPickerControls != 'only-alpha'\"\n        class=\"circle button\"\n      >\n        <div\n          *ngIf=\"!this.indexSeleccionado\"\n          style=\"\n            position: absolute;\n            height: 7px;\n            width: 7px;\n            border: 1px solid rgba(0, 0, 0, 0.03);\n            border-radius: 100%;\n            top: 0;\n            right: 0;\n          \"\n          [ngStyle]=\"getBackgroundColor(color)\"\n        ></div>\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          height=\"24px\"\n          viewBox=\"0 0 24 24\"\n          width=\"24px\"\n          fill=\"#222222\"\n        >\n          <path d=\"M24 24H0V0h24v24z\" fill=\"none\" opacity=\".87\" />\n          <path d=\"M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6-1.41-1.41z\" />\n        </svg>\n        <!-- <div class=\"add\">\n          <icons icon=\"add\"></icons>\n        </div> -->\n      </div>\n      <color-picker\n        *ngIf=\"!hideColorPicker && this.colorPickerControls == 'only-alpha'\"\n        [controls]=\"colorPickerControls\"\n        [color]=\"hsva\"\n        (colorChange)=\"onChangeColorPicker($event)\"\n        (onAlphaChange)=\"onAlphaChange($event)\"\n      ></color-picker>\n    </div>\n  </ng-container>\n  <ng-container *ngIf=\"menu == 2\">\n    <div class=\"colors\" [@colorsAnimation]=\"colorsAnimationEffect\">\n      <div class=\"circle wrapper\">\n        <div (click)=\"onClickBack()\" class=\"add\">\n          <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            width=\"24\"\n            height=\"24\"\n            viewBox=\"0 0 24 24\"\n          >\n            <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n            <path\n              d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\"\n            />\n          </svg>\n        </div>\n      </div>\n\n      <ng-container *ngFor=\"let variant of variants\">\n        <div class=\"circle wrapper color\">\n          <div\n            (click)=\"changeColor(variant)\"\n            class=\"circle circle-border\"\n            [ngStyle]=\"{ background: variant }\"\n          >\n            <div *ngIf=\"isSelected(variant)\" class=\"selected\"></div>\n          </div>\n        </div>\n      </ng-container>\n    </div>\n  </ng-container>\n  <ng-container *ngIf=\"menu == 3\">\n    <div class=\"nav-wrapper\">\n      <div\n        (click)=\"onClickBack()\"\n        class=\"round-button button\"\n        style=\"float: left\"\n      >\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          width=\"24\"\n          height=\"24\"\n          viewBox=\"0 0 24 24\"\n        >\n          <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n          <path\n            d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\"\n          />\n        </svg>\n      </div>\n      <button (click)=\"emitClose('cancel')\" style=\"float: right\">\n        {{ cancelLabel }}\n      </button>\n      <button (click)=\"emitClose('accept')\" style=\"float: right\">\n        {{ acceptLabel }}\n      </button>\n    </div>\n    <div class=\"color-picker-wrapper\">\n      <!-- <span [(colorPicker)]=\"color\"></span> -->\n      <color-picker\n        [controls]=\"colorPickerControls\"\n        [color]=\"hsva\"\n        (sliderChange)=\"onChangeColorPicker($event)\"\n      ></color-picker>\n    </div>\n  </ng-container>\n  <div class=\"manual-input-wrapper\" *ngIf=\"!hideTextInput\">\n    <p (click)=\"nextFormat()\">{{ colorFormats[format] }}</p>\n    <div class=\"g-input\">\n      <input\n        placeholder=\"#FFFFFF\"\n        type=\"text\"\n        [value]=\"color\"\n        [style.font-size.px]=\"color && color.length > 23 ? 9 : 10\"\n        [style.letter-spacing.px]=\"color && color.length > 16 ? 0 : 1.5\"\n        (keyup)=\"changeColorManual(paintInput.value)\"\n        (keydown.enter)=\"emitClose('accept')\"\n        #paintInput\n      />\n    </div>\n  </div>\n</div>\n", styles: [":host{position:fixed;z-index:2001}.hidden{display:none}.button{display:flex;align-items:center;justify-content:center}.top{transform:translateY(-100%)}.opened{box-sizing:border-box;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f;background:#fff;max-width:250px;border-radius:5px;position:absolute}.opened button{border:none;font-family:inherit;font-size:12px;background-color:unset;-webkit-user-select:none;user-select:none;padding:10px;letter-spacing:1px;color:#222;border-radius:3px;line-height:20px}.opened button:hover,.opened .button:hover{background-color:#0000000d;transition:opacity .2s cubic-bezier(.35,0,.25,1),background-color .2s cubic-bezier(.35,0,.25,1);transition-property:opacity,background-color;transition-duration:.2s,.2s;transition-timing-function:cubic-bezier(.35,0,.25,1),cubic-bezier(.35,0,.25,1);transition-delay:0s,0s}.opened button:focus{outline:none}.opened .colors{display:grid;grid-template-columns:repeat(5,auto);grid-row-gap:6px;row-gap:6px;grid-column-gap:8px;column-gap:8px;margin:15px}.opened .colors .circle{height:34px;width:34px;box-sizing:border-box;border-radius:100%;cursor:pointer}.opened .colors .circle .add{font-size:20px;line-height:45px;text-align:center}.opened .colors .circle .selected{border:2px solid white;border-radius:100%;height:28px;width:28px;box-sizing:border-box;margin:2px}.opened .colors .circle.wrapper.color{background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.opened .colors .circle-border{border:1px solid rgba(0,0,0,.03)}.opened .colors .eyedropper{background:whitesmoke}.opened .color-picker-wrapper{margin:5px 15px}.opened .nav-wrapper{overflow:hidden;margin:5px}.opened .nav-wrapper .round-button{padding:5px 0;width:40px;height:40px;box-sizing:border-box;border-radius:100%;text-align:center;line-height:45px}.opened .manual-input-wrapper{display:flex;margin:15px;font-family:sans-serif}.opened .manual-input-wrapper p{margin:0;text-align:center;font-size:10px;letter-spacing:1.5px;text-transform:uppercase;line-height:48px;width:145px;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}.opened .manual-input-wrapper .g-input{border:1px solid #e8ebed;height:45px;border-radius:5px;width:100%}.opened .manual-input-wrapper .g-input input{font-size:9px;border:none;width:100%;text-transform:uppercase;outline:none;text-align:center;letter-spacing:1px;color:#595b65;height:100%;border-radius:5px;margin:0;padding:0}\n"], components: [{ type: i2.ColorPickerComponent, selector: "color-picker", inputs: ["color", "controls"], outputs: ["sliderChange", "onAlphaChange"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], animations: [
        trigger("colorsAnimation", [
            transition("void => slide-in", [
                // Initially all colors are hidden
                query(":enter", style({ opacity: 0 }), { optional: true }),
                //slide-in animation
                query(":enter", stagger("10ms", [
                    animate(".3s ease-in", keyframes([
                        style({ opacity: 0, transform: "translatex(-50%)", offset: 0 }),
                        style({
                            opacity: 0.5,
                            transform: "translatex(-10px) scale(1.1)",
                            offset: 0.3,
                        }),
                        style({ opacity: 1, transform: "translatex(0)", offset: 1 }),
                    ])),
                ]), { optional: true }),
            ]),
            //popup animation
            transition("void => popup", [
                query(":enter", style({ opacity: 0, transform: "scale(0)" }), {
                    optional: true,
                }),
                query(":enter", stagger("10ms", [
                    animate("500ms ease-out", keyframes([
                        style({ opacity: 0.5, transform: "scale(.5)", offset: 0.3 }),
                        style({ opacity: 1, transform: "scale(1.1)", offset: 0.8 }),
                        style({ opacity: 1, transform: "scale(1)", offset: 1 }),
                    ])),
                ]), { optional: true }),
            ]),
        ]),
    ] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: PanelComponent, decorators: [{
            type: Component,
            args: [{ selector: "ngx-colors-panel", animations: [
                        trigger("colorsAnimation", [
                            transition("void => slide-in", [
                                // Initially all colors are hidden
                                query(":enter", style({ opacity: 0 }), { optional: true }),
                                //slide-in animation
                                query(":enter", stagger("10ms", [
                                    animate(".3s ease-in", keyframes([
                                        style({ opacity: 0, transform: "translatex(-50%)", offset: 0 }),
                                        style({
                                            opacity: 0.5,
                                            transform: "translatex(-10px) scale(1.1)",
                                            offset: 0.3,
                                        }),
                                        style({ opacity: 1, transform: "translatex(0)", offset: 1 }),
                                    ])),
                                ]), { optional: true }),
                            ]),
                            //popup animation
                            transition("void => popup", [
                                query(":enter", style({ opacity: 0, transform: "scale(0)" }), {
                                    optional: true,
                                }),
                                query(":enter", stagger("10ms", [
                                    animate("500ms ease-out", keyframes([
                                        style({ opacity: 0.5, transform: "scale(.5)", offset: 0.3 }),
                                        style({ opacity: 1, transform: "scale(1.1)", offset: 0.8 }),
                                        style({ opacity: 1, transform: "scale(1)", offset: 1 }),
                                    ])),
                                ]), { optional: true }),
                            ]),
                        ]),
                    ], template: "<div class=\"opened\" [style]=\"positionString\" #dialog>\n  <ng-container *ngIf=\"menu == 1\">\n    <div class=\"colors\" [@colorsAnimation]=\"colorsAnimationEffect\">\n\n      <div *ngIf=\"showEyeDropper\" class=\"circle button eyedropper\" (click)=\"openEyeDropper()\">\n        <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"#222222\"><path d=\"M17.542 13.147l-7.455-6.667 1.334-1.49c.822.736 2.087.666 2.822-.159l3.503-3.831c.593-.663 1.414-1 2.238-1 1.666 0 3.016 1.358 3.016 2.996 0 .723-.271 1.435-.78 2.005l-3.503 3.83c-.735.824-.666 2.087.158 2.825l-1.333 1.491zm-4.314-1.175l-7.791 8.65c-.314.352-1.322.323-1.853.557.172-.554.048-1.538.362-1.89l7.791-8.651-1.491-1.333-7.9 8.794c-1.277 1.423-.171 2.261-1.149 4.052-.135.244-.197.48-.197.698 0 .661.54 1.151 1.141 1.151.241 0 .492-.079.724-.256 1.733-1.332 2.644-.184 3.954-1.647l7.9-8.792-1.491-1.333z\"/></svg>\n      </div>\n\n      <ng-container *ngFor=\"let color of palette; let i = index\">\n        <div class=\"circle wrapper color\">\n          <div\n            (click)=\"onColorClick(color)\"\n            class=\"circle color circle-border\"\n            [ngStyle]=\"getBackgroundColor(color)\"\n          >\n            <div *ngIf=\"i == this.indexSeleccionado\" class=\"selected\"></div>\n          </div>\n        </div>\n      </ng-container>\n      <div\n        style=\"background: rgb(245 245 245); position: relative\"\n        (click)=\"addColor()\"\n        *ngIf=\"!hideColorPicker && this.colorPickerControls != 'only-alpha'\"\n        class=\"circle button\"\n      >\n        <div\n          *ngIf=\"!this.indexSeleccionado\"\n          style=\"\n            position: absolute;\n            height: 7px;\n            width: 7px;\n            border: 1px solid rgba(0, 0, 0, 0.03);\n            border-radius: 100%;\n            top: 0;\n            right: 0;\n          \"\n          [ngStyle]=\"getBackgroundColor(color)\"\n        ></div>\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          height=\"24px\"\n          viewBox=\"0 0 24 24\"\n          width=\"24px\"\n          fill=\"#222222\"\n        >\n          <path d=\"M24 24H0V0h24v24z\" fill=\"none\" opacity=\".87\" />\n          <path d=\"M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6-1.41-1.41z\" />\n        </svg>\n        <!-- <div class=\"add\">\n          <icons icon=\"add\"></icons>\n        </div> -->\n      </div>\n      <color-picker\n        *ngIf=\"!hideColorPicker && this.colorPickerControls == 'only-alpha'\"\n        [controls]=\"colorPickerControls\"\n        [color]=\"hsva\"\n        (colorChange)=\"onChangeColorPicker($event)\"\n        (onAlphaChange)=\"onAlphaChange($event)\"\n      ></color-picker>\n    </div>\n  </ng-container>\n  <ng-container *ngIf=\"menu == 2\">\n    <div class=\"colors\" [@colorsAnimation]=\"colorsAnimationEffect\">\n      <div class=\"circle wrapper\">\n        <div (click)=\"onClickBack()\" class=\"add\">\n          <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            width=\"24\"\n            height=\"24\"\n            viewBox=\"0 0 24 24\"\n          >\n            <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n            <path\n              d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\"\n            />\n          </svg>\n        </div>\n      </div>\n\n      <ng-container *ngFor=\"let variant of variants\">\n        <div class=\"circle wrapper color\">\n          <div\n            (click)=\"changeColor(variant)\"\n            class=\"circle circle-border\"\n            [ngStyle]=\"{ background: variant }\"\n          >\n            <div *ngIf=\"isSelected(variant)\" class=\"selected\"></div>\n          </div>\n        </div>\n      </ng-container>\n    </div>\n  </ng-container>\n  <ng-container *ngIf=\"menu == 3\">\n    <div class=\"nav-wrapper\">\n      <div\n        (click)=\"onClickBack()\"\n        class=\"round-button button\"\n        style=\"float: left\"\n      >\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          width=\"24\"\n          height=\"24\"\n          viewBox=\"0 0 24 24\"\n        >\n          <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n          <path\n            d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\"\n          />\n        </svg>\n      </div>\n      <button (click)=\"emitClose('cancel')\" style=\"float: right\">\n        {{ cancelLabel }}\n      </button>\n      <button (click)=\"emitClose('accept')\" style=\"float: right\">\n        {{ acceptLabel }}\n      </button>\n    </div>\n    <div class=\"color-picker-wrapper\">\n      <!-- <span [(colorPicker)]=\"color\"></span> -->\n      <color-picker\n        [controls]=\"colorPickerControls\"\n        [color]=\"hsva\"\n        (sliderChange)=\"onChangeColorPicker($event)\"\n      ></color-picker>\n    </div>\n  </ng-container>\n  <div class=\"manual-input-wrapper\" *ngIf=\"!hideTextInput\">\n    <p (click)=\"nextFormat()\">{{ colorFormats[format] }}</p>\n    <div class=\"g-input\">\n      <input\n        placeholder=\"#FFFFFF\"\n        type=\"text\"\n        [value]=\"color\"\n        [style.font-size.px]=\"color && color.length > 23 ? 9 : 10\"\n        [style.letter-spacing.px]=\"color && color.length > 16 ? 0 : 1.5\"\n        (keyup)=\"changeColorManual(paintInput.value)\"\n        (keydown.enter)=\"emitClose('accept')\"\n        #paintInput\n      />\n    </div>\n  </div>\n</div>\n", styles: [":host{position:fixed;z-index:2001}.hidden{display:none}.button{display:flex;align-items:center;justify-content:center}.top{transform:translateY(-100%)}.opened{box-sizing:border-box;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f;background:#fff;max-width:250px;border-radius:5px;position:absolute}.opened button{border:none;font-family:inherit;font-size:12px;background-color:unset;-webkit-user-select:none;user-select:none;padding:10px;letter-spacing:1px;color:#222;border-radius:3px;line-height:20px}.opened button:hover,.opened .button:hover{background-color:#0000000d;transition:opacity .2s cubic-bezier(.35,0,.25,1),background-color .2s cubic-bezier(.35,0,.25,1);transition-property:opacity,background-color;transition-duration:.2s,.2s;transition-timing-function:cubic-bezier(.35,0,.25,1),cubic-bezier(.35,0,.25,1);transition-delay:0s,0s}.opened button:focus{outline:none}.opened .colors{display:grid;grid-template-columns:repeat(5,auto);grid-row-gap:6px;row-gap:6px;grid-column-gap:8px;column-gap:8px;margin:15px}.opened .colors .circle{height:34px;width:34px;box-sizing:border-box;border-radius:100%;cursor:pointer}.opened .colors .circle .add{font-size:20px;line-height:45px;text-align:center}.opened .colors .circle .selected{border:2px solid white;border-radius:100%;height:28px;width:28px;box-sizing:border-box;margin:2px}.opened .colors .circle.wrapper.color{background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.opened .colors .circle-border{border:1px solid rgba(0,0,0,.03)}.opened .colors .eyedropper{background:whitesmoke}.opened .color-picker-wrapper{margin:5px 15px}.opened .nav-wrapper{overflow:hidden;margin:5px}.opened .nav-wrapper .round-button{padding:5px 0;width:40px;height:40px;box-sizing:border-box;border-radius:100%;text-align:center;line-height:45px}.opened .manual-input-wrapper{display:flex;margin:15px;font-family:sans-serif}.opened .manual-input-wrapper p{margin:0;text-align:center;font-size:10px;letter-spacing:1.5px;text-transform:uppercase;line-height:48px;width:145px;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}.opened .manual-input-wrapper .g-input{border:1px solid #e8ebed;height:45px;border-radius:5px;width:100%}.opened .manual-input-wrapper .g-input input{font-size:9px;border:none;width:100%;text-transform:uppercase;outline:none;text-align:center;letter-spacing:1px;color:#595b65;height:100%;border-radius:5px;margin:0;padding:0}\n"] }]
        }], ctorParameters: function () { return [{ type: i1.ConverterService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { click: [{
                type: HostListener,
                args: ["document:mousedown", ["$event"]]
            }], onScroll: [{
                type: HostListener,
                args: ["document:scroll"]
            }], onResize: [{
                type: HostListener,
                args: ["window:resize"]
            }], top: [{
                type: HostBinding,
                args: ["style.top.px"]
            }], left: [{
                type: HostBinding,
                args: ["style.left.px"]
            }], panelRef: [{
                type: ViewChild,
                args: ["dialog"]
            }] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFuZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNvbG9ycy9zcmMvbGliL2NvbXBvbmVudHMvcGFuZWwvcGFuZWwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNvbG9ycy9zcmMvbGliL2NvbXBvbmVudHMvcGFuZWwvcGFuZWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFNVCxTQUFTLEVBRVQsWUFBWSxFQUNaLFdBQVcsR0FDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsT0FBTyxFQUNQLFVBQVUsRUFDVixLQUFLLEVBQ0wsS0FBSyxFQUNMLE9BQU8sRUFDUCxPQUFPLEVBQ1AsU0FBUyxHQUNWLE1BQU0scUJBQXFCLENBQUM7QUFFN0IsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRW5ELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFaEQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7Ozs7QUFzRDlDLE1BQU0sT0FBTyxjQUFjO0lBb0J6QixZQUNTLE9BQXlCLEVBQ3hCLEdBQXNCO1FBRHZCLFlBQU8sR0FBUCxPQUFPLENBQWtCO1FBQ3hCLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBR3pCLFVBQUssR0FBRyxTQUFTLENBQUM7UUFDbEIsaUJBQVksR0FBVyxTQUFTLENBQUM7UUFDakMsU0FBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTVCLDBCQUFx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QUFRLENBQUM7Z0JBUTlDLFFBQVE7c0JBRFAsWUFBWTt1QkFBQyxpQkFBaUI7Z0JBSy9CLFFBQVE7c0JBRFAsWUFBWTt1QkFBQyxlQUFlO2dCQUtPLEdBQUc7c0JBQXRDLFdBQVc7dUJBQUMsY0FBYztnQkFDVSxJQUFJO3NCQUF4QyxXQUFXO3VCQUFDLGVBQWU7Z0JBQ1AsUUFBUTtzQkFBNUIsU0FBUzt1QkFBQyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBPbkluaXQsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIFZpZXdDaGlsZCxcbiAgRWxlbWVudFJlZixcbiAgSG9zdExpc3RlbmVyLFxuICBIb3N0QmluZGluZyxcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7XG4gIHRyaWdnZXIsXG4gIHRyYW5zaXRpb24sXG4gIHF1ZXJ5LFxuICBzdHlsZSxcbiAgc3RhZ2dlcixcbiAgYW5pbWF0ZSxcbiAga2V5ZnJhbWVzLFxufSBmcm9tIFwiQGFuZ3VsYXIvYW5pbWF0aW9uc1wiO1xuaW1wb3J0IHsgaXNEZXNjZW5kYW50T3JTYW1lIH0gZnJvbSBcIi4uLy4uL2hlbHBlcnMvaGVscGVyc1wiO1xuaW1wb3J0IHsgQ29sb3JGb3JtYXRzIH0gZnJvbSBcIi4uLy4uL2VudW1zL2Zvcm1hdHNcIjtcbmltcG9ydCB7IENvbnZlcnRlclNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vc2VydmljZXMvY29udmVydGVyLnNlcnZpY2VcIjtcbmltcG9ydCB7IGRlZmF1bHRDb2xvcnMgfSBmcm9tIFwiLi4vLi4vaGVscGVycy9kZWZhdWx0LWNvbG9yc1wiO1xuaW1wb3J0IHsgZm9ybWF0cyB9IGZyb20gXCIuLi8uLi9oZWxwZXJzL2Zvcm1hdHNcIjtcbmltcG9ydCB7IE5neENvbG9yc1RyaWdnZXJEaXJlY3RpdmUgfSBmcm9tIFwiLi4vLi4vZGlyZWN0aXZlcy9uZ3gtY29sb3JzLXRyaWdnZXIuZGlyZWN0aXZlXCI7XG5pbXBvcnQgeyBIc3ZhIH0gZnJvbSBcIi4uLy4uL2NsYXNlcy9mb3JtYXRzXCI7XG5pbXBvcnQgeyBOZ3hDb2xvciB9IGZyb20gXCIuLi8uLi9jbGFzZXMvY29sb3JcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcIm5neC1jb2xvcnMtcGFuZWxcIixcbiAgdGVtcGxhdGVVcmw6IFwiLi9wYW5lbC5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vcGFuZWwuY29tcG9uZW50LnNjc3NcIl0sXG4gIGFuaW1hdGlvbnM6IFtcbiAgICB0cmlnZ2VyKFwiY29sb3JzQW5pbWF0aW9uXCIsIFtcbiAgICAgIHRyYW5zaXRpb24oXCJ2b2lkID0+IHNsaWRlLWluXCIsIFtcbiAgICAgICAgLy8gSW5pdGlhbGx5IGFsbCBjb2xvcnMgYXJlIGhpZGRlblxuICAgICAgICBxdWVyeShcIjplbnRlclwiLCBzdHlsZSh7IG9wYWNpdHk6IDAgfSksIHsgb3B0aW9uYWw6IHRydWUgfSksXG4gICAgICAgIC8vc2xpZGUtaW4gYW5pbWF0aW9uXG4gICAgICAgIHF1ZXJ5KFxuICAgICAgICAgIFwiOmVudGVyXCIsXG4gICAgICAgICAgc3RhZ2dlcihcIjEwbXNcIiwgW1xuICAgICAgICAgICAgYW5pbWF0ZShcbiAgICAgICAgICAgICAgXCIuM3MgZWFzZS1pblwiLFxuICAgICAgICAgICAgICBrZXlmcmFtZXMoW1xuICAgICAgICAgICAgICAgIHN0eWxlKHsgb3BhY2l0eTogMCwgdHJhbnNmb3JtOiBcInRyYW5zbGF0ZXgoLTUwJSlcIiwgb2Zmc2V0OiAwIH0pLFxuICAgICAgICAgICAgICAgIHN0eWxlKHtcbiAgICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAuNSxcbiAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybTogXCJ0cmFuc2xhdGV4KC0xMHB4KSBzY2FsZSgxLjEpXCIsXG4gICAgICAgICAgICAgICAgICBvZmZzZXQ6IDAuMyxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBzdHlsZSh7IG9wYWNpdHk6IDEsIHRyYW5zZm9ybTogXCJ0cmFuc2xhdGV4KDApXCIsIG9mZnNldDogMSB9KSxcbiAgICAgICAgICAgICAgXSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgXSksXG4gICAgICAgICAgeyBvcHRpb25hbDogdHJ1ZSB9XG4gICAgICAgICksXG4gICAgICBdKSxcbiAgICAgIC8vcG9wdXAgYW5pbWF0aW9uXG4gICAgICB0cmFuc2l0aW9uKFwidm9pZCA9PiBwb3B1cFwiLCBbXG4gICAgICAgIHF1ZXJ5KFwiOmVudGVyXCIsIHN0eWxlKHsgb3BhY2l0eTogMCwgdHJhbnNmb3JtOiBcInNjYWxlKDApXCIgfSksIHtcbiAgICAgICAgICBvcHRpb25hbDogdHJ1ZSxcbiAgICAgICAgfSksXG4gICAgICAgIHF1ZXJ5KFxuICAgICAgICAgIFwiOmVudGVyXCIsXG4gICAgICAgICAgc3RhZ2dlcihcIjEwbXNcIiwgW1xuICAgICAgICAgICAgYW5pbWF0ZShcbiAgICAgICAgICAgICAgXCI1MDBtcyBlYXNlLW91dFwiLFxuICAgICAgICAgICAgICBrZXlmcmFtZXMoW1xuICAgICAgICAgICAgICAgIHN0eWxlKHsgb3BhY2l0eTogMC41LCB0cmFuc2Zvcm06IFwic2NhbGUoLjUpXCIsIG9mZnNldDogMC4zIH0pLFxuICAgICAgICAgICAgICAgIHN0eWxlKHsgb3BhY2l0eTogMSwgdHJhbnNmb3JtOiBcInNjYWxlKDEuMSlcIiwgb2Zmc2V0OiAwLjggfSksXG4gICAgICAgICAgICAgICAgc3R5bGUoeyBvcGFjaXR5OiAxLCB0cmFuc2Zvcm06IFwic2NhbGUoMSlcIiwgb2Zmc2V0OiAxIH0pLFxuICAgICAgICAgICAgICBdKVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICBdKSxcbiAgICAgICAgICB7IG9wdGlvbmFsOiB0cnVlIH1cbiAgICAgICAgKSxcbiAgICAgIF0pLFxuICAgIF0pLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBQYW5lbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBIb3N0TGlzdGVuZXIoXCJkb2N1bWVudDptb3VzZWRvd25cIiwgW1wiJGV2ZW50XCJdKVxuICBjbGljayhldmVudCkge1xuICAgIGlmICh0aGlzLmlzT3V0c2lkZShldmVudCkpIHtcbiAgICAgIHRoaXMuZW1pdENsb3NlKFwiY2FuY2VsXCIpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoXCJkb2N1bWVudDpzY3JvbGxcIilcbiAgb25TY3JvbGwoKSB7XG4gICAgdGhpcy5vblNjcmVlbk1vdmVtZW50KCk7XG4gIH1cbiAgQEhvc3RMaXN0ZW5lcihcIndpbmRvdzpyZXNpemVcIilcbiAgb25SZXNpemUoKSB7XG4gICAgdGhpcy5vblNjcmVlbk1vdmVtZW50KCk7XG4gIH1cblxuICBASG9zdEJpbmRpbmcoXCJzdHlsZS50b3AucHhcIikgcHVibGljIHRvcDogbnVtYmVyO1xuICBASG9zdEJpbmRpbmcoXCJzdHlsZS5sZWZ0LnB4XCIpIHB1YmxpYyBsZWZ0OiBudW1iZXI7XG4gIEBWaWV3Q2hpbGQoXCJkaWFsb2dcIikgcGFuZWxSZWY6IEVsZW1lbnRSZWY7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBzZXJ2aWNlOiBDb252ZXJ0ZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxuICApIHt9XG5cbiAgcHVibGljIGNvbG9yID0gXCIjMDAwMDAwXCI7XG4gIHB1YmxpYyBwcmV2aWV3Q29sb3I6IHN0cmluZyA9IFwiIzAwMDAwMFwiO1xuICBwdWJsaWMgaHN2YSA9IG5ldyBIc3ZhKDAsIDEsIDEsIDEpO1xuXG4gIHB1YmxpYyBjb2xvcnNBbmltYXRpb25FZmZlY3QgPSBcInBvcHVwXCI7XG5cbiAgcHVibGljIHBhbGV0dGUgPSBkZWZhdWx0Q29sb3JzO1xuICBwdWJsaWMgdmFyaWFudHMgPSBbXTtcblxuICBwdWJsaWMgY29sb3JGb3JtYXRzID0gZm9ybWF0cztcbiAgcHVibGljIGZvcm1hdDogQ29sb3JGb3JtYXRzID0gQ29sb3JGb3JtYXRzLkhFWDtcblxuICBwdWJsaWMgY2FuQ2hhbmdlRm9ybWF0OiBib29sZWFuID0gdHJ1ZTtcblxuICBwdWJsaWMgbWVudSA9IDE7XG5cbiAgcHVibGljIHNob3dFeWVEcm9wcGVyOiBib29sZWFuID0gZmFsc2U7XG4gIHB1YmxpYyBoaWRlQ29sb3JQaWNrZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGhpZGVUZXh0SW5wdXQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGFjY2VwdExhYmVsOiBzdHJpbmc7XG4gIHB1YmxpYyBjYW5jZWxMYWJlbDogc3RyaW5nO1xuICBwdWJsaWMgY29sb3JQaWNrZXJDb250cm9sczogXCJkZWZhdWx0XCIgfCBcIm9ubHktYWxwaGFcIiB8IFwibm8tYWxwaGFcIiA9IFwiZGVmYXVsdFwiO1xuICBwcml2YXRlIHRyaWdnZXJJbnN0YW5jZTogTmd4Q29sb3JzVHJpZ2dlckRpcmVjdGl2ZTtcbiAgcHJpdmF0ZSBUcmlnZ2VyQkJveDtcbiAgcHVibGljIGlzU2VsZWN0ZWRDb2xvckluUGFsZXR0ZTogYm9vbGVhbjtcbiAgcHVibGljIGluZGV4U2VsZWNjaW9uYWRvO1xuICBwdWJsaWMgcG9zaXRpb25TdHJpbmc7XG4gIHB1YmxpYyB0ZW1wb3JhbENvbG9yO1xuICBwdWJsaWMgYmFja3VwQ29sb3I7XG5cbiAgcHVibGljIG5nT25Jbml0KCkge1xuICAgIHRoaXMuc2V0UG9zaXRpb24oKTtcbiAgICB0aGlzLmhzdmEgPSB0aGlzLnNlcnZpY2Uuc3RyaW5nVG9Ic3ZhKHRoaXMuY29sb3IpO1xuICAgIHRoaXMuaW5kZXhTZWxlY2Npb25hZG8gPSB0aGlzLmZpbmRJbmRleFNlbGVjdGVkQ29sb3IodGhpcy5wYWxldHRlKTtcbiAgfVxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuc2V0UG9zaXRpb25ZKCk7XG4gIH1cblxuICBwcml2YXRlIG9uU2NyZWVuTW92ZW1lbnQoKSB7XG4gICAgdGhpcy5zZXRQb3NpdGlvbigpO1xuICAgIHRoaXMuc2V0UG9zaXRpb25ZKCk7XG4gICAgaWYgKCF0aGlzLnBhbmVsUmVmLm5hdGl2ZUVsZW1lbnQuc3R5bGUudHJhbnNpdGlvbikge1xuICAgICAgdGhpcy5wYW5lbFJlZi5uYXRpdmVFbGVtZW50LnN0eWxlLnRyYW5zaXRpb24gPSBcInRyYW5zZm9ybSAwLjVzIGVhc2Utb3V0XCI7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmaW5kSW5kZXhTZWxlY3RlZENvbG9yKGNvbG9ycyk6IG51bWJlciB7XG4gICAgbGV0IHJlc3VsdEluZGV4ID0gdW5kZWZpbmVkO1xuICAgIGlmICh0aGlzLmNvbG9yKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbG9ycy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjb2xvciA9IGNvbG9yc1tpXTtcbiAgICAgICAgaWYgKHR5cGVvZiBjb2xvciA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLnN0cmluZ1RvRm9ybWF0KHRoaXMuY29sb3IsIENvbG9yRm9ybWF0cy5IRVgpID09XG4gICAgICAgICAgICB0aGlzLnNlcnZpY2Uuc3RyaW5nVG9Gb3JtYXQoY29sb3IsIENvbG9yRm9ybWF0cy5IRVgpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXN1bHRJbmRleCA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLmZpbmRJbmRleFNlbGVjdGVkQ29sb3IoY29sb3IudmFyaWFudHMpICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmVzdWx0SW5kZXggPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0SW5kZXg7XG4gIH1cblxuICBwdWJsaWMgaW5pY2lhdGUoXG4gICAgdHJpZ2dlckluc3RhbmNlOiBOZ3hDb2xvcnNUcmlnZ2VyRGlyZWN0aXZlLFxuICAgIHRyaWdnZXJFbGVtZW50UmVmLFxuICAgIGNvbG9yLFxuICAgIHBhbGV0dGUsXG4gICAgYW5pbWF0aW9uLFxuICAgIGZvcm1hdDogc3RyaW5nLFxuICAgIGhpZGVUZXh0SW5wdXQ6IGJvb2xlYW4sXG4gICAgaGlkZUNvbG9yUGlja2VyOiBib29sZWFuLFxuICAgIGFjY2VwdExhYmVsOiBzdHJpbmcsXG4gICAgY2FuY2VsTGFiZWw6IHN0cmluZyxcbiAgICBjb2xvclBpY2tlckNvbnRyb2xzOiBcImRlZmF1bHRcIiB8IFwib25seS1hbHBoYVwiIHwgXCJuby1hbHBoYVwiLFxuICAgIHBvc2l0aW9uOiBcInRvcFwiIHwgXCJib3R0b21cIlxuICApIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdGhpcy5zaG93RXllRHJvcHBlciA9ICEhd2luZG93LkV5ZURyb3BwZXI7XG4gICAgdGhpcy5jb2xvclBpY2tlckNvbnRyb2xzID0gY29sb3JQaWNrZXJDb250cm9scztcbiAgICB0aGlzLnRyaWdnZXJJbnN0YW5jZSA9IHRyaWdnZXJJbnN0YW5jZTtcbiAgICB0aGlzLlRyaWdnZXJCQm94ID0gdHJpZ2dlckVsZW1lbnRSZWY7XG4gICAgdGhpcy5jb2xvciA9IGNvbG9yO1xuICAgIHRoaXMuaGlkZUNvbG9yUGlja2VyID0gaGlkZUNvbG9yUGlja2VyO1xuICAgIHRoaXMuaGlkZVRleHRJbnB1dCA9IGhpZGVUZXh0SW5wdXQ7XG4gICAgdGhpcy5hY2NlcHRMYWJlbCA9IGFjY2VwdExhYmVsO1xuICAgIHRoaXMuY2FuY2VsTGFiZWwgPSBjYW5jZWxMYWJlbDtcbiAgICBpZiAoZm9ybWF0KSB7XG4gICAgICBpZiAoZm9ybWF0cy5pbmNsdWRlcyhmb3JtYXQpKSB7XG4gICAgICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0cy5pbmRleE9mKGZvcm1hdC50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgdGhpcy5jYW5DaGFuZ2VGb3JtYXQgPSBmYWxzZTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuc2VydmljZS5nZXRGb3JtYXRCeVN0cmluZyh0aGlzLmNvbG9yKSAhPSBmb3JtYXQudG9Mb3dlckNhc2UoKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLnNldENvbG9yKHRoaXMuc2VydmljZS5zdHJpbmdUb0hzdmEodGhpcy5jb2xvcikpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiRm9ybWF0IHByb3ZpZGVkIGlzIGludmFsaWQsIHVzaW5nIEhFWFwiKTtcbiAgICAgICAgdGhpcy5mb3JtYXQgPSBDb2xvckZvcm1hdHMuSEVYO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdHMuaW5kZXhPZih0aGlzLnNlcnZpY2UuZ2V0Rm9ybWF0QnlTdHJpbmcodGhpcy5jb2xvcikpO1xuICAgIH1cblxuICAgIHRoaXMucHJldmlld0NvbG9yID0gdGhpcy5jb2xvcjtcbiAgICB0aGlzLnBhbGV0dGUgPSBwYWxldHRlID8/IGRlZmF1bHRDb2xvcnM7XG4gICAgdGhpcy5jb2xvcnNBbmltYXRpb25FZmZlY3QgPSBhbmltYXRpb247XG4gICAgaWYgKHBvc2l0aW9uID09IFwidG9wXCIpIHtcbiAgICAgIGxldCBUcmlnZ2VyQkJveCA9IHRoaXMuVHJpZ2dlckJCb3gubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHRoaXMucG9zaXRpb25TdHJpbmcgPVxuICAgICAgICBcInRyYW5zZm9ybTogdHJhbnNsYXRlWShjYWxjKCAtMTAwJSAtIFwiICsgVHJpZ2dlckJCb3guaGVpZ2h0ICsgXCJweCApKVwiO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXRQb3NpdGlvbigpIHtcbiAgICBpZiAodGhpcy5UcmlnZ2VyQkJveCkge1xuICAgICAgdmFyIHZpZXdwb3J0T2Zmc2V0ID1cbiAgICAgICAgdGhpcy5UcmlnZ2VyQkJveC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgdGhpcy50b3AgPSB2aWV3cG9ydE9mZnNldC50b3AgKyB2aWV3cG9ydE9mZnNldC5oZWlnaHQ7XG4gICAgICB0aGlzLmxlZnQgPVxuICAgICAgICB2aWV3cG9ydE9mZnNldC5sZWZ0ICsgMjUwID4gd2luZG93LmlubmVyV2lkdGhcbiAgICAgICAgICA/IHZpZXdwb3J0T2Zmc2V0LnJpZ2h0IC0gMjUwXG4gICAgICAgICAgOiB2aWV3cG9ydE9mZnNldC5sZWZ0O1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0UG9zaXRpb25ZKCkge1xuICAgIHZhciB0cmlnZ2VyQkJveCA9IHRoaXMuVHJpZ2dlckJCb3gubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB2YXIgcGFuZWxCQm94ID0gdGhpcy5wYW5lbFJlZi5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHZhciBwYW5lbEhlaWdodCA9IHBhbmVsQkJveC5oZWlnaHQ7XG5cbiAgICAvL0NoZWNrIGZvciBzcGFjZSBhYm92ZSB0aGUgdHJpZ2dlclxuICAgIGlmICgwID4gcGFuZWxCQm94LnRvcCAtIDUpIHtcbiAgICAgIHRoaXMucG9zaXRpb25TdHJpbmcgPSBcIlwiO1xuICAgIH1cbiAgICAvL0NoZWNrIGZvciBzcGFjZSBiZWxvdyB0aGUgdHJpZ2dlclxuICAgIGlmIChwYW5lbEhlaWdodCA+IHdpbmRvdy5pbm5lckhlaWdodCAtIChwYW5lbEJCb3gudG9wIC0gNSkpIHtcbiAgICAgIC8vdGhlcmUgaXMgbm8gc3BhY2UsIG1vdmUgcGFuZWwgb3ZlciB0aGUgdHJpZ2dlclxuICAgICAgdGhpcy5wb3NpdGlvblN0cmluZyA9XG4gICAgICAgIFwidHJhbnNmb3JtOiB0cmFuc2xhdGVZKGNhbGMoIC0xMDAlIC0gXCIgKyB0cmlnZ2VyQkJveC5oZWlnaHQgKyBcInB4ICkpO1wiO1xuICAgIH1cbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwdWJsaWMgaGFzVmFyaWFudChjb2xvcik6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5wcmV2aWV3Q29sb3IpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIHR5cGVvZiBjb2xvciAhPSBcInN0cmluZ1wiICYmXG4gICAgICBjb2xvci52YXJpYW50cy5zb21lKFxuICAgICAgICAodikgPT4gdi50b1VwcGVyQ2FzZSgpID09IHRoaXMucHJldmlld0NvbG9yLnRvVXBwZXJDYXNlKClcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGlzU2VsZWN0ZWQoY29sb3IpIHtcbiAgICBpZiAoIXRoaXMucHJldmlld0NvbG9yKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiAoXG4gICAgICB0eXBlb2YgY29sb3IgPT0gXCJzdHJpbmdcIiAmJlxuICAgICAgY29sb3IudG9VcHBlckNhc2UoKSA9PSB0aGlzLnByZXZpZXdDb2xvci50b1VwcGVyQ2FzZSgpXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRCYWNrZ3JvdW5kQ29sb3IoY29sb3IpIHtcbiAgICBpZiAodHlwZW9mIGNvbG9yID09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiB7IGJhY2tncm91bmQ6IGNvbG9yIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IGJhY2tncm91bmQ6IGNvbG9yPy5wcmV2aWV3IH07XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG9uQWxwaGFDaGFuZ2UoZXZlbnQpIHtcbiAgICB0aGlzLnBhbGV0dGUgPSB0aGlzLkNoYW5nZUFscGhhT25QYWxldHRlKGV2ZW50LCB0aGlzLnBhbGV0dGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBDaGFuZ2VBbHBoYU9uUGFsZXR0ZShcbiAgICBhbHBoYSxcbiAgICBjb2xvcnM6IEFycmF5PHN0cmluZyB8IE5neENvbG9yPlxuICApOiBBcnJheTxhbnk+IHtcbiAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2xvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGNvbG9yID0gY29sb3JzW2ldO1xuICAgICAgaWYgKHR5cGVvZiBjb2xvciA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGxldCBuZXdDb2xvciA9IHRoaXMuc2VydmljZS5zdHJpbmdUb0hzdmEoY29sb3IpO1xuICAgICAgICBuZXdDb2xvci5vbkFscGhhQ2hhbmdlKGFscGhhKTtcbiAgICAgICAgcmVzdWx0LnB1c2godGhpcy5zZXJ2aWNlLnRvRm9ybWF0KG5ld0NvbG9yLCB0aGlzLmZvcm1hdCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IG5ld0NvbG9yID0gbmV3IE5neENvbG9yKCk7XG4gICAgICAgIGxldCBuZXdDb2xvclByZXZpZXcgPSB0aGlzLnNlcnZpY2Uuc3RyaW5nVG9Ic3ZhKGNvbG9yLnByZXZpZXcpO1xuICAgICAgICBuZXdDb2xvclByZXZpZXcub25BbHBoYUNoYW5nZShhbHBoYSk7XG4gICAgICAgIG5ld0NvbG9yLnByZXZpZXcgPSB0aGlzLnNlcnZpY2UudG9Gb3JtYXQobmV3Q29sb3JQcmV2aWV3LCB0aGlzLmZvcm1hdCk7XG4gICAgICAgIG5ld0NvbG9yLnZhcmlhbnRzID0gdGhpcy5DaGFuZ2VBbHBoYU9uUGFsZXR0ZShhbHBoYSwgY29sb3IudmFyaWFudHMpO1xuICAgICAgICByZXN1bHQucHVzaChuZXdDb2xvcik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ2hhbmdlIGNvbG9yIGZyb20gZGVmYXVsdCBjb2xvcnNcbiAgICogQHBhcmFtIHN0cmluZyBjb2xvclxuICAgKi9cbiAgcHVibGljIGNoYW5nZUNvbG9yKGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnNldENvbG9yKHRoaXMuc2VydmljZS5zdHJpbmdUb0hzdmEoY29sb3IpKTtcbiAgICAvLyB0aGlzLnRyaWdnZXJJbnN0YW5jZS5vbkNoYW5nZSgpO1xuICAgIHRoaXMuZW1pdENsb3NlKFwiYWNjZXB0XCIpO1xuICB9XG5cbiAgcHVibGljIG9uQ2hhbmdlQ29sb3JQaWNrZXIoZXZlbnQ6IEhzdmEpIHtcbiAgICB0aGlzLnRlbXBvcmFsQ29sb3IgPSBldmVudDtcbiAgICB0aGlzLmNvbG9yID0gdGhpcy5zZXJ2aWNlLnRvRm9ybWF0KGV2ZW50LCB0aGlzLmZvcm1hdCk7XG4gICAgLy8gdGhpcy5zZXRDb2xvcihldmVudCk7XG4gICAgdGhpcy50cmlnZ2VySW5zdGFuY2Uuc2xpZGVyQ2hhbmdlKFxuICAgICAgdGhpcy5zZXJ2aWNlLnRvRm9ybWF0KGV2ZW50LCB0aGlzLmZvcm1hdClcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGNoYW5nZUNvbG9yTWFudWFsKGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnByZXZpZXdDb2xvciA9IGNvbG9yO1xuICAgIHRoaXMuY29sb3IgPSBjb2xvcjtcbiAgICB0aGlzLmhzdmEgPSB0aGlzLnNlcnZpY2Uuc3RyaW5nVG9Ic3ZhKGNvbG9yKTtcbiAgICB0aGlzLnRyaWdnZXJJbnN0YW5jZS5zZXRDb2xvcih0aGlzLmNvbG9yKTtcbiAgICAvLyB0aGlzLnRyaWdnZXJJbnN0YW5jZS5vbkNoYW5nZSgpO1xuICB9XG5cbiAgcHVibGljIG9wZW5FeWVEcm9wcGVyKCk6IHZvaWQge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBpZiAoIXdpbmRvdy5FeWVEcm9wcGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICBcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgY29uc3QgZXllRHJvcHBlciA9IG5ldyBFeWVEcm9wcGVyKCk7XG4gIFxuICAgIGV5ZURyb3BwZXIub3BlbigpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIGNvbnN0IGNvbG9yID0gcmVzdWx0LnNSR0JIZXg7XG4gICAgICB0aGlzLmNoYW5nZUNvbG9yKGNvbG9yKTtcbiAgICB9KS5jYXRjaChlID0+IHt9KTtcbiAgfVxuXG4gIHNldENvbG9yKHZhbHVlOiBIc3ZhKSB7XG4gICAgdGhpcy5oc3ZhID0gdmFsdWU7XG4gICAgdGhpcy5jb2xvciA9IHRoaXMuc2VydmljZS50b0Zvcm1hdCh2YWx1ZSwgdGhpcy5mb3JtYXQpO1xuICAgIHRoaXMuc2V0UHJldmlld0NvbG9yKHZhbHVlKTtcbiAgICB0aGlzLnRyaWdnZXJJbnN0YW5jZS5zZXRDb2xvcih0aGlzLmNvbG9yKTtcbiAgfVxuXG4gIHNldFByZXZpZXdDb2xvcih2YWx1ZTogSHN2YSkge1xuICAgIHRoaXMucHJldmlld0NvbG9yID0gdGhpcy5zZXJ2aWNlLmhzdmFUb1JnYmEodmFsdWUpLnRvU3RyaW5nKCk7XG4gIH1cbiAgaHN2YVRvUmdiYTtcbiAgb25DaGFuZ2UoKSB7XG4gICAgLy8gdGhpcy50cmlnZ2VySW5zdGFuY2Uub25DaGFuZ2UoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkNvbG9yQ2xpY2soY29sb3IpIHtcbiAgICBpZiAodHlwZW9mIGNvbG9yID09IFwic3RyaW5nXCIpIHtcbiAgICAgIHRoaXMuY2hhbmdlQ29sb3IoY29sb3IpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnZhcmlhbnRzID0gY29sb3IudmFyaWFudHM7XG4gICAgICB0aGlzLm1lbnUgPSAyO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhZGRDb2xvcigpIHtcbiAgICB0aGlzLm1lbnUgPSAzO1xuICAgIHRoaXMuYmFja3VwQ29sb3IgPSB0aGlzLmNvbG9yO1xuICAgIHRoaXMuY29sb3IgPSBcIiNGRjAwMDBcIjtcbiAgICB0aGlzLnRlbXBvcmFsQ29sb3IgPSB0aGlzLnNlcnZpY2Uuc3RyaW5nVG9Ic3ZhKHRoaXMuY29sb3IpO1xuICB9XG5cbiAgcHVibGljIG5leHRGb3JtYXQoKSB7XG4gICAgaWYgKHRoaXMuY2FuQ2hhbmdlRm9ybWF0KSB7XG4gICAgICB0aGlzLmZvcm1hdCA9ICh0aGlzLmZvcm1hdCArIDEpICUgdGhpcy5jb2xvckZvcm1hdHMubGVuZ3RoO1xuICAgICAgdGhpcy5zZXRDb2xvcih0aGlzLmhzdmEpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBlbWl0Q2xvc2Uoc3RhdHVzOiBcImNhbmNlbFwiIHwgXCJhY2NlcHRcIikge1xuICAgIGlmICh0aGlzLm1lbnUgPT0gMykge1xuICAgICAgaWYgKHN0YXR1cyA9PSBcImNhbmNlbFwiKSB7XG4gICAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PSBcImFjY2VwdFwiKSB7XG4gICAgICAgIHRoaXMuc2V0Q29sb3IodGhpcy50ZW1wb3JhbENvbG9yKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy50cmlnZ2VySW5zdGFuY2UuY2xvc2UoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkNsaWNrQmFjaygpIHtcbiAgICBpZiAodGhpcy5tZW51ID09IDMpIHtcbiAgICAgIHRoaXMuY29sb3IgPSB0aGlzLmJhY2t1cENvbG9yO1xuICAgICAgdGhpcy5oc3ZhID0gdGhpcy5zZXJ2aWNlLnN0cmluZ1RvSHN2YSh0aGlzLmNvbG9yKTtcbiAgICB9XG4gICAgdGhpcy5pbmRleFNlbGVjY2lvbmFkbyA9IHRoaXMuZmluZEluZGV4U2VsZWN0ZWRDb2xvcih0aGlzLnBhbGV0dGUpO1xuICAgIHRoaXMubWVudSA9IDE7XG4gIH1cblxuICBpc091dHNpZGUoZXZlbnQpIHtcbiAgICByZXR1cm4gZXZlbnQudGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucyhcIm5neC1jb2xvcnMtb3ZlcmxheVwiKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm9wZW5lZFwiIFtzdHlsZV09XCJwb3NpdGlvblN0cmluZ1wiICNkaWFsb2c+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJtZW51ID09IDFcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sb3JzXCIgW0Bjb2xvcnNBbmltYXRpb25dPVwiY29sb3JzQW5pbWF0aW9uRWZmZWN0XCI+XG5cbiAgICAgIDxkaXYgKm5nSWY9XCJzaG93RXllRHJvcHBlclwiIGNsYXNzPVwiY2lyY2xlIGJ1dHRvbiBleWVkcm9wcGVyXCIgKGNsaWNrKT1cIm9wZW5FeWVEcm9wcGVyKClcIj5cbiAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCIjMjIyMjIyXCI+PHBhdGggZD1cIk0xNy41NDIgMTMuMTQ3bC03LjQ1NS02LjY2NyAxLjMzNC0xLjQ5Yy44MjIuNzM2IDIuMDg3LjY2NiAyLjgyMi0uMTU5bDMuNTAzLTMuODMxYy41OTMtLjY2MyAxLjQxNC0xIDIuMjM4LTEgMS42NjYgMCAzLjAxNiAxLjM1OCAzLjAxNiAyLjk5NiAwIC43MjMtLjI3MSAxLjQzNS0uNzggMi4wMDVsLTMuNTAzIDMuODNjLS43MzUuODI0LS42NjYgMi4wODcuMTU4IDIuODI1bC0xLjMzMyAxLjQ5MXptLTQuMzE0LTEuMTc1bC03Ljc5MSA4LjY1Yy0uMzE0LjM1Mi0xLjMyMi4zMjMtMS44NTMuNTU3LjE3Mi0uNTU0LjA0OC0xLjUzOC4zNjItMS44OWw3Ljc5MS04LjY1MS0xLjQ5MS0xLjMzMy03LjkgOC43OTRjLTEuMjc3IDEuNDIzLS4xNzEgMi4yNjEtMS4xNDkgNC4wNTItLjEzNS4yNDQtLjE5Ny40OC0uMTk3LjY5OCAwIC42NjEuNTQgMS4xNTEgMS4xNDEgMS4xNTEuMjQxIDAgLjQ5Mi0uMDc5LjcyNC0uMjU2IDEuNzMzLTEuMzMyIDIuNjQ0LS4xODQgMy45NTQtMS42NDdsNy45LTguNzkyLTEuNDkxLTEuMzMzelwiLz48L3N2Zz5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2xvciBvZiBwYWxldHRlOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjaXJjbGUgd3JhcHBlciBjb2xvclwiPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIChjbGljayk9XCJvbkNvbG9yQ2xpY2soY29sb3IpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY2lyY2xlIGNvbG9yIGNpcmNsZS1ib3JkZXJcIlxuICAgICAgICAgICAgW25nU3R5bGVdPVwiZ2V0QmFja2dyb3VuZENvbG9yKGNvbG9yKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImkgPT0gdGhpcy5pbmRleFNlbGVjY2lvbmFkb1wiIGNsYXNzPVwic2VsZWN0ZWRcIj48L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxkaXZcbiAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiByZ2IoMjQ1IDI0NSAyNDUpOyBwb3NpdGlvbjogcmVsYXRpdmVcIlxuICAgICAgICAoY2xpY2spPVwiYWRkQ29sb3IoKVwiXG4gICAgICAgICpuZ0lmPVwiIWhpZGVDb2xvclBpY2tlciAmJiB0aGlzLmNvbG9yUGlja2VyQ29udHJvbHMgIT0gJ29ubHktYWxwaGEnXCJcbiAgICAgICAgY2xhc3M9XCJjaXJjbGUgYnV0dG9uXCJcbiAgICAgID5cbiAgICAgICAgPGRpdlxuICAgICAgICAgICpuZ0lmPVwiIXRoaXMuaW5kZXhTZWxlY2Npb25hZG9cIlxuICAgICAgICAgIHN0eWxlPVwiXG4gICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICBoZWlnaHQ6IDdweDtcbiAgICAgICAgICAgIHdpZHRoOiA3cHg7XG4gICAgICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMDMpO1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMTAwJTtcbiAgICAgICAgICAgIHRvcDogMDtcbiAgICAgICAgICAgIHJpZ2h0OiAwO1xuICAgICAgICAgIFwiXG4gICAgICAgICAgW25nU3R5bGVdPVwiZ2V0QmFja2dyb3VuZENvbG9yKGNvbG9yKVwiXG4gICAgICAgID48L2Rpdj5cbiAgICAgICAgPHN2Z1xuICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuICAgICAgICAgIGhlaWdodD1cIjI0cHhcIlxuICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjQgMjRcIlxuICAgICAgICAgIHdpZHRoPVwiMjRweFwiXG4gICAgICAgICAgZmlsbD1cIiMyMjIyMjJcIlxuICAgICAgICA+XG4gICAgICAgICAgPHBhdGggZD1cIk0yNCAyNEgwVjBoMjR2MjR6XCIgZmlsbD1cIm5vbmVcIiBvcGFjaXR5PVwiLjg3XCIgLz5cbiAgICAgICAgICA8cGF0aCBkPVwiTTE2LjU5IDguNTlMMTIgMTMuMTcgNy40MSA4LjU5IDYgMTBsNiA2IDYtNi0xLjQxLTEuNDF6XCIgLz5cbiAgICAgICAgPC9zdmc+XG4gICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cImFkZFwiPlxuICAgICAgICAgIDxpY29ucyBpY29uPVwiYWRkXCI+PC9pY29ucz5cbiAgICAgICAgPC9kaXY+IC0tPlxuICAgICAgPC9kaXY+XG4gICAgICA8Y29sb3ItcGlja2VyXG4gICAgICAgICpuZ0lmPVwiIWhpZGVDb2xvclBpY2tlciAmJiB0aGlzLmNvbG9yUGlja2VyQ29udHJvbHMgPT0gJ29ubHktYWxwaGEnXCJcbiAgICAgICAgW2NvbnRyb2xzXT1cImNvbG9yUGlja2VyQ29udHJvbHNcIlxuICAgICAgICBbY29sb3JdPVwiaHN2YVwiXG4gICAgICAgIChjb2xvckNoYW5nZSk9XCJvbkNoYW5nZUNvbG9yUGlja2VyKCRldmVudClcIlxuICAgICAgICAob25BbHBoYUNoYW5nZSk9XCJvbkFscGhhQ2hhbmdlKCRldmVudClcIlxuICAgICAgPjwvY29sb3ItcGlja2VyPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1lbnUgPT0gMlwiPlxuICAgIDxkaXYgY2xhc3M9XCJjb2xvcnNcIiBbQGNvbG9yc0FuaW1hdGlvbl09XCJjb2xvcnNBbmltYXRpb25FZmZlY3RcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjaXJjbGUgd3JhcHBlclwiPlxuICAgICAgICA8ZGl2IChjbGljayk9XCJvbkNsaWNrQmFjaygpXCIgY2xhc3M9XCJhZGRcIj5cbiAgICAgICAgICA8c3ZnXG4gICAgICAgICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcbiAgICAgICAgICAgIHdpZHRoPVwiMjRcIlxuICAgICAgICAgICAgaGVpZ2h0PVwiMjRcIlxuICAgICAgICAgICAgdmlld0JveD1cIjAgMCAyNCAyNFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHBhdGggZD1cIk0wIDBoMjR2MjRIMHpcIiBmaWxsPVwibm9uZVwiIC8+XG4gICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICBkPVwiTTIwIDExSDcuODNsNS41OS01LjU5TDEyIDRsLTggOCA4IDggMS40MS0xLjQxTDcuODMgMTNIMjB2LTJ6XCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9zdmc+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHZhcmlhbnQgb2YgdmFyaWFudHNcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNpcmNsZSB3cmFwcGVyIGNvbG9yXCI+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgKGNsaWNrKT1cImNoYW5nZUNvbG9yKHZhcmlhbnQpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY2lyY2xlIGNpcmNsZS1ib3JkZXJcIlxuICAgICAgICAgICAgW25nU3R5bGVdPVwieyBiYWNrZ3JvdW5kOiB2YXJpYW50IH1cIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc1NlbGVjdGVkKHZhcmlhbnQpXCIgY2xhc3M9XCJzZWxlY3RlZFwiPjwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1lbnUgPT0gM1wiPlxuICAgIDxkaXYgY2xhc3M9XCJuYXYtd3JhcHBlclwiPlxuICAgICAgPGRpdlxuICAgICAgICAoY2xpY2spPVwib25DbGlja0JhY2soKVwiXG4gICAgICAgIGNsYXNzPVwicm91bmQtYnV0dG9uIGJ1dHRvblwiXG4gICAgICAgIHN0eWxlPVwiZmxvYXQ6IGxlZnRcIlxuICAgICAgPlxuICAgICAgICA8c3ZnXG4gICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgICAgICAgd2lkdGg9XCIyNFwiXG4gICAgICAgICAgaGVpZ2h0PVwiMjRcIlxuICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjQgMjRcIlxuICAgICAgICA+XG4gICAgICAgICAgPHBhdGggZD1cIk0wIDBoMjR2MjRIMHpcIiBmaWxsPVwibm9uZVwiIC8+XG4gICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgIGQ9XCJNMjAgMTFINy44M2w1LjU5LTUuNTlMMTIgNGwtOCA4IDggOCAxLjQxLTEuNDFMNy44MyAxM0gyMHYtMnpcIlxuICAgICAgICAgIC8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9kaXY+XG4gICAgICA8YnV0dG9uIChjbGljayk9XCJlbWl0Q2xvc2UoJ2NhbmNlbCcpXCIgc3R5bGU9XCJmbG9hdDogcmlnaHRcIj5cbiAgICAgICAge3sgY2FuY2VsTGFiZWwgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiZW1pdENsb3NlKCdhY2NlcHQnKVwiIHN0eWxlPVwiZmxvYXQ6IHJpZ2h0XCI+XG4gICAgICAgIHt7IGFjY2VwdExhYmVsIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sb3ItcGlja2VyLXdyYXBwZXJcIj5cbiAgICAgIDwhLS0gPHNwYW4gWyhjb2xvclBpY2tlcildPVwiY29sb3JcIj48L3NwYW4+IC0tPlxuICAgICAgPGNvbG9yLXBpY2tlclxuICAgICAgICBbY29udHJvbHNdPVwiY29sb3JQaWNrZXJDb250cm9sc1wiXG4gICAgICAgIFtjb2xvcl09XCJoc3ZhXCJcbiAgICAgICAgKHNsaWRlckNoYW5nZSk9XCJvbkNoYW5nZUNvbG9yUGlja2VyKCRldmVudClcIlxuICAgICAgPjwvY29sb3ItcGlja2VyPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbiAgPGRpdiBjbGFzcz1cIm1hbnVhbC1pbnB1dC13cmFwcGVyXCIgKm5nSWY9XCIhaGlkZVRleHRJbnB1dFwiPlxuICAgIDxwIChjbGljayk9XCJuZXh0Rm9ybWF0KClcIj57eyBjb2xvckZvcm1hdHNbZm9ybWF0XSB9fTwvcD5cbiAgICA8ZGl2IGNsYXNzPVwiZy1pbnB1dFwiPlxuICAgICAgPGlucHV0XG4gICAgICAgIHBsYWNlaG9sZGVyPVwiI0ZGRkZGRlwiXG4gICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgW3ZhbHVlXT1cImNvbG9yXCJcbiAgICAgICAgW3N0eWxlLmZvbnQtc2l6ZS5weF09XCJjb2xvciAmJiBjb2xvci5sZW5ndGggPiAyMyA/IDkgOiAxMFwiXG4gICAgICAgIFtzdHlsZS5sZXR0ZXItc3BhY2luZy5weF09XCJjb2xvciAmJiBjb2xvci5sZW5ndGggPiAxNiA/IDAgOiAxLjVcIlxuICAgICAgICAoa2V5dXApPVwiY2hhbmdlQ29sb3JNYW51YWwocGFpbnRJbnB1dC52YWx1ZSlcIlxuICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJlbWl0Q2xvc2UoJ2FjY2VwdCcpXCJcbiAgICAgICAgI3BhaW50SW5wdXRcbiAgICAgIC8+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=