@nova-ui/bits
Version:
SolarWinds Nova Framework
109 lines • 21.8 kB
JavaScript
// © 2022 SolarWinds Worldwide, LLC. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import { CdkDrag, CdkDropList } from "@angular/cdk/drag-drop";
import { ContentChildren, Directive, ElementRef, Input, QueryList, Renderer2, } from "@angular/core";
import { combineLatest, fromEvent, merge, of, Subject } from "rxjs";
import { distinctUntilChanged, map, mapTo, shareReplay, startWith, switchMap, takeUntil, tap, } from "rxjs/operators";
import * as i0 from "@angular/core";
import * as i1 from "@angular/cdk/drag-drop";
export class DndDropTargetDirective {
// true when the drag has started
get isDropZoneActive() {
// Using cdk default isReceiving and isDragging (When the item is assigned without drop to dropList,
// isReceiving returns false, and we replace it with isDragging to maintain the expected behavior.)
return (this.targetDropList._dropListRef.isReceiving() ||
this.targetDropList._dropListRef.isDragging());
}
// and also available for consumer to be able to use it without async
get canLastDragItemBeDropped() {
return this._canLastDragItemBeDropped;
}
// canDrop primitive value is used for the host element class binding
constructor(targetDropList, renderer, hostElement) {
this.targetDropList = targetDropList;
this.renderer = renderer;
this.itemDragStarted$ = new Subject();
this._destroy$ = new Subject();
const mouseEnter$ = fromEvent(hostElement.nativeElement, "mouseenter");
// Cdk bug fix: When an item is dragged outside of the container but not into another container,
// the placeholder is not removed. So, to fix this, we're removing the placeholder if the user's mouse
// cursor leaves the container.
const mouseLeave$ = fromEvent(hostElement.nativeElement, "mouseleave");
// Events streams for switching the drop zone state.
const showDropZoneTrigger$ = merge(mouseEnter$, this.itemDragStarted$, this.targetDropList.entered);
const hideDropZoneTrigger$ = merge(mouseLeave$, this.targetDropList.dropped, this.targetDropList.exited);
// Main placeholder stream that decides to show/hide drop zone
this.showDropZone$ = merge(showDropZoneTrigger$.pipe(mapTo(true)), hideDropZoneTrigger$.pipe(mapTo(false))).pipe(distinctUntilChanged(), shareReplay());
// Merging observables to obtain reliable draggedItem reference
const draggedItem$ = merge(this.targetDropList.entered.pipe(map((event) => event.item)), this.itemDragStarted$).pipe(shareReplay());
// Drop zone state stream used to return the result of the predicate provided by user.
// Here we're taking the current moving item in case the drop zone is active to be able to execute the callback.
this.canLastDragItemBeDropped$ = combineLatest([
this.showDropZone$,
draggedItem$,
]).pipe(switchMap(([showDropZone, drag]) => {
const canBeDropped = showDropZone
? this.canBeDropped?.(drag.data, this.targetDropList) ??
true
: false;
this._canLastDragItemBeDropped = canBeDropped;
return of(canBeDropped);
}), distinctUntilChanged(), shareReplay());
// If consumer will not subscribe in the template to canDrop$ we should set proper classes anyway.
// That's why we're subscribing also here, the number of observables will remain the same because of shareReplay
this.canLastDragItemBeDropped$
.pipe(takeUntil(this._destroy$))
.subscribe();
}
ngAfterContentInit() {
// Using this to provide current draggable item reference that is needed for predicate validation
// cdkDropList is not throwing any event on dragStart, then we should subscribe to dragStartEventEmitter from item
this.draggables.changes
.pipe(startWith(this.draggables.toArray()), switchMap((items) => merge(...items.map((drag) => drag.started))), tap((item) => this.itemDragStarted$.next(item.source)), takeUntil(this._destroy$))
.subscribe();
}
ngOnDestroy() {
this._destroy$.next();
this._destroy$.complete();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DndDropTargetDirective, deps: [{ token: i1.CdkDropList }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: DndDropTargetDirective, selector: "[cdkDropList][nuiDndDropTarget]", inputs: { canBeDropped: "canBeDropped" }, host: { properties: { "class.nui-dnd-dropzone": "true", "class.nui-dnd-dropzone--active": "isDropZoneActive", "class.nui-dnd-dropzone--drop-allowed": "isDropZoneActive && canLastDragItemBeDropped", "class.nui-dnd-dropzone--drop-not-allowed": "isDropZoneActive && canLastDragItemBeDropped === false" } }, queries: [{ propertyName: "draggables", predicate: CdkDrag, descendants: true }], exportAs: ["nuiDndDropTarget"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DndDropTargetDirective, decorators: [{
type: Directive,
args: [{
selector: "[cdkDropList][nuiDndDropTarget]",
exportAs: "nuiDndDropTarget",
host: {
// Setting proper highlight state class on host container,
// to let the user customize drop zone only via css
"[class.nui-dnd-dropzone]": "true",
"[class.nui-dnd-dropzone--active]": "isDropZoneActive",
"[class.nui-dnd-dropzone--drop-allowed]": "isDropZoneActive && canLastDragItemBeDropped",
"[class.nui-dnd-dropzone--drop-not-allowed]": "isDropZoneActive && canLastDragItemBeDropped === false",
},
}]
}], ctorParameters: () => [{ type: i1.CdkDropList }, { type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { draggables: [{
type: ContentChildren,
args: [CdkDrag, { descendants: true }]
}], canBeDropped: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG5kLWRyb3AtdGFyZ2V0LmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZG5kL2RuZC1kcm9wLXRhcmdldC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sRUFBRSxPQUFPLEVBQWdCLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzVFLE9BQU8sRUFFSCxlQUFlLEVBQ2YsU0FBUyxFQUNULFVBQVUsRUFDVixLQUFLLEVBRUwsU0FBUyxFQUNULFNBQVMsR0FDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsYUFBYSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRixPQUFPLEVBQ0gsb0JBQW9CLEVBQ3BCLEdBQUcsRUFDSCxLQUFLLEVBQ0wsV0FBVyxFQUNYLFNBQVMsRUFDVCxTQUFTLEVBQ1QsU0FBUyxFQUNULEdBQUcsR0FDTixNQUFNLGdCQUFnQixDQUFDOzs7QUFnQnhCLE1BQU0sT0FBTyxzQkFBc0I7SUFZL0IsaUNBQWlDO0lBQ2pDLElBQVcsZ0JBQWdCO1FBQ3ZCLG9HQUFvRztRQUNwRyxtR0FBbUc7UUFDbkcsT0FBTyxDQUNILElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRTtZQUM5QyxJQUFJLENBQUMsY0FBYyxDQUFD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QUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQ3BDLFNBQVMsQ0FBQyxDQUFDLEtBQWdCLEVBQUUsRUFBRSxDQUMzQixLQUFLLENBQUMsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBYSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FDdkQsRUFDRCxHQUFHLENBQUMsQ0FBQyxJQUFrQixFQUFFLEVBQUUsQ0FDdkIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQzFDLEVBQ0QsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FDNUI7YUFDQSxTQUFTLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRU0sV0FBVztRQUNkLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUM5QixDQUFDOytHQXBIUSxzQkFBc0I7bUdBQXRCLHNCQUFzQiw0YkFDZCxPQUFPOzs0RkFEZixzQkFBc0I7a0JBZGxDLFNBQVM7bUJBQUM7b0JBQ1AsUUFBUSxFQUFFLGlDQUFpQztvQkFDM0MsUUFBUSxFQUFFLGtCQUFrQjtvQkFDNUIsSUFBSSxFQUFFO3dCQUNGLDBEQUEwRDt3QkFDMUQsbURBQW1EO3dCQUNuRCwwQkFBMEIsRUFBRSxNQUFNO3dCQUNsQyxrQ0FBa0MsRUFBRSxrQkFBa0I7d0JBQ3RELHdDQUF3QyxFQUNwQyw4Q0FBOEM7d0JBQ2xELDRDQUE0QyxFQUN4Qyx3REFBd0Q7cUJBQy9EO2lCQUNKO2lJQUdHLFVBQVU7c0JBRFQsZUFBZTt1QkFBQyxPQUFPLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFO2dCQUd0QyxZQUFZO3NCQUFwQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7IENka0RyYWcsIENka0RyYWdTdGFydCwgQ2RrRHJvcExpc3QgfSBmcm9tIFwiQGFuZ3VsYXIvY2RrL2RyYWctZHJvcFwiO1xuaW1wb3J0IHtcbiAgICBBZnRlckNvbnRlbnRJbml0LFxuICAgIENvbnRlbnRDaGlsZHJlbixcbiAgICBEaXJlY3RpdmUsXG4gICAgRWxlbWVudFJlZixcbiAgICBJbnB1dCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgUXVlcnlMaXN0LFxuICAgIFJlbmRlcmVyMixcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QsIGZyb21FdmVudCwgbWVyZ2UsIE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7XG4gICAgZGlzdGluY3RVbnRpbENoYW5nZWQsXG4gICAgbWFwLFxuICAgIG1hcFRvLFxuICAgIHNoYXJlUmVwbGF5LFxuICAgIHN0YXJ0V2l0aCxcbiAgICBzd2l0Y2hNYXAsXG4gICAgdGFrZVVudGlsLFxuICAgIHRhcCxcbn0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiBcIltjZGtEcm9wTGlzdF1bbnVpRG5kRHJvcFRhcmdldF1cIixcbiAgICBleHBvcnRBczogXCJudWlEbmREcm9wVGFyZ2V0XCIsXG4gICAgaG9zdDoge1xuICAgICAgICAvLyBTZXR0aW5nIHByb3BlciBoaWdobGlnaHQgc3RhdGUgY2xhc3Mgb24gaG9zdCBjb250YWluZXIsXG4gICAgICAgIC8vIHRvIGxldCB0aGUgdXNlciBjdXN0b21pemUgZHJvcCB6b25lIG9ubHkgdmlhIGNzc1xuICAgICAgICBcIltjbGFzcy5udWktZG5kLWRyb3B6b25lXVwiOiBcInRydWVcIixcbiAgICAgICAgXCJbY2xhc3MubnVpLWRuZC1kcm9wem9uZS0tYWN0aXZlXVwiOiBcImlzRHJvcFpvbmVBY3RpdmVcIixcbiAgICAgICAgXCJbY2xhc3MubnVpLWRuZC1kcm9wem9uZS0tZHJvcC1hbGxvd2VkXVwiOlxuICAgICAgICAgICAgXCJpc0Ryb3Bab25lQWN0aXZlICYmIGNhbkxhc3REcmFnSXRlbUJlRHJvcHBlZFwiLFxuICAgICAgICBcIltjbGFzcy5udWktZG5kLWRyb3B6b25lLS1kcm9wLW5vdC1hbGxvd2VkXVwiOlxuICAgICAgICAgICAgXCJpc0Ryb3Bab25lQWN0aXZlICYmIGNhbkxhc3REcmFnSXRlbUJlRHJvcHBlZCA9PT0gZmFsc2VcIixcbiAgICB9LFxufSlcbmV4cG9ydCBjbGFzcyBEbmREcm9wVGFyZ2V0RGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95IHtcbiAgICBAQ29udGVudENoaWxkcmVuKENka0RyYWcsIHsgZGVzY2VuZGFudHM6IHRydWUgfSlcbiAgICBkcmFnZ2FibGVzOiBRdWVyeUxpc3Q8Q2RrRHJhZz47XG5cbiAgICBASW5wdXQoKSBjYW5CZURyb3BwZWQ6IChpdGVtOiBhbnksIGRyb3BMaXN0UmVmPzogQ2RrRHJvcExpc3QpID0+IGJvb2xlYW47XG5cbiAgICBwdWJsaWMgc2hvd0Ryb3Bab25lJDogT2JzZXJ2YWJsZTxib29sZWFuPjtcbiAgICBwdWJsaWMgY2FuTGFzdERyYWdJdGVtQmVEcm9wcGVkJDogT2JzZXJ2YWJsZTxib29sZWFuPjtcblxuICAgIHByaXZhdGUgaXRlbURyYWdTdGFydGVkJCA9IG5ldyBTdWJqZWN0PENka0RyYWc+KCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgLy8gdHJ1ZSB3aGVuIHRoZSBkcmFnIGhhcyBzdGFydGVkXG4gICAgcHVibGljIGdldCBpc0Ryb3Bab25lQWN0aXZlKCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBVc2luZyBjZGsgZGVmYXVsdCBpc1JlY2VpdmluZyBhbmQgaXNEcmFnZ2luZyAoV2hlbiB0aGUgaXRlbSBpcyBhc3NpZ25lZCB3aXRob3V0IGRyb3AgdG8gZHJvcExpc3QsXG4gICAgICAgIC8vIGlzUmVjZWl2aW5nIHJldHVybnMgZmFsc2UsIGFuZCB3ZSByZXBsYWNlIGl0IHdpdGggaXNEcmFnZ2luZyB0byBtYWludGFpbiB0aGUgZXhwZWN0ZWQgYmVoYXZpb3IuKVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgdGhpcy50YXJnZXREcm9wTGlzdC5fZHJvcExpc3RSZWYuaXNSZWNlaXZpbmcoKSB8fFxuICAgICAgICAgICAgdGhpcy50YXJnZXREcm9wTGlzdC5fZHJvcExpc3RSZWYuaXNEcmFnZ2luZygpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY2FuTGFzdERyYWdJdGVtQmVEcm9wcGVkOiBib29sZWFuO1xuXG4gICAgLy8gYW5kIGFsc28gYXZhaWxhYmxlIGZvciBjb25zdW1lciB0byBiZSBhYmxlIHRvIHVzZSBpdCB3aXRob3V0IGFzeW5jXG4gICAgcHVibGljIGdldCBjYW5MYXN0RHJhZ0l0ZW1CZURyb3BwZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYW5MYXN0RHJhZ0l0ZW1CZURyb3BwZWQ7XG4gICAgfVxuXG4gICAgLy8gY2FuRHJvcCBwcmltaXRpdmUgdmFsdWUgaXMgdXNlZCBmb3IgdGhlIGhvc3QgZWxlbWVudCBjbGFzcyBiaW5kaW5nXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgdGFyZ2V0RHJvcExpc3Q6IENka0Ryb3BMaXN0LFxuICAgICAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgICAgIGhvc3RFbGVtZW50OiBFbGVtZW50UmVmXG4gICAgKSB7XG4gICAgICAgIGNvbnN0IG1vdXNlRW50ZXIkOiBPYnNlcnZhYmxlPHVua25vd24+ID0gZnJvbUV2ZW50KFxuICAgICAgICAgICAgaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudCxcbiAgICAgICAgICAgIFwibW91c2VlbnRlclwiXG4gICAgICAgICk7XG4gICAgICAgIC8vIENkayBidWcgZml4OiBXaGVuIGFuIGl0ZW0gaXMgZHJhZ2dlZCBvdXRzaWRlIG9mIHRoZSBjb250YWluZXIgYnV0IG5vdCBpbnRvIGFub3RoZXIgY29udGFpbmVyLFxuICAgICAgICAvLyB0aGUgcGxhY2Vob2xkZXIgaXMgbm90IHJlbW92ZWQuIFNvLCB0byBmaXggdGhpcywgd2UncmUgcmVtb3ZpbmcgdGhlIHBsYWNlaG9sZGVyIGlmIHRoZSB1c2VyJ3MgbW91c2VcbiAgICAgICAgLy8gY3Vyc29yIGxlYXZlcyB0aGUgY29udGFpbmVyLlxuICAgICAgICBjb25zdCBtb3VzZUxlYXZlJDogT2JzZXJ2YWJsZTx1bmtub3duPiA9IGZyb21FdmVudChcbiAgICAgICAgICAgIGhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgICBcIm1vdXNlbGVhdmVcIlxuICAgICAgICApO1xuXG4gICAgICAgIC8vIEV2ZW50cyBzdHJlYW1zIGZvciBzd2l0Y2hpbmcgdGhlIGRyb3Agem9uZSBzdGF0ZS5cbiAgICAgICAgY29uc3Qgc2hvd0Ryb3Bab25lVHJpZ2dlciQ6IE9ic2VydmFibGU8dW5rbm93bj4gPSBtZXJnZShcbiAgICAgICAgICAgIG1vdXNlRW50ZXIkLFxuICAgICAgICAgICAgdGhpcy5pdGVtRHJhZ1N0YXJ0ZWQkLFxuICAgICAgICAgICAgdGhpcy50YXJnZXREcm9wTGlzdC5lbnRlcmVkXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGhpZGVEcm9wWm9uZVRyaWdnZXIkOiBPYnNlcnZhYmxlPHVua25vd24+ID0gbWVyZ2UoXG4gICAgICAgICAgICBtb3VzZUxlYXZlJCxcbiAgICAgICAgICAgIHRoaXMudGFyZ2V0RHJvcExpc3QuZHJvcHBlZCxcbiAgICAgICAgICAgIHRoaXMudGFyZ2V0RHJvcExpc3QuZXhpdGVkXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gTWFpbiBwbGFjZWhvbGRlciBzdHJlYW0gdGhhdCBkZWNpZGVzIHRvIHNob3cvaGlkZSBkcm9wIHpvbmVcbiAgICAgICAgdGhpcy5zaG93RHJvcFpvbmUkID0gbWVyZ2UoXG4gICAgICAgICAgICBzaG93RHJvcFpvbmVUcmlnZ2VyJC5waXBlKG1hcFRvKHRydWUpKSxcbiAgICAgICAgICAgIGhpZGVEcm9wWm9uZVRyaWdnZXIkLnBpcGUobWFwVG8oZmFsc2UpKVxuICAgICAgICApLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSwgc2hhcmVSZXBsYXkoKSk7XG5cbiAgICAgICAgLy8gTWVyZ2luZyBvYnNlcnZhYmxlcyB0byBvYnRhaW4gcmVsaWFibGUgZHJhZ2dlZEl0ZW0gcmVmZXJlbmNlXG4gICAgICAgIGNvbnN0IGRyYWdnZWRJdGVtJDogT2JzZXJ2YWJsZTxDZGtEcmFnPiA9IG1lcmdlKFxuICAgICAgICAgICAgdGhpcy50YXJnZXREcm9wTGlzdC5lbnRlcmVkLnBpcGUobWFwKChldmVudCkgPT4gZXZlbnQuaXRlbSkpLFxuICAgICAgICAgICAgdGhpcy5pdGVtRHJhZ1N0YXJ0ZWQkXG4gICAgICAgICkucGlwZShzaGFyZVJlcGxheSgpKTtcblxuICAgICAgICAvLyBEcm9wIHpvbmUgc3RhdGUgc3RyZWFtIHVzZWQgdG8gcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIHByZWRpY2F0ZSBwcm92aWRlZCBieSB1c2VyLlxuICAgICAgICAvLyBIZXJlIHdlJ3JlIHRha2luZyB0aGUgY3VycmVudCBtb3ZpbmcgaXRlbSBpbiBjYXNlIHRoZSBkcm9wIHpvbmUgaXMgYWN0aXZlIHRvIGJlIGFibGUgdG8gZXhlY3V0ZSB0aGUgY2FsbGJhY2suXG4gICAgICAgIHRoaXMuY2FuTGFzdERyYWdJdGVtQmVEcm9wcGVkJCA9IGNvbWJpbmVMYXRlc3QoW1xuICAgICAgICAgICAgdGhpcy5zaG93RHJvcFpvbmUkLFxuICAgICAgICAgICAgZHJhZ2dlZEl0ZW0kLFxuICAgICAgICBdKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChbc2hvd0Ryb3Bab25lLCBkcmFnXSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbkJlRHJvcHBlZCA9IHNob3dEcm9wWm9uZVxuICAgICAgICAgICAgICAgICAgICA/IHRoaXMuY2FuQmVEcm9wcGVkPy4oZHJhZy5kYXRhLCB0aGlzLnRhcmdldERyb3BMaXN0KSA/P1xuICAgICAgICAgICAgICAgICAgICAgIHRydWVcbiAgICAgICAgICAgICAgICAgICAgOiBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLl9jYW5MYXN0RHJhZ0l0ZW1CZURyb3BwZWQgPSBjYW5CZURyb3BwZWQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9mKGNhbkJlRHJvcHBlZCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICAgICAgICBzaGFyZVJlcGxheSgpXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gSWYgY29uc3VtZXIgd2lsbCBub3Qgc3Vic2NyaWJlIGluIHRoZSB0ZW1wbGF0ZSB0byBjYW5Ecm9wJCB3ZSBzaG91bGQgc2V0IHByb3BlciBjbGFzc2VzIGFueXdheS5cbiAgICAgICAgLy8gVGhhdCdzIHdoeSB3ZSdyZSBzdWJzY3JpYmluZyBhbHNvIGhlcmUsIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YWJsZXMgd2lsbCByZW1haW4gdGhlIHNhbWUgYmVjYXVzZSBvZiBzaGFyZVJlcGxheVxuICAgICAgICB0aGlzLmNhbkxhc3REcmFnSXRlbUJlRHJvcHBlZCRcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICAgICAgLy8gVXNpbmcgdGhpcyB0byBwcm92aWRlIGN1cnJlbnQgZHJhZ2dhYmxlIGl0ZW0gcmVmZXJlbmNlIHRoYXQgaXMgbmVlZGVkIGZvciBwcmVkaWNhdGUgdmFsaWRhdGlvblxuICAgICAgICAvLyBjZGtEcm9wTGlzdCBpcyBub3QgdGhyb3dpbmcgYW55IGV2ZW50IG9uIGRyYWdTdGFydCwgdGhlbiB3ZSBzaG91bGQgc3Vic2NyaWJlIHRvIGRyYWdTdGFydEV2ZW50RW1pdHRlciBmcm9tIGl0ZW1cbiAgICAgICAgdGhpcy5kcmFnZ2FibGVzLmNoYW5nZXNcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIHN0YXJ0V2l0aCh0aGlzLmRyYWdnYWJsZXMudG9BcnJheSgpKSxcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKGl0ZW1zOiBDZGtEcmFnW10pID0+XG4gICAgICAgICAgICAgICAgICAgIG1lcmdlKC4uLml0ZW1zLm1hcCgoZHJhZzogQ2RrRHJhZykgPT4gZHJhZy5zdGFydGVkKSlcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIHRhcCgoaXRlbTogQ2RrRHJhZ1N0YXJ0KSA9PlxuICAgICAgICAgICAgICAgICAgICB0aGlzLml0ZW1EcmFnU3RhcnRlZCQubmV4dChpdGVtLnNvdXJjZSlcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JClcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3kkLm5leHQoKTtcbiAgICAgICAgdGhpcy5fZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB9XG59XG4iXX0=