UNPKG

com.phloxui

Version:

PhloxUI Ng2+ Framework

536 lines (535 loc) 63.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import * as tslib_1 from "tslib"; import { Directive, ElementRef, ViewContainerRef, Input, NgZone } from '@angular/core'; import { AbstractHasOptions } from '../share/AbstractHasOptions'; import { Option } from '../decorator/decorators'; const /** @type {?} */ DEFAULT_ACCEPT = '*'; const /** @type {?} */ DEFAULT_ALWAYS_FIRE_EVENT = false; const /** @type {?} */ DEFAULT_AUTO_ADD_CLASS = true; const /** @type {?} */ DEFAULT_DRAG_OVER_TIMEOUT = 10; const /** @type {?} */ DEFAULT_DRAG_LEAVE_TIMEOUT = 10; const /** @type {?} */ DEFAULT_DROP_CLASS_RESET_TIMEOUT = 400; const /** @type {?} */ CLASS_NAME_DRAG_OVER = 'drag-over'; const /** @type {?} */ CLASS_NAME_DROP_ACCEPTED = 'drop-accepted'; const /** @type {?} */ CLASS_NAME_DROP_REJECTED = 'drop-rejected'; export class Droppable extends AbstractHasOptions { /** * @param {?} elRef * @param {?} viewConRef * @param {?} ngZone */ constructor(elRef, viewConRef, ngZone) { super(); this.elementRef = elRef; // Resolve component instance try { this.component = (/** @type {?} */ (viewConRef))._data.componentView.component; } catch (/** @type {?} */ error) { } // Add drag event listeners ngZone.runOutsideAngular(() => { this.bindEvents(); }); } /** * @param {?} event * @return {?} */ static getParsedData(event) { if (event === null || typeof event === 'undefined') { return null; } if (event.dataTransfer === null || typeof event.dataTransfer === 'undefined') { return null; } if (event.dataTransfer.types === null || !Array.isArray(event.dataTransfer.types)) { return null; } let /** @type {?} */ result = []; for (let /** @type {?} */ format of event.dataTransfer.types) { result.push(Droppable.parseData(format, event.dataTransfer.getData(format))); } if (result.length <= 0) { return null; } else if (result.length === 1) { return result[0]; } return result; } /** * @param {?} format * @param {?} eventData * @return {?} */ static parseData(format, eventData) { if (format === null || typeof format !== 'string') { return null; } let /** @type {?} */ result = eventData; if (format.toLowerCase() === 'application/json') { try { result = JSON.parse(eventData); } catch (/** @type {?} */ e) { } } return result; } /** * @param {?} event * @param {?} acceptFormats * @param {?} target * @param {?=} checkData * @return {?} */ static isAccept(event, acceptFormats, target, checkData = true) { let /** @type {?} */ accept = []; if (Array.isArray(acceptFormats)) { for (let /** @type {?} */ format of acceptFormats) { if (format === null || typeof format !== 'string') { continue; } accept.push(format.toLowerCase()); } } else if (typeof acceptFormats === 'string') { accept.push(acceptFormats.toLowerCase()); } let /** @type {?} */ acceptFormat = false; // If there is "any" (*) format, accept immediately. for (let /** @type {?} */ format of accept) { if (format === '*') { acceptFormat = true; break; } } // Check that the event.dataTransfer has accepted data format or not. if (!acceptFormat) { if (event !== null && typeof event !== 'undefined' && event.dataTransfer !== null && typeof event.dataTransfer !== 'undefined') { if (Array.isArray(event.dataTransfer.types) && event.dataTransfer.types.length > 0) { for (let /** @type {?} */ dataFormat of event.dataTransfer.types) { if (dataFormat === null || typeof dataFormat !== 'string') { continue; } if (accept.indexOf(dataFormat.toLowerCase()) >= 0) { acceptFormat = true; break; } } } else { // If there is no data specified in dataTransfer, always accept it in this step. // (We'll test it in isAcceptDragData(event, null, null) below) acceptFormat = true; } } } if (!acceptFormat) { return false; } if ((event !== null && typeof event !== 'undefined' && event.type !== 'drop') || !checkData) { // According to browser sepc, the dataTransfer.data is available when 'drop' event // occurs only (browser security). So, if the event.type is not 'drop', we'll not // going to check isAcceptDragData(), then, return "true" immediately. return true; } if (target !== null && typeof target !== 'undefined' && typeof target.isAcceptDragData === 'function') { if (event !== null && typeof event !== 'undefined' && event.dataTransfer !== null && typeof event.dataTransfer !== 'undefined') { if (Array.isArray(event.dataTransfer.types) && event.dataTransfer.types.length > 0) { // Check that the component accepts dataTransfer.data or not. acceptFormat = false; for (let /** @type {?} */ dataFormat of event.dataTransfer.types) { let /** @type {?} */ parsedData = Droppable.parseData(dataFormat, event.dataTransfer.getData(dataFormat)); if (target.isAcceptDragData(event, dataFormat, parsedData)) { acceptFormat = true; break; } } return acceptFormat; } else { // There is no "data" specified in dataTransfer. return target.isAcceptDragData(event, null, null); } } } // Default value is "false" (not accept). return false; } /** * @return {?} */ bindEvents() { if (this.elementRef !== null && typeof this.elementRef !== 'undefined') { $(this.elementRef.nativeElement).on('dragenter', (event) => { this.onDragEnter.call(this, event.originalEvent); }); $(this.elementRef.nativeElement).on('dragover', (event) => { this.onDragOver.call(this, event.originalEvent); }); $(this.elementRef.nativeElement).on('dragleave', (event) => { this.onDragLeave.call(this, event.originalEvent); }); $(this.elementRef.nativeElement).on('drop', (event) => { this.onDrop.call(this, event.originalEvent); }); } } /** * @return {?} */ ngOnInit() { if (this.accept === null || (typeof this.accept !== 'string' && !Array.isArray(this.accept))) { this.accept = DEFAULT_ACCEPT; } if (this.component === null || typeof this.component === 'undefined') { // Try to resolve "component" from @Input() options; if (this.options !== null && typeof this.options !== 'undefined') { // Test that it is a component instance if (typeof this.options.isAcceptDragData === 'function') { this.component = this.options; } } } if (this.alwaysFireEvent === null || typeof this.alwaysFireEvent === 'undefined') { this.alwaysFireEvent = DEFAULT_ALWAYS_FIRE_EVENT; } if (this.autoAddClass === null || typeof this.autoAddClass === 'undefined') { this.autoAddClass = DEFAULT_AUTO_ADD_CLASS; } if (this.dragOverTimeout === null || typeof this.dragOverTimeout === 'undefined') { this.dragOverTimeout = DEFAULT_DRAG_OVER_TIMEOUT; } if (this.dragLeaveTimeout === null || typeof this.dragLeaveTimeout === 'undefined') { this.dragLeaveTimeout = DEFAULT_DRAG_LEAVE_TIMEOUT; } if (this.dropClassResetTimeout === null || typeof this.dropClassResetTimeout === 'undefined') { this.dropClassResetTimeout = DEFAULT_DROP_CLASS_RESET_TIMEOUT; } } /** * @param {?} className * @return {?} */ addStyleClass(className) { if (this.elementRef !== null && typeof this.elementRef !== 'undefined') { $(this.elementRef.nativeElement).addClass(className); } if (this.component !== null && typeof this.component !== 'undefined' && this.component.elementRef !== null && typeof this.component.elementRef !== 'undefined') { $(this.component.elementRef.nativeElement).addClass(className); } } /** * @param {?} className * @return {?} */ removeStyleClass(className) { if (this.elementRef !== null && typeof this.elementRef !== 'undefined') { $(this.elementRef.nativeElement).removeClass(className); } if (this.component !== null && typeof this.component !== 'undefined' && this.component.elementRef !== null && typeof this.component.elementRef !== 'undefined') { $(this.component.elementRef.nativeElement).removeClass(className); } } /** * @param {?} event * @param {?=} checkData * @return {?} */ isAccept(event, checkData = true) { return Droppable.isAccept(event, this.accept, this.component, checkData); } /** * @param {?} event * @return {?} */ onDragEnter(event) { if (this.component === null || typeof this.component === 'undefined') { return; } let /** @type {?} */ accept = this.isAccept(event, true); if (accept) { // Call event.preventDefault() to accept dataTransfer (see browser spec for more details). event.preventDefault(); } if (typeof this.component.onDragEnter === 'function') { if (this.alwaysFireEvent || this.isAccept(event, true)) { this.component.onDragEnter(event); } } } /** * @param {?} event * @return {?} */ onDragOver(event) { if (this.component === null || typeof this.component === 'undefined') { return; } if (this.dragLeaveTimer !== null && typeof this.dragLeaveTimer !== 'undefined') { clearTimeout(this.dragLeaveTimer); this.dragLeaveTimer = null; } let /** @type {?} */ accept = this.isAccept(event, true); if (accept) { // Call event.preventDefault() to accept dataTransfer (see browser spec for more details). event.preventDefault(); } if (!this.alwaysFireEvent && !accept) { return; } if (event !== null && typeof event !== 'undefined') { if (typeof this.component.getDragOverDataTransfer === 'function') { // Auto set data transfer properties if getDragOverDataTransfer() is available. let /** @type {?} */ dataTransfer = this.component.getDragOverDataTransfer(event); if (dataTransfer !== null && typeof dataTransfer !== 'undefined') { // Set dataTransfer.dropEffect if (typeof dataTransfer.dropEffect === 'function') { // Auto resolve value from function's returned value if it is a function. event.dataTransfer.dropEffect = dataTransfer.dropEffect(event); } else if (typeof dataTransfer.dropEffect !== 'undefined') { event.dataTransfer.dropEffect = dataTransfer.dropEffect; } // The other properties in dataTransfer should be set in "dragstart" event. } } } if (this.dragOverTimer !== null && typeof this.dragOverTimer !== 'undefined') { // Drag over timer is triggering return; } this.dragOverTimer = setTimeout(() => { this.dragOverTimer = null; if (this.autoAddClass) { this.addStyleClass(CLASS_NAME_DRAG_OVER); } if (typeof this.component.onDragOver === 'function') { this.component.onDragOver(event); } }, this.dragOverTimeout); } /** * @param {?} event * @return {?} */ onDragLeave(event) { if (this.component === null || typeof this.component === 'undefined') { return; } if (this.dragOverTimer !== null && typeof this.dragOverTimer !== 'undefined') { clearTimeout(this.dragOverTimer); this.dragOverTimer = null; } if (this.dragLeaveTimer !== null && typeof this.dragLeaveTimer !== 'undefined') { return; } this.dragLeaveTimer = setTimeout(() => { this.dragLeaveTimer = null; if (this.autoAddClass) { this.removeStyleClass(CLASS_NAME_DRAG_OVER); } if (typeof this.component.onDragLeave === 'function') { if (this.alwaysFireEvent || this.isAccept(event, true)) { this.component.onDragLeave(event); } } }, this.dragLeaveTimeout); } /** * @param {?} event * @return {?} */ onDrop(event) { if (this.component === null || typeof this.component === 'undefined') { return; } if (this.dragLeaveTimer !== null && typeof this.dragLeaveTimer !== 'undefined') { clearTimeout(this.dragLeaveTimer); this.dragLeaveTimer = null; } if (this.dragOverTimer !== null && typeof this.dragOverTimer !== 'undefined') { clearTimeout(this.dragOverTimer); this.dragOverTimer = null; } if (this.autoAddClass) { this.removeStyleClass(CLASS_NAME_DRAG_OVER); } if (typeof this.component.onDrop === 'function') { if (this.alwaysFireEvent || this.isAccept(event, false)) { this.component.onDrop(event); } } if (this.isAccept(event, true)) { if (this.autoAddClass) { // Add/remove style this.removeStyleClass(CLASS_NAME_DROP_REJECTED); this.addStyleClass(CLASS_NAME_DROP_ACCEPTED); // Clear auto reset timers if (this.dropAcceptedRemoveClassTimer !== null && typeof this.dropAcceptedRemoveClassTimer !== 'undefined') { clearTimeout(this.dropAcceptedRemoveClassTimer); this.dropAcceptedRemoveClassTimer = null; } if (this.dropRejectedRemoveClassTimer !== null && typeof this.dropRejectedRemoveClassTimer !== 'undefined') { clearTimeout(this.dropRejectedRemoveClassTimer); this.dropRejectedRemoveClassTimer = null; } // Set auto reset timer this.dropAcceptedRemoveClassTimer = setTimeout(() => { this.dropAcceptedRemoveClassTimer = null; this.removeStyleClass(CLASS_NAME_DROP_ACCEPTED); }, this.dropClassResetTimeout); } // Fire event handler if (typeof this.component.onDropAccepted === 'function') { this.component.onDropAccepted(event, Droppable.getParsedData(event)); } } else { if (this.autoAddClass) { // Add/remove style this.removeStyleClass(CLASS_NAME_DROP_ACCEPTED); this.addStyleClass(CLASS_NAME_DROP_REJECTED); // Clear auto reset timers if (this.dropAcceptedRemoveClassTimer !== null && typeof this.dropAcceptedRemoveClassTimer !== 'undefined') { clearTimeout(this.dropAcceptedRemoveClassTimer); this.dropAcceptedRemoveClassTimer = null; } if (this.dropRejectedRemoveClassTimer !== null && typeof this.dropRejectedRemoveClassTimer !== 'undefined') { clearTimeout(this.dropRejectedRemoveClassTimer); this.dropRejectedRemoveClassTimer = null; } // Set auto reset timer this.dropRejectedRemoveClassTimer = setTimeout(() => { this.dropRejectedRemoveClassTimer = null; this.removeStyleClass(CLASS_NAME_DROP_REJECTED); }, this.dropClassResetTimeout); } // Fire event handler if (typeof this.component.onDropRejected === 'function') { this.component.onDropRejected(event); } } } } Droppable.DEFAULT_ACCEPT = DEFAULT_ACCEPT; Droppable.DEFAULT_ALWAYS_FIRE_EVENT = DEFAULT_ALWAYS_FIRE_EVENT; Droppable.DEFAULT_AUTO_ADD_CLASS = DEFAULT_AUTO_ADD_CLASS; Droppable.CLASS_NAME_DRAG_OVER = CLASS_NAME_DRAG_OVER; Droppable.CLASS_NAME_DROP_ACCEPTED = CLASS_NAME_DROP_ACCEPTED; Droppable.CLASS_NAME_DROP_REJECTED = CLASS_NAME_DROP_REJECTED; Droppable.DEFAULT_DRAG_OVER_TIMEOUT = DEFAULT_DRAG_OVER_TIMEOUT; Droppable.DEFAULT_DRAG_LEAVE_TIMEOUT = DEFAULT_DRAG_LEAVE_TIMEOUT; Droppable.DEFAULT_DROP_CLASS_RESET_TIMEOUT = DEFAULT_DROP_CLASS_RESET_TIMEOUT; Droppable.decorators = [ { type: Directive, args: [{ selector: '[phxDroppable]' },] }, ]; /** @nocollapse */ Droppable.ctorParameters = () => [ { type: ElementRef, }, { type: ViewContainerRef, }, { type: NgZone, }, ]; Droppable.propDecorators = { "options": [{ type: Input, args: ['phxDroppable',] },], "accept": [{ type: Input, args: ['dropAccept',] },], "component": [{ type: Input, args: ['dropTarget',] },], "alwaysFireEvent": [{ type: Input, args: ['dropFireEvent',] },], "autoAddClass": [{ type: Input, args: ['dropAddClass',] },], "dragLeaveTimeout": [{ type: Input, args: ['dropDragLeaveTimeout',] },], "dragOverTimeout": [{ type: Input, args: ['dropDragOverTimeout',] },], "dropClassResetTimeout": [{ type: Input, args: ['dropClassResetTimeout',] },], }; tslib_1.__decorate([ Option('accept'), tslib_1.__metadata("design:type", Object) ], Droppable.prototype, "accept", void 0); tslib_1.__decorate([ Option('target'), tslib_1.__metadata("design:type", Object) ], Droppable.prototype, "component", void 0); tslib_1.__decorate([ Option('fireEvent'), tslib_1.__metadata("design:type", Boolean) ], Droppable.prototype, "alwaysFireEvent", void 0); tslib_1.__decorate([ Option('addClass'), tslib_1.__metadata("design:type", Boolean) ], Droppable.prototype, "autoAddClass", void 0); tslib_1.__decorate([ Option('dragLeaveTimeout'), tslib_1.__metadata("design:type", Number) ], Droppable.prototype, "dragLeaveTimeout", void 0); tslib_1.__decorate([ Option('dragOverTimeout'), tslib_1.__metadata("design:type", Number) ], Droppable.prototype, "dragOverTimeout", void 0); tslib_1.__decorate([ Option('dropClassResetTimeout'), tslib_1.__metadata("design:type", Number) ], Droppable.prototype, "dropClassResetTimeout", void 0); function Droppable_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ Droppable.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ Droppable.ctorParameters; /** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */ Droppable.propDecorators; /** @type {?} */ Droppable.DEFAULT_ACCEPT; /** @type {?} */ Droppable.DEFAULT_ALWAYS_FIRE_EVENT; /** @type {?} */ Droppable.DEFAULT_AUTO_ADD_CLASS; /** @type {?} */ Droppable.CLASS_NAME_DRAG_OVER; /** @type {?} */ Droppable.CLASS_NAME_DROP_ACCEPTED; /** @type {?} */ Droppable.CLASS_NAME_DROP_REJECTED; /** @type {?} */ Droppable.DEFAULT_DRAG_OVER_TIMEOUT; /** @type {?} */ Droppable.DEFAULT_DRAG_LEAVE_TIMEOUT; /** @type {?} */ Droppable.DEFAULT_DROP_CLASS_RESET_TIMEOUT; /** @type {?} */ Droppable.prototype.options; /** @type {?} */ Droppable.prototype.accept; /** @type {?} */ Droppable.prototype.component; /** @type {?} */ Droppable.prototype.alwaysFireEvent; /** @type {?} */ Droppable.prototype.autoAddClass; /** @type {?} */ Droppable.prototype.dragLeaveTimeout; /** @type {?} */ Droppable.prototype.dragOverTimeout; /** @type {?} */ Droppable.prototype.dropClassResetTimeout; /** @type {?} */ Droppable.prototype.elementRef; /** @type {?} */ Droppable.prototype.dragOverTimer; /** @type {?} */ Droppable.prototype.dragLeaveTimer; /** @type {?} */ Droppable.prototype.dropAcceptedRemoveClassTimer; /** @type {?} */ Droppable.prototype.dropRejectedRemoveClassTimer; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRHJvcHBhYmxlLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2NvbS5waGxveHVpLyIsInNvdXJjZXMiOlsibGliL2RpcmVjdGl2ZS9Ecm9wcGFibGUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFxQixTQUFTLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLEtBQUssRUFBZ0IsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXhILE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRWpFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQU1qRCx1QkFBTSxjQUFjLEdBQVcsR0FBRyxDQUFDO0FBQ25DLHVCQUFNLHlCQUF5QixHQUFZLEtBQUssQ0FBQztBQUNqRCx1QkFBTSxzQkFBc0IsR0FBWSxJQUFJLENBQUM7QUFDN0MsdUJBQU0seUJBQXlCLEdBQVcsRUFBRSxDQUFDO0FBQzdDLHVCQUFNLDBCQUEwQixHQUFXLEVBQUUsQ0FBQztBQUM5Qyx1QkFBTSxnQ0FBZ0MsR0FBVyxHQUFHLENBQUM7QUFDckQsdUJBQU0sb0JBQW9CLEdBQVcsV0FBVyxDQUFDO0FBQ2pELHVCQUFNLHdCQUF3QixHQUFXLGVBQWUsQ0FBQztBQUN6RCx1QkFBTSx3QkFBd0IsR0FBVyxlQUFlLENBQUM7QUFPekQsTUFBTSxnQkFBaUIsU0FBUSxrQkFBa0I7Ozs7OztJQTRLL0MsWUFBWSxLQUFpQixFQUFFLFVBQTRCLEVBQUUsTUFBYztRQUN6RSxLQUFLLEVBQUUsQ0FBQztRQUVSLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDOztRQUd4QixJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsU0FBUyxHQUFHLG1CQUFNLFVBQVUsRUFBQyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDO1NBQ2xFO1FBQUMsS0FBSyxDQUFDLENBQUMsaUJBQUEsS0FBSyxFQUFFLENB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bkluaXQsIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgVmlld0NvbnRhaW5lclJlZiwgSW5wdXQsIEhvc3RMaXN0ZW5lciwgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IEFic3RyYWN0SGFzT3B0aW9ucyB9IGZyb20gJy4uL3NoYXJlL0Fic3RyYWN0SGFzT3B0aW9ucyc7XG5cbmltcG9ydCB7IE9wdGlvbiB9IGZyb20gJy4uL2RlY29yYXRvci9kZWNvcmF0b3JzJztcblxuaW1wb3J0IHsgRHJhZ0RhdGFUcmFuc2ZlciB9IGZyb20gJy4uL2NvbXBvbmVudC9tb2RlbC9tb2RlbHMnO1xuXG5pbXBvcnQgeyBJRHJvcHBhYmxlIH0gZnJvbSAnLi4vY29tcG9uZW50L0lEcm9wcGFibGUnO1xuXG5jb25zdCBERUZBVUxUX0FDQ0VQVDogc3RyaW5nID0gJyonO1xuY29uc3QgREVGQVVMVF9BTFdBWVNfRklSRV9FVkVOVDogYm9vbGVhbiA9IGZhbHNlO1xuY29uc3QgREVGQVVMVF9BVVRPX0FERF9DTEFTUzogYm9vbGVhbiA9IHRydWU7XG5jb25zdCBERUZBVUxUX0RSQUdfT1ZFUl9USU1FT1VUOiBudW1iZXIgPSAxMDtcbmNvbnN0IERFRkFVTFRfRFJBR19MRUFWRV9USU1FT1VUOiBudW1iZXIgPSAxMDtcbmNvbnN0IERFRkFVTFRfRFJPUF9DTEFTU19SRVNFVF9USU1FT1VUOiBudW1iZXIgPSA0MDA7XG5jb25zdCBDTEFTU19OQU1FX0RSQUdfT1ZFUjogc3RyaW5nID0gJ2RyYWctb3Zlcic7XG5jb25zdCBDTEFTU19OQU1FX0RST1BfQUNDRVBURUQ6IHN0cmluZyA9ICdkcm9wLWFjY2VwdGVkJztcbmNvbnN0IENMQVNTX05BTUVfRFJPUF9SRUpFQ1RFRDogc3RyaW5nID0gJ2Ryb3AtcmVqZWN0ZWQnO1xuXG5kZWNsYXJlIHZhciAkOiBhbnk7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1twaHhEcm9wcGFibGVdJ1xufSlcbmV4cG9ydCBjbGFzcyBEcm9wcGFibGUgZXh0ZW5kcyBBYnN0cmFjdEhhc09wdGlvbnMgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9BQ0NFUFQ6IHN0cmluZyA9IERFRkFVTFRfQUNDRVBUO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfQUxXQVlTX0ZJUkVfRVZFTlQ6IGJvb2xlYW4gPSBERUZBVUxUX0FMV0FZU19GSVJFX0VWRU5UO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfQVVUT19BRERfQ0xBU1M6IGJvb2xlYW4gPSBERUZBVUxUX0FVVE9fQUREX0NMQVNTO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENMQVNTX05BTUVfRFJBR19PVkVSOiBzdHJpbmcgPSBDTEFTU19OQU1FX0RSQUdfT1ZFUjtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBDTEFTU19OQU1FX0RST1BfQUNDRVBURUQ6IHN0cmluZyA9IENMQVNTX05BTUVfRFJPUF9BQ0NFUFRFRDtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBDTEFTU19OQU1FX0RST1BfUkVKRUNURUQ6IHN0cmluZyA9IENMQVNTX05BTUVfRFJPUF9SRUpFQ1RFRDtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBERUZBVUxUX0RSQUdfT1ZFUl9USU1FT1VUOiBudW1iZXIgPSBERUZBVUxUX0RSQUdfT1ZFUl9USU1FT1VUO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfRFJBR19MRUFWRV9USU1FT1VUOiBudW1iZXIgPSBERUZBVUxUX0RSQUdfTEVBVkVfVElNRU9VVDtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBERUZBVUxUX0RST1BfQ0xBU1NfUkVTRVRfVElNRU9VVDogbnVtYmVyID0gREVGQVVMVF9EUk9QX0NMQVNTX1JFU0VUX1RJTUVPVVQ7XG5cbiAgcHVibGljIHN0YXRpYyBnZXRQYXJzZWREYXRhKGV2ZW50OiBhbnkpOiBhbnkge1xuICAgIGlmIChldmVudCA9PT0gbnVsbCB8fCB0eXBlb2YgZXZlbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKGV2ZW50LmRhdGFUcmFuc2ZlciA9PT0gbnVsbCB8fCB0eXBlb2YgZXZlbnQuZGF0YVRyYW5zZmVyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChldmVudC5kYXRhVHJhbnNmZXIudHlwZXMgPT09IG51bGwgfHwgIUFycmF5LmlzQXJyYXkoZXZlbnQuZGF0YVRyYW5zZmVyLnR5cGVzKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgbGV0IHJlc3VsdDogYW55W10gPSBbXTtcbiAgICBmb3IgKGxldCBmb3JtYXQgb2YgZXZlbnQuZGF0YVRyYW5zZmVyLnR5cGVzKSB7XG4gICAgICByZXN1bHQucHVzaChEcm9wcGFibGUucGFyc2VEYXRhKGZvcm1hdCwgZXZlbnQuZGF0YVRyYW5zZmVyLmdldERhdGEoZm9ybWF0KSkpO1xuICAgIH1cblxuICAgIGlmIChyZXN1bHQubGVuZ3RoIDw9IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAocmVzdWx0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIHJlc3VsdFswXTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBwYXJzZURhdGEoZm9ybWF0OiBzdHJpbmcsIGV2ZW50RGF0YTogYW55KTogYW55IHtcbiAgICBpZiAoZm9ybWF0ID09PSBudWxsIHx8IHR5cGVvZiBmb3JtYXQgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBsZXQgcmVzdWx0OiBhbnkgPSBldmVudERhdGE7XG4gICAgaWYgKGZvcm1hdC50b0xvd2VyQ2FzZSgpID09PSAnYXBwbGljYXRpb24vanNvbicpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc3VsdCA9IEpTT04ucGFyc2UoZXZlbnREYXRhKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBpc0FjY2VwdChldmVudDogYW55LCBhY2NlcHRGb3JtYXRzOiBhbnksIHRhcmdldDogSURyb3BwYWJsZSwgY2hlY2tEYXRhOiBib29sZWFuID0gdHJ1ZSk6IGJvb2xlYW4ge1xuICAgIGxldCBhY2NlcHQ6IHN0cmluZ1tdID0gW107XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYWNjZXB0Rm9ybWF0cykpIHtcbiAgICAgIGZvciAobGV0IGZvcm1hdCBvZiBhY2NlcHRGb3JtYXRzKSB7XG4gICAgICAgIGlmIChmb3JtYXQgPT09IG51bGwgfHwgdHlwZW9mIGZvcm1hdCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGFjY2VwdC5wdXNoKGZvcm1hdC50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBhY2NlcHRGb3JtYXRzID09PSAnc3RyaW5nJykge1xuICAgICAgYWNjZXB0LnB1c2goYWNjZXB0Rm9ybWF0cy50b0xvd2VyQ2FzZSgpKTtcbiAgICB9XG5cbiAgICBsZXQgYWNjZXB0Rm9ybWF0OiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvLyBJZiB0aGVyZSBpcyBcImFueVwiICgqKSBmb3JtYXQsIGFjY2VwdCBpbW1lZGlhdGVseS5cbiAgICBmb3IgKGxldCBmb3JtYXQgb2YgYWNjZXB0KSB7XG4gICAgICBpZiAoZm9ybWF0ID09PSAnKicpIHtcbiAgICAgICAgYWNjZXB0Rm9ybWF0ID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgdGhhdCB0aGUgZXZlbnQuZGF0YVRyYW5zZmVyIGhhcyBhY2NlcHRlZCBkYXRhIGZvcm1hdCBvciBub3QuXG4gICAgaWYgKCFhY2NlcHRGb3JtYXQpIHtcbiAgICAgIGlmIChldmVudCAhPT0gbnVsbCAmJiB0eXBlb2YgZXZlbnQgIT09ICd1bmRlZmluZWQnICYmIGV2ZW50LmRhdGFUcmFuc2ZlciAhPT0gbnVsbCAmJiB0eXBlb2YgZXZlbnQuZGF0YVRyYW5zZmVyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShldmVudC5kYXRhVHJhbnNmZXIudHlwZXMpICYmIGV2ZW50LmRhdGFUcmFuc2Zlci50eXBlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgZm9yIChsZXQgZGF0YUZvcm1hdCBvZiBldmVudC5kYXRhVHJhbnNmZXIudHlwZXMpIHtcbiAgICAgICAgICAgIGlmIChkYXRhRm9ybWF0ID09PSBudWxsIHx8IHR5cGVvZiBkYXRhRm9ybWF0ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhY2NlcHQuaW5kZXhPZihkYXRhRm9ybWF0LnRvTG93ZXJDYXNlKCkpID49IDApIHtcbiAgICAgICAgICAgICAgYWNjZXB0Rm9ybWF0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGRhdGEgc3BlY2lmaWVkIGluIGRhdGFUcmFuc2ZlciwgYWx3YXlzIGFjY2VwdCBpdCBpbiB0aGlzIHN0ZXAuXG4gICAgICAgICAgLy8gKFdlJ2xsIHRlc3QgaXQgaW4gaXNBY2NlcHREcmFnRGF0YShldmVudCwgbnVsbCwgbnVsbCkgYmVsb3cpXG4gICAgICAgICAgYWNjZXB0Rm9ybWF0ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghYWNjZXB0Rm9ybWF0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKChldmVudCAhPT0gbnVsbCAmJiB0eXBlb2YgZXZlbnQgIT09ICd1bmRlZmluZWQnICYmIGV2ZW50LnR5cGUgIT09ICdkcm9wJykgfHwgIWNoZWNrRGF0YSkge1xuICAgICAgLy8gQWNjb3JkaW5nIHRvIGJyb3dzZXIgc2VwYywgdGhlIGRhdGFUcmFuc2Zlci5kYXRhIGlzIGF2YWlsYWJsZSB3aGVuICdkcm9wJyBldmVudFxuICAgICAgLy8gb2NjdXJzIG9ubHkgKGJyb3dzZXIgc2VjdXJpdHkpLiBTbywgaWYgdGhlIGV2ZW50LnR5cGUgaXMgbm90ICdkcm9wJywgd2UnbGwgbm90XG4gICAgICAvLyBnb2luZyB0byBjaGVjayBpc0FjY2VwdERyYWdEYXRhKCksIHRoZW4sIHJldHVybiBcInRydWVcIiBpbW1lZGlhdGVseS5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0YXJnZXQgIT09IG51bGwgJiYgdHlwZW9mIHRhcmdldCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHRhcmdldC5pc0FjY2VwdERyYWdEYXRhID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoZXZlbnQgIT09IG51bGwgJiYgdHlwZW9mIGV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBldmVudC5kYXRhVHJhbnNmZXIgIT09IG51bGwgJiYgdHlwZW9mIGV2ZW50LmRhdGFUcmFuc2ZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZXZlbnQuZGF0YVRyYW5zZmVyLnR5cGVzKSAmJiBldmVudC5kYXRhVHJhbnNmZXIudHlwZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIC8vIENoZWNrIHRoYXQgdGhlIGNvbXBvbmVudCBhY2NlcHRzIGRhdGFUcmFuc2Zlci5kYXRhIG9yIG5vdC5cbiAgICAgICAgICBhY2NlcHRGb3JtYXQgPSBmYWxzZTtcbiAgICAgICAgICBmb3IgKGxldCBkYXRhRm9ybWF0IG9mIGV2ZW50LmRhdGFUcmFuc2Zlci50eXBlcykge1xuICAgICAgICAgICAgbGV0IHBhcnNlZERhdGE6IGFueSA9IERyb3BwYWJsZS5wYXJzZURhdGEoZGF0YUZvcm1hdCwgZXZlbnQuZGF0YVRyYW5zZmVyLmdldERhdGEoZGF0YUZvcm1hdCkpO1xuXG4gICAgICAgICAgICBpZiAodGFyZ2V0LmlzQWNjZXB0RHJhZ0RhdGEoZXZlbnQsIGRhdGFGb3JtYXQsIHBhcnNlZERhdGEpKSB7XG4gICAgICAgICAgICAgIGFjY2VwdEZvcm1hdCA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBhY2NlcHRGb3JtYXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVGhlcmUgaXMgbm8gXCJkYXRhXCIgc3BlY2lmaWVkIGluIGRhdGFUcmFuc2Zlci5cbiAgICAgICAgICByZXR1cm4gdGFyZ2V0LmlzQWNjZXB0RHJhZ0RhdGEoZXZlbnQsIG51bGwsIG51bGwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRGVmYXVsdCB2YWx1ZSBpcyBcImZhbHNlXCIgKG5vdCBhY2NlcHQpLlxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIEBJbnB1dCgncGh4RHJvcHBhYmxlJylcbiAgcHJvdGVjdGVkIG9wdGlvbnM6IGFueTtcblxuICBASW5wdXQoJ2Ryb3BBY2NlcHQnKVxuICBAT3B0aW9uKCdhY2NlcHQnKVxuICBwcml2YXRlIGFjY2VwdDogYW55O1xuXG4gIEBJbnB1dCgnZHJvcFRhcmdldCcpXG4gIEBPcHRpb24oJ3RhcmdldCcpXG4gIHByaXZhdGUgY29tcG9uZW50OiBhbnk7XG5cbiAgQElucHV0KCdkcm9wRmlyZUV2ZW50JylcbiAgQE9wdGlvbignZmlyZUV2ZW50JylcbiAgcHJpdmF0ZSBhbHdheXNGaXJlRXZlbnQ6IGJvb2xlYW47XG5cbiAgQElucHV0KCdkcm9wQWRkQ2xhc3MnKVxuICBAT3B0aW9uKCdhZGRDbGFzcycpXG4gIHByaXZhdGUgYXV0b0FkZENsYXNzOiBib29sZWFuO1xuXG4gIEBJbnB1dCgnZHJvcERyYWdMZWF2ZVRpbWVvdXQnKVxuICBAT3B0aW9uKCdkcmFnTGVhdmVUaW1lb3V0JylcbiAgcHJpdmF0ZSBkcmFnTGVhdmVUaW1lb3V0OiBudW1iZXI7XG5cbiAgQElucHV0KCdkcm9wRHJhZ092ZXJUaW1lb3V0JylcbiAgQE9wdGlvbignZHJhZ092ZXJUaW1lb3V0JylcbiAgcHJpdmF0ZSBkcmFnT3ZlclRpbWVvdXQ6IG51bWJlcjtcblxuICBASW5wdXQoJ2Ryb3BDbGFzc1Jlc2V0VGltZW91dCcpXG4gIEBPcHRpb24oJ2Ryb3BDbGFzc1Jlc2V0VGltZW91dCcpXG4gIHByaXZhdGUgZHJvcENsYXNzUmVzZXRUaW1lb3V0OiBudW1iZXI7XG5cbiAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmO1xuICBwcml2YXRlIGRyYWdPdmVyVGltZXI6IGFueTtcbiAgcHJpdmF0ZSBkcmFnTGVhdmVUaW1lcjogYW55O1xuICBwcml2YXRlIGRyb3BBY2NlcHRlZFJlbW92ZUNs