UNPKG

@cisstech/nge

Version:

NG Essentials is a collection of libraries for Angular developers.

117 lines 27.6 kB
import { Component, ContentChildren, EventEmitter, Input, Output, } from '@angular/core'; import { ListTemplateComponent } from './list-template.component'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "@angular/forms"; import * as i3 from "ngx-pipes"; export class ListComponent { constructor() { this.items = []; this.selectable = false; this.filterBy = []; this.selections = []; this.selectionsChange = new EventEmitter(); this._selectionStates = {}; this._noResultTemplate = null; this._emptyStateTemplate = null; this._empty = false; } get hasSelection() { return !!this.selections.length; } get classes() { if (!this.containerClass) { return {}; } return { [this.containerClass]: true, }; } ngOnChanges() { this._empty = !this.items?.length; setTimeout(() => { this.checkSelections(); }, 300); } ngAfterContentInit() { this._noResultTemplate = this.templates.find((e) => e.slot === 'noresult')?.template || null; this._emptyStateTemplate = this.templates.find((e) => e.slot === 'empty')?.template || null; } unselect(item) { const id = item[this.idField]; this.selections = this.selections.filter((e) => e !== item); this._selectionStates[id] = false; this.selectionsChange.emit(this.selections); } _trackBy(index, item) { if (this.trackBy) { return item[this.trackBy] ?? index; } return index; } _template(context, slot) { return (this.templates.find((e) => { if (e.slot === slot && e.when) { return e.when(context); } return false; })?.template || this.templates.find((e) => e.slot === slot && !e.when)?.template || null); } _isSelected(item) { return !!this.selections.find((e) => e === item); } _toggleSelection(item) { for (let i = 0; i < this.selections.length; i++) { if (this.equals(this.selections[i], item)) { this.selections.splice(i, 1); this.selectionsChange.emit(this.selections); return; } } this.selections.push(item); this.selectionsChange.emit(this.selections); } equals(a, b) { return a[this.idField] === b[this.idField]; } checkSelections() { this.selections = this.selections.filter((selection) => { if (this.items.find((item) => this.equals(item, selection))) { return true; } delete this._selectionStates[selection[this.idField]]; return false; }); this.selectionsChange.emit(this.selections); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: ListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.1", type: ListComponent, selector: "ui-list", inputs: { idField: "idField", items: "items", trackBy: "trackBy", selectable: "selectable", filter: "filter", filterBy: "filterBy", selections: "selections", containerClass: "containerClass" }, outputs: { selectionsChange: "selectionsChange" }, queries: [{ propertyName: "templates", predicate: ListTemplateComponent }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"selectable\">\n <ng-container *ngFor=\"let item of selections; trackBy: _trackBy.bind(this)\">\n <ng-container *ngTemplateOutlet=\"_template(item, 'selection'); context: {item: item}\"></ng-container>\n </ng-container>\n</ng-container>\n\n<!-- TEMPLATE FOR EMPTY STATE -->\n<ng-template #emptyStateTemplate>\n <!-- SHOW EMPTY STATE TEMPLATE IF FILTER IS DEFINED -->\n <ng-container *ngIf=\"!filter?.trim(); else: noResult\">\n <ng-container *ngTemplateOutlet=\"_emptyStateTemplate\"></ng-container>\n </ng-container>\n <!-- SHOW NO RESULT TEMPLATE IF FILTER IS DEFINED -->\n <ng-template #noResult>\n <ng-container *ngTemplateOutlet=\"_noResultTemplate; context: { $implicit: filter }\"></ng-container>\n </ng-template>\n</ng-template>\n\n<!-- APPLY CURRENT FILTER TO ITEMS IF NEEDED AND STORE THE RESULT TO A VARIABLE `filtered` -->\n<ng-container *ngIf=\"(filter ? (items | filterBy: filterBy: filter) : items) as filtered\">\n <!-- SHOW EMPTY STATE IF NO ITEM ELSE SHOW ROWS -->\n <ng-container *ngIf=\"filtered.length; else: emptyStateTemplate\">\n <ul class=\"ui-list-container\" [ngClass]=\"classes\">\n <ng-container *ngFor=\"let item of filtered; trackBy: _trackBy.bind(this) let index=index; let first=first; let last=last; let even=even; let odd=odd\">\n <ng-container *ngIf=\"{item: item, items: filtered, odd: odd, last: last, even: even, index: index, first: first} as context\">\n <div class=\"ui-list-item\">\n <!-- HEADER -->\n <ng-container *ngIf=\"_template(context, 'header') as header\">\n <li class=\"ui-list-item-header\">\n <ng-container *ngTemplateOutlet=\"header; context: context\"></ng-container>\n </li>\n </ng-container>\n <!-- ROW -->\n <ng-container *ngIf=\"_template(context, 'row') as row\">\n <li class=\"ui-list-item-content\" [class.selectable]=\"selectable\">\n <ng-container *ngTemplateOutlet=\"row; context: context\"></ng-container>\n <!-- CHECKBOX -->\n <label class=\"ui-list-label\" *ngIf=\"selectable\">\n <input\n class=\"ui-list-label__checkbox\"\n type=\"checkbox\"\n [(ngModel)]=\"_selectionStates[$any(item)[idField]]\"\n (ngModelChange)=\"_toggleSelection(item)\"/>\n <span class=\"ui-list-label__text\">\n <span class=\"ui-list-label__check\">\n <span class=\"ui-list-label__icon\">\u2713</span>\n </span>\n </span>\n </label>\n </li>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </ul>\n </ng-container>\n</ng-container>\n", styles: [":host{display:block;min-height:100%;height:auto;width:100%;position:relative;--inner-margin-bottom: 12px}ul,li{margin:0;padding:0;list-style:none}li{display:block}li.selectable{display:grid;grid-template-columns:90% 10%;column-gap:12px;align-items:center}.ui-list-item{margin-bottom:var(--inner-margin-bottom)}.ui-list-label__checkbox{display:none}.ui-list-label__check{display:inline-block;border-radius:50%;border:5px solid rgba(0,0,0,.1);background:#fff;vertical-align:middle;margin-right:20px;width:2em;height:2em;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:border .3s ease}.ui-list-label__check .label__icon{opacity:.2;color:transparent;transition:opacity .3s .1s ease;-webkit-text-stroke:3px rgba(0,0,0,.5)}.ui-list-label__check:hover{border:5px solid rgba(0,0,0,.2)}.ui-list-label__checkbox:checked+.ui-list-label__text .ui-list-label__check{animation:check .5s cubic-bezier(.895,.03,.685,.22) forwards}.ui-list-label__checkbox:checked+.ui-list-label__text .ui-list-label__check .ui-list-label__icon{opacity:1;transform:scale(0);color:#fff;-webkit-text-stroke:0;animation:icon .3s cubic-bezier(1,.008,.565,1.65) .1s 1 forwards}.spacer{flex:1}@keyframes icon{0%{opacity:0;transform:scale(.3)}to{opacity:1;transform:scale(1)}}@keyframes check{0%{width:1.5em;height:1.5em;border-width:5px}10%{width:1.5em;height:1.5em;opacity:.1;background:#0003;border-width:15px}12%{width:1.5em;height:1.5em;opacity:.4;background:#0000001a;border-width:0}50%{width:2em;height:2em;background:#00d478;border:0;opacity:.6}to{width:2em;height:2em;background:#00d478;border:0;opacity:1}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i3.FilterByPipe, name: "filterBy" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: ListComponent, decorators: [{ type: Component, args: [{ selector: 'ui-list', template: "<ng-container *ngIf=\"selectable\">\n <ng-container *ngFor=\"let item of selections; trackBy: _trackBy.bind(this)\">\n <ng-container *ngTemplateOutlet=\"_template(item, 'selection'); context: {item: item}\"></ng-container>\n </ng-container>\n</ng-container>\n\n<!-- TEMPLATE FOR EMPTY STATE -->\n<ng-template #emptyStateTemplate>\n <!-- SHOW EMPTY STATE TEMPLATE IF FILTER IS DEFINED -->\n <ng-container *ngIf=\"!filter?.trim(); else: noResult\">\n <ng-container *ngTemplateOutlet=\"_emptyStateTemplate\"></ng-container>\n </ng-container>\n <!-- SHOW NO RESULT TEMPLATE IF FILTER IS DEFINED -->\n <ng-template #noResult>\n <ng-container *ngTemplateOutlet=\"_noResultTemplate; context: { $implicit: filter }\"></ng-container>\n </ng-template>\n</ng-template>\n\n<!-- APPLY CURRENT FILTER TO ITEMS IF NEEDED AND STORE THE RESULT TO A VARIABLE `filtered` -->\n<ng-container *ngIf=\"(filter ? (items | filterBy: filterBy: filter) : items) as filtered\">\n <!-- SHOW EMPTY STATE IF NO ITEM ELSE SHOW ROWS -->\n <ng-container *ngIf=\"filtered.length; else: emptyStateTemplate\">\n <ul class=\"ui-list-container\" [ngClass]=\"classes\">\n <ng-container *ngFor=\"let item of filtered; trackBy: _trackBy.bind(this) let index=index; let first=first; let last=last; let even=even; let odd=odd\">\n <ng-container *ngIf=\"{item: item, items: filtered, odd: odd, last: last, even: even, index: index, first: first} as context\">\n <div class=\"ui-list-item\">\n <!-- HEADER -->\n <ng-container *ngIf=\"_template(context, 'header') as header\">\n <li class=\"ui-list-item-header\">\n <ng-container *ngTemplateOutlet=\"header; context: context\"></ng-container>\n </li>\n </ng-container>\n <!-- ROW -->\n <ng-container *ngIf=\"_template(context, 'row') as row\">\n <li class=\"ui-list-item-content\" [class.selectable]=\"selectable\">\n <ng-container *ngTemplateOutlet=\"row; context: context\"></ng-container>\n <!-- CHECKBOX -->\n <label class=\"ui-list-label\" *ngIf=\"selectable\">\n <input\n class=\"ui-list-label__checkbox\"\n type=\"checkbox\"\n [(ngModel)]=\"_selectionStates[$any(item)[idField]]\"\n (ngModelChange)=\"_toggleSelection(item)\"/>\n <span class=\"ui-list-label__text\">\n <span class=\"ui-list-label__check\">\n <span class=\"ui-list-label__icon\">\u2713</span>\n </span>\n </span>\n </label>\n </li>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </ul>\n </ng-container>\n</ng-container>\n", styles: [":host{display:block;min-height:100%;height:auto;width:100%;position:relative;--inner-margin-bottom: 12px}ul,li{margin:0;padding:0;list-style:none}li{display:block}li.selectable{display:grid;grid-template-columns:90% 10%;column-gap:12px;align-items:center}.ui-list-item{margin-bottom:var(--inner-margin-bottom)}.ui-list-label__checkbox{display:none}.ui-list-label__check{display:inline-block;border-radius:50%;border:5px solid rgba(0,0,0,.1);background:#fff;vertical-align:middle;margin-right:20px;width:2em;height:2em;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:border .3s ease}.ui-list-label__check .label__icon{opacity:.2;color:transparent;transition:opacity .3s .1s ease;-webkit-text-stroke:3px rgba(0,0,0,.5)}.ui-list-label__check:hover{border:5px solid rgba(0,0,0,.2)}.ui-list-label__checkbox:checked+.ui-list-label__text .ui-list-label__check{animation:check .5s cubic-bezier(.895,.03,.685,.22) forwards}.ui-list-label__checkbox:checked+.ui-list-label__text .ui-list-label__check .ui-list-label__icon{opacity:1;transform:scale(0);color:#fff;-webkit-text-stroke:0;animation:icon .3s cubic-bezier(1,.008,.565,1.65) .1s 1 forwards}.spacer{flex:1}@keyframes icon{0%{opacity:0;transform:scale(.3)}to{opacity:1;transform:scale(1)}}@keyframes check{0%{width:1.5em;height:1.5em;border-width:5px}10%{width:1.5em;height:1.5em;opacity:.1;background:#0003;border-width:15px}12%{width:1.5em;height:1.5em;opacity:.4;background:#0000001a;border-width:0}50%{width:2em;height:2em;background:#00d478;border:0;opacity:.6}to{width:2em;height:2em;background:#00d478;border:0;opacity:1}}\n"] }] }], propDecorators: { templates: [{ type: ContentChildren, args: [ListTemplateComponent] }], idField: [{ type: Input }], items: [{ type: Input }], trackBy: [{ type: Input }], selectable: [{ type: Input }], filter: [{ type: Input }], filterBy: [{ type: Input }], selections: [{ type: Input }], containerClass: [{ type: Input }], selectionsChange: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ2UvdWkvbGlzdC9zcmMvbGlzdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ2UvdWkvbGlzdC9zcmMvbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUNULGVBQWUsRUFDZixZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sR0FHUCxNQUFNLGVBQWUsQ0FBQTtBQUV0QixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQTs7Ozs7QUFPakUsTUFBTSxPQUFPLGFBQWE7SUFMMUI7UUFhRSxVQUFLLEdBQVEsRUFBRSxDQUFBO1FBTWYsZUFBVSxHQUFHLEtBQUssQ0FBQTtRQU1sQixhQUFRLEdBQWEsRUFBRSxDQUFBO1FBR3ZCLGVBQVUsR0FBUSxFQUFFLENBQUE7UUFNcEIscUJBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQTtRQUUxQyxxQkFBZ0IsR0FBNEIsRUFBRSxDQUFBO1FBQzlDLHNCQUFpQixHQUE0QixJQUFJLENBQUE7UUFDakQsd0JBQW1CLEdBQTRCLElBQUksQ0FBQTtRQUVuRCxXQUFNLEdBQUcsS0FBSyxDQUFBO0tBb0ZmO0lBbEZDLElBQUksWUFBWTtRQUNkLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFBO0lBQ2pDLENBQUM7SUFFRCxJQUFjLE9BQU87UUFDbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN6QixPQUFPLEVBQUUsQ0FBQTtRQUNYLENBQUM7UUFDRCxPQUFPO1lBQ0wsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsSUFBSTtTQUM1QixDQUFBO0lBQ0gsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsTUFBTSxH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VCxLQUFLO2dCQUlOLE1BQU07c0JBREwsS0FBSztnQkFJTixRQUFRO3NCQURQLEtBQUs7Z0JBSU4sVUFBVTtzQkFEVCxLQUFLO2dCQUlOLGNBQWM7c0JBRGIsS0FBSztnQkFJTixnQkFBZ0I7c0JBRGYsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBUZW1wbGF0ZVJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcbmltcG9ydCB7IExpc3RDb250ZXh0LCBMaXN0VGVtcGxhdGVTbG90cyB9IGZyb20gJy4vbGlzdCdcbmltcG9ydCB7IExpc3RUZW1wbGF0ZUNvbXBvbmVudCB9IGZyb20gJy4vbGlzdC10ZW1wbGF0ZS5jb21wb25lbnQnXG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3VpLWxpc3QnLFxuICB0ZW1wbGF0ZVVybDogJy4vbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2xpc3QuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgTGlzdENvbXBvbmVudDxUPiBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgQWZ0ZXJDb250ZW50SW5pdCB7XG4gIEBDb250ZW50Q2hpbGRyZW4oTGlzdFRlbXBsYXRlQ29tcG9uZW50KVxuICB0ZW1wbGF0ZXMhOiBRdWVyeUxpc3Q8TGlzdFRlbXBsYXRlQ29tcG9uZW50PFQ+PlxuXG4gIEBJbnB1dCgpXG4gIGlkRmllbGQhOiBzdHJpbmdcblxuICBASW5wdXQoKVxuICBpdGVtczogVFtdID0gW11cblxuICBASW5wdXQoKVxuICB0cmFja0J5Pzogc3RyaW5nXG5cbiAgQElucHV0KClcbiAgc2VsZWN0YWJsZSA9IGZhbHNlXG5cbiAgQElucHV0KClcbiAgZmlsdGVyPzogc3RyaW5nXG5cbiAgQElucHV0KClcbiAgZmlsdGVyQnk6IHN0cmluZ1tdID0gW11cblxuICBASW5wdXQoKVxuICBzZWxlY3Rpb25zOiBUW10gPSBbXVxuXG4gIEBJbnB1dCgpXG4gIGNvbnRhaW5lckNsYXNzPzogc3RyaW5nXG5cbiAgQE91dHB1dCgpXG4gIHNlbGVjdGlvbnNDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFRbXT4oKVxuXG4gIF9zZWxlY3Rpb25TdGF0ZXM6IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+ID0ge31cbiAgX25vUmVzdWx0VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsID0gbnVsbFxuICBfZW1wdHlTdGF0ZVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbCA9IG51bGxcblxuICBfZW1wdHkgPSBmYWxzZVxuXG4gIGdldCBoYXNTZWxlY3Rpb24oKSB7XG4gICAgcmV0dXJuICEhdGhpcy5zZWxlY3Rpb25zLmxlbmd0aFxuICB9XG5cbiAgcHJvdGVjdGVkIGdldCBjbGFzc2VzKCkge1xuICAgIGlmICghdGhpcy5jb250YWluZXJDbGFzcykge1xuICAgICAgcmV0dXJuIHt9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBbdGhpcy5jb250YWluZXJDbGFzc106IHRydWUsXG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgdGhpcy5fZW1wdHkgPSAhdGhpcy5pdGVtcz8ubGVuZ3RoXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmNoZWNrU2VsZWN0aW9ucygpXG4gICAgfSwgMzAwKVxuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgIHRoaXMuX25vUmVzdWx0VGVtcGxhdGUgPSB0aGlzLnRlbXBsYXRlcy5maW5kKChlKSA9PiBlLnNsb3QgPT09ICdub3Jlc3VsdCcpPy50ZW1wbGF0ZSB8fCBudWxsXG4gICAgdGhpcy5fZW1wdHlTdGF0ZVRlbXBsYXRlID0gdGhpcy50ZW1wbGF0ZXMuZmluZCgoZSkgPT4gZS5zbG90ID09PSAnZW1wdHknKT8udGVtcGxhdGUgfHwgbnVsbFxuICB9XG5cbiAgdW5zZWxlY3QoaXRlbTogVCkge1xuICAgIGNvbnN0IGlkID0gKGl0ZW0gYXMgYW55KVt0aGlzLmlkRmllbGRdXG4gICAgdGhpcy5zZWxlY3Rpb25zID0gdGhpcy5zZWxlY3Rpb25zLmZpbHRlcigoZSkgPT4gZSAhPT0gaXRlbSlcbiAgICB0aGlzLl9zZWxlY3Rpb25TdGF0ZXNbaWRdID0gZmFsc2VcbiAgICB0aGlzLnNlbGVjdGlvbnNDaGFuZ2UuZW1pdCh0aGlzLnNlbGVjdGlvbnMpXG4gIH1cblxuICBfdHJhY2tCeShpbmRleDogbnVtYmVyLCBpdGVtOiBhbnkpOiBhbnkge1xuICAgIGlmICh0aGlzLnRyYWNrQnkpIHtcbiAgICAgIHJldHVybiBpdGVtW3RoaXMudHJhY2tCeV0gPz8gaW5kZXhcbiAgICB9XG4gICAgcmV0dXJuIGluZGV4XG4gIH1cblxuICBfdGVtcGxhdGUoY29udGV4dDogVCB8IExpc3RDb250ZXh0PFQ+LCBzbG90OiBMaXN0VGVtcGxhdGVTbG90cyk6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy50ZW1wbGF0ZXMuZmluZCgoZSkgPT4ge1xuICAgICAgICBpZiAoZS5zbG90ID09PSBzbG90ICYmIGUud2hlbikge1xuICAgICAgICAgIHJldHVybiBlLndoZW4oY29udGV4dClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH0pPy50ZW1wbGF0ZSB8fFxuICAgICAgdGhpcy50ZW1wbGF0ZXMuZmluZCgoZSkgPT4gZS5zbG90ID09PSBzbG90ICYmICFlLndoZW4pPy50ZW1wbGF0ZSB8fFxuICAgICAgbnVsbFxuICAgIClcbiAgfVxuXG4gIF9pc1NlbGVjdGVkKGl0ZW06IFQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLnNlbGVjdGlvbnMuZmluZCgoZSkgPT4gZSA9PT0gaXRlbSlcbiAgfVxuXG4gIF90b2dnbGVTZWxlY3Rpb24oaXRlbTogVCk6IHZvaWQge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zZWxlY3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGhpcy5lcXVhbHModGhpcy5zZWxlY3Rpb25zW2ldLCBpdGVtKSkge1xuICAgICAgICB0aGlzLnNlbGVjdGlvbnMuc3BsaWNlKGksIDEpXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uc0NoYW5nZS5lbWl0KHRoaXMuc2VsZWN0aW9ucylcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0aW9ucy5wdXNoKGl0ZW0pXG4gICAgdGhpcy5zZWxlY3Rpb25zQ2hhbmdlLmVtaXQodGhpcy5zZWxlY3Rpb25zKVxuICB9XG5cbiAgcHJpdmF0ZSBlcXVhbHMoYTogYW55LCBiOiBhbnkpIHtcbiAgICByZXR1cm4gYVt0aGlzLmlkRmllbGRdID09PSBiW3RoaXMuaWRGaWVsZF1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tTZWxlY3Rpb25zKCkge1xuICAgIHRoaXMuc2VsZWN0aW9ucyA9IHRoaXMuc2VsZWN0aW9ucy5maWx0ZXIoKHNlbGVjdGlvbjogYW55KSA9PiB7XG4gICAgICBpZiAodGhpcy5pdGVtcy5maW5kKChpdGVtKSA9PiB0aGlzLmVxdWFscyhpdGVtLCBzZWxlY3Rpb24pKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgICAgZGVsZXRlIHRoaXMuX3NlbGVjdGlvblN0YXRlc1tzZWxlY3Rpb25bdGhpcy5pZEZpZWxkXV1cbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH0pXG4gICAgdGhpcy5zZWxlY3Rpb25zQ2hhbmdlLmVtaXQodGhpcy5zZWxlY3Rpb25zKVxuICB9XG59XG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0YWJsZVwiPlxuICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHNlbGVjdGlvbnM7IHRyYWNrQnk6IF90cmFja0J5LmJpbmQodGhpcylcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJfdGVtcGxhdGUoaXRlbSwgJ3NlbGVjdGlvbicpOyBjb250ZXh0OiB7aXRlbTogaXRlbX1cIj48L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLWNvbnRhaW5lcj5cblxuPCEtLSBURU1QTEFURSBGT1IgRU1QVFkgU1RBVEUgLS0+XG48bmctdGVtcGxhdGUgI2VtcHR5U3RhdGVUZW1wbGF0ZT5cbiAgPCEtLSBTSE9XIEVNUFRZIFNUQVRFIFRFTVBMQVRFIElGIEZJTFRFUiBJUyBERUZJTkVEIC0tPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWZpbHRlcj8udHJpbSgpOyBlbHNlOiBub1Jlc3VsdFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJfZW1wdHlTdGF0ZVRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuICA8IS0tIFNIT1cgTk8gUkVTVUxUIFRFTVBMQVRFIElGIEZJTFRFUiBJUyBERUZJTkVEIC0tPlxuICA8bmctdGVtcGxhdGUgI25vUmVzdWx0PlxuICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJfbm9SZXN1bHRUZW1wbGF0ZTsgY29udGV4dDogeyAkaW1wbGljaXQ6IGZpbHRlciB9XCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctdGVtcGxhdGU+XG48L25nLXRlbXBsYXRlPlxuXG48IS0tIEFQUExZIENVUlJFTlQgRklMVEVSIFRPIElURU1TIElGIE5FRURFRCBBTkQgU1RPUkUgVEhFIFJFU1VMVCBUTyBBIFZBUklBQkxFIGBmaWx0ZXJlZGAgLS0+XG48bmctY29udGFpbmVyICpuZ0lmPVwiKGZpbHRlciA/IChpdGVtcyB8IGZpbHRlckJ5OiBmaWx0ZXJCeTogZmlsdGVyKSA6IGl0ZW1zKSBhcyBmaWx0ZXJlZFwiPlxuICA8IS0tIFNIT1cgRU1QVFkgU1RBVEUgSUYgTk8gSVRFTSBFTFNFIFNIT1cgUk9XUyAtLT5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImZpbHRlcmVkLmxlbmd0aDsgZWxzZTogZW1wdHlTdGF0ZVRlbXBsYXRlXCI+XG4gIDx1bCBjbGFzcz1cInVpLWxpc3QtY29udGFpbmVyXCIgW25nQ2xhc3NdPVwiY2xhc3Nlc1wiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgZmlsdGVyZWQ7IHRyYWNrQnk6IF90cmFja0J5LmJpbmQodGhpcykgbGV0IGluZGV4PWluZGV4OyBsZXQgZmlyc3Q9Zmlyc3Q7IGxldCBsYXN0PWxhc3Q7IGxldCBldmVuPWV2ZW47IGxldCBvZGQ9b2RkXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwie2l0ZW06IGl0ZW0sIGl0ZW1zOiBmaWx0ZXJlZCwgb2RkOiBvZGQsIGxhc3Q6IGxhc3QsIGV2ZW46IGV2ZW4sIGluZGV4OiBpbmRleCwgZmlyc3Q6IGZpcnN0fSBhcyBjb250ZXh0XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ1aS1saXN0LWl0ZW1cIj5cbiAgICAgICAgICA8IS0tIEhFQURFUiAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiX3RlbXBsYXRlKGNvbnRleHQsICdoZWFkZXInKSBhcyBoZWFkZXJcIj5cbiAgICAgICAgICAgIDxsaSBjbGFzcz1cInVpLWxpc3QtaXRlbS1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhlYWRlcjsgY29udGV4dDogY29udGV4dFwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8IS0tIFJPVyAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiX3RlbXBsYXRlKGNvbnRleHQsICdyb3cnKSBhcyByb3dcIj5cbiAgICAgICAgICAgIDxsaSBjbGFzcz1cInVpLWxpc3QtaXRlbS1jb250ZW50XCIgW2NsYXNzLnNlbGVjdGFibGVdPVwic2VsZWN0YWJsZVwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwicm93OyBjb250ZXh0OiBjb250ZXh0XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwhLS0gQ0hFQ0tCT1ggLS0+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInVpLWxpc3QtbGFiZWxcIiAqbmdJZj1cInNlbGVjdGFibGVcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwidWktbGlzdC1sYWJlbF9fY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiX3NlbGVjdGlvblN0YXRlc1skYW55KGl0ZW0pW2lkRmllbGRdXVwiXG4gICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJfdG9nZ2xlU2VsZWN0aW9uKGl0ZW0pXCIvPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidWktbGlzdC1sYWJlbF9fdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ1aS1saXN0LWxhYmVsX19jaGVja1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInVpLWxpc3QtbGFiZWxfX2ljb25cIj7inJM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC91bD5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLWNvbnRhaW5lcj5cbiJdfQ==