UNPKG

ngx-slice-kit

Version:

[![npm version](https://badge.fury.io/js/ngx-slice-kit.svg)](https://badge.fury.io/js/ngx-slice-kit)

254 lines 40.4 kB
import { Component, EventEmitter, forwardRef, HostBinding, Inject, Input, Output, PLATFORM_ID, ViewChild } from '@angular/core'; import { DOCUMENT, isPlatformServer } from '@angular/common'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { BehaviorSubject, fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "../dropdown.service"; import * as i2 from "../options.service"; import * as i3 from "../../core/layout-control/layout-control.service"; import * as i4 from "@angular/common"; import * as i5 from "../../buttons/icon/icon.component"; export class AutocompleteComponent { constructor(document, platformId, dropdownService, optionsService, renderer, layoutControlService) { this.document = document; this.platformId = platformId; this.dropdownService = dropdownService; this.optionsService = optionsService; this.renderer = renderer; this.layoutControlService = layoutControlService; this.$options = new BehaviorSubject(null); this.label = ''; this.placeholder = ''; this.small = false; this.caption = ''; this.focusEvent = new EventEmitter(); this.blurEvent = new EventEmitter(); this.resultEvent = new EventEmitter(); this.valueChanges = new EventEmitter(); this.error = undefined; this.value = ''; this.uid = layoutControlService.generateLayoutElementHash(); } set options(o) { this.$options.next(o); if (this.isOpen) { this.optionsService.options = this.getOptions(); } } get options() { return this.$options.getValue(); } set required(val) { this.req = val === '' || val === true; } get required() { return this.req; } get isDisabled() { return this.disabled; } getOptions() { return [...this.options].map(o => { o.selected = this.currentValue === o; return o; }); } isInactive() { return !this.currentValue; } hasValuesToDrop() { return !this.isInactive(); } onOpen() { this.isOpen = true; this.emitFocus(); } onClose() { this.isOpen = false; this.emitBlur(); } emitBlur() { if (this.focused) { this.focused = false; this.blurEvent.emit(); } } emitFocus() { if (!this.focused) { this.focused = true; this.focusEvent.emit(); } } selected() { return this.currentValue?.label ?? ''; } onResult(option) { this.onTouched(); this.writeValue(option); } writeValue(val) { if (val?.size > 0) { this.currentValues = val; const multipleResult = this.options.filter(o => this.currentValues.has(o)); this.onChange(multipleResult); this.resultEvent.emit(multipleResult); } else { this.currentValue = val; this.onChange(val); this.resultEvent.emit(this.currentValue); } } addValue(o) { const alreadySelected = this.currentValues.has(o); o.selected = !alreadySelected; alreadySelected ? this.currentValues.delete(o) : this.currentValues.add(o); this.writeValue(this.currentValues); } clearValue(e) { e.stopPropagation(); this.valueChanges.emit(null); this.currentValue = undefined; this.writeValue(undefined); } onChange(value) { } onTouched() { } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } setDisabledState(isDisabled) { this.disabled = isDisabled; } setInputSubscription() { this.sub = fromEvent(this.inputElementRef.nativeElement, `keyup`).pipe(debounceTime(500)).subscribe((e) => { if (e.code === 'ArrowUp' || e.code === 'ArrowDown' || e.code === 'Escape' || e.code === 'Enter') { e.preventDefault(); e.stopPropagation(); return; } const value = e?.target?.value; this.valueChanges.emit(value); }); } onInput(ev) { if (ev.code === 'ArrowUp' || ev.code === 'ArrowDown' || ev.code === 'Escape' || ev.code === 'Enter') { ev.preventDefault(); ev.stopPropagation(); return; } const value = ev?.target?.value; this.valueChanges.emit(value); } showDropdown() { if (isPlatformServer(this.platformId)) { return; } if (this.isOpen) { return; } this.onOpen(); this.optionsService.options = this.getOptions(); const opts = { triggerRect: this.autocomplete.nativeElement.getBoundingClientRect(), fitWidth: true, multi: false, hideBackdrop: true, parentElem: this.autocomplete.nativeElement, }; this.dropdownService.showDropdown(opts).subscribe(res => { this.onClose(); // this.optionsService.options = null; if (res) { this.inputElementRef.nativeElement.blur(); this.onResult(res); } }); } // public ngOnInit(): void { // // this.setInputSubscription(); // } ngOnDestroy() { this.sub?.unsubscribe(); this.blurEvent.complete(); this.focusEvent.complete(); this.resultEvent.complete(); this.valueChanges.complete(); } } AutocompleteComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.3", ngImport: i0, type: AutocompleteComponent, deps: [{ token: DOCUMENT }, { token: PLATFORM_ID }, { token: i1.DropdownService }, { token: i2.OptionsService }, { token: i0.Renderer2 }, { token: i3.LayoutControlService }], target: i0.ɵɵFactoryTarget.Component }); AutocompleteComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.3", type: AutocompleteComponent, selector: "sdk-autocomplete", inputs: { options: "options", required: "required", label: "label", placeholder: "placeholder", disabled: "disabled", small: "small", icon: "icon", caption: "caption", error: "error", isDisabled: "isDisabled" }, outputs: { focusEvent: "focusEvent", blurEvent: "blurEvent", resultEvent: "resultEvent", valueChanges: "valueChanges" }, host: { properties: { "class.invalid": "this.error", "class.disabled": "this.isDisabled" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => AutocompleteComponent), multi: true } ], viewQueries: [{ propertyName: "autocomplete", first: true, predicate: ["autocomplete"], descendants: true, static: true }, { propertyName: "inputElementRef", first: true, predicate: ["input"], descendants: true, static: true }], ngImport: i0, template: "<label for=\"{{uid}}\" class=\"sdk-autocomplete-label\"\n [class.active]=\"value !== undefined\"\n [class.small]=\"small\">\n {{label}}\n <span *ngIf=\"required\" class=\"sdk-autocomplete-label-required-mark\">&nbsp;*</span>\n</label>\n\n<div class=\"sdk-autocomplete-wrap\" #autocomplete>\n <div class=\"sdk-autocomplete\" (click)=\"showDropdown()\"\n [ngClass]=\"{\n active: isOpen,\n small: small,\n invalid: error\n }\">\n <span class=\"sdk-autocomplete-icon\" *ngIf=\"icon\">\n <sdk-icon [icon]=\"icon\" [size]=\"small ? 16 : 24\"></sdk-icon>\n </span>\n <input class=\"sdk-autocomplete-input\" type=\"text\"\n value=\"{{selected()}}\"\n id=\"{{uid}}\"\n [placeholder]=\"placeholder\"\n (keyup)=\"onInput($event)\"\n (focus)=\"emitFocus()\"\n (blur)=\"emitBlur()\"\n #input>\n <span class=\"sdk-autocomplete-actions\">\n <ng-container *ngIf=\"!hasValuesToDrop()\">\n <div class=\"interface-icon-wrap icon-chevron\" [class.active]=\"isOpen\">\n <sdk-icon icon=\"chevron_down\" [size]=\"24\"></sdk-icon>\n </div>\n </ng-container>\n <ng-container *ngIf=\"hasValuesToDrop()\">\n <div class=\"interface-icon-wrap icon-clear\">\n <sdk-icon icon=\"close\" [size]=\"16\" [inline]=\"true\" (click)=\"clearValue($event)\"></sdk-icon>\n </div>\n </ng-container>\n </span>\n </div>\n</div>\n\n<div class=\"sdk-caption\" *ngIf=\"caption\">\n {{caption}}\n</div>\n<div class=\"sdk-error\" *ngIf=\"error\">\n <sdk-icon icon=\"alert\" size=\"12\"></sdk-icon>\n {{error ? error : ''}}\n</div>\n", styles: [":host{display:flex;width:100%;flex-direction:column;margin-bottom:10px;position:relative}:host.sdk-autocomplete--invalid{animation:shake .4s}:host.disabled{opacity:.6;pointer-events:none;cursor:default}.sdk-autocomplete-label-required-mark{color:var(--warn)}.sdk-autocomplete-label{color:var(--base-a50);transition:all .2s;font-size:17px;margin-bottom:2px}.sdk-autocomplete-label.small{font-size:15px}.sdk-autocomplete-label.active{color:var(--base-a90)}.sdk-autocomplete-wrap{position:relative;background-color:var(--background-a90);border-radius:8px;overflow:hidden}.sdk-autocomplete{display:flex;align-items:center;align-content:center;flex-wrap:nowrap;white-space:nowrap;padding:10px 16px;border-radius:8px;height:44px;min-width:256px;cursor:pointer;position:relative;z-index:3;border-color:var(--regular-a50);border-width:1px;border-style:solid;transition:.4s}.sdk-autocomplete.invalid{transition:all .2s ease;border-color:var(--warn);background-color:var(--warn-a20-rgb)}.sdk-autocomplete.full-width{width:100%}.sdk-autocomplete.small{padding:5px 12px;height:32px}.sdk-autocomplete.small .sdk-autocomplete-input{font-size:15px}.sdk-autocomplete.small .sdk-autocomplete-icon{margin-right:4px}.sdk-autocomplete.active{z-index:23;border-color:var(--regular-a100)}.sdk-autocomplete .sdk-autocomplete-icon{margin-right:8px}.sdk-autocomplete .sdk-autocomplete-input,.sdk-autocomplete .sdk-autocomplete-value{flex-basis:100%;color:var(--base-a90);background-color:transparent;max-width:100%;font-size:17px;font-weight:400;line-height:24px;outline:none;border:none;transition:all .4s;font-family:Inter,sans-serif;overflow:hidden;white-space:nowrap;-ms-text-overflow:ellipsis;text-overflow:ellipsis}.sdk-menu-more__item-icon{height:16px;width:20px;position:relative;top:2px}.sdk-autocomplete__arrow-button{outline:none;display:flex;margin:auto auto auto -32px;cursor:pointer;transition:transform .2s,opacity .2s}.sdk-autocomplete__arrow-button:hover{opacity:.8}.sdk-autocomplete__overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:20}.select__arrow-button--open img{transform:rotate(180deg)}.inactive{color:var(--base-a50)}.sdk-autocomplete__interface-icon{transition:all .4s}.sdk-autocomplete__interface-icon:hover{opacity:.6}.sdk-autocomplete__interface-icon .interface-icon__wrapper--open{height:24px;width:24px}.sdk-autocomplete__interface-icon .interface-icon__wrapper--clear{height:16px;width:16px}.interface-icon-wrap{display:flex;align-items:center;justify-content:center;width:24px;height:24px;transition:all .2s}.interface-icon-wrap.active{transform:scaleY(-1)}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.IconComponent, selector: "sdk-icon", inputs: ["icon", "image", "inline", "size", "color"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.3", ngImport: i0, type: AutocompleteComponent, decorators: [{ type: Component, args: [{ selector: 'sdk-autocomplete', providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => AutocompleteComponent), multi: true } ], template: "<label for=\"{{uid}}\" class=\"sdk-autocomplete-label\"\n [class.active]=\"value !== undefined\"\n [class.small]=\"small\">\n {{label}}\n <span *ngIf=\"required\" class=\"sdk-autocomplete-label-required-mark\">&nbsp;*</span>\n</label>\n\n<div class=\"sdk-autocomplete-wrap\" #autocomplete>\n <div class=\"sdk-autocomplete\" (click)=\"showDropdown()\"\n [ngClass]=\"{\n active: isOpen,\n small: small,\n invalid: error\n }\">\n <span class=\"sdk-autocomplete-icon\" *ngIf=\"icon\">\n <sdk-icon [icon]=\"icon\" [size]=\"small ? 16 : 24\"></sdk-icon>\n </span>\n <input class=\"sdk-autocomplete-input\" type=\"text\"\n value=\"{{selected()}}\"\n id=\"{{uid}}\"\n [placeholder]=\"placeholder\"\n (keyup)=\"onInput($event)\"\n (focus)=\"emitFocus()\"\n (blur)=\"emitBlur()\"\n #input>\n <span class=\"sdk-autocomplete-actions\">\n <ng-container *ngIf=\"!hasValuesToDrop()\">\n <div class=\"interface-icon-wrap icon-chevron\" [class.active]=\"isOpen\">\n <sdk-icon icon=\"chevron_down\" [size]=\"24\"></sdk-icon>\n </div>\n </ng-container>\n <ng-container *ngIf=\"hasValuesToDrop()\">\n <div class=\"interface-icon-wrap icon-clear\">\n <sdk-icon icon=\"close\" [size]=\"16\" [inline]=\"true\" (click)=\"clearValue($event)\"></sdk-icon>\n </div>\n </ng-container>\n </span>\n </div>\n</div>\n\n<div class=\"sdk-caption\" *ngIf=\"caption\">\n {{caption}}\n</div>\n<div class=\"sdk-error\" *ngIf=\"error\">\n <sdk-icon icon=\"alert\" size=\"12\"></sdk-icon>\n {{error ? error : ''}}\n</div>\n", styles: [":host{display:flex;width:100%;flex-direction:column;margin-bottom:10px;position:relative}:host.sdk-autocomplete--invalid{animation:shake .4s}:host.disabled{opacity:.6;pointer-events:none;cursor:default}.sdk-autocomplete-label-required-mark{color:var(--warn)}.sdk-autocomplete-label{color:var(--base-a50);transition:all .2s;font-size:17px;margin-bottom:2px}.sdk-autocomplete-label.small{font-size:15px}.sdk-autocomplete-label.active{color:var(--base-a90)}.sdk-autocomplete-wrap{position:relative;background-color:var(--background-a90);border-radius:8px;overflow:hidden}.sdk-autocomplete{display:flex;align-items:center;align-content:center;flex-wrap:nowrap;white-space:nowrap;padding:10px 16px;border-radius:8px;height:44px;min-width:256px;cursor:pointer;position:relative;z-index:3;border-color:var(--regular-a50);border-width:1px;border-style:solid;transition:.4s}.sdk-autocomplete.invalid{transition:all .2s ease;border-color:var(--warn);background-color:var(--warn-a20-rgb)}.sdk-autocomplete.full-width{width:100%}.sdk-autocomplete.small{padding:5px 12px;height:32px}.sdk-autocomplete.small .sdk-autocomplete-input{font-size:15px}.sdk-autocomplete.small .sdk-autocomplete-icon{margin-right:4px}.sdk-autocomplete.active{z-index:23;border-color:var(--regular-a100)}.sdk-autocomplete .sdk-autocomplete-icon{margin-right:8px}.sdk-autocomplete .sdk-autocomplete-input,.sdk-autocomplete .sdk-autocomplete-value{flex-basis:100%;color:var(--base-a90);background-color:transparent;max-width:100%;font-size:17px;font-weight:400;line-height:24px;outline:none;border:none;transition:all .4s;font-family:Inter,sans-serif;overflow:hidden;white-space:nowrap;-ms-text-overflow:ellipsis;text-overflow:ellipsis}.sdk-menu-more__item-icon{height:16px;width:20px;position:relative;top:2px}.sdk-autocomplete__arrow-button{outline:none;display:flex;margin:auto auto auto -32px;cursor:pointer;transition:transform .2s,opacity .2s}.sdk-autocomplete__arrow-button:hover{opacity:.8}.sdk-autocomplete__overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:20}.select__arrow-button--open img{transform:rotate(180deg)}.inactive{color:var(--base-a50)}.sdk-autocomplete__interface-icon{transition:all .4s}.sdk-autocomplete__interface-icon:hover{opacity:.6}.sdk-autocomplete__interface-icon .interface-icon__wrapper--open{height:24px;width:24px}.sdk-autocomplete__interface-icon .interface-icon__wrapper--clear{height:16px;width:16px}.interface-icon-wrap{display:flex;align-items:center;justify-content:center;width:24px;height:24px;transition:all .2s}.interface-icon-wrap.active{transform:scaleY(-1)}\n"] }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: i1.DropdownService }, { type: i2.OptionsService }, { type: i0.Renderer2 }, { type: i3.LayoutControlService }]; }, propDecorators: { options: [{ type: Input }], required: [{ type: Input }], autocomplete: [{ type: ViewChild, args: ['autocomplete', { static: true }] }], inputElementRef: [{ type: ViewChild, args: ['input', { static: true }] }], label: [{ type: Input }], placeholder: [{ type: Input }], disabled: [{ type: Input }], small: [{ type: Input }], icon: [{ type: Input }], caption: [{ type: Input }], focusEvent: [{ type: Output }], blurEvent: [{ type: Output }], resultEvent: [{ type: Output }], valueChanges: [{ type: Output }], error: [{ type: Input }, { type: HostBinding, args: ['class.invalid'] }], isDisabled: [{ type: Input }, { type: HostBinding, args: ['class.disabled'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0b2NvbXBsZXRlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbmd4LXNsaWNlLWtpdC9zcmMvbGliL2Ryb3Bkb3ducy9hdXRvY29tcGxldGUvYXV0b2NvbXBsZXRlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbmd4LXNsaWNlLWtpdC9zcmMvbGliL2Ryb3Bkb3ducy9hdXRvY29tcGxldGUvYXV0b2NvbXBsZXRlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDSCxTQUFTLEVBRVQsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsTUFBTSxFQUNOLEtBQUssRUFFTCxNQUFNLEVBQ04sV0FBVyxFQUVYLFNBQVMsRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDN0QsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7QUFtQjlDLE1BQU0sT0FBTyxxQkFBcUI7SUF1RDlCLFlBQzhCLFFBQWEsRUFDVixVQUFlLEVBQ3BDLGVBQWdDLEVBQ2hDLGNBQThCLEVBQzlCLFFBQW1CLEVBQ25CLG9CQUEwQztRQUx4QixhQUFRLEdBQVIsUUFBUSxDQUFLO1FBQ1YsZUFBVSxHQUFWLFVBQVUsQ0FBSztRQUNwQyxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDaEMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIseUJBQW9CLEdBQXBCLG9CQUFvQixDQUFzQjtRQTNEOUMsYUFBUSxHQUFtQyxJ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QUs7c0JBQXBCLEtBQUs7Z0JBQ1UsV0FBVztzQkFBMUIsS0FBSztnQkFDVSxRQUFRO3NCQUF2QixLQUFLO2dCQUNVLEtBQUs7c0JBQXBCLEtBQUs7Z0JBQ1UsSUFBSTtzQkFBbkIsS0FBSztnQkFDVSxPQUFPO3NCQUF0QixLQUFLO2dCQUVXLFVBQVU7c0JBQTFCLE1BQU07Z0JBQ1UsU0FBUztzQkFBekIsTUFBTTtnQkFDVSxXQUFXO3NCQUEzQixNQUFNO2dCQUNVLFlBQVk7c0JBQTVCLE1BQU07Z0JBR0EsS0FBSztzQkFEWCxLQUFLOztzQkFBSSxXQUFXO3VCQUFDLGVBQWU7Z0JBSTFCLFVBQVU7c0JBRHBCLEtBQUs7O3NCQUFJLFdBQVc7dUJBQUMsZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDb21wb25lbnQsXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgZm9yd2FyZFJlZixcbiAgICBIb3N0QmluZGluZyxcbiAgICBJbmplY3QsXG4gICAgSW5wdXQsXG4gICAgT25EZXN0cm95LFxuICAgIE91dHB1dCxcbiAgICBQTEFURk9STV9JRCxcbiAgICBSZW5kZXJlcjIsXG4gICAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRE9DVU1FTlQsIGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBmcm9tRXZlbnQsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgT3B0aW9uTW9kZWwgfSBmcm9tICcuLi9kcm9wZG93bi1vcHRpb24ubW9kZWwnO1xuaW1wb3J0IHsgRHJvcGRvd25PcHRpb25zIH0gZnJvbSAnLi4vZHJvcGRvd24ubW9kZWwnO1xuaW1wb3J0IHsgRHJvcGRvd25TZXJ2aWNlIH0gZnJvbSAnLi4vZHJvcGRvd24uc2VydmljZSc7XG5pbXBvcnQgeyBPcHRpb25zU2VydmljZSB9IGZyb20gJy4uL29wdGlvbnMuc2VydmljZSc7XG5pbXBvcnQgeyBMYXlvdXRDb250cm9sU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvbGF5b3V0LWNvbnRyb2wvbGF5b3V0LWNvbnRyb2wuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnc2RrLWF1dG9jb21wbGV0ZScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2F1dG9jb21wbGV0ZS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vYXV0b2NvbXBsZXRlLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gQXV0b2NvbXBsZXRlQ29tcG9uZW50KSxcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXG4gICAgICAgIH1cbiAgICBdXG59KVxuZXhwb3J0IGNsYXNzIEF1dG9jb21wbGV0ZUNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkRlc3Ryb3kge1xuXG4gICAgcHJpdmF0ZSAkb3B0aW9uczogQmVoYXZpb3JTdWJqZWN0PE9wdGlvbk1vZGVsW10+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxPcHRpb25Nb2RlbFtdPihudWxsKTtcbiAgICBwcml2YXRlIHJlcTogYm9vbGVhbjtcblxuICAgIEBJbnB1dCgpIHB1YmxpYyBzZXQgb3B0aW9ucyhvOiBPcHRpb25Nb2RlbFtdKSB7XG4gICAgICAgIHRoaXMuJG9wdGlvbnMubmV4dChvKTtcbiAgICAgICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnNTZXJ2aWNlLm9wdGlvbnMgPSB0aGlzLmdldE9wdGlvbnMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgb3B0aW9ucygpOiBPcHRpb25Nb2RlbFtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJG9wdGlvbnMuZ2V0VmFsdWUoKTtcbiAgICB9XG5cbiAgICBASW5wdXQoKSBwdWJsaWMgc2V0IHJlcXVpcmVkKHZhbDogYW55KSB7XG4gICAgICAgIHRoaXMucmVxID0gdmFsID09PSAnJyB8fCB2YWwgPT09IHRydWU7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCByZXF1aXJlZCgpOiBhbnkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXE7XG4gICAgfVxuXG4gICAgcHVibGljIHN1YjogU3Vic2NyaXB0aW9uO1xuICAgIEBWaWV3Q2hpbGQoJ2F1dG9jb21wbGV0ZScsIHtzdGF0aWM6IHRydWV9KSBwdWJsaWMgYXV0b2NvbXBsZXRlOiBFbGVtZW50UmVmO1xuICAgIEBWaWV3Q2hpbGQoJ2lucHV0Jywge3N0YXRpYzogdHJ1ZX0pIHB1YmxpYyBpbnB1dEVsZW1lbnRSZWY6IEVsZW1lbnRSZWY7XG4gICAgQElucHV0KCkgcHVibGljIGxhYmVsID0gJyc7XG4gICAgQElucHV0KCkgcHVibGljIHBsYWNlaG9sZGVyID0gJyc7XG4gICAgQElucHV0KCkgcHVibGljIGRpc2FibGVkOiBib29sZWFuO1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzbWFsbDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIHB1YmxpYyBpY29uOiBzdHJpbmc7XG4gICAgQElucHV0KCkgcHVibGljIGNhcHRpb246IHN0cmluZyA9ICcnO1xuXG4gICAgQE91dHB1dCgpIHB1YmxpYyBmb2N1c0V2ZW50OiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICBAT3V0cHV0KCkgcHVibGljIGJsdXJFdmVudDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgQE91dHB1dCgpIHB1YmxpYyByZXN1bHRFdmVudDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgQE91dHB1dCgpIHB1YmxpYyB2YWx1ZUNoYW5nZXM6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgQElucHV0KCkgQEhvc3RCaW5kaW5nKCdjbGFzcy5pbnZhbGlkJylcbiAgICBwdWJsaWMgZXJyb3I6IHN0cmluZyA9IHVuZGVmaW5lZDtcblxuICAgIEBJbnB1dCgpIEBIb3N0QmluZGluZygnY2xhc3MuZGlzYWJsZWQnKVxuICAgIHB1YmxpYyBnZXQgaXNEaXNhYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGlzT3BlbjogYm9vbGVhbjtcbiAgICBwdWJsaWMgZm9jdXNlZDogYm9vbGVhbjtcbiAgICBwdWJsaWMgY3VycmVudFZhbHVlOiBPcHRpb25Nb2RlbDtcbiAgICBwdWJsaWMgY3VycmVudFZhbHVlczogU2V0PE9wdGlvbk1vZGVsPjtcbiAgICBwdWJsaWMgdWlkOiBzdHJpbmc7XG5cbiAgICBwdWJsaWMgdmFsdWU6IHN0cmluZyA9ICcnO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jdW1lbnQ6IGFueSxcbiAgICAgICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBhbnksXG4gICAgICAgIHByaXZhdGUgZHJvcGRvd25TZXJ2aWNlOiBEcm9wZG93blNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgb3B0aW9uc1NlcnZpY2U6IE9wdGlvbnNTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgICAgIHByaXZhdGUgbGF5b3V0Q29udHJvbFNlcnZpY2U6IExheW91dENvbnRyb2xTZXJ2aWNlXG4gICAgKSB7XG4gICAgICAgIHRoaXMudWlkID0gbGF5b3V0Q29udHJvbFNlcnZpY2UuZ2VuZXJhdGVMYXlvdXRFbGVtZW50SGFzaCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRPcHRpb25zKCk6IE9wdGlvbk1vZGVsW10ge1xuICAgICAgICByZXR1cm4gWy4uLnRoaXMub3B0aW9uc10ubWFwKG8gPT4ge1xuICAgICAgICAgICAgby5zZWxlY3RlZCA9IHRoaXMuY3VycmVudFZhbHVlID09PSBvO1xuICAgICAgICAgICAgcmV0dXJuIG87XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0luYWN0aXZlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gIXRoaXMuY3VycmVudFZhbHVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBoYXNWYWx1ZXNUb0Ryb3AoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhdGhpcy5pc0luYWN0aXZlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uT3BlbigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pc09wZW4gPSB0cnVlO1xuICAgICAgICB0aGlzLmVtaXRGb2N1cygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkNsb3NlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xuICAgICAgICB0aGlzLmVtaXRCbHVyKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGVtaXRCbHVyKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5mb2N1c2VkKSB7XG4gICAgICAgICAgICB0aGlzLmZvY3VzZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuYmx1ckV2ZW50LmVtaXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBlbWl0Rm9jdXMoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5mb2N1c2VkKSB7XG4gICAgICAgICAgICB0aGlzLmZvY3VzZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5mb2N1c0V2ZW50LmVtaXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzZWxlY3RlZCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50VmFsdWU/LmxhYmVsID8/ICcnO1xuICAgIH1cblxuICAgIHB1YmxpYyBvblJlc3VsdChvcHRpb246IE9wdGlvbk1vZGVsKTogdm9pZCB7XG4gICAgICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gICAgICAgIHRoaXMud3JpdGVWYWx1ZShvcHRpb24pO1xuICAgIH1cblxuICAgIHB1YmxpYyB3cml0ZVZhbHVlKHZhbCk6IHZvaWQge1xuICAgICAgICBpZiAodmFsPy5zaXplID4gMCkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50VmFsdWVzID0gdmFsO1xuICAgICAgICAgICAgY29uc3QgbXVsdGlwbGVSZXN1bHQgPSB0aGlzLm9wdGlvbnMuZmlsdGVyKG8gPT4gdGhpcy5jdXJyZW50VmFsdWVzLmhhcyhvKSk7XG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlKG11bHRpcGxlUmVzdWx0KTtcbiAgICAgICAgICAgIHRoaXMucmVzdWx0RXZlbnQuZW1pdChtdWx0aXBsZVJlc3VsdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRWYWx1ZSA9IHZhbDtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UodmFsKTtcbiAgICAgICAgICAgIHRoaXMucmVzdWx0RXZlbnQuZW1pdCh0aGlzLmN1cnJlbnRWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkVmFsdWUobzogT3B0aW9uTW9kZWwpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgYWxyZWFkeVNlbGVjdGVkID0gdGhpcy5jdXJyZW50VmFsdWVzLmhhcyhvKTtcbiAgICAgICAgby5zZWxlY3RlZCA9ICFhbHJlYWR5U2VsZWN0ZWQ7XG4gICAgICAgIGFscmVhZHlTZWxlY3RlZCA/IHRoaXMuY3VycmVudFZhbHVlcy5kZWxldGUobykgOiB0aGlzLmN1cnJlbnRWYWx1ZXMuYWRkKG8pO1xuICAgICAgICB0aGlzLndyaXRlVmFsdWUodGhpcy5jdXJyZW50VmFsdWVzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY2xlYXJWYWx1ZShlKTogdm9pZCB7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMudmFsdWVDaGFuZ2VzLmVtaXQobnVsbCk7XG4gICAgICAgIHRoaXMuY3VycmVudFZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLndyaXRlVmFsdWUodW5kZWZpbmVkKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25DaGFuZ2UodmFsdWUpOiB2b2lkIHtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25Ub3VjaGVkKCk6IHZvaWQge1xuICAgIH1cblxuICAgIHB1YmxpYyByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gICAgfVxuXG4gICAgcHVibGljIHNldERpc2FibGVkU3RhdGU/KGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIHNldElucHV0U3Vic2NyaXB0aW9uKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnN1YiA9IGZyb21FdmVudCh0aGlzLmlucHV0RWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCBga2V5dXBgKS5waXBlKFxuICAgICAgICAgICAgZGVib3VuY2VUaW1lKDUwMClcbiAgICAgICAgKS5zdWJzY3JpYmUoKGU6IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKGUuY29kZSA9PT0gJ0Fycm93VXAnIHx8XG4gICAgICAgICAgICAgICAgZS5jb2RlID09PSAnQXJyb3dEb3duJyB8fFxuICAgICAgICAgICAgICAgIGUuY29kZSA9PT0gJ0VzY2FwZScgfHxcbiAgICAgICAgICAgICAgICBlLmNvZGUgPT09ICdFbnRlcicpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZT8udGFyZ2V0Py52YWx1ZTtcbiAgICAgICAgICAgIHRoaXMudmFsdWVDaGFuZ2VzLmVtaXQodmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25JbnB1dChldjogYW55KTogdm9pZCB7XG4gICAgICAgIGlmIChldi5jb2RlID09PSAnQXJyb3dVcCcgfHxcbiAgICAgICAgICAgIGV2LmNvZGUgPT09ICdBcnJvd0Rvd24nIHx8XG4gICAgICAgICAgICBldi5jb2RlID09PSAnRXNjYXBlJyB8fFxuICAgICAgICAgICAgZXYuY29kZSA9PT0gJ0VudGVyJykge1xuICAgICAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlID0gZXY/LnRhcmdldD8udmFsdWU7XG4gICAgICAgIHRoaXMudmFsdWVDaGFuZ2VzLmVtaXQodmFsdWUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzaG93RHJvcGRvd24oKTogdm9pZCB7XG4gICAgICAgIGlmIChpc1BsYXRmb3JtU2VydmVyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmlzT3Blbikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub25PcGVuKCk7XG4gICAgICAgIHRoaXMub3B0aW9uc1NlcnZpY2Uub3B0aW9ucyA9IHRoaXMuZ2V0T3B0aW9ucygpO1xuXG4gICAgICAgIGNvbnN0IG9wdHM6IERyb3Bkb3duT3B0aW9ucyA9IHtcbiAgICAgICAgICAgIHRyaWdnZXJSZWN0OiB0aGlzLmF1dG9jb21wbGV0ZS5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgICAgICAgZml0V2lkdGg6IHRydWUsXG4gICAgICAgICAgICBtdWx0aTogZmFsc2UsXG4gICAgICAgICAgICBoaWRlQmFja2Ryb3A6IHRydWUsXG4gICAgICAgICAgICBwYXJlbnRFbGVtOiB0aGlzLmF1dG9jb21wbGV0ZS5uYXRpdmVFbGVtZW50LFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZHJvcGRvd25TZXJ2aWNlLnNob3dEcm9wZG93bihvcHRzKS5zdWJzY3JpYmUocmVzID0+IHtcbiAgICAgICAgICAgIHRoaXMub25DbG9zZSgpO1xuICAgICAgICAgICAgLy8gdGhpcy5vcHRpb25zU2VydmljZS5vcHRpb25zID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlucHV0RWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmJsdXIoKTtcbiAgICAgICAgICAgICAgICB0aGlzLm9uUmVzdWx0KHJlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAvLyAgICAgLy8gdGhpcy5zZXRJbnB1dFN1YnNjcmlwdGlvbigpO1xuICAgIC8vIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuYmx1ckV2ZW50LmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuZm9jdXNFdmVudC5jb21wbGV0ZSgpO1xuICAgICAgICB0aGlzLnJlc3VsdEV2ZW50LmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMudmFsdWVDaGFuZ2VzLmNvbXBsZXRlKCk7XG4gICAgfVxufVxuIiwiPGxhYmVsIGZvcj1cInt7dWlkfX1cIiBjbGFzcz1cInNkay1hdXRvY29tcGxldGUtbGFiZWxcIlxuICAgICAgIFtjbGFzcy5hY3RpdmVdPVwidmFsdWUgIT09IHVuZGVmaW5lZFwiXG4gICAgICAgW2NsYXNzLnNtYWxsXT1cInNtYWxsXCI+XG4gICAge3tsYWJlbH19XG4gICAgPHNwYW4gKm5nSWY9XCJyZXF1aXJlZFwiIGNsYXNzPVwic2RrLWF1dG9jb21wbGV0ZS1sYWJlbC1yZXF1aXJlZC1tYXJrXCI+Jm5ic3A7Kjwvc3Bhbj5cbjwvbGFiZWw+XG5cbjxkaXYgY2xhc3M9XCJzZGstYXV0b2NvbXBsZXRlLXdyYXBcIiAjYXV0b2NvbXBsZXRlPlxuICAgIDxkaXYgY2xhc3M9XCJzZGstYXV0b2NvbXBsZXRlXCIgKGNsaWNrKT1cInNob3dEcm9wZG93bigpXCJcbiAgICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgIGFjdGl2ZTogaXNPcGVuLFxuICAgICAgICAgICAgc21hbGw6IHNtYWxsLFxuICAgICAgICAgICAgaW52YWxpZDogZXJyb3JcbiAgICAgICAgIH1cIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJzZGstYXV0b2NvbXBsZXRlLWljb25cIiAqbmdJZj1cImljb25cIj5cbiAgICAgICAgICAgIDxzZGstaWNvbiBbaWNvbl09XCJpY29uXCIgW3NpemVdPVwic21hbGwgPyAxNiA6IDI0XCI+PC9zZGstaWNvbj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8aW5wdXQgY2xhc3M9XCJzZGstYXV0b2NvbXBsZXRlLWlucHV0XCIgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgdmFsdWU9XCJ7e3NlbGVjdGVkKCl9fVwiXG4gICAgICAgICAgICAgICBpZD1cInt7dWlkfX1cIlxuICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgIChrZXl1cCk9XCJvbklucHV0KCRldmVudClcIlxuICAgICAgICAgICAgICAgKGZvY3VzKT1cImVtaXRGb2N1cygpXCJcbiAgICAgICAgICAgICAgIChibHVyKT1cImVtaXRCbHVyKClcIlxuICAgICAgICAgICAgICAgI2lucHV0PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNkay1hdXRvY29tcGxldGUtYWN0aW9uc1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFoYXNWYWx1ZXNUb0Ryb3AoKVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnRlcmZhY2UtaWNvbi13cmFwIGljb24tY2hldnJvblwiIFtjbGFzcy5hY3RpdmVdPVwiaXNPcGVuXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzZGstaWNvbiBpY29uPVwiY2hldnJvbl9kb3duXCIgW3NpemVdPVwiMjRcIj48L3Nkay1pY29uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaGFzVmFsdWVzVG9Ecm9wKClcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW50ZXJmYWNlLWljb24td3JhcCBpY29uLWNsZWFyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzZGstaWNvbiBpY29uPVwiY2xvc2VcIiBbc2l6ZV09XCIxNlwiIFtpbmxpbmVdPVwidHJ1ZVwiIChjbGljayk9XCJjbGVhclZhbHVlKCRldmVudClcIj48L3Nkay1pY29uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvc3Bhbj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuXG48ZGl2IGNsYXNzPVwic2RrLWNhcHRpb25cIiAqbmdJZj1cImNhcHRpb25cIj5cbiAgICB7e2NhcHRpb259fVxuPC9kaXY+XG48ZGl2IGNsYXNzPVwic2RrLWVycm9yXCIgKm5nSWY9XCJlcnJvclwiPlxuICAgIDxzZGstaWNvbiBpY29uPVwiYWxlcnRcIiBzaXplPVwiMTJcIj48L3Nkay1pY29uPlxuICAgIHt7ZXJyb3IgPyBlcnJvciA6ICcnfX1cbjwvZGl2PlxuIl19