UNPKG

@nova-ui/bits

Version:

SolarWinds Nova Framework

179 lines 25.5 kB
// © 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 { DOCUMENT } from "@angular/common"; import { Inject, Injectable } from "@angular/core"; import _capitalize from "lodash/capitalize"; import _get from "lodash/get"; import _isNil from "lodash/isNil"; import _parseInt from "lodash/parseInt"; import { DomUtilService } from "./dom-util.service"; import { LoggerService } from "./log-service"; import * as i0 from "@angular/core"; import * as i1 from "./log-service"; import * as i2 from "./dom-util.service"; /** * <example-url>./../examples/index.html#/common/edge-detection-service</example-url> */ /** * @dynamic * @ignore * Service that helps to calculate free space for dynamic elements (popover, dropdown, etc.) and define the best * direction to show them. There are two ways how detection can be made: * 1) default one - detection is made within viewport area. * 2) custom container can be used for detection. Identify such container using 'nui-edge-definer' CSS-class. * * __Name :__ * Edge Detection Service */ export class EdgeDetectionService { constructor(domUtilService, document, logger) { this.domUtilService = domUtilService; this.document = document; this.logger = logger; this.edgeDefinerSelector = ".nui-edge-definer"; this.canBe = (basePoint, placed, edgeDefinerElement) => { if (!basePoint || !placed) { this.logger.error("basePoint: Element and placed: Element arguments are required!"); return; } const result = this.initialEdgeDetectionResult; const edgeDefiner = edgeDefinerElement || this.domUtilService.getClosest(basePoint, this.edgeDefinerSelector); const basePosition = this.offset(basePoint).position; const baseWidth = this.outer(basePoint, "width"); const baseHeight = this.outer(basePoint, "height"); const depositWidth = this.outer(placed, "width"); const depositHeight = this.outer(placed, "height"); const container = this.getEdgeDefinerMeasurements(edgeDefiner); if (_isNil(this.document.defaultView)) { throw new Error("Document defaultView is not available"); } result.placed.top = basePosition.top - container.position.top - depositHeight > this.document.defaultView.pageYOffset; result.placed.right = basePosition.left - container.position.left + baseWidth + depositWidth < container.width + this.document.defaultView.pageXOffset; result.placed.bottom = edgeDefiner ? basePosition.top + baseHeight + depositHeight < container.position.top + container.height : basePosition.top - container.position.top + baseHeight + depositHeight < container.height + this.document.defaultView.pageYOffset; result.placed.left = basePosition.left - container.position.left - depositWidth > this.document.defaultView.pageXOffset; result.aligned.top = basePosition.top - container.position.top + depositHeight < this.document.defaultView.pageYOffset + container.height; result.aligned.right = basePosition.left - container.position.left + baseWidth - depositWidth > this.document.defaultView.pageXOffset; result.aligned.bottom = basePosition.top - container.position.top + baseHeight - depositHeight > this.document.defaultView.pageYOffset; result.aligned.left = basePosition.left - container.position.left + depositWidth < this.document.defaultView.pageXOffset + container.width; return result; }; this.initialEdgeDetectionResult = { placed: { top: false, right: false, bottom: false, left: false, }, aligned: { top: false, right: false, bottom: false, left: false, }, }; } outer(element, dimension) { const clientValue = _get(element, `offset${_capitalize(dimension)}`); if (clientValue) { return clientValue; } return _parseInt(_get(getComputedStyle(element), dimension)); } offset(element) { const rect = element.getBoundingClientRect(); const scrollLeft = this.document.defaultView?.pageXOffset || this.document.documentElement.scrollLeft; const scrollTop = this.document.defaultView?.pageYOffset || this.document.documentElement.scrollTop; const rectHeight = rect.top < 0 ? rect.height + rect.top : rect.height; return { position: { top: rect.top + scrollTop, left: rect.left + scrollLeft, }, height: rectHeight, }; } getEdgeDefinerMeasurements(edgeDefiner) { if (edgeDefiner) { return { position: this.offset(edgeDefiner).position, width: edgeDefiner.clientWidth, height: this.offset(edgeDefiner).height, scrollY: edgeDefiner.scrollTop, scrollX: edgeDefiner.scrollLeft, }; } if (_isNil(this.document.defaultView)) { throw new Error("Document defaultView is not available"); } return { position: { top: 0, left: 0 }, width: this.document.defaultView.innerWidth, height: this.document.defaultView.innerHeight, scrollY: this.document.defaultView.pageYOffset, scrollX: this.document.defaultView.pageXOffset, }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeDetectionService, deps: [{ token: DomUtilService }, { token: DOCUMENT }, { token: i1.LoggerService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeDetectionService, providedIn: "root" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeDetectionService, decorators: [{ type: Injectable, args: [{ providedIn: "root" }] }], ctorParameters: () => [{ type: i2.DomUtilService, decorators: [{ type: Inject, args: [DomUtilService] }] }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: i1.LoggerService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRnZS1kZXRlY3Rpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9lZGdlLWRldGVjdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlEQUF5RDtBQUN6RCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw0REFBNEQ7QUFDNUQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSx1REFBdUQ7QUFDdkQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsK0VBQStFO0FBQy9FLDBFQUEwRTtBQUMxRSxpRkFBaUY7QUFDakYsNkVBQTZFO0FBQzdFLGlCQUFpQjtBQUVqQixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxXQUFXLE1BQU0sbUJBQW1CLENBQUM7QUFDNUMsT0FBTyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQzlCLE9BQU8sTUFBTSxNQUFNLGNBQWMsQ0FBQztBQUNsQyxPQUFPLFNBQVMsTUFBTSxpQkFBaUIsQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7OztBQU85Qzs7R0FFRztBQUVIOzs7Ozs7Ozs7O0dBVUc7QUFHSCxNQUFNLE9BQU8sb0JBQW9CO0lBSTdCLFlBQ29DLGNBQThCLEVBQ3BDLFFBQWtCLEVBQ3BDLE1BQXFCO1FBRkcsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQ3BDLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDcEMsV0FBTSxHQUFOLE1BQU0sQ0FBZTtRQU4xQix3QkFBbUIsR0FBRyxtQkFBbUIsQ0FBQztR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LFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUNuQyxNQUFNLElBQUksS0FBSyxDQUFDLHVDQUF1QyxDQUFDLENBQUM7U0FDNUQ7UUFFRCxPQUFPO1lBQ0gsUUFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFO1lBQzdCLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxVQUFVO1lBQzNDLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxXQUFXO1lBQzdDLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxXQUFXO1lBQzlDLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxXQUFXO1NBQ2pELENBQUM7SUFDTixDQUFDOytHQWpKUSxvQkFBb0Isa0JBS2pCLGNBQWMsYUFDZCxRQUFRO21IQU5YLG9CQUFvQixjQURQLE1BQU07OzRGQUNuQixvQkFBb0I7a0JBRGhDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFOzswQkFNekIsTUFBTTsyQkFBQyxjQUFjOzswQkFDckIsTUFBTTsyQkFBQyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCBfY2FwaXRhbGl6ZSBmcm9tIFwibG9kYXNoL2NhcGl0YWxpemVcIjtcbmltcG9ydCBfZ2V0IGZyb20gXCJsb2Rhc2gvZ2V0XCI7XG5pbXBvcnQgX2lzTmlsIGZyb20gXCJsb2Rhc2gvaXNOaWxcIjtcbmltcG9ydCBfcGFyc2VJbnQgZnJvbSBcImxvZGFzaC9wYXJzZUludFwiO1xuXG5pbXBvcnQgeyBEb21VdGlsU2VydmljZSB9IGZyb20gXCIuL2RvbS11dGlsLnNlcnZpY2VcIjtcbmltcG9ydCB7IExvZ2dlclNlcnZpY2UgfSBmcm9tIFwiLi9sb2ctc2VydmljZVwiO1xuaW1wb3J0IHtcbiAgICBJRWRnZURlZmluZXJNZWFzdXJlbWVudHMsXG4gICAgSUVkZ2VEZXRlY3Rpb25Qcm9wZXJ0aWVzLFxuICAgIElFZGdlRGV0ZWN0aW9uUmVzdWx0LFxufSBmcm9tIFwiLi9wdWJsaWMtYXBpXCI7XG5cbi8qKlxuICogPGV4YW1wbGUtdXJsPi4vLi4vZXhhbXBsZXMvaW5kZXguaHRtbCMvY29tbW9uL2VkZ2UtZGV0ZWN0aW9uLXNlcnZpY2U8L2V4YW1wbGUtdXJsPlxuICovXG5cbi8qKlxuICogQGR5bmFtaWNcbiAqIEBpZ25vcmVcbiAqICBTZXJ2aWNlIHRoYXQgaGVscHMgdG8gY2FsY3VsYXRlIGZyZWUgc3BhY2UgZm9yIGR5bmFtaWMgZWxlbWVudHMgKHBvcG92ZXIsIGRyb3Bkb3duLCBldGMuKSBhbmQgZGVmaW5lIHRoZSBiZXN0XG4gKiAgZGlyZWN0aW9uIHRvIHNob3cgdGhlbS4gVGhlcmUgYXJlIHR3byB3YXlzIGhvdyBkZXRlY3Rpb24gY2FuIGJlIG1hZGU6XG4gKiAgMSkgZGVmYXVsdCBvbmUgLSBkZXRlY3Rpb24gaXMgbWFkZSB3aXRoaW4gdmlld3BvcnQgYXJlYS5cbiAqICAyKSBjdXN0b20gY29udGFpbmVyIGNhbiBiZSB1c2VkIGZvciBkZXRlY3Rpb24uIElkZW50aWZ5IHN1Y2ggY29udGFpbmVyIHVzaW5nICdudWktZWRnZS1kZWZpbmVyJyBDU1MtY2xhc3MuXG4gKlxuICogX19OYW1lIDpfX1xuICogRWRnZSBEZXRlY3Rpb24gU2VydmljZVxuICovXG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogXCJyb290XCIgfSlcbmV4cG9ydCBjbGFzcyBFZGdlRGV0ZWN0aW9uU2VydmljZSB7XG4gICAgcHVibGljIGVkZ2VEZWZpbmVyU2VsZWN0b3IgPSBcIi5udWktZWRnZS1kZWZpbmVyXCI7XG4gICAgcHVibGljIGluaXRpYWxFZGdlRGV0ZWN0aW9uUmVzdWx0OiBJRWRnZURldGVjdGlvblJlc3VsdDtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBASW5qZWN0KERvbVV0aWxTZXJ2aWNlKSBwcml2YXRlIGRvbVV0aWxTZXJ2aWNlOiBEb21VdGlsU2VydmljZSxcbiAgICAgICAgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2N1bWVudDogRG9jdW1lbnQsXG4gICAgICAgIHByaXZhdGUgbG9nZ2VyOiBMb2dnZXJTZXJ2aWNlXG4gICAgKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbEVkZ2VEZXRlY3Rpb25SZXN1bHQgPSB7XG4gICAgICAgICAgICBwbGFjZWQ6IHtcbiAgICAgICAgICAgICAgICB0b3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBib3R0b206IGZhbHNlLFxuICAgICAgICAgICAgICAgIGxlZnQ6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFsaWduZWQ6IHtcbiAgICAgICAgICAgICAgICB0b3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBib3R0b206IGZhbHNlLFxuICAgICAgICAgICAgICAgIGxlZnQ6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY2FuQmUgPSAoXG4gICAgICAgIGJhc2VQb2ludDogSFRNTEVsZW1lbnQsXG4gICAgICAgIHBsYWNlZDogSFRNTEVsZW1lbnQsXG4gICAgICAgIGVkZ2VEZWZpbmVyRWxlbWVudD86IEVsZW1lbnRcbiAgICApOiBJRWRnZURldGVjdGlvblJlc3VsdCB8IHVuZGVmaW5lZCA9PiB7XG4gICAgICAgIGlmICghYmFzZVBvaW50IHx8ICFwbGFjZWQpIHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgIFwiYmFzZVBvaW50OiBFbGVtZW50IGFuZCBwbGFjZWQ6IEVsZW1lbnQgYXJndW1lbnRzIGFyZSByZXF1aXJlZCFcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuaW5pdGlhbEVkZ2VEZXRlY3Rpb25SZXN1bHQ7XG4gICAgICAgIGNvbnN0IGVkZ2VEZWZpbmVyID1cbiAgICAgICAgICAgIGVkZ2VEZWZpbmVyRWxlbWVudCB8fFxuICAgICAgICAgICAgdGhpcy5kb21VdGlsU2VydmljZS5nZXRDbG9zZXN0KGJhc2VQb2ludCwgdGhpcy5lZGdlRGVmaW5lclNlbGVjdG9yKTtcbiAgICAgICAgY29uc3QgYmFzZVBvc2l0aW9uID0gdGhpcy5vZmZzZXQoYmFzZVBvaW50KS5wb3NpdGlvbjtcbiAgICAgICAgY29uc3QgYmFzZVdpZHRoID0gdGhpcy5vdXRlcihiYXNlUG9pbnQsIFwid2lkdGhcIik7XG4gICAgICAgIGNvbnN0IGJhc2VIZWlnaHQgPSB0aGlzLm91dGVyKGJhc2VQb2ludCwgXCJoZWlnaHRcIik7XG4gICAgICAgIGNvbnN0IGRlcG9zaXRXaWR0aCA9IHRoaXMub3V0ZXIocGxhY2VkLCBcIndpZHRoXCIpO1xuICAgICAgICBjb25zdCBkZXBvc2l0SGVpZ2h0ID0gdGhpcy5vdXRlcihwbGFjZWQsIFwiaGVpZ2h0XCIpO1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmdldEVkZ2VEZWZpbmVyTWVhc3VyZW1lbnRzKDxFbGVtZW50PmVkZ2VEZWZpbmVyKTtcblxuICAgICAgICBpZiAoX2lzTmlsKHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXcpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEb2N1bWVudCBkZWZhdWx0VmlldyBpcyBub3QgYXZhaWxhYmxlXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzdWx0LnBsYWNlZC50b3AgPVxuICAgICAgICAgICAgYmFzZVBvc2l0aW9uLnRvcCAtIGNvbnRhaW5lci5wb3NpdGlvbi50b3AgLSBkZXBvc2l0SGVpZ2h0ID5cbiAgICAgICAgICAgIHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXcucGFnZVlPZmZzZXQ7XG4gICAgICAgIHJlc3VsdC5wbGFjZWQucmlnaHQgPVxuICAgICAgICAgICAgYmFzZVBvc2l0aW9uLmxlZnQgLVxuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5wb3NpdGlvbi5sZWZ0ICtcbiAgICAgICAgICAgICAgICBiYXNlV2lkdGggK1xuICAgICAgICAgICAgICAgIGRlcG9zaXRXaWR0aCA8XG4gICAgICAgICAgICBjb250YWluZXIud2lkdGggKyB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3LnBhZ2VYT2Zmc2V0O1xuICAgICAgICByZXN1bHQucGxhY2VkLmJvdHRvbSA9IGVkZ2VEZWZpbmVyXG4gICAgICAgICAgICA/IGJhc2VQb3NpdGlvbi50b3AgKyBiYXNlSGVpZ2h0ICsgZGVwb3NpdEhlaWdodCA8XG4gICAgICAgICAgICAgIGNvbnRhaW5lci5wb3NpdGlvbi50b3AgKyBjb250YWluZXIuaGVpZ2h0XG4gICAgICAgICAgICA6IGJhc2VQb3NpdGlvbi50b3AgLVxuICAgICAgICAgICAgICAgICAgY29udGFpbmVyLnBvc2l0aW9uLnRvcCArXG4gICAgICAgICAgICAgICAgICBiYXNlSGVpZ2h0ICtcbiAgICAgICAgICAgICAgICAgIGRlcG9zaXRIZWlnaHQgPFxuICAgICAgICAgICAgICBjb250YWluZXIuaGVpZ2h0ICsgdGhpcy5kb2N1bWVudC5kZWZhdWx0Vmlldy5wYWdlWU9mZnNldDtcbiAgICAgICAgcmVzdWx0LnBsYWNlZC5sZWZ0ID1cbiAgICAgICAgICAgIGJhc2VQb3NpdGlvbi5sZWZ0IC0gY29udGFpbmVyLnBvc2l0aW9uLmxlZnQgLSBkZXBvc2l0V2lkdGggPlxuICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5kZWZhdWx0Vmlldy5wYWdlWE9mZnNldDtcblxuICAgICAgICByZXN1bHQuYWxpZ25lZC50b3AgPVxuICAgICAgICAgICAgYmFzZVBvc2l0aW9uLnRvcCAtIGNvbnRhaW5lci5wb3NpdGlvbi50b3AgKyBkZXBvc2l0SGVpZ2h0IDxcbiAgICAgICAgICAgIHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXcucGFnZVlPZmZzZXQgKyBjb250YWluZXIuaGVpZ2h0O1xuICAgICAgICByZXN1bHQuYWxpZ25lZC5yaWdodCA9XG4gICAgICAgICAgICBiYXNlUG9zaXRpb24ubGVmdCAtXG4gICAgICAgICAgICAgICAgY29udGFpbmVyLnBvc2l0aW9uLmxlZnQgK1xuICAgICAgICAgICAgICAgIGJhc2VXaWR0aCAtXG4gICAgICAgICAgICAgICAgZGVwb3NpdFdpZHRoID5cbiAgICAgICAgICAgIHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXcucGFnZVhPZmZzZXQ7XG4gICAgICAgIHJlc3VsdC5hbGlnbmVkLmJvdHRvbSA9XG4gICAgICAgICAgICBiYXNlUG9zaXRpb24udG9wIC1cbiAgICAgICAgICAgICAgICBjb250YWluZXIucG9zaXRpb24udG9wICtcbiAgICAgICAgICAgICAgICBiYXNlSGVpZ2h0IC1cbiAgICAgICAgICAgICAgICBkZXBvc2l0SGVpZ2h0ID5cbiAgICAgICAgICAgIHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXcucGFnZVlPZmZzZXQ7XG4gICAgICAgIHJlc3VsdC5hbGlnbmVkLmxlZnQgPVxuICAgICAgICAgICAgYmFzZVBvc2l0aW9uLmxlZnQgLSBjb250YWluZXIucG9zaXRpb24ubGVmdCArIGRlcG9zaXRXaWR0aCA8XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3LnBhZ2VYT2Zmc2V0ICsgY29udGFpbmVyLndpZHRoO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb3V0ZXIoZWxlbWVudDogSFRNTEVsZW1lbnQsIGRpbWVuc2lvbjogXCJ3aWR0aFwiIHwgXCJoZWlnaHRcIik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGNsaWVudFZhbHVlID0gX2dldChlbGVtZW50LCBgb2Zmc2V0JHtfY2FwaXRhbGl6ZShkaW1lbnNpb24pfWApO1xuICAgICAgICBpZiAoY2xpZW50VmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiBjbGllbnRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX3BhcnNlSW50KF9nZXQoZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KSwgZGltZW5zaW9uKSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvZmZzZXQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBJRWRnZURldGVjdGlvblByb3BlcnRpZXMge1xuICAgICAgICBjb25zdCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsTGVmdCA9XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3Py5wYWdlWE9mZnNldCB8fFxuICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICAgICAgY29uc3Qgc2Nyb2xsVG9wID1cbiAgICAgICAgICAgIHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXc/LnBhZ2VZT2Zmc2V0IHx8XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3A7XG4gICAgICAgIGNvbnN0IHJlY3RIZWlnaHQgPSByZWN0LnRvcCA8IDAgPyByZWN0LmhlaWdodCArIHJlY3QudG9wIDogcmVjdC5oZWlnaHQ7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgICAgIHRvcDogcmVjdC50b3AgKyBzY3JvbGxUb3AsXG4gICAgICAgICAgICAgICAgbGVmdDogcmVjdC5sZWZ0ICsgc2Nyb2xsTGVmdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBoZWlnaHQ6IHJlY3RIZWlnaHQsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRFZGdlRGVmaW5lck1lYXN1cmVtZW50cyhcbiAgICAgICAgZWRnZURlZmluZXI6IEVsZW1lbnRcbiAgICApOiBJRWRnZURlZmluZXJNZWFzdXJlbWVudHMge1xuICAgICAgICBpZiAoZWRnZURlZmluZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246IHRoaXMub2Zmc2V0KGVkZ2VEZWZpbmVyIGFzIEhUTUxFbGVtZW50KS5wb3NpdGlvbixcbiAgICAgICAgICAgICAgICB3aWR0aDogZWRnZURlZmluZXIuY2xpZW50V2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLm9mZnNldChlZGdlRGVmaW5lciBhcyBIVE1MRWxlbWVudCkuaGVpZ2h0LFxuICAgICAgICAgICAgICAgIHNjcm9sbFk6IGVkZ2VEZWZpbmVyLnNjcm9sbFRvcCxcbiAgICAgICAgICAgICAgICBzY3JvbGxYOiBlZGdlRGVmaW5lci5zY3JvbGxMZWZ0LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChfaXNOaWwodGhpcy5kb2N1bWVudC5kZWZhdWx0VmlldykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkRvY3VtZW50IGRlZmF1bHRWaWV3IGlzIG5vdCBhdmFpbGFibGVcIik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcG9zaXRpb246IHsgdG9wOiAwLCBsZWZ0OiAwIH0sXG4gICAgICAgICAgICB3aWR0aDogdGhpcy5kb2N1bWVudC5kZWZhdWx0Vmlldy5pbm5lcldpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3LmlubmVySGVpZ2h0LFxuICAgICAgICAgICAgc2Nyb2xsWTogdGhpcy5kb2N1bWVudC5kZWZhdWx0Vmlldy5wYWdlWU9mZnNldCxcbiAgICAgICAgICAgIHNjcm9sbFg6IHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXcucGFnZVhPZmZzZXQsXG4gICAgICAgIH07XG4gICAgfVxufVxuIl19