UNPKG

ngx-pluto

Version:
542 lines 46.9 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { coerceArray, coerceBooleanProperty } from '@angular/cdk/coercion'; import { ContentChildren, ElementRef, EventEmitter, forwardRef, Input, Output, QueryList, Optional, Directive, ChangeDetectorRef, SkipSelf, Inject, } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { Directionality } from '@angular/cdk/bidi'; import { CdkDrag } from './drag'; import { DragDropRegistry } from '../drag-drop-registry'; import { CDK_DROP_LIST_CONTAINER } from '../drop-list-container'; import { CdkDropListGroup } from './drop-list-group'; import { DropListRef } from '../drop-list-ref'; import { DragDrop } from '../drag-drop'; import { Subject } from 'rxjs'; import { startWith, takeUntil } from 'rxjs/operators'; /** * Counter used to generate unique ids for drop zones. * @type {?} */ let _uniqueIdCounter = 0; /** * @ignore * Internal compile-time-only representation of a `CdkDropList`. * Used to avoid circular import issues between the `CdkDropList` and the `CdkDrag`. * \@docs-private * @record */ export function CdkDropListInternal() { } const ɵ0 = undefined; // @breaking-change 8.0.0 `CdkDropList` implements `CdkDropListContainer` for backwards // compatiblity. The implements clause, as well as all the methods that it enforces can // be removed when `CdkDropListContainer` is deleted. /** * @ignore * Container that wraps a set of draggable items. * * @template T */ export class CdkDropList { /** * @param {?} element * @param {?} dragDropRegistry * @param {?} _changeDetectorRef * @param {?=} _dir * @param {?=} _group * @param {?=} _document * @param {?=} dragDrop */ constructor(element, dragDropRegistry, _changeDetectorRef, _dir, _group, _document, /** * @deprecated `dragDropRegistry` and `_document` parameters to be removed. * Also `dragDrop` parameter to be made required. * @breaking-change 8.0.0. */ dragDrop) { this.element = element; this._changeDetectorRef = _changeDetectorRef; this._dir = _dir; this._group = _group; /** * Emits when the list has been destroyed. */ this._destroyed = new Subject(); /** * Other draggable containers that this container is connected to and into which the * container's items can be transferred. Can either be references to other drop containers, * or their unique IDs. */ this.connectedTo = []; /** * Direction in which the list is oriented. */ this.orientation = 'vertical'; /** * Unique ID for the drop zone. Can be used as a reference * in the `connectedTo` of another `CdkDropList`. */ this.id = `cdk-drop-list-${_uniqueIdCounter++}`; this._disabled = false; /** * Function that is used to determine whether an item * is allowed to be moved into a drop container. */ this.enterPredicate = (/** * @return {?} */ () => true); /** * Emits when the user drops an item inside the container. */ this.dropped = new EventEmitter(); /** * Emits when the user has moved a new drag item into this container. */ this.entered = new EventEmitter(); /** * Emits when the user removes an item from the container * by dragging it into another container. */ this.exited = new EventEmitter(); /** * Emits as the user is swapping items while actively dragging. */ this.sorted = new EventEmitter(); // @breaking-change 8.0.0 Remove null check once `dragDrop` parameter is made required. if (dragDrop) { this._dropListRef = dragDrop.createDropList(element); } else { this._dropListRef = new DropListRef(element, dragDropRegistry, _document || document); } this._dropListRef.data = this; this._dropListRef.enterPredicate = (/** * @param {?} drag * @param {?} drop * @return {?} */ (drag, drop) => { return this.enterPredicate(drag.data, drop.data); }); this._syncInputs(this._dropListRef); this._handleEvents(this._dropListRef); CdkDropList._dropLists.push(this); if (_group) { _group._items.add(this); } } /** * Whether starting a dragging sequence from this container is disabled. * @return {?} */ get disabled() { return this._disabled || (!!this._group && this._group.disabled); } /** * @param {?} value * @return {?} */ set disabled(value) { this._disabled = coerceBooleanProperty(value); } /** * @return {?} */ ngAfterContentInit() { this._draggables.changes .pipe(startWith(this._draggables), takeUntil(this._destroyed)) .subscribe((/** * @param {?} items * @return {?} */ (items) => { this._dropListRef.withItems(items.map((/** * @param {?} drag * @return {?} */ drag => drag._dragRef))); })); } /** * @return {?} */ ngOnDestroy() { /** @type {?} */ const index = CdkDropList._dropLists.indexOf(this); if (index > -1) { CdkDropList._dropLists.splice(index, 1); } if (this._group) { this._group._items.delete(this); } this._dropListRef.dispose(); this._destroyed.next(); this._destroyed.complete(); } /** * Starts dragging an item. * @return {?} */ start() { this._dropListRef.start(); } /** * Drops an item into this container. * @param {?} item Item being dropped into the container. * @param {?} currentIndex Index at which the item should be inserted. * @param {?} previousContainer Container from which the item got dragged in. * @param {?} isPointerOverContainer Whether the user's pointer was over the * container when the item was dropped. * @return {?} */ drop(item, currentIndex, previousContainer, isPointerOverContainer) { this._dropListRef.drop(item._dragRef, currentIndex, ((/** @type {?} */ (previousContainer)))._dropListRef, isPointerOverContainer); } /** * Emits an event to indicate that the user moved an item into the container. * @param {?} item Item that was moved into the container. * @param {?} pointerX Position of the item along the X axis. * @param {?} pointerY Position of the item along the Y axis. * @return {?} */ enter(item, pointerX, pointerY) { this._dropListRef.enter(item._dragRef, pointerX, pointerY); } /** * Removes an item from the container after it was dragged into another container by the user. * @param {?} item Item that was dragged out. * @return {?} */ exit(item) { this._dropListRef.exit(item._dragRef); } /** * Figures out the index of an item in the container. * @param {?} item Item whose index should be determined. * @return {?} */ getItemIndex(item) { return this._dropListRef.getItemIndex(item._dragRef); } /** * Sorts an item inside the container based on its position. * @param {?} item Item to be sorted. * @param {?} pointerX Position of the item along the X axis. * @param {?} pointerY Position of the item along the Y axis. * @param {?} pointerDelta Direction in which the pointer is moving along each axis. * @return {?} */ _sortItem(item, pointerX, pointerY, pointerDelta) { return this._dropListRef._sortItem(item._dragRef, pointerX, pointerY, pointerDelta); } /** * Figures out whether an item should be moved into a sibling * drop container, based on its current position. * @param {?} item Drag item that is being moved. * @param {?} x Position of the item along the X axis. * @param {?} y Position of the item along the Y axis. * @return {?} */ _getSiblingContainerFromPosition(item, x, y) { /** @type {?} */ const result = this._dropListRef._getSiblingContainerFromPosition(item._dragRef, x, y); return result ? result.data : null; } /** * Checks whether the user's pointer is positioned over the container. * @param {?} x Pointer position along the X axis. * @param {?} y Pointer position along the Y axis. * @return {?} */ _isOverContainer(x, y) { return this._dropListRef._isOverContainer(x, y); } /** * Syncs the inputs of the CdkDropList with the options of the underlying DropListRef. * @private * @param {?} ref * @return {?} */ _syncInputs(ref) { if (this._dir) { this._dir.change .pipe(startWith(this._dir.value), takeUntil(this._destroyed)) .subscribe((/** * @param {?} value * @return {?} */ value => ref.withDirection(value))); } ref.beforeStarted.subscribe((/** * @return {?} */ () => { /** @type {?} */ const siblings = coerceArray(this.connectedTo).map((/** * @param {?} drop * @return {?} */ drop => { return typeof drop === 'string' ? (/** @type {?} */ (CdkDropList._dropLists.find((/** * @param {?} list * @return {?} */ list => list.id === drop)))) : drop; })); if (this._group) { this._group._items.forEach((/** * @param {?} drop * @return {?} */ drop => { if (siblings.indexOf(drop) === -1) { siblings.push(drop); } })); } ref.lockAxis = this.lockAxis; ref .connectedTo(siblings.filter((/** * @param {?} drop * @return {?} */ drop => drop && drop !== this)).map((/** * @param {?} list * @return {?} */ list => list._dropListRef))) .withOrientation(this.orientation); })); } /** * Handles events from the underlying DropListRef. * @private * @param {?} ref * @return {?} */ _handleEvents(ref) { ref.beforeStarted.subscribe((/** * @return {?} */ () => { this._changeDetectorRef.markForCheck(); })); ref.entered.subscribe((/** * @param {?} event * @return {?} */ event => { this.entered.emit({ container: this, item: event.item.data }); })); ref.exited.subscribe((/** * @param {?} event * @return {?} */ event => { this.exited.emit({ container: this, item: event.item.data }); })); ref.sorted.subscribe((/** * @param {?} event * @return {?} */ event => { this.sorted.emit({ previousIndex: event.previousIndex, currentIndex: event.currentIndex, container: this, item: event.item.data }); })); ref.dropped.subscribe((/** * @param {?} event * @return {?} */ event => { this.dropped.emit({ previousIndex: event.previousIndex, currentIndex: event.currentIndex, previousContainer: event.previousContainer.data, container: event.container.data, item: event.item.data, isPointerOverContainer: event.isPointerOverContainer }); // Mark for check since all of these events run outside of change // detection and we're not guaranteed for something else to have triggered it. this._changeDetectorRef.markForCheck(); })); } } /** * Keeps track of the drop lists that are currently on the page. */ CdkDropList._dropLists = []; CdkDropList.decorators = [ { type: Directive, args: [{ selector: '[cdkDropList], cdk-drop-list', exportAs: 'cdkDropList', providers: [ // Prevent child drop lists from picking up the same group as their parent. { provide: CdkDropListGroup, useValue: ɵ0 }, { provide: CDK_DROP_LIST_CONTAINER, useExisting: CdkDropList }, ], host: { 'class': 'cdk-drop-list', '[id]': 'id', '[class.cdk-drop-list-disabled]': 'disabled', '[class.cdk-drop-list-dragging]': '_dropListRef.isDragging()', '[class.cdk-drop-list-receiving]': '_dropListRef.isReceiving()', } },] } ]; /** @nocollapse */ CdkDropList.ctorParameters = () => [ { type: ElementRef }, { type: DragDropRegistry }, { type: ChangeDetectorRef }, { type: Directionality, decorators: [{ type: Optional }] }, { type: CdkDropListGroup, decorators: [{ type: Optional }, { type: SkipSelf }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] }] }, { type: DragDrop } ]; CdkDropList.propDecorators = { _draggables: [{ type: ContentChildren, args: [forwardRef((/** * @return {?} */ () => CdkDrag)), { // Explicitly set to false since some of the logic below makes assumptions about it. // The `.withItems` call below should be updated if we ever need to switch this to `true`. descendants: false },] }], connectedTo: [{ type: Input, args: ['cdkDropListConnectedTo',] }], data: [{ type: Input, args: ['cdkDropListData',] }], orientation: [{ type: Input, args: ['cdkDropListOrientation',] }], id: [{ type: Input }], lockAxis: [{ type: Input, args: ['cdkDropListLockAxis',] }], disabled: [{ type: Input, args: ['cdkDropListDisabled',] }], enterPredicate: [{ type: Input, args: ['cdkDropListEnterPredicate',] }], dropped: [{ type: Output, args: ['cdkDropListDropped',] }], entered: [{ type: Output, args: ['cdkDropListEntered',] }], exited: [{ type: Output, args: ['cdkDropListExited',] }], sorted: [{ type: Output, args: ['cdkDropListSorted',] }] }; if (false) { /** * Keeps track of the drop lists that are currently on the page. * @type {?} * @private */ CdkDropList._dropLists; /** * Emits when the list has been destroyed. * @type {?} * @private */ CdkDropList.prototype._destroyed; /** * Reference to the underlying drop list instance. * @type {?} */ CdkDropList.prototype._dropListRef; /** * Draggable items in the container. * @type {?} */ CdkDropList.prototype._draggables; /** * Other draggable containers that this container is connected to and into which the * container's items can be transferred. Can either be references to other drop containers, * or their unique IDs. * @type {?} */ CdkDropList.prototype.connectedTo; /** * Arbitrary data to attach to this container. * @type {?} */ CdkDropList.prototype.data; /** * Direction in which the list is oriented. * @type {?} */ CdkDropList.prototype.orientation; /** * Unique ID for the drop zone. Can be used as a reference * in the `connectedTo` of another `CdkDropList`. * @type {?} */ CdkDropList.prototype.id; /** * Locks the position of the draggable elements inside the container along the specified axis. * @type {?} */ CdkDropList.prototype.lockAxis; /** * @type {?} * @private */ CdkDropList.prototype._disabled; /** * Function that is used to determine whether an item * is allowed to be moved into a drop container. * @type {?} */ CdkDropList.prototype.enterPredicate; /** * Emits when the user drops an item inside the container. * @type {?} */ CdkDropList.prototype.dropped; /** * Emits when the user has moved a new drag item into this container. * @type {?} */ CdkDropList.prototype.entered; /** * Emits when the user removes an item from the container * by dragging it into another container. * @type {?} */ CdkDropList.prototype.exited; /** * Emits as the user is swapping items while actively dragging. * @type {?} */ CdkDropList.prototype.sorted; /** * Element that the drop list is attached to. * @type {?} */ CdkDropList.prototype.element; /** * @type {?} * @private */ CdkDropList.prototype._changeDetectorRef; /** * @type {?} * @private */ CdkDropList.prototype._dir; /** * @type {?} * @private */ CdkDropList.prototype._group; } export { ɵ0 }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcC1saXN0LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LXBsdXRvLyIsInNvdXJjZXMiOlsibGliL2RyYWctZHJvcC9kaXJlY3RpdmVzL2Ryb3AtbGlzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQVFBLE9BQU8sRUFBQyxXQUFXLEVBQUUscUJBQXFCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUN6RSxPQUFPLEVBQ0wsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNULFFBQVEsRUFDUixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2pCLFFBQVEsRUFDUixNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBRXZELE9BQU8sRUFBQyx1QkFBdUIsRUFBdUIsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRixPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRCxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFFN0MsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUN0QyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBQyxTQUFTLEVBQUUsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7Ozs7O0lBR2hELGdCQUFnQixHQUFHLENBQUM7Ozs7Ozs7O0FBUXhCLHlDQUEyRDtXQWVqQixTQUFTOzs7Ozs7Ozs7O0FBV25ELE1BQU0sT0FBTyxXQUFXOzs7Ozs7Ozs7O0lBOEV0QixZQUVTLE9BQWdDLEVBQ3ZDLGdCQUF3RCxFQUNoRCxrQkFBcUMsRUFDekIsSUFBcUIsRUFDVCxNQUFzQyxFQUN4QyxTQUFlO0lBRTdDOzs7O09BSUc7SUFDSCxRQUFtQjtRQVpaLFlBQU8sR0FBUCxPQUFPLENBQXlCO1FBRS9CLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBbUI7UUFDekIsU0FBSSxHQUFKLElBQUksQ0FBaUI7UUFDVCxXQUFNLEdBQU4sTUFBTSxDQUFnQzs7OztRQWxGaEUsZUFBVSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7Ozs7OztRQXFCekMsZ0JBQVcsR0FBb0QsRUFBRSxDQUFDOzs7O1FBTWpDLGdCQUFXLEdBQThCLFVBQVUsQ0FBQzs7Ozs7UUFNNUUsT0FBRSxHQUFXLGlCQUFpQixnQkFBZ0IsRUFBRSxFQUFFLENBQUM7UUFhcEQsY0FBUyxHQUFHLEtBQUssQ0FBQzs7Ozs7UUFPMUIsbUJBQWM7OztRQUFrRCxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQUE7Ozs7UUFJMUUsWUFBTyxHQUFzQyxJQUFJLFlBQVksRUFBdUIsQ0FBQzs7OztRQU1yRixZQUFPLEdBQWtDLElBQUksWUFBWSxFQUFtQixDQUFDOzs7OztRQU83RSxXQUFNLEdBQWlDLElBQUksWUFBWSxFQUFrQixDQUFDOzs7O1FBSTFFLFdBQU0sR0FBc0MsSUFBSSxZQUFZLEVBQXVCLENBQUM7UUFrQmxGLHVGQUF1RjtRQUN2RixJQUFJLFFBQVEsRUFBRTtZQUNaLElBQUksQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUN0RDthQUFNO1lBQ0wsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLFdBQVcsQ0FBQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsU0FBUyxJQUFJLFFBQVEsQ0FBQyxDQUFDO1NBQ3ZGO1FBRUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQzlCLElBQUksQ0FBQyxZQUFZLENBQUMsY0FBYzs7Ozs7UUFBRyxDQUFDLElBQXNCLEVBQUUsSUFBOEIsRUFBRSxFQUFFO1lBQzVGLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUEsQ0FBQztRQUVGLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3RDLFdBQVcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWxDLElBQUksTUFBTSxFQUFFO1lBQ1YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDekI7SUFDSCxDQUFDOzs7OztJQXhFRCxJQUNJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ25FLENBQUM7Ozs7O0lBQ0QsSUFBSSxRQUFRLENBQUMsS0FBYztRQUN6QixJQUFJLENBQUMsU0FBUyxHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hELENBQUM7Ozs7SUFvRUQsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTzthQUNyQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQzdELFNBQVM7Ozs7UUFBQyxDQUFDLEtBQXlCLEVBQUUsRUFBRTtZQUN2QyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRzs7OztZQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxFQUFDLENBQUM7SUFDUCxDQUFDOzs7O0lBRUQsV0FBVzs7Y0FDSCxLQUFLLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO1FBRWxELElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFO1lBQ2QsV0FBVyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQ3pDO1FBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ2pDO1FBRUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDN0IsQ0FBQzs7Ozs7SUFHRCxLQUFLO1FBQ0gsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM1QixDQUFDOzs7Ozs7Ozs7O0lBVUQsSUFBSSxDQUFDLElBQWEsRUFBRSxZQUFvQixFQUFFLGlCQUFnRCxFQUN4RixzQkFBK0I7UUFDL0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQ2hELENBQUMsbUJBQUEsaUJBQWlCLEVBQWUsQ0FBQyxDQUFDLFlBQVksRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO0lBQzdFLENBQUM7Ozs7Ozs7O0lBUUQsS0FBSyxDQUFDLElBQWEsRUFBRSxRQUFnQixFQUFFLFFBQWdCO1FBQ3JELElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzdELENBQUM7Ozs7OztJQU1ELElBQUksQ0FBQyxJQUFhO1FBQ2hCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN4QyxDQUFDOzs7Ozs7SUFNRCxZQUFZLENBQUMsSUFBYTtRQUN4QixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN2RCxDQUFDOzs7Ozs7Ozs7SUFTRCxTQUFTLENBQUMsSUFBYSxFQUFFLFFBQWdCLEVBQUUsUUFBZ0IsRUFDakQsWUFBb0M7UUFDNUMsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDdEYsQ0FBQzs7Ozs7Ozs7O0lBU0QsZ0NBQWdDLENBQUMsSUFBYSxFQUFFLENBQVMsRUFBRSxDQUFTOztjQUU1RCxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxnQ0FBZ0MsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdEYsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUNyQyxDQUFDOzs7Ozs7O0lBT0QsZ0JBQWdCLENBQUMsQ0FBUyxFQUFFLENBQVM7UUFDbkMsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNsRCxDQUFDOzs7Ozs7O0lBR08sV0FBVyxDQUFDLEdBQTZCO1FBQy9DLElBQUksSUFBSSxDQUFDLElBQUksRUFBRTtZQUNiLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTTtpQkFDYixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztpQkFDNUQsU0FBUzs7OztZQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDO1NBQ2pEO1FBRUQsR0FBRyxDQUFDLGFBQWEsQ0FBQyxTQUFTOzs7UUFBQyxHQUFHLEVBQUU7O2tCQUN6QixRQUFRLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxHQUFHOzs7O1lBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3hELE9BQU8sT0FBTyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUM7b0JBQzdCLG1CQUFBLFdBQVcsQ0FBQyxVQUFVLENBQUMsSUFBSTs7OztvQkFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssSUFBSSxFQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ3BFLENBQUMsRUFBQztZQUVGLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDZixJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPOzs7O2dCQUFDLElBQUksQ0FBQyxFQUFFO29CQUNoQyxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7d0JBQ2pDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7cUJBQ3JCO2dCQUNILENBQUMsRUFBQyxDQUFDO2FBQ0o7WUFFRCxHQUFHLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDN0IsR0FBRztpQkFDQSxXQUFXLENBQUMsUUFBUSxDQUFDLE1BQU07Ozs7WUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksSUFBSSxJQUFJLEtBQUssSUFBSSxFQUFDLENBQUMsR0FBRzs7OztZQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBQyxDQUFDO2lCQUMxRixlQUFlLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsRUFBQyxDQUFDO0lBQ0wsQ0FBQzs7Ozs7OztJQUdPLGFBQWEsQ0FBQyxHQUE2QjtRQUNqRCxHQUFHLENBQUMsYUFBYSxDQUFDLFNBQVM7OztRQUFDLEdBQUcsRUFBRTtZQUMvQixJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDekMsQ0FBQyxFQUFDLENBQUM7UUFFSCxHQUFHLENBQUMsT0FBTyxDQUFDLFNBQVM7Ozs7UUFBQyxLQUFLLENBQUMsRUFBRTtZQUM1QixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztnQkFDaEIsU0FBUyxFQUFFLElBQUk7Z0JBQ2YsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSTthQUN0QixDQUFDLENBQUM7UUFDTCxDQUFDLEVBQUMsQ0FBQztRQUVILEdBQUcsQ0FBQyxNQUFNLENBQUMsU0FBUzs7OztRQUFDLEtBQUssQ0FBQyxFQUFFO1lBQzNCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO2dCQUNmLFNBQVMsRUFBRSxJQUFJO2dCQUNmLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUk7YUFDdEIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxFQUFDLENBQUM7UUFFSCxHQUFHLENBQUMsTUFBTSxDQUFDLFNBQVM7Ozs7UUFBQyxLQUFLLENBQUMsRUFBRTtZQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztnQkFDZixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7Z0JBQ2xDLFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWTtnQkFDaEMsU0FBUyxFQUFFLElBQUk7Z0JBQ2YsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSTthQUN0QixDQUFDLENBQUM7UUFDTCxDQUFDLEVBQUMsQ0FBQztRQUVILEdBQUcsQ0FBQyxPQUFPLENBQUMsU0FBUzs7OztRQUFDLEtBQUssQ0FBQyxFQUFFO1lBQzVCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO2dCQUNoQixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7Z0JBQ2xDLFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWTtnQkFDaEMsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGlCQUFpQixDQUFDLElBQUk7Z0JBQy9DLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUk7Z0JBQy9CLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUk7Z0JBQ3JCLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxzQkFBc0I7YUFDckQsQ0FBQyxDQUFDO1lBRUgsaUVBQWlFO1lBQ2pFLDhFQUE4RTtZQUM5RSxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDekMsQ0FBQyxFQUFDLENBQUM7SUFDTCxDQUFDOzs7OztBQTdSYyxzQkFBVSxHQUFrQixFQUFFLENBQUM7O1lBckIvQyxTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLDhCQUE4QjtnQkFDeEMsUUFBUSxFQUFFLGFBQWE7Z0JBQ3ZCLFNBQVMsRUFBRTtvQkFDVCwyRUFBMkU7b0JBQzNFLEVBQUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsSUFBVyxFQUFDO29CQUNoRCxFQUFDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFDO2lCQUM3RDtnQkFDRCxJQUFJLEVBQUU7b0JBQ0osT0FBTyxFQUFFLGVBQWU7b0JBQ3hCLE1BQU0sRUFBRSxJQUFJO29CQUNaLGdDQUFnQyxFQUFFLFVBQVU7b0JBQzVDLGdDQUFnQyxFQUFFLDJCQUEyQjtvQkFDN0QsaUNBQWlDLEVBQUUsNEJBQTRCO2lCQUNoRTthQUNGOzs7O1lBN0RDLFVBQVU7WUFpQkosZ0JBQWdCO1lBUnRCLGlCQUFpQjtZQU1YLGNBQWMsdUJBa0lqQixRQUFRO1lBN0hMLGdCQUFnQix1QkE4SG5CLFFBQVEsWUFBSSxRQUFROzRDQUNwQixRQUFRLFlBQUksTUFBTSxTQUFDLFFBQVE7WUE1SHhCLFFBQVE7OzswQkFrRGIsZUFBZSxTQUFDLFVBQVU7OztnQkFBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUMsRUFBRTs7O29CQUcxQyxXQUFXLEVBQUUsS0FBSztpQkFDbkI7MEJBT0EsS0FBSyxTQUFDLHdCQUF3QjttQkFJOUIsS0FBSyxTQUFDLGlCQUFpQjswQkFHdkIsS0FBSyxTQUFDLHdCQUF3QjtpQkFNOUIsS0FBSzt1QkFHTCxLQUFLLFNBQUMscUJBQXFCO3VCQUczQixLQUFLLFNBQUMscUJBQXFCOzZCQWEzQixLQUFLLFNBQUMsMkJBQTJCO3NCQUlqQyxNQUFNLFNBQUMsb0JBQW9CO3NCQU0zQixNQUFNLFNBQUMsb0JBQW9CO3FCQU8zQixNQUFNLFNBQUMsbUJBQW1CO3FCQUkxQixNQUFNLFNBQUMsbUJBQW1COzs7Ozs7OztJQXRFM0IsdUJBQThDOzs7Ozs7SUFIOUMsaUNBQXlDOzs7OztJQU16QyxtQ0FBMEM7Ozs7O0lBRzFDLGtDQUltQzs7Ozs7OztJQU9uQyxrQ0FDa0U7Ozs7O0lBR2xFLDJCQUFrQzs7Ozs7SUFHbEMsa0NBQXFGOzs7Ozs7SUFNckYseUJBQTREOzs7OztJQUc1RCwrQkFBa0Q7Ozs7O0lBVWxELGdDQUEwQjs7Ozs7O0lBTTFCLHFDQUMwRTs7Ozs7SUFHMUUsOEJBQ3FGOzs7OztJQUtyRiw4QkFDNkU7Ozs7OztJQU03RSw2QkFDMEU7Ozs7O0lBRzFFLDZCQUNvRjs7Ozs7SUFJbEYsOEJBQXVDOzs7OztJQUV2Qyx5Q0FBNkM7Ozs7O0lBQzdDLDJCQUF5Qzs7Ozs7SUFDekMsNkJBQXNFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEBsaWNlbnNlXHJcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXHJcbiAqXHJcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXHJcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcclxuICovXHJcblxyXG5pbXBvcnQge2NvZXJjZUFycmF5LCBjb2VyY2VCb29sZWFuUHJvcGVydHl9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2VyY2lvbic7XHJcbmltcG9ydCB7XHJcbiAgQ29udGVudENoaWxkcmVuLFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIGZvcndhcmRSZWYsXHJcbiAgSW5wdXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIE91dHB1dCxcclxuICBRdWVyeUxpc3QsXHJcbiAgT3B0aW9uYWwsXHJcbiAgRGlyZWN0aXZlLFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIFNraXBTZWxmLFxyXG4gIEluamVjdCxcclxuICBBZnRlckNvbnRlbnRJbml0LFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0RPQ1VNRU5UfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQge0RpcmVjdGlvbmFsaXR5fSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XHJcbmltcG9ydCB7Q2RrRHJhZ30gZnJvbSAnLi9kcmFnJztcclxuaW1wb3J0IHtEcmFnRHJvcFJlZ2lzdHJ5fSBmcm9tICcuLi9kcmFnLWRyb3AtcmVnaXN0cnknO1xyXG5pbXBvcnQge0Nka0RyYWdEcm9wLCBDZGtEcmFnRW50ZXIsIENka0RyYWdFeGl0LCBDZGtEcmFnU29ydEV2ZW50fSBmcm9tICcuLi9kcmFnLWV2ZW50cyc7XHJcbmltcG9ydCB7Q0RLX0RST1BfTElTVF9DT05UQUlORVIsIENka0Ryb3BMaXN0Q29udGFpbmVyfSBmcm9tICcuLi9kcm9wLWxpc3QtY29udGFpbmVyJztcclxuaW1wb3J0IHtDZGtEcm9wTGlzdEdyb3VwfSBmcm9tICcuL2Ryb3AtbGlzdC1ncm91cCc7XHJcbmltcG9ydCB7RHJvcExpc3RSZWZ9IGZyb20gJy4uL2Ryb3AtbGlzdC1yZWYnO1xyXG5pbXBvcnQge0RyYWdSZWZ9IGZyb20gJy4uL2RyYWctcmVmJztcclxuaW1wb3J0IHtEcmFnRHJvcH0gZnJvbSAnLi4vZHJhZy1kcm9wJztcclxuaW1wb3J0IHtTdWJqZWN0fSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtzdGFydFdpdGgsIHRha2VVbnRpbH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuLyoqIENvdW50ZXIgdXNlZCB0byBnZW5lcmF0ZSB1bmlxdWUgaWRzIGZvciBkcm9wIHpvbmVzLiAqL1xyXG5sZXQgX3VuaXF1ZUlkQ291bnRlciA9IDA7XHJcblxyXG4vKipcclxuICogQGlnbm9yZVxyXG4gKiBJbnRlcm5hbCBjb21waWxlLXRpbWUtb25seSByZXByZXNlbnRhdGlvbiBvZiBhIGBDZGtEcm9wTGlzdGAuXHJcbiAqIFVzZWQgdG8gYXZvaWQgY2lyY3VsYXIgaW1wb3J0IGlzc3VlcyBiZXR3ZWVuIHRoZSBgQ2RrRHJvcExpc3RgIGFuZCB0aGUgYENka0RyYWdgLlxyXG4gKiBAZG9jcy1wcml2YXRlXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIENka0Ryb3BMaXN0SW50ZXJuYWwgZXh0ZW5kcyBDZGtEcm9wTGlzdCB7fVxyXG5cclxuLy8gQGJyZWFraW5nLWNoYW5nZSA4LjAuMCBgQ2RrRHJvcExpc3RgIGltcGxlbWVudHMgYENka0Ryb3BMaXN0Q29udGFpbmVyYCBmb3IgYmFja3dhcmRzXHJcbi8vIGNvbXBhdGlibGl0eS4gVGhlIGltcGxlbWVudHMgY2xhdXNlLCBhcyB3ZWxsIGFzIGFsbCB0aGUgbWV0aG9kcyB0aGF0IGl0IGVuZm9yY2VzIGNhblxyXG4vLyBiZSByZW1vdmVkIHdoZW4gYENka0Ryb3BMaXN0Q29udGFpbmVyYCBpcyBkZWxldGVkLlxyXG5cclxuLyoqIFxyXG4gKiBAaWdub3JlXHJcbiAqIENvbnRhaW5lciB0aGF0IHdyYXBzIGEgc2V0IG9mIGRyYWdnYWJsZSBpdGVtcy4gXHJcbiAqICovXHJcbkBEaXJlY3RpdmUoe1xyXG4gIHNlbGVjdG9yOiAnW2Nka0Ryb3BMaXN0XSwgY2RrLWRyb3AtbGlzdCcsXHJcbiAgZXhwb3J0QXM6ICdjZGtEcm9wTGlzdCcsXHJcbiAgcHJvdmlkZXJzOiBbXHJcbiAgICAvLyBQcmV2ZW50IGNoaWxkIGRyb3AgbGlzdHMgZnJvbSBwaWNraW5nIHVwIHRoZSBzYW1lIGdyb3VwIGFzIHRoZWlyIHBhcmVudC5cclxuICAgIHtwcm92aWRlOiBDZGtEcm9wTGlzdEdyb3VwLCB1c2VWYWx1ZTogdW5kZWZpbmVkfSxcclxuICAgIHtwcm92aWRlOiBDREtfRFJPUF9MSVNUX0NPTlRBSU5FUiwgdXNlRXhpc3Rpbmc6IENka0Ryb3BMaXN0fSxcclxuICBdLFxyXG4gIGhvc3Q6IHtcclxuICAgICdjbGFzcyc6ICdjZGstZHJvcC1saXN0JyxcclxuICAgICdbaWRdJzogJ2lkJyxcclxuICAgICdbY2xhc3MuY2RrLWRyb3AtbGlzdC1kaXNhYmxlZF0nOiAnZGlzYWJsZWQnLFxyXG4gICAgJ1tjbGFzcy5jZGstZHJvcC1saXN0LWRyYWdnaW5nXSc6ICdfZHJvcExpc3RSZWYuaXNEcmFnZ2luZygpJyxcclxuICAgICdbY2xhc3MuY2RrLWRyb3AtbGlzdC1yZWNlaXZpbmddJzogJ19kcm9wTGlzdFJlZi5pc1JlY2VpdmluZygpJyxcclxuICB9XHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDZGtEcm9wTGlzdDxUID0gYW55PiBpbXBsZW1lbnRzIENka0Ryb3BMaXN0Q29udGFpbmVyLCBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xyXG4gIC8qKiBFbWl0cyB3aGVuIHRoZSBsaXN0IGhhcyBiZWVuIGRlc3Ryb3llZC4gKi9cclxuICBwcml2YXRlIF9kZXN0cm95ZWQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICAvKiogS2VlcHMgdHJhY2sgb2YgdGhlIGRyb3AgbGlzdHMgdGhhdCBhcmUgY3VycmVudGx5IG9uIHRoZSBwYWdlLiAqL1xyXG4gIHByaXZhdGUgc3RhdGljIF9kcm9wTGlzdHM6IENka0Ryb3BMaXN0W10gPSBbXTtcclxuXHJcbiAgLyoqIFJlZmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBkcm9wIGxpc3QgaW5zdGFuY2UuICovXHJcbiAgX2Ryb3BMaXN0UmVmOiBEcm9wTGlzdFJlZjxDZGtEcm9wTGlzdDxUPj47XHJcblxyXG4gIC8qKiBEcmFnZ2FibGUgaXRlbXMgaW4gdGhlIGNvbnRhaW5lci4gKi9cclxuICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gQ2RrRHJhZyksIHtcclxuICAgIC8vIEV4cGxpY2l0bHkgc2V0IHRvIGZhbHNlIHNpbmNlIHNvbWUgb2YgdGhlIGxvZ2ljIGJlbG93IG1ha2VzIGFzc3VtcHRpb25zIGFib3V0IGl0LlxyXG4gICAgLy8gVGhlIGAud2l0aEl0ZW1zYCBjYWxsIGJlbG93IHNob3VsZCBiZSB1cGRhdGVkIGlmIHdlIGV2ZXIgbmVlZCB0byBzd2l0Y2ggdGhpcyB0byBgdHJ1ZWAuXHJcbiAgICBkZXNjZW5kYW50czogZmFsc2VcclxuICB9KSBfZHJhZ2dhYmxlczogUXVlcnlMaXN0PENka0RyYWc+O1xyXG5cclxuICAvKipcclxuICAgKiBPdGhlciBkcmFnZ2FibGUgY29udGFpbmVycyB0aGF0IHRoaXMgY29udGFpbmVyIGlzIGNvbm5lY3RlZCB0byBhbmQgaW50byB3aGljaCB0aGVcclxuICAgKiBjb250YWluZXIncyBpdGVtcyBjYW4gYmUgdHJhbnNmZXJyZWQuIENhbiBlaXRoZXIgYmUgcmVmZXJlbmNlcyB0byBvdGhlciBkcm9wIGNvbnRhaW5lcnMsXHJcbiAgICogb3IgdGhlaXIgdW5pcXVlIElEcy5cclxuICAgKi9cclxuICBASW5wdXQoJ2Nka0Ryb3BMaXN0Q29ubmVjdGVkVG8nKVxyXG4gIGNvbm5lY3RlZFRvOiAoQ2RrRHJvcExpc3QgfCBzdHJpbmcpW10gfCBDZGtEcm9wTGlzdCB8IHN0cmluZyA9IFtdO1xyXG5cclxuICAvKiogQXJiaXRyYXJ5IGRhdGEgdG8gYXR0YWNoIHRvIHRoaXMgY29udGFpbmVyLiAqL1xyXG4gIEBJbnB1dCgnY2RrRHJvcExpc3REYXRhJykgZGF0YTogVDtcclxuXHJcbiAgLyoqIERpcmVjdGlvbiBpbiB3aGljaCB0aGUgbGlzdCBpcyBvcmllbnRlZC4gKi9cclxuICBASW5wdXQoJ2Nka0Ryb3BMaXN0T3JpZW50YXRpb24nKSBvcmllbnRhdGlvbjogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJyA9ICd2ZXJ0aWNhbCc7XHJcblxyXG4gIC8qKlxyXG4gICAqIFVuaXF1ZSBJRCBmb3IgdGhlIGRyb3Agem9uZS4gQ2FuIGJlIHVzZWQgYXMgYSByZWZlcmVuY2VcclxuICAgKiBpbiB0aGUgYGNvbm5lY3RlZFRvYCBvZiBhbm90aGVyIGBDZGtEcm9wTGlzdGAuXHJcbiAgICovXHJcbiAgQElucHV0KCkgaWQ6IHN0cmluZyA9IGBjZGstZHJvcC1saXN0LSR7X3VuaXF1ZUlkQ291bnRlcisrfWA7XHJcblxyXG4gIC8qKiBMb2NrcyB0aGUgcG9zaXRpb24gb2YgdGhlIGRyYWdnYWJsZSBlbGVtZW50cyBpbnNpZGUgdGhlIGNvbnRhaW5lciBhbG9uZyB0aGUgc3BlY2lmaWVkIGF4aXMuICovXHJcbiAgQElucHV0KCdjZGtEcm9wTGlzdExvY2tBeGlzJykgbG9ja0F4aXM6ICd4JyB8ICd5JztcclxuXHJcbiAgLyoqIFdoZXRoZXIgc3RhcnRpbmcgYSBkcmFnZ2luZyBzZXF1ZW5jZSBmcm9tIHRoaXMgY29udGFpbmVyIGlzIGRpc2FibGVkLiAqL1xyXG4gIEBJbnB1dCgnY2RrRHJvcExpc3REaXNhYmxlZCcpXHJcbiAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2Rpc2FibGVkIHx8ICghIXRoaXMuX2dyb3VwICYmIHRoaXMuX2dyb3VwLmRpc2FibGVkKTtcclxuICB9XHJcbiAgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLl9kaXNhYmxlZCA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XHJcbiAgfVxyXG4gIHByaXZhdGUgX2Rpc2FibGVkID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZ1bmN0aW9uIHRoYXQgaXMgdXNlZCB0byBkZXRlcm1pbmUgd2hldGhlciBhbiBpdGVtXHJcbiAgICogaXMgYWxsb3dlZCB0byBiZSBtb3ZlZCBpbnRvIGEgZHJvcCBjb250YWluZXIuXHJcbiAgICovXHJcbiAgQElucHV0KCdjZGtEcm9wTGlzdEVudGVyUHJlZGljYXRlJylcclxuICBlbnRlclByZWRpY2F0ZTogKGRyYWc6IENka0RyYWcsIGRyb3A6IENka0Ryb3BMaXN0KSA9PiBib29sZWFuID0gKCkgPT4gdHJ1ZVxyXG5cclxuICAvKiogRW1pdHMgd2hlbiB0aGUgdXNlciBkcm9wcyBhbiBpdGVtIGluc2lkZSB0aGUgY29udGFpbmVyLiAqL1xyXG4gIEBPdXRwdXQoJ2Nka0Ryb3BMaXN0RHJvcHBlZCcpXHJcbiAgZHJvcHBlZDogRXZlbnRFbWl0dGVyPENka0RyYWdEcm9wPFQsIGFueT4+ID0gbmV3IEV2ZW50RW1pdHRlcjxDZGtEcmFnRHJvcDxULCBhbnk+PigpO1xyXG5cclxuICAvKipcclxuICAgKiBFbWl0cyB3aGVuIHRoZSB1c2VyIGhhcyBtb3ZlZCBhIG5ldyBkcmFnIGl0ZW0gaW50byB0aGlzIGNvbnRhaW5lci5cclxuICAgKi9cclxuICBAT3V0cHV0KCdjZGtEcm9wTGlzdEVudGVyZWQnKVxyXG4gIGVudGVyZWQ6IEV2ZW50RW1pdHRlcjxDZGtEcmFnRW50ZXI8VD4+ID0gbmV3IEV2ZW50RW1pdHRlcjxDZGtEcmFnRW50ZXI8VD4+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEVtaXRzIHdoZW4gdGhlIHVzZXIgcmVtb3ZlcyBhbiBpdGVtIGZyb20gdGhlIGNvbnRhaW5lclxyXG4gICAqIGJ5IGRyYWdnaW5nIGl0IGludG8gYW5vdGhlciBjb250YWluZXIuXHJcbiAgICovXHJcbiAgQE91dHB1dCgnY2RrRHJvcExpc3RFeGl0ZWQnKVxyXG4gIGV4aXRlZDogRXZlbnRFbWl0dGVyPENka0RyYWdFeGl0PFQ+PiA9IG5ldyBFdmVudEVtaXR0ZXI8Q2RrRHJhZ0V4aXQ8VD4+KCk7XHJcblxyXG4gIC8qKiBFbWl0cyBhcyB0aGUgdXNlciBpcyBzd2FwcGluZyBpdGVtcyB3aGlsZSBhY3RpdmVseSBkcmFnZ2luZy4gKi9cclxuICBAT3V0cHV0KCdjZGtEcm9wTGlzdFNvcnRlZCcpXHJcbiAgc29ydGVkOiBFdmVudEVtaXR0ZXI8Q2RrRHJhZ1NvcnRFdmVudDxUPj4gPSBuZXcgRXZlbnRFbWl0dGVyPENka0RyYWdTb3J0RXZlbnQ8VD4+KCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgLyoqIEVsZW1lbnQgdGhhdCB0aGUgZHJvcCBsaXN0IGlzIGF0dGFjaGVkIHRvLiAqL1xyXG4gICAgcHVibGljIGVsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxyXG4gICAgZHJhZ0Ryb3BSZWdpc3RyeTogRHJhZ0Ryb3BSZWdpc3RyeTxEcmFnUmVmLCBEcm9wTGlzdFJlZj4sXHJcbiAgICBwcml2YXRlIF9jaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIF9kaXI/OiBEaXJlY3Rpb25hbGl0eSxcclxuICAgIEBPcHRpb25hbCgpIEBTa2lwU2VsZigpIHByaXZhdGUgX2dyb3VwPzogQ2RrRHJvcExpc3RHcm91cDxDZGtEcm9wTGlzdD4sXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERPQ1VNRU5UKSBfZG9jdW1lbnQ/OiBhbnksXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBgZHJhZ0Ryb3BSZWdpc3RyeWAgYW5kIGBfZG9jdW1lbnRgIHBhcmFtZXRlcnMgdG8gYmUgcmVtb3ZlZC5cclxuICAgICAqIEFsc28gYGRyYWdEcm9wYCBwYXJhbWV0ZXIgdG8gYmUgbWFkZSByZXF1aXJlZC5cclxuICAgICAqIEBicmVha2luZy1jaGFuZ2UgOC4wLjAuXHJcbiAgICAgKi9cclxuICAgIGRyYWdEcm9wPzogRHJhZ0Ryb3ApIHtcclxuXHJcbiAgICAvLyBAYnJlYWtpbmctY2hhbmdlIDguMC4wIFJlbW92ZSBudWxsIGNoZWNrIG9uY2UgYGRyYWdEcm9wYCBwYXJhbWV0ZXIgaXMgbWFkZSByZXF1aXJlZC5cclxuICAgIGlmIChkcmFnRHJvcCkge1xyXG4gICAgICB0aGlzLl9kcm9wTGlzdFJlZiA9IGRyYWdEcm9wLmNyZWF0ZURyb3BMaXN0KGVsZW1lbnQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5fZHJvcExpc3RSZWYgPSBuZXcgRHJvcExpc3RSZWYoZWxlbWVudCwgZHJhZ0Ryb3BSZWdpc3RyeSwgX2RvY3VtZW50IHx8IGRvY3VtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9kcm9wTGlzdFJlZi5kYXRhID0gdGhpcztcclxuICAgIHRoaXMuX2Ryb3BMaXN0UmVmLmVudGVyUHJlZGljYXRlID0gKGRyYWc6IERyYWdSZWY8Q2RrRHJhZz4sIGRyb3A6IERyb3BMaXN0UmVmPENka0Ryb3BMaXN0PikgPT4ge1xyXG4gICAgICByZXR1cm4gdGhpcy5lbnRlclByZWRpY2F0ZShkcmFnLmRhdGEsIGRyb3AuZGF0YSk7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuX3N5bmNJbnB1dHModGhpcy5fZHJvcExpc3RSZWYpO1xyXG4gICAgdGhpcy5faGFuZGxlRXZlbnRzKHRoaXMuX2Ryb3BMaXN0UmVmKTtcclxuICAgIENka0Ryb3BMaXN0Ll9kcm9wTGlzdHMucHVzaCh0aGlzKTtcclxuXHJcbiAgICBpZiAoX2dyb3VwKSB7XHJcbiAgICAgIF9ncm91cC5faXRlbXMuYWRkKHRoaXMpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xyXG4gICAgdGhpcy5fZHJhZ2dhYmxlcy5jaGFuZ2VzXHJcbiAgICAgIC5waXBlKHN0YXJ0V2l0aCh0aGlzLl9kcmFnZ2FibGVzKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKGl0ZW1zOiBRdWVyeUxpc3Q8Q2RrRHJhZz4pID0+IHtcclxuICAgICAgICB0aGlzLl9kcm9wTGlzdFJlZi53aXRoSXRlbXMoaXRlbXMubWFwKGRyYWcgPT4gZHJhZy5fZHJhZ1JlZikpO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgY29uc3QgaW5kZXggPSBDZGtEcm9wTGlzdC5fZHJvcExpc3RzLmluZGV4T2YodGhpcyk7XHJcblxyXG4gICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgQ2RrRHJvcExpc3QuX2Ryb3BMaXN0cy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9ncm91cCkge1xyXG4gICAgICB0aGlzLl9ncm91cC5faXRlbXMuZGVsZXRlKHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2Ryb3BMaXN0UmVmLmRpc3Bvc2UoKTtcclxuICAgIHRoaXMuX2Rlc3Ryb3llZC5uZXh0KCk7XHJcbiAgICB0aGlzLl9kZXN0cm95ZWQuY29tcGxldGUoKTtcclxuICB9XHJcblxyXG4gIC8qKiBTdGFydHMgZHJhZ2dpbmcgYW4gaXRlbS4gKi9cclxuICBzdGFydCgpOiB2b2lkIHtcclxuICAgIHRoaXMuX2Ryb3BMaXN0UmVmLnN0YXJ0KCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEcm9wcyBhbiBpdGVtIGludG8gdGhpcyBjb250YWluZXIuXHJcbiAgICogQHBhcmFtIGl0ZW0gSXRlbSBiZWluZyBkcm9wcGVkIGludG8gdGhlIGNvbnRhaW5lci5cclxuICAgKiBAcGFyYW0gY3VycmVudEluZGV4IEluZGV4IGF0IHdoaWNoIHRoZSBpdGVtIHNob3VsZCBiZSBpbnNlcnRlZC5cclxuICAgKiBAcGFyYW0gcHJldmlvdXNDb250YWluZXIgQ29udGFpbmVyIGZyb20gd2hpY2ggdGhlIGl0ZW0gZ290IGRyYWdnZWQgaW4uXHJcbiAgICogQHBhcmFtIGlzUG9pbnRlck92ZXJDb250YWluZXIgV2hldGhlciB0aGUgdXNlcidzIHBvaW50ZXIgd2FzIG92ZXIgdGhlXHJcbiAgICogICAgY29udGFpbmVyIHdoZW4gdGhlIGl0ZW0gd2FzIGRyb3BwZWQuXHJcbiAgICovXHJcbiAgZHJvcChpdGVtOiBDZGtEcmFnLCBjdXJyZW50SW5kZXg6IG51bWJlciwgcHJldmlvdXNDb250YWluZXI6IFBhcnRpYWw8Q2RrRHJvcExpc3RDb250YWluZXI+LFxyXG4gICAgaXNQb2ludGVyT3ZlckNvbnRhaW5lcjogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgdGhpcy5fZHJvcExpc3RSZWYuZHJvcChpdGVtLl9kcmFnUmVmLCBjdXJyZW50SW5kZXgsXHJcbiAgICAgIChwcmV2aW91c0NvbnRhaW5lciBhcyBDZGtEcm9wTGlzdCkuX2Ryb3BMaXN0UmVmLCBpc1BvaW50ZXJPdmVyQ29udGFpbmVyKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEVtaXRzIGFuIGV2ZW50IHRvIGluZGljYXRlIHRoYXQgdGhlIHVzZXIgbW92ZWQgYW4gaXRlbSBpbnRvIHRoZSBjb250YWluZXIuXHJcbiAgICogQHBhcmFtIGl0ZW0gSXRlbSB0aGF0IHdhcyBtb3ZlZCBpbnRvIHRoZSBjb250YWluZXIuXHJcbiAgICogQHBhcmFtIHBvaW50ZXJYIFBvc2l0aW9uIG9mIHRoZSBpdGVtIGFsb25nIHRoZSBYIGF4aXMuXHJcbiAgICogQHBhcmFtIHBvaW50ZXJZIFBvc2l0aW9uIG9mIHRoZSBpdGVtIGFsb25nIHRoZSBZIGF4aXMuXHJcbiAgICovXHJcbiAgZW50ZXIoaXRlbTogQ2RrRHJhZywgcG9pbnRlclg6IG51bWJlciwgcG9pbnRlclk6IG51bWJlcik6IHZvaWQge1xyXG4gICAgdGhpcy5fZHJvcExpc3RSZWYuZW50ZXIoaXRlbS5fZHJhZ1JlZiwgcG9pbnRlclgsIHBvaW50ZXJZKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlbW92ZXMgYW4gaXRlbSBmcm9tIHRoZSBjb250YWluZXIgYWZ0ZXIgaXQgd2FzIGRyYWdnZWQgaW50byBhbm90aGVyIGNvbnRhaW5lciBieSB0aGUgdXNlci5cclxuICAgKiBAcGFyYW0gaXRlbSBJdGVtIHRoYXQgd2FzIGRyYWdnZWQgb3V0LlxyXG4gICAqL1xyXG4gIGV4aXQoaXRlbTogQ2RrRHJhZyk6IHZvaWQge1xyXG4gICAgdGhpcy5fZHJvcExpc3RSZWYuZXhpdChpdGVtLl9kcmFnUmVmKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpZ3VyZXMgb3V0IHRoZSBpbmRleCBvZiBhbiBpdGVtIGluIHRoZSBjb250YWluZXIuXHJcbiAgICogQHBhcmFtIGl0ZW0gSXRlbSB3aG9zZSBpbmRleCBzaG91bGQgYmUgZGV0ZXJtaW5lZC5cclxuICAgKi9cclxuICBnZXRJdGVtSW5kZXgoaXRlbTogQ2RrRHJhZyk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5fZHJvcExpc3RSZWYuZ2V0SXRlbUluZGV4KGl0ZW0uX2RyYWdSZWYpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU29ydHMgYW4gaXRlbSBpbnNpZGUgdGhlIGNvbnRhaW5lciBiYXNlZCBvbiBpdHMgcG9zaXRpb24uXHJcbiAgICogQHBhcmFtIGl0ZW0gSXRlbSB0byBiZSBzb3J0ZWQuXHJcbiAgICogQHBhcmFtIHBvaW50ZXJYIFBvc2l0aW9uIG9mIHRoZSBpdGVtIGFsb25nIHRoZSBYIGF4aXMuXHJcbiAgICogQHBhcmFtIHBvaW50ZXJZIFBvc2l0aW9uIG9mIHRoZSBpdGVtIGFsb25nIHRoZSBZIGF4aXMuXHJcbiAgICogQHBhcmFtIHBvaW50ZXJEZWx0YSBEaXJlY3Rpb24gaW4gd2hpY2ggdGhlIHBvaW50ZXIgaXMgbW92aW5nIGFsb25nIGVhY2ggYXhpcy5cclxuICAgKi9cclxuICBfc29ydEl0ZW0oaXRlbTogQ2RrRHJhZywgcG9pbnRlclg6IG51bWJlciwgcG9pbnRlclk6IG51bWJlcixcclxuICAgICAgICAgICAgcG9pbnRlckRlbHRhOiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9KTogdm9pZCB7XHJcbiAgICByZXR1cm4gdGhpcy5fZHJvcExpc3RSZWYuX3NvcnRJdGVtKGl0ZW0uX2RyYWdSZWYsIHBvaW50ZXJYLCBwb2ludGVyWSwgcG9pbnRlckRlbHRhKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpZ3VyZXMgb3V0IHdoZXRoZXIgYW4gaXRlbSBzaG91bGQgYmUgbW92ZWQgaW50byBhIHNpYmxpbmdcclxuICAgKiBkcm9wIGNvbnRhaW5lciwgYmFzZWQgb24gaXRzIGN1cnJlbnQgcG9zaXRpb24uXHJcbiAgICogQHBhcmFtIGl0ZW0gRHJhZyBpdGVtIHRoYXQgaXMgYmVpbmcgbW92ZWQuXHJcbiAgICogQHBhcmFtIHggUG9zaXRpb24gb2YgdGhlIGl0ZW0gYWxvbmcgdGhlIFggYXhpcy5cclxuICAgKiBAcGFyYW0geSBQb3NpdGlvbiBvZiB0aGUgaXRlbSBhbG9uZyB0aGUgWSBheGlzLlxyXG4gICAqL1xyXG4gIF9nZXRTaWJsaW5nQ29udGFpbmVyRnJvbVBvc2l0aW9uKGl0ZW06IENka0RyYWcsIHg6IG51bWJlciwgeTogbnVtYmVyKTpcclxuICAgIENka0Ryb3BMaXN0Q29udGFpbmVyIHwgbnVsbCB7XHJcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kcm9wTGlzdFJlZi5fZ2V0U2libGluZ0NvbnRhaW5lckZyb21Qb3NpdGlvbihpdGVtLl9kcmFnUmVmLCB4LCB5KTtcclxuICAgIHJldHVybiByZXN1bHQgPyByZXN1bHQuZGF0YSA6IG51bGw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVja3Mgd2hldGhlciB0aGUgdXNlcidzIHBvaW50ZXIgaXMgcG9zaXRpb25lZCBvdmVyIHRoZSBjb250YWluZXIuXHJcbiAgICogQHBhcmFtIHggUG9pbnRlciBwb3NpdGlvbiBhbG9uZyB0aGUgWCBheGlzLlxyXG4gICAqIEBwYXJhbSB5IFBvaW50ZXIgcG9zaXRpb24gYWxvbmcgdGhlIFkgYXhpcy5cclxuICAgKi9cclxuICBfaXNPdmVyQ29udGFpbmVyKHg6IG51bWJlciwgeTogbnVtYmVyKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5fZHJvcExpc3RSZWYuX2lzT3ZlckNvbnRhaW5lcih4LCB5KTtcclxuICB9XHJcblxyXG4gIC8qKiBTeW5jcyB0aGUgaW5wdXRzIG9mIHRoZSBDZGtEcm9wTGlzdCB3aXRoIHRoZSBvcHRpb25zIG9mIHRoZSB1bmRlcmx5aW5nIERyb3BMaXN0UmVmLiAqL1xyXG4gIHByaXZhdGUgX3N5bmNJbnB1dHMocmVmOiBEcm9wTGlzdFJlZjxDZGtEcm9wTGlzdD4pIHtcclxuICAgIGlmICh0aGlzLl9kaXIpIHtcclxuICAgICAgdGhpcy5fZGlyLmNoYW5nZVxyXG4gICAgICAgIC5waXBlKHN0YXJ0V2l0aCh0aGlzLl9kaXIudmFsdWUpLCB0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSlcclxuICAgICAgICAuc3Vic2NyaWJlKHZhbHVlID0+IHJlZi53aXRoRGlyZWN0aW9uKHZhbHVlKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVmLmJlZm9yZVN0YXJ0ZWQuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgY29uc3Qgc2libGluZ3MgPSBjb2VyY2VBcnJheSh0aGlzLmNvbm5lY3RlZFRvKS5tYXAoZHJvcCA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBkcm9wID09PSAnc3RyaW5nJyA/XHJcbiAgICAgICAgICAgIENka0Ryb3BMaXN0Ll9kcm9wTGlzdHMuZmluZChsaXN0ID0+IGxpc3QuaWQgPT09IGRyb3ApISA6IGRyb3A7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaWYgKHRoaXMuX2dyb3VwKSB7XHJcbiAgICAgICAgdGhpcy5fZ3JvdXAuX2l0ZW1zLmZvckVhY2goZHJvcCA9PiB7XHJcbiAgICAgICAgICBpZiAoc2libGluZ3MuaW5kZXhPZihkcm9wKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgc2libGluZ3MucHVzaChkcm9wKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmVmLmxvY2tBeGlzID0gdGhpcy5sb2NrQXhpcztcclxuICAgICAgcmVmXHJcbiAgICAgICAgLmNvbm5lY3RlZFRvKHNpYmxpbmdzLmZpbHRlcihkcm9wID0+IGRyb3AgJiYgZHJvcCAhPT0gdGhpcykubWFwKGxpc3QgPT4gbGlzdC5fZHJvcExpc3RSZWYpKVxyXG4gICAgICAgIC53aXRoT3JpZW50YXRpb24odGhpcy5vcmllbnRhdGlvbik7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKiBIYW5kbGVzIGV2ZW50cyBmcm9tIHRoZSB1bmRlcmx5aW5nIERyb3BMaXN0UmVmLiAqL1xyXG4gIHByaXZhdGUgX2hhbmRsZUV2ZW50cyhyZWY6IERyb3BMaXN0UmVmPENka0Ryb3BMaXN0Pikge1xyXG4gICAgcmVmLmJlZm9yZVN0YXJ0ZWQuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZWYuZW50ZXJlZC5zdWJzY3JpYmUoZXZlbnQgPT4ge1xyXG4gICAgICB0aGlzLmVudGVyZWQuZW1pdCh7XHJcbiAgICAgICAgY29udGFpbmVyOiB0aGlzLFxyXG4gICAgICAgIGl0ZW06IGV2ZW50Lml0ZW0uZGF0YVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJlZi5leGl0ZWQuc3Vic2NyaWJlKGV2ZW50ID0+IHtcclxuICAgICAgdGhpcy5leGl0ZWQuZW1pdCh7XHJcbiAgICAgICAgY29udGFpbmVyOiB0aGlzLFxyXG4gICAgICAgIGl0ZW06IGV2ZW50Lml0ZW0uZGF0YVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJlZi5zb3J0ZWQuc3Vic2NyaWJlKGV2ZW50ID0+IHtcclxuICAgICAgdGhpcy5zb3J0ZWQuZW1pdCh7XHJcbiAgICAgICAgcHJldmlvdXNJbmRleDogZXZlbnQucHJldmlvdXNJbmRleCxcclxuICAgICAgICBjdXJyZW50SW5kZXg6IGV2ZW50LmN1cnJlbnRJbmRleCxcclxuICAgICAgICBjb250YWluZXI6IHRoaXMsXHJcbiAgICAgICAgaXRlbTogZXZlbnQuaXRlbS5kYXRhXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmVmLmRyb3BwZWQuc3Vic2NyaWJlKGV2ZW50ID0+IHtcclxuICAgICAgdGhpcy5kcm9wcGVkLmVtaXQoe1xyXG4gICAgICAgIHByZXZpb3VzSW5kZXg6IGV2ZW50LnByZXZpb3VzSW5kZXgsXHJcbiAgICAgICAgY3VycmVudEluZGV4OiBldmVudC5jdXJyZW50SW5kZXgsXHJcbiAgICAgICAgcHJldmlvdXNDb250YWluZXI6IGV2ZW50LnByZXZpb3VzQ29udGFpbmVyLmRhdGEsXHJcbiAgICAgICAgY29udGFpbmVyOiBldmVudC5jb250YWluZXIuZGF0YSxcclxuICAgICAgICBpdGVtOiBldmVudC5pdGVtLmRhdGEsXHJcbiAgICAgICAgaXNQb2ludGVyT3ZlckNvbnRhaW5lcjogZXZlbnQuaXNQb2ludGVyT3ZlckNvbnRhaW5lclxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIE1hcmsgZm9yIGNoZWNrIHNpbmNlIGFsbCBvZiB0aGVzZSBldmVudHMgcnVuIG91dHNpZGUgb2YgY2hhbmdlXHJcbiAgICAgIC8vIGRldGVjdGlvbiBhbmQgd2UncmUgbm90IGd1YXJhbnRlZWQgZm9yIHNvbWV0aGluZyBlbHNlIHRvIGhhdmUgdHJpZ2dlcmVkIGl0LlxyXG4gICAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbn1cclxuIl19