ngx-spinner
Version:
A library with more than 50 different loading spinners for Angular 4 - 17. (https://napster2210.github.io/ngx-spinner/)
245 lines • 30.8 kB
JavaScript
import { Component, Input, ChangeDetectionStrategy, ViewChild, Optional, Inject, } from "@angular/core";
import { Subject } from "rxjs";
import { takeUntil } from "rxjs/operators";
import { LOADERS, DEFAULTS, NgxSpinner, PRIMARY_SPINNER, } from "./ngx-spinner.enum";
import { trigger, state, style, transition, animate, } from "@angular/animations";
import { NGX_SPINNER_CONFIG } from "./config";
import { SafeHtmlPipe } from "./safe-html.pipe";
import { NgFor, NgIf } from "@angular/common";
import * as i0 from "@angular/core";
import * as i1 from "./ngx-spinner.service";
export class NgxSpinnerComponent {
// TODO: https://github.com/Napster2210/ngx-spinner/issues/259
// @HostListener("document:keydown", ["$event"])
// handleKeyboardEvent(event: KeyboardEvent) {
// if (this.spinnerDOM && this.spinnerDOM.nativeElement) {
// if (
// this.fullScreen ||
// (!this.fullScreen && this.isSpinnerZone(event.target))
// ) {
// event.returnValue = false;
// event.preventDefault();
// }
// }
// }
/**
* Creates an instance of NgxSpinnerComponent.
*
* @memberof NgxSpinnerComponent
*/
constructor(spinnerService, changeDetector, elementRef, globalConfig) {
this.spinnerService = spinnerService;
this.changeDetector = changeDetector;
this.elementRef = elementRef;
this.globalConfig = globalConfig;
/**
* To enable/disable animation
*
* @type {boolean}
* @memberof NgxSpinnerComponent
*/
this.disableAnimation = false;
/**
* Spinner Object
*
* @memberof NgxSpinnerComponent
*/
this.spinner = new NgxSpinner();
/**
* Unsubscribe from spinner's observable
*
* @memberof NgxSpinnerComponent
**/
this.ngUnsubscribe = new Subject();
/**
* To set default ngx-spinner options
*
* @memberof NgxSpinnerComponent
*/
this.setDefaultOptions = () => {
const { type } = this.globalConfig ?? {};
this.spinner = NgxSpinner.create({
name: this.name,
bdColor: this.bdColor,
size: this.size,
color: this.color,
type: this.type ?? type,
fullScreen: this.fullScreen,
divArray: this.divArray,
divCount: this.divCount,
show: this.show,
zIndex: this.zIndex,
template: this.template,
showSpinner: this.showSpinner,
});
};
this.bdColor = DEFAULTS.BD_COLOR;
this.zIndex = DEFAULTS.Z_INDEX;
this.color = DEFAULTS.SPINNER_COLOR;
this.size = "large";
this.fullScreen = true;
this.name = PRIMARY_SPINNER;
this.template = null;
this.showSpinner = false;
this.divArray = [];
this.divCount = 0;
this.show = false;
}
initObservable() {
this.spinnerService
.getSpinner(this.name)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe((spinner) => {
this.setDefaultOptions();
Object.assign(this.spinner, spinner);
if (spinner.show) {
this.onInputChange();
}
this.changeDetector.detectChanges();
});
}
/**
* Initialization method
*
* @memberof NgxSpinnerComponent
*/
ngOnInit() {
this.setDefaultOptions();
this.initObservable();
}
/**
* To check event triggers inside the Spinner Zone
*
* @param {*} element
* @returns {boolean}
* @memberof NgxSpinnerComponent
*/
isSpinnerZone(element) {
if (element === this.elementRef.nativeElement.parentElement) {
return true;
}
return element.parentNode && this.isSpinnerZone(element.parentNode);
}
/**
* On changes event for input variables
*
* @memberof NgxSpinnerComponent
*/
ngOnChanges(changes) {
for (const propName in changes) {
if (propName) {
const changedProp = changes[propName];
if (changedProp.isFirstChange()) {
return;
}
else if (typeof changedProp.currentValue !== "undefined" &&
changedProp.currentValue !== changedProp.previousValue) {
if (changedProp.currentValue !== "") {
this.spinner[propName] = changedProp.currentValue;
if (propName === "showSpinner") {
if (changedProp.currentValue) {
this.spinnerService.show(this.spinner.name, this.spinner);
}
else {
this.spinnerService.hide(this.spinner.name);
}
}
if (propName === "name") {
this.initObservable();
}
}
}
}
}
}
/**
* To get class for spinner
*
* @memberof NgxSpinnerComponent
*/
getClass(type, size) {
this.spinner.divCount = LOADERS[type];
this.spinner.divArray = Array(this.spinner.divCount)
.fill(0)
.map((_, i) => i);
let sizeClass = "";
switch (size.toLowerCase()) {
case "small":
sizeClass = "la-sm";
break;
case "medium":
sizeClass = "la-2x";
break;
case "large":
sizeClass = "la-3x";
break;
default:
break;
}
return "la-" + type + " " + sizeClass;
}
/**
* Check if input variables have changed
*
* @memberof NgxSpinnerComponent
*/
onInputChange() {
this.spinner.class = this.getClass(this.spinner.type, this.spinner.size);
}
/**
* Component destroy event
*
* @memberof NgxSpinnerComponent
*/
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: NgxSpinnerComponent, deps: [{ token: i1.NgxSpinnerService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: NGX_SPINNER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.8", type: NgxSpinnerComponent, isStandalone: true, selector: "ngx-spinner", inputs: { bdColor: "bdColor", size: "size", color: "color", type: "type", fullScreen: "fullScreen", name: "name", zIndex: "zIndex", template: "template", showSpinner: "showSpinner", disableAnimation: "disableAnimation" }, viewQueries: [{ propertyName: "spinnerDOM", first: true, predicate: ["overlay"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n [@.disabled]=\"disableAnimation\"\n [@fadeIn]=\"'in'\"\n *ngIf=\"spinner.show\"\n class=\"ngx-spinner-overlay\"\n [style.background-color]=\"spinner.bdColor\"\n [style.z-index]=\"spinner.zIndex\"\n [style.position]=\"spinner.fullScreen ? 'fixed' : 'absolute'\"\n #overlay\n>\n <div *ngIf=\"!template\" [class]=\"spinner.class\" [style.color]=\"spinner.color\">\n <div *ngFor=\"let index of spinner.divArray\"></div>\n </div>\n <div *ngIf=\"template\" [innerHTML]=\"template | safeHtml\"></div>\n <div class=\"loading-text\" [style.z-index]=\"spinner.zIndex\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [".ngx-spinner-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ngx-spinner-overlay>div:not(.loading-text){top:50%;left:50%;margin:0;position:absolute;transform:translate(-50%,-50%)}.loading-text{position:absolute;top:60%;left:50%;transform:translate(-50%,-60%)}\n"], dependencies: [{ kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], animations: [
trigger("fadeIn", [
state("in", style({ opacity: 1 })),
transition(":enter", [style({ opacity: 0 }), animate(300)]),
transition(":leave", animate(200, style({ opacity: 0 }))),
]),
], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: NgxSpinnerComponent, decorators: [{
type: Component,
args: [{ imports: [SafeHtmlPipe, NgIf, NgFor], standalone: true, selector: "ngx-spinner", changeDetection: ChangeDetectionStrategy.OnPush, animations: [
trigger("fadeIn", [
state("in", style({ opacity: 1 })),
transition(":enter", [style({ opacity: 0 }), animate(300)]),
transition(":leave", animate(200, style({ opacity: 0 }))),
]),
], template: "<div\n [@.disabled]=\"disableAnimation\"\n [@fadeIn]=\"'in'\"\n *ngIf=\"spinner.show\"\n class=\"ngx-spinner-overlay\"\n [style.background-color]=\"spinner.bdColor\"\n [style.z-index]=\"spinner.zIndex\"\n [style.position]=\"spinner.fullScreen ? 'fixed' : 'absolute'\"\n #overlay\n>\n <div *ngIf=\"!template\" [class]=\"spinner.class\" [style.color]=\"spinner.color\">\n <div *ngFor=\"let index of spinner.divArray\"></div>\n </div>\n <div *ngIf=\"template\" [innerHTML]=\"template | safeHtml\"></div>\n <div class=\"loading-text\" [style.z-index]=\"spinner.zIndex\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [".ngx-spinner-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ngx-spinner-overlay>div:not(.loading-text){top:50%;left:50%;margin:0;position:absolute;transform:translate(-50%,-50%)}.loading-text{position:absolute;top:60%;left:50%;transform:translate(-50%,-60%)}\n"] }]
}], ctorParameters: () => [{ type: i1.NgxSpinnerService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [NGX_SPINNER_CONFIG]
}] }], propDecorators: { bdColor: [{
type: Input
}], size: [{
type: Input
}], color: [{
type: Input
}], type: [{
type: Input
}], fullScreen: [{
type: Input
}], name: [{
type: Input
}], zIndex: [{
type: Input
}], template: [{
type: Input
}], showSpinner: [{
type: Input
}], disableAnimation: [{
type: Input
}], spinnerDOM: [{
type: ViewChild,
args: ["overlay"]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXNwaW5uZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNwaW5uZXIvc3JjL2xpYi9uZ3gtc3Bpbm5lci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc3Bpbm5lci9zcmMvbGliL25neC1zcGlubmVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBRVQsS0FBSyxFQUlMLHVCQUF1QixFQUd2QixTQUFTLEVBRVQsUUFBUSxFQUNSLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsT0FBTyxFQUNQLFFBQVEsRUFFUixVQUFVLEVBQ1YsZUFBZSxHQUNoQixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFDTCxPQUFPLEVBQ1AsS0FBSyxFQUNMLEtBQUssRUFDTCxVQUFVLEVBQ1YsT0FBTyxHQUNSLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFvQixrQkFBa0IsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7O0FBaUI5QyxNQUFNLE9BQU8sbUJBQW1CO0lBc0c5Qiw4REFBOEQ7SUFDOUQsZ0RBQWdEO0lBQ2hELDhDQUE4QztJQUM5Qyw0REFBNEQ7SUFDNUQsV0FBVztJQUNYLDJCQUEyQjtJQUMzQiwrREFBK0Q7SUFDL0QsVUFBVTtJQUNWLG1DQUFtQztJQUNuQyxnQ0FBZ0M7SUFDaEMsUUFBUTtJQUNSLE1BQU07SUFDTixJQUFJO0lBRUo7Ozs7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QUcsRUFBRSxLQUFLLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3lCQUMxRCxDQUFDO3FCQUNIOzswQkErSEUsUUFBUTs7MEJBQ1IsTUFBTTsyQkFBQyxrQkFBa0I7eUNBeEhuQixPQUFPO3NCQUFmLEtBQUs7Z0JBTUcsSUFBSTtzQkFBWixLQUFLO2dCQU1HLEtBQUs7c0JBQWIsS0FBSztnQkFNRyxJQUFJO3NCQUFaLEtBQUs7Z0JBTUcsVUFBVTtzQkFBbEIsS0FBSztnQkFNRyxJQUFJO3NCQUFaLEtBQUs7Z0JBTUcsTUFBTTtzQkFBZCxLQUFLO2dCQU1HLFFBQVE7c0JBQWhCLEtBQUs7Z0JBT0csV0FBVztzQkFBbkIsS0FBSztnQkFRRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBcUNnQixVQUFVO3NCQUEvQixTQUFTO3VCQUFDLFNBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIE9uRGVzdHJveSxcbiAgSW5wdXQsXG4gIE9uSW5pdCxcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2UsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgSG9zdExpc3RlbmVyLFxuICBWaWV3Q2hpbGQsXG4gIEVsZW1lbnRSZWYsXG4gIE9wdGlvbmFsLFxuICBJbmplY3QsXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBOZ3hTcGlubmVyU2VydmljZSB9IGZyb20gXCIuL25neC1zcGlubmVyLnNlcnZpY2VcIjtcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5pbXBvcnQge1xuICBMT0FERVJTLFxuICBERUZBVUxUUyxcbiAgU2l6ZSxcbiAgTmd4U3Bpbm5lcixcbiAgUFJJTUFSWV9TUElOTkVSLFxufSBmcm9tIFwiLi9uZ3gtc3Bpbm5lci5lbnVtXCI7XG5pbXBvcnQge1xuICB0cmlnZ2VyLFxuICBzdGF0ZSxcbiAgc3R5bGUsXG4gIHRyYW5zaXRpb24sXG4gIGFuaW1hdGUsXG59IGZyb20gXCJAYW5ndWxhci9hbmltYXRpb25zXCI7XG5pbXBvcnQgeyBOZ3hTcGlubmVyQ29uZmlnLCBOR1hfU1BJTk5FUl9DT05GSUcgfSBmcm9tIFwiLi9jb25maWdcIjtcbmltcG9ydCB7IFNhZmVIdG1sUGlwZSB9IGZyb20gXCIuL3NhZmUtaHRtbC5waXBlXCI7XG5pbXBvcnQgeyBOZ0ZvciwgTmdJZiB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcblxuQENvbXBvbmVudCh7XG4gIGltcG9ydHM6IFtTYWZlSHRtbFBpcGUsIE5nSWYsIE5nRm9yXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgc2VsZWN0b3I6IFwibmd4LXNwaW5uZXJcIixcbiAgdGVtcGxhdGVVcmw6IFwibmd4LXNwaW5uZXIuY29tcG9uZW50Lmh0bWxcIixcbiAgc3R5bGVVcmxzOiBbXCIuL25neC1zcGlubmVyLmNvbXBvbmVudC5jc3NcIl0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBhbmltYXRpb25zOiBbXG4gICAgdHJpZ2dlcihcImZhZGVJblwiLCBbXG4gICAgICBzdGF0ZShcImluXCIsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSksXG4gICAgICB0cmFuc2l0aW9uKFwiOmVudGVyXCIsIFtzdHlsZSh7IG9wYWNpdHk6IDAgfSksIGFuaW1hdGUoMzAwKV0pLFxuICAgICAgdHJhbnNpdGlvbihcIjpsZWF2ZVwiLCBhbmltYXRlKDIwMCwgc3R5bGUoeyBvcGFjaXR5OiAwIH0pKSksXG4gICAgXSksXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIE5neFNwaW5uZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgLyoqXG4gICAqIFRvIHNldCBiYWNrZHJvcCBjb2xvclxuICAgKiBPbmx5IHN1cHBvcnRzIFJHQkEgY29sb3IgZm9ybWF0XG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKSBiZENvbG9yOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUbyBzZXQgc3Bpbm5lciBzaXplXG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKSBzaXplOiBTaXplO1xuICAvKipcbiAgICogVG8gc2V0IHNwaW5uZXIgY29sb3IoREVGQVVMVFMuU1BJTk5FUl9DT0xPUilcbiAgICpcbiAgICogQG1lbWJlcm9mIE5neFNwaW5uZXJDb21wb25lbnRcbiAgICovXG4gIEBJbnB1dCgpIGNvbG9yOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUbyBzZXQgdHlwZSBvZiBzcGlubmVyXG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKSB0eXBlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUbyB0b2dnbGUgZnVsbHNjcmVlbiBtb2RlXG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKSBmdWxsU2NyZWVuOiBib29sZWFuO1xuICAvKipcbiAgICogU3Bpbm5lciBuYW1lXG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKSBuYW1lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiB6LWluZGV4IHZhbHVlXG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKSB6SW5kZXg6IG51bWJlcjtcbiAgLyoqXG4gICAqIEN1c3RvbSB0ZW1wbGF0ZSBmb3Igc3Bpbm5lci9sb2FkZXJcbiAgICpcbiAgICogQG1lbWJlcm9mIE5neFNwaW5uZXJDb21wb25lbnRcbiAgICovXG4gIEBJbnB1dCgpIHRlbXBsYXRlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBTaG93L0hpZGUgdGhlIHNwaW5uZXJcbiAgICpcbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKSBzaG93U3Bpbm5lcjogYm9vbGVhbjtcblxuICAvKipcbiAgICogVG8gZW5hYmxlL2Rpc2FibGUgYW5pbWF0aW9uXG4gICAqXG4gICAqIEB0eXBlIHtib29sZWFufVxuICAgKiBAbWVtYmVyb2YgTmd4U3Bpbm5lckNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KCkgZGlzYWJsZUFuaW1hdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xuICAvKipcbiAgICogU3Bpbm5lciBPYmplY3RcbiAgICpcbiAgICogQG1lbWJlcm9mIE5neFNwaW5uZXJDb21wb25lbnRcbiAgICovXG4gIHNwaW5uZXI6IE5neFNwaW5uZXIgPSBuZXcgTmd4U3Bpbm5lcigpO1xuICAvKipcbiAgICogQXJyYXkgZm9yIHNwaW5uZXIncyBkaXZcbiAgICpcbiAgICogQG1lbWJlcm9mIE5neFNwaW5uZXJDb21wb25lbnRcbiAgICovXG4gIGRpdkFycmF5OiBBcnJheTxudW1iZXI+O1xuICAvKipcbiAgICogQ291bnRlciBmb3IgZGl2XG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqXG4gICAqL1xuICBkaXZDb3VudDogbnVtYmVyO1xuICAvKipcbiAgICogU2hvdyBzcGlubmVyXG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqKi9cbiAgc2hvdzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFVuc3Vic2NyaWJlIGZyb20gc3Bpbm5lcidzIG9ic2VydmFibGVcbiAgICpcbiAgICogQG1lbWJlcm9mIE5neFNwaW5uZXJDb21wb25lbnRcbiAgICoqL1xuICBuZ1Vuc3Vic2NyaWJlOiBTdWJqZWN0PHZvaWQ+ID0gbmV3IFN1YmplY3QoKTtcbiAgLyoqXG4gICAqIEVsZW1lbnQgUmVmZXJlbmNlXG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBAVmlld0NoaWxkKFwib3ZlcmxheVwiKSBzcGlubmVyRE9NOiB7IG5hdGl2ZUVsZW1lbnQ6IGFueSB9O1xuXG4gIC8vIFRPRE86IGh0dHBzOi8vZ2l0aHViLmNvbS9OYXBzdGVyMjIxMC9uZ3gtc3Bpbm5lci9pc3N1ZXMvMjU5XG4gIC8vIEBIb3N0TGlzdGVuZXIoXCJkb2N1bWVudDprZXlkb3duXCIsIFtcIiRldmVudFwiXSlcbiAgLy8gaGFuZGxlS2V5Ym9hcmRFdmVudChldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAvLyAgIGlmICh0aGlzLnNwaW5uZXJET00gJiYgdGhpcy5zcGlubmVyRE9NLm5hdGl2ZUVsZW1lbnQpIHtcbiAgLy8gICAgIGlmIChcbiAgLy8gICAgICAgdGhpcy5mdWxsU2NyZWVuIHx8XG4gIC8vICAgICAgICghdGhpcy5mdWxsU2NyZWVuICYmIHRoaXMuaXNTcGlubmVyWm9uZShldmVudC50YXJnZXQpKVxuICAvLyAgICAgKSB7XG4gIC8vICAgICAgIGV2ZW50LnJldHVyblZhbHVlID0gZmFsc2U7XG4gIC8vICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIC8vICAgICB9XG4gIC8vICAgfVxuICAvLyB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgTmd4U3Bpbm5lckNvbXBvbmVudC5cbiAgICpcbiAgICogQG1lbWJlcm9mIE5neFNwaW5uZXJDb21wb25lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgc3Bpbm5lclNlcnZpY2U6IE5neFNwaW5uZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBAT3B0aW9uYWwoKVxuICAgIEBJbmplY3QoTkdYX1NQSU5ORVJfQ09ORklHKVxuICAgIHByaXZhdGUgZ2xvYmFsQ29uZmlnOiBOZ3hTcGlubmVyQ29uZmlnXG4gICkge1xuICAgIHRoaXMuYmRDb2xvciA9IERFRkFVTFRTLkJEX0NPTE9SO1xuICAgIHRoaXMuekluZGV4ID0gREVGQVVMVFMuWl9JTkRFWDtcbiAgICB0aGlzLmNvbG9yID0gREVGQVVMVFMuU1BJTk5FUl9DT0xPUjtcbiAgICB0aGlzLnNpemUgPSBcImxhcmdlXCI7XG4gICAgdGhpcy5mdWxsU2NyZWVuID0gdHJ1ZTtcbiAgICB0aGlzLm5hbWUgPSBQUklNQVJZX1NQSU5ORVI7XG4gICAgdGhpcy50ZW1wbGF0ZSA9IG51bGw7XG4gICAgdGhpcy5zaG93U3Bpbm5lciA9IGZhbHNlO1xuXG4gICAgdGhpcy5kaXZBcnJheSA9IFtdO1xuICAgIHRoaXMuZGl2Q291bnQgPSAwO1xuICAgIHRoaXMuc2hvdyA9IGZhbHNlO1xuICB9XG5cbiAgaW5pdE9ic2VydmFibGUoKSB7XG4gICAgdGhpcy5zcGlubmVyU2VydmljZVxuICAgICAgLmdldFNwaW5uZXIodGhpcy5uYW1lKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMubmdVbnN1YnNjcmliZSkpXG4gICAgICAuc3Vic2NyaWJlKChzcGlubmVyOiBOZ3hTcGlubmVyKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0RGVmYXVsdE9wdGlvbnMoKTtcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLnNwaW5uZXIsIHNwaW5uZXIpO1xuICAgICAgICBpZiAoc3Bpbm5lci5zaG93KSB7XG4gICAgICAgICAgdGhpcy5vbklucHV0Q2hhbmdlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXphdGlvbiBtZXRob2RcbiAgICpcbiAgICogQG1lbWJlcm9mIE5neFNwaW5uZXJDb21wb25lbnRcbiAgICovXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuc2V0RGVmYXVsdE9wdGlvbnMoKTtcbiAgICB0aGlzLmluaXRPYnNlcnZhYmxlKCk7XG4gIH1cblxuICAvKipcbiAgICogVG8gY2hlY2sgZXZlbnQgdHJpZ2dlcnMgaW5zaWRlIHRoZSBTcGlubmVyIFpvbmVcbiAgICpcbiAgICogQHBhcmFtIHsqfSBlbGVtZW50XG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKiBAbWVtYmVyb2YgTmd4U3Bpbm5lckNvbXBvbmVudFxuICAgKi9cbiAgaXNTcGlubmVyWm9uZShlbGVtZW50OiBhbnkpOiBib29sZWFuIHtcbiAgICBpZiAoZWxlbWVudCA9PT0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucGFyZW50RWxlbWVudCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBlbGVtZW50LnBhcmVudE5vZGUgJiYgdGhpcy5pc1NwaW5uZXJab25lKGVsZW1lbnQucGFyZW50Tm9kZSk7XG4gIH1cblxuICAvKipcbiAgICogVG8gc2V0IGRlZmF1bHQgbmd4LXNwaW5uZXIgb3B0aW9uc1xuICAgKlxuICAgKiBAbWVtYmVyb2YgTmd4U3Bpbm5lckNvbXBvbmVudFxuICAgKi9cbiAgc2V0RGVmYXVsdE9wdGlvbnMgPSAoKSA9PiB7XG4gICAgY29uc3QgeyB0eXBlIH0gPSB0aGlzLmdsb2JhbENvbmZpZyA/PyB7fTtcbiAgICB0aGlzLnNwaW5uZXIgPSBOZ3hTcGlubmVyLmNyZWF0ZSh7XG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICBiZENvbG9yOiB0aGlzLmJkQ29sb3IsXG4gICAgICBzaXplOiB0aGlzLnNpemUsXG4gICAgICBjb2xvcjogdGhpcy5jb2xvcixcbiAgICAgIHR5cGU6IHRoaXMudHlwZSA/PyB0eXBlLFxuICAgICAgZnVsbFNjcmVlbjogdGhpcy5mdWxsU2NyZWVuLFxuICAgICAgZGl2QXJyYXk6IHRoaXMuZGl2QXJyYXksXG4gICAgICBkaXZDb3VudDogdGhpcy5kaXZDb3VudCxcbiAgICAgIHNob3c6IHRoaXMuc2hvdyxcbiAgICAgIHpJbmRleDogdGhpcy56SW5kZXgsXG4gICAgICB0ZW1wbGF0ZTogdGhpcy50ZW1wbGF0ZSxcbiAgICAgIHNob3dTcGlubmVyOiB0aGlzLnNob3dTcGlubmVyLFxuICAgIH0pO1xuICB9O1xuICAvKipcbiAgICogT24gY2hhbmdlcyBldmVudCBmb3IgaW5wdXQgdmFyaWFibGVzXG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiB7IFtwcm9wS2V5OiBzdHJpbmddOiBTaW1wbGVDaGFuZ2UgfSkge1xuICAgIGZvciAoY29uc3QgcHJvcE5hbWUgaW4gY2hhbmdlcykge1xuICAgICAgaWYgKHByb3BOYW1lKSB7XG4gICAgICAgIGNvbnN0IGNoYW5nZWRQcm9wID0gY2hhbmdlc1twcm9wTmFtZV07XG4gICAgICAgIGlmIChjaGFuZ2VkUHJvcC5pc0ZpcnN0Q2hhbmdlKCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgdHlwZW9mIGNoYW5nZWRQcm9wLmN1cnJlbnRWYWx1ZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgIGNoYW5nZWRQcm9wLmN1cnJlbnRWYWx1ZSAhPT0gY2hhbmdlZFByb3AucHJldmlvdXNWYWx1ZVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAoY2hhbmdlZFByb3AuY3VycmVudFZhbHVlICE9PSBcIlwiKSB7XG4gICAgICAgICAgICB0aGlzLnNwaW5uZXJbcHJvcE5hbWVdID0gY2hhbmdlZFByb3AuY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgaWYgKHByb3BOYW1lID09PSBcInNob3dTcGlubmVyXCIpIHtcbiAgICAgICAgICAgICAgaWYgKGNoYW5nZWRQcm9wLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lclNlcnZpY2Uuc2hvdyh0aGlzLnNwaW5uZXIubmFtZSwgdGhpcy5zcGlubmVyKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXJTZXJ2aWNlLmhpZGUodGhpcy5zcGlubmVyLm5hbWUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwcm9wTmFtZSA9PT0gXCJuYW1lXCIpIHtcbiAgICAgICAgICAgICAgdGhpcy5pbml0T2JzZXJ2YWJsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICAvKipcbiAgICogVG8gZ2V0IGNsYXNzIGZvciBzcGlubmVyXG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBnZXRDbGFzcyh0eXBlOiBzdHJpbmcsIHNpemU6IFNpemUpOiBzdHJpbmcge1xuICAgIHRoaXMuc3Bpbm5lci5kaXZDb3VudCA9IExPQURFUlNbdHlwZV07XG4gICAgdGhpcy5zcGlubmVyLmRpdkFycmF5ID0gQXJyYXkodGhpcy5zcGlubmVyLmRpdkNvdW50KVxuICAgICAgLmZpbGwoMClcbiAgICAgIC5tYXAoKF8sIGkpID0+IGkpO1xuICAgIGxldCBzaXplQ2xhc3MgPSBcIlwiO1xuICAgIHN3aXRjaCAoc2l6ZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlIFwic21hbGxcIjpcbiAgICAgICAgc2l6ZUNsYXNzID0gXCJsYS1zbVwiO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJtZWRpdW1cIjpcbiAgICAgICAgc2l6ZUNsYXNzID0gXCJsYS0yeFwiO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJsYXJnZVwiOlxuICAgICAgICBzaXplQ2xhc3MgPSBcImxhLTN4XCI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBcImxhLVwiICsgdHlwZSArIFwiIFwiICsgc2l6ZUNsYXNzO1xuICB9XG4gIC8qKlxuICAgKiBDaGVjayBpZiBpbnB1dCB2YXJpYWJsZXMgaGF2ZSBjaGFuZ2VkXG4gICAqXG4gICAqIEBtZW1iZXJvZiBOZ3hTcGlubmVyQ29tcG9uZW50XG4gICAqL1xuICBvbklucHV0Q2hhbmdlKCkge1xuICAgIHRoaXMuc3Bpbm5lci5jbGFzcyA9IHRoaXMuZ2V0Q2xhc3ModGhpcy5zcGlubmVyLnR5cGUsIHRoaXMuc3Bpbm5lci5zaXplKTtcbiAgfVxuICAvKipcbiAgICogQ29tcG9uZW50IGRlc3Ryb3kgZXZlbnRcbiAgICpcbiAgICogQG1lbWJlcm9mIE5neFNwaW5uZXJDb21wb25lbnRcbiAgICovXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMubmdVbnN1YnNjcmliZS5uZXh0KCk7XG4gICAgdGhpcy5uZ1Vuc3Vic2NyaWJlLmNvbXBsZXRlKCk7XG4gIH1cbn1cbiIsIjxkaXZcbiAgW0AuZGlzYWJsZWRdPVwiZGlzYWJsZUFuaW1hdGlvblwiXG4gIFtAZmFkZUluXT1cIidpbidcIlxuICAqbmdJZj1cInNwaW5uZXIuc2hvd1wiXG4gIGNsYXNzPVwibmd4LXNwaW5uZXItb3ZlcmxheVwiXG4gIFtzdHlsZS5iYWNrZ3JvdW5kLWNvbG9yXT1cInNwaW5uZXIuYmRDb2xvclwiXG4gIFtzdHlsZS56LWluZGV4XT1cInNwaW5uZXIuekluZGV4XCJcbiAgW3N0eWxlLnBvc2l0aW9uXT1cInNwaW5uZXIuZnVsbFNjcmVlbiA/ICdmaXhlZCcgOiAnYWJzb2x1dGUnXCJcbiAgI292ZXJsYXlcbj5cbiAgPGRpdiAqbmdJZj1cIiF0ZW1wbGF0ZVwiIFtjbGFzc109XCJzcGlubmVyLmNsYXNzXCIgW3N0eWxlLmNvbG9yXT1cInNwaW5uZXIuY29sb3JcIj5cbiAgICA8ZGl2ICpuZ0Zvcj1cImxldCBpbmRleCBvZiBzcGlubmVyLmRpdkFycmF5XCI+PC9kaXY+XG4gIDwvZGl2PlxuICA8ZGl2ICpuZ0lmPVwidGVtcGxhdGVcIiBbaW5uZXJIVE1MXT1cInRlbXBsYXRlIHwgc2FmZUh0bWxcIj48L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImxvYWRpbmctdGV4dFwiIFtzdHlsZS56LWluZGV4XT1cInNwaW5uZXIuekluZGV4XCI+XG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19