UNPKG

@santinobch/os-window-angular

Version:

Create windows inside a browser window!

355 lines 50 kB
import { coerceNumberProperty } from '@angular/cdk/coercion'; import { StyleClass } from './Style.class'; export function clamp(v, min = 0, max = Number.MAX_SAFE_INTEGER) { return Math.max(min, Math.min(max, coerceNumberProperty(v))); } export class OsWindowClass { constructor(componentElement, renderer, globalConfigService) { this.componentElement = componentElement; this.renderer = renderer; this.globalConfigService = globalConfigService; this.mousePos = { x: 0, y: 0 }; //Anchor stores temporary point of the current resize CdkDragMove event this.anchor = { x: 0, y: 0 }; this.minHeight = 200; this.minWidth = 200; this.size = { height: { previous: 200, current: 200, unit: 'px', }, width: { previous: 200, current: 200, unit: 'px', }, }; this.position = { resize: { x: 0, y: 0 }, current: { x: 0, y: 0 }, next: { x: 0, y: 0 }, zIndex: { current: 0, next: 1, }, }; this.cdkAnchors = { n: { x: 0, y: 0 }, ne: { x: 0, y: 0 }, e: { x: 0, y: 0 }, se: { x: 0, y: 0 }, s: { x: 0, y: 0 }, sw: { x: 0, y: 0 }, w: { x: 0, y: 0 }, nw: { x: 0, y: 0 }, }; this.state = { minimized: false, maximized: false, }; this.rules = { disableResize: false, minimizable: true, maximizable: true, closable: true, }; this.styleConfig = new StyleClass(componentElement, renderer, globalConfigService, 'window'); } setStyle(_elementRef, property, value) { _elementRef.nativeElement.style.setProperty(property, value); } getStyle(_elementRef, property) { return getComputedStyle(_elementRef.nativeElement).getPropertyValue(property); } clamp(input, max) { return input >= max ? input : max; } clampHeight(_elementRef, _height, _minHeight) { if (_minHeight) { _height = this.clamp(_height, _minHeight); } return _height; } clampWidth(_elementRef, _width, _minWidth) { if (_minWidth) { _width = this.clamp(_width, _minWidth); } return _width; } setDimesions() { this.size.width.current = this.clampWidth(this.componentElement, this.size.width.current, this.minWidth); this.size.height.current = this.clampHeight(this.componentElement, this.size.height.current, this.minHeight); } //////////////////////// // Position // //////////////////////// setPosition(positionStr) { const X = parseInt(positionStr[0]); const Y = parseInt(positionStr[1]); if (!Number.isNaN(X)) { this.position.next.x = X; } else { switch (positionStr[0]) { case 'left': this.position.next.x = 0; break; case 'center': this.position.next.x = window.innerWidth / 2 - this.size.width.current / 2; break; case 'right': this.position.next.x = window.innerWidth - this.size.width.current; break; default: this.position.next.x = 0; break; } } if (!Number.isNaN(Y)) { this.position.next.y = Y + window.innerHeight; } else { //To hide the window element we need to set it top: -100% in scss, //so we later need to calculate everything + innerHeight switch (positionStr[1]) { case 'top': this.position.next.y = window.innerHeight; break; case 'center': this.position.next.y = window.innerHeight + (window.innerHeight / 2 - this.size.height.current / 2); break; case 'bottom': this.position.next.y = window.innerHeight + (window.innerHeight - this.size.height.current); break; default: this.position.next.y = window.innerHeight; break; } } this.position.current = this.position.next; } //////////////////////// // Style // //////////////////////// //////////////////////// // Rules // //////////////////////// loadRules() { //Minimizable? if (!this.rules.minimizable) { this.setStyle(this.componentElement, '--minimizeButton', 'none'); } //Maximizable? if (!this.rules.maximizable) { this.setStyle(this.componentElement, '--maximizeButton', 'none'); } //Closable? if (!this.rules.closable) { this.setStyle(this.componentElement, '--closeButton', 'none'); } //Resizable? if (this.rules.disableResize) { this.setStyle(this.componentElement, '--cursorN', 'auto'); this.setStyle(this.componentElement, '--cursorNE', 'auto'); this.setStyle(this.componentElement, '--cursorE', 'auto'); this.setStyle(this.componentElement, '--cursorSE', 'auto'); this.setStyle(this.componentElement, '--cursorS', 'auto'); this.setStyle(this.componentElement, '--cursorSW', 'auto'); this.setStyle(this.componentElement, '--cursorW', 'auto'); this.setStyle(this.componentElement, '--cursorNW', 'auto'); } } //////////////////////// // Controls // //////////////////////// minimize() { //TODO } maximize() { if (this.rules.maximizable) { if (this.state.maximized == false) { //Saving value for later this.size.height.previous = this.size.height.current; this.size.width.previous = this.size.width.current; this.size.height.current = 100; this.size.height.unit = 'vh'; this.size.width.current = 100; this.size.width.unit = 'vw'; this.position.current = { x: 0, y: window.innerHeight }; this.state.maximized = true; this.rules.disableResize = true; } else { //Restoring window size this.size.height.current = this.size.height.previous; this.size.height.unit = 'px'; this.size.width.current = this.size.width.previous; this.size.width.unit = 'px'; this.position.current = this.position.next; this.state.maximized = false; this.rules.disableResize = false; } } } //When maximized and then dragged the window demaximizes //and puts itself aligned with the mouse position demaximize() { if (this.state.maximized == true) { this.position.next = { x: this.mousePos.x - this.size.width.current / 2, y: this.mousePos.y + window.innerHeight - 20, }; this.maximize(); } } close() { this.componentElement.nativeElement.remove(); } //////////////////////// // Resize & movement // //////////////////////// storeMousePos(event) { this.mousePos = { x: event.x, y: event.y, }; } //Sets some variables when the resize drag starts, we use them later startResize() { this.size.height.previous = this.size.height.current; this.size.width.previous = this.size.width.current; } resize(dragEvent, direction) { let directionSplit = [direction.charAt(0), direction.charAt(1)]; this.anchor = dragEvent.source.getFreeDragPosition(); directionSplit.forEach(dir => { this.resizeDirection(dir); }); //Reset anchor position switch (direction) { case 'n': this.cdkAnchors.n = { x: 0, y: 0 }; break; case 'ne': this.cdkAnchors.n = { x: 0, y: 0 }; break; case 'e': this.cdkAnchors.e = { x: 0, y: 0 }; break; case 'se': this.cdkAnchors.se = { x: 0, y: 0 }; break; case 's': this.cdkAnchors.s = { x: 0, y: 0 }; break; case 'sw': this.cdkAnchors.sw = { x: 0, y: 0 }; break; case 'w': this.cdkAnchors.w = { x: 0, y: 0 }; break; case 'nw': this.cdkAnchors.nw = { x: 0, y: 0 }; break; } } resizeDirection(direction) { this.position.resize = this.position.next; switch (direction) { case 'n': //Checks that the new position and dimesions produce a minHeight lower than the required if (this.size.height.previous - this.anchor.y >= this.minHeight) { this.position.resize = { x: this.position.resize.x, y: this.position.next.y + this.anchor.y, }; this.size.height.current = this.size.height.previous - this.anchor.y; this.size.height.current = this.clampHeight(this.componentElement, this.size.height.current, this.minHeight); this.position.current = { x: this.position.current.x, y: this.position.resize.y, }; } break; case 'e': this.size.width.current = this.size.width.previous + this.anchor.x; this.size.width.current = this.clampWidth(this.componentElement, this.size.width.current, this.minWidth); break; case 's': this.size.height.current = this.size.height.previous + this.anchor.y; this.size.height.current = this.clampHeight(this.componentElement, this.size.height.current, this.minHeight); break; case 'w': //Checks that the new position and dimesions produce a minHeight lower than the required if (this.size.width.previous - this.anchor.x >= this.minWidth) { this.position.resize = { x: this.position.next.x + this.anchor.x, y: this.position.resize.y, }; this.size.width.current = this.size.width.previous - this.anchor.x; this.size.width.current = this.clampWidth(this.componentElement, this.size.width.current, this.minWidth); this.position.current = { x: this.position.resize.x, y: this.position.current.y, }; } break; } } endResize() { this.position.next = this.position.current; } //When releasing the os-window the user may leave it outside of the browser window //which would make it imposible to interact with the component again, //this makes the window 'bounce' back into sight correctEndPosition(event) { this.position.next = event.source.getFreeDragPosition(); //Fix for Y position, the window-bar will always be visible if (this.position.next.y < window.innerHeight) { this.position.next.y = window.innerHeight; } else if (this.position.next.y > window.innerHeight * 2 - 40) { this.position.next.y = window.innerHeight * 2 - 40; } //Fix for X position, a quarter of the window will always be visible if (this.position.next.x < -((this.size.width.current / 4) * 3)) { this.position.next.x = -((this.size.width.current / 4) * 3); } else if (this.position.next.x > window.innerWidth - this.size.width.current / 4) { this.position.next.x = window.innerWidth - this.size.width.current / 4; } this.position.current = this.position.next; } ////////////////////////////// // Other user interaction // ////////////////////////////// //When a window is clicked we want to change it's z-index value and apply some styles focus() { //We get the current global z-index this.position.zIndex.next = this.globalConfigService.getZIndex(); //This will be unequal if another window has been focused on if (this.position.zIndex.current != this.position.zIndex.next) { this.position.zIndex.next++; this.position.zIndex.current = this.position.zIndex.next; //Updating global z-index this.globalConfigService.setZIndex(this.position.zIndex.current); } //After that we remove the 'focused' class from all the windows let focused = document.getElementsByClassName('focused'); let i = 0; while (i < focused.length) { this.renderer.removeClass(focused[i], 'focused'); i++; } //We add the 'focused' class to the current window this.renderer.addClass(this.componentElement.nativeElement.firstChild, 'focused'); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT3NXaW5kb3cuY2xhc3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vcy13aW5kb3ctYW5ndWxhci9zcmMvbGliL2NsYXNzZXMvT3NXaW5kb3cuY2xhc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFNN0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUczQyxNQUFNLFVBQVUsS0FBSyxDQUFDLENBQVMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxNQUFNLENBQUMsZ0JBQWdCO0lBQ3JFLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFFRCxNQUFNLE9BQU8sYUFBYTtJQUd4QixZQUNTLGdCQUF5QyxFQUN6QyxRQUFtQixFQUNuQixtQkFBb0M7UUFGcEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUF5QjtRQUN6QyxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQ25CLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBaUI7UUFVckMsYUFBUSxHQUFrQixFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBRWpELHVFQUF1RTtRQUMvRCxXQUFNLEdBQWtCLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFFeEMsY0FBUyxHQUFXLEdBQUcsQ0FBQztRQUN4QixhQUFRLEdBQVcsR0FBRyxDQUFDO1FBRXZCLFNBQUksR0FBYztZQUN2QixNQUFNLEVBQUU7Z0JBQ04sUUFBUSxFQUFFLEdBQUc7Z0JBQ2IsT0FBTyxFQUFFLEdBQUc7Z0JBQ1osSUFBSSxFQUFFLElB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UUFDSCxtQ0FBbUM7UUFDbkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVqRSw0REFBNEQ7UUFDNUQsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFO1lBQzdELElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7WUFFekQseUJBQXlCO1lBQ3pCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDbEU7UUFFRCwrREFBK0Q7UUFDL0QsSUFBSSxPQUFPLEdBQUcsUUFBUSxDQUFDLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxHQUFXLENBQUMsQ0FBQztRQUNsQixPQUFPLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFO1lBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUNqRCxDQUFDLEVBQUUsQ0FBQztTQUNMO1FBRUQsa0RBQWtEO1FBQ2xELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUNwQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFDOUMsU0FBUyxDQUNWLENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDZGtEcmFnRW5kLCBDZGtEcmFnTW92ZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9kcmFnLWRyb3AnO1xuaW1wb3J0IHsgRWxlbWVudFJlZiwgUmVuZGVyZXIyLCBTaW1wbGVDaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBjb2VyY2VOdW1iZXJQcm9wZXJ0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2VyY2lvbic7XG5cbmltcG9ydCB7IE9zQ29uZmlnU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL29zLWNvbmZpZy9vcy1jb25maWcuc2VydmljZSc7XG5pbXBvcnQgeyBUd29Qb2ludE1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL1R3b1BvaW50Lm1vZGVsJztcbmltcG9ydCB7IFBvc2l0aW9uTW9kZWwgfSBmcm9tICcuLi9tb2RlbHMvUG9zaXRpb24ubW9kZWwnO1xuaW1wb3J0IHsgUmVzaXplTW9kZWwgfSBmcm9tICcuLi9tb2RlbHMvUmVzaXplLm1vZGVsJztcbmltcG9ydCB7IFN0eWxlQ2xhc3MgfSBmcm9tICcuL1N0eWxlLmNsYXNzJztcbmltcG9ydCB7IFNpemVNb2RlbCB9IGZyb20gJy4uL21vZGVscy9TaXplLm1vZGVsJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNsYW1wKHY6IE51bWJlciwgbWluID0gMCwgbWF4ID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgcmV0dXJuIE1hdGgubWF4KG1pbiwgTWF0aC5taW4obWF4LCBjb2VyY2VOdW1iZXJQcm9wZXJ0eSh2KSkpO1xufVxuXG5leHBvcnQgY2xhc3MgT3NXaW5kb3dDbGFzcyB7XG4gIHB1YmxpYyBzdHlsZUNvbmZpZyE6IFN0eWxlQ2xhc3M7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGNvbXBvbmVudEVsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIHB1YmxpYyByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHB1YmxpYyBnbG9iYWxDb25maWdTZXJ2aWNlOiBPc0NvbmZpZ1NlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5zdHlsZUNvbmZpZyA9IG5ldyBTdHlsZUNsYXNzKFxuICAgICAgY29tcG9uZW50RWxlbWVudCxcbiAgICAgIHJlbmRlcmVyLFxuICAgICAgZ2xvYmFsQ29uZmlnU2VydmljZSxcbiAgICAgICd3aW5kb3cnXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbW91c2VQb3M6IFR3b1BvaW50TW9kZWwgPSB7IHg6IDAsIHk6IDAgfTtcblxuICAvL0FuY2hvciBzdG9yZXMgdGVtcG9yYXJ5IHBvaW50IG9mIHRoZSBjdXJyZW50IHJlc2l6ZSBDZGtEcmFnTW92ZSBldmVudFxuICBwcml2YXRlIGFuY2hvcjogVHdvUG9pbnRNb2RlbCA9IHsgeDogMCwgeTogMCB9O1xuXG4gIHB1YmxpYyBtaW5IZWlnaHQ6IG51bWJlciA9IDIwMDtcbiAgcHVibGljIG1pbldpZHRoOiBudW1iZXIgPSAyMDA7XG5cbiAgcHVibGljIHNpemU6IFNpemVNb2RlbCA9IHtcbiAgICBoZWlnaHQ6IHtcbiAgICAgIHByZXZpb3VzOiAyMDAsXG4gICAgICBjdXJyZW50OiAyMDAsXG4gICAgICB1bml0OiAncHgnLFxuICAgIH0sXG4gICAgd2lkdGg6IHtcbiAgICAgIHByZXZpb3VzOiAyMDAsXG4gICAgICBjdXJyZW50OiAyMDAsXG4gICAgICB1bml0OiAncHgnLFxuICAgIH0sXG4gIH07XG5cbiAgcHVibGljIHBvc2l0aW9uOiBQb3NpdGlvbk1vZGVsID0ge1xuICAgIHJlc2l6ZTogeyB4OiAwLCB5OiAwIH0sXG4gICAgY3VycmVudDogeyB4OiAwLCB5OiAwIH0sXG4gICAgbmV4dDogeyB4OiAwLCB5OiAwIH0sXG4gICAgekluZGV4OiB7XG4gICAgICBjdXJyZW50OiAwLFxuICAgICAgbmV4dDogMSxcbiAgICB9LFxuICB9O1xuXG4gIHB1YmxpYyBjZGtBbmNob3JzOiBSZXNpemVNb2RlbCA9IHtcbiAgICBuOiB7IHg6IDAsIHk6IDAgfSxcbiAgICBuZTogeyB4OiAwLCB5OiAwIH0sXG4gICAgZTogeyB4OiAwLCB5OiAwIH0sXG4gICAgc2U6IHsgeDogMCwgeTogMCB9LFxuICAgIHM6IHsgeDogMCwgeTogMCB9LFxuICAgIHN3OiB7IHg6IDAsIHk6IDAgfSxcbiAgICB3OiB7IHg6IDAsIHk6IDAgfSxcbiAgICBudzogeyB4OiAwLCB5OiAwIH0sXG4gIH07XG5cbiAgcHVibGljIHN0YXRlID0ge1xuICAgIG1pbmltaXplZDogZmFsc2UsXG4gICAgbWF4aW1pemVkOiBmYWxzZSxcbiAgfTtcblxuICBwdWJsaWMgcnVsZXMgPSB7XG4gICAgZGlzYWJsZVJlc2l6ZTogZmFsc2UsXG4gICAgbWluaW1pemFibGU6IHRydWUsXG4gICAgbWF4aW1pemFibGU6IHRydWUsXG4gICAgY2xvc2FibGU6IHRydWUsXG4gIH07XG5cbiAgcHJpdmF0ZSBzZXRTdHlsZShfZWxlbWVudFJlZjogRWxlbWVudFJlZiwgcHJvcGVydHk6IHN0cmluZywgdmFsdWU6IHN0cmluZykge1xuICAgIF9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkocHJvcGVydHksIHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3R5bGUoX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWYsIHByb3BlcnR5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gZ2V0Q29tcHV0ZWRTdHlsZShfZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKFxuICAgICAgcHJvcGVydHlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGFtcChpbnB1dDogbnVtYmVyLCBtYXg6IG51bWJlcikge1xuICAgIHJldHVybiBpbnB1dCA+PSBtYXggPyBpbnB1dCA6IG1heDtcbiAgfVxuXG4gIHByaXZhdGUgY2xhbXBIZWlnaHQoXG4gICAgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgX2hlaWdodDogbnVtYmVyLFxuICAgIF9taW5IZWlnaHQ/OiBudW1iZXJcbiAgKSB7XG4gICAgaWYgKF9taW5IZWlnaHQpIHtcbiAgICAgIF9oZWlnaHQgPSB0aGlzLmNsYW1wKF9oZWlnaHQsIF9taW5IZWlnaHQpO1xuICAgIH1cblxuICAgIHJldHVybiBfaGVpZ2h0O1xuICB9XG5cbiAgcHJpdmF0ZSBjbGFtcFdpZHRoKFxuICAgIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIF93aWR0aDogbnVtYmVyLFxuICAgIF9taW5XaWR0aD86IG51bWJlclxuICApIHtcbiAgICBpZiAoX21pbldpZHRoKSB7XG4gICAgICBfd2lkdGggPSB0aGlzLmNsYW1wKF93aWR0aCwgX21pbldpZHRoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gX3dpZHRoO1xuICB9XG5cbiAgc2V0RGltZXNpb25zKCkge1xuICAgIHRoaXMuc2l6ZS53aWR0aC5jdXJyZW50ID0gdGhpcy5jbGFtcFdpZHRoKFxuICAgICAgdGhpcy5jb21wb25lbnRFbGVtZW50LFxuICAgICAgdGhpcy5zaXplLndpZHRoLmN1cnJlbnQsXG4gICAgICB0aGlzLm1pbldpZHRoXG4gICAgKTtcbiAgICB0aGlzLnNpemUuaGVpZ2h0LmN1cnJlbnQgPSB0aGlzLmNsYW1wSGVpZ2h0KFxuICAgICAgdGhpcy5jb21wb25lbnRFbGVtZW50LFxuICAgICAgdGhpcy5zaXplLmhlaWdodC5jdXJyZW50LFxuICAgICAgdGhpcy5taW5IZWlnaHRcbiAgICApO1xuICB9XG5cbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gIC8vICAgICAgUG9zaXRpb24gICAgICAvL1xuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICBzZXRQb3NpdGlvbihwb3NpdGlvblN0cjogc3RyaW5nW10pIHtcbiAgICBjb25zdCBYID0gcGFyc2VJbnQocG9zaXRpb25TdHJbMF0pO1xuICAgIGNvbnN0IFkgPSBwYXJzZUludChwb3NpdGlvblN0clsxXSk7XG5cbiAgICBpZiAoIU51bWJlci5pc05hTihYKSkge1xuICAgICAgdGhpcy5wb3NpdGlvbi5uZXh0LnggPSBYO1xuICAgIH0gZWxzZSB7XG4gICAgICBzd2l0Y2ggKHBvc2l0aW9uU3RyWzBdKSB7XG4gICAgICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgICAgIHRoaXMucG9zaXRpb24ubmV4dC54ID0gMDtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgICAgIHRoaXMucG9zaXRpb24ubmV4dC54ID1cbiAgICAgICAgICAgIHdpbmRvdy5pbm5lcldpZHRoIC8gMiAtIHRoaXMuc2l6ZS53aWR0aC5jdXJyZW50IC8gMjtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgdGhpcy5wb3NpdGlvbi5uZXh0LnggPSB3aW5kb3cuaW5uZXJXaWR0aCAtIHRoaXMuc2l6ZS53aWR0aC5jdXJyZW50O1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhpcy5wb3NpdGlvbi5uZXh0LnggPSAwO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghTnVtYmVyLmlzTmFOKFkpKSB7XG4gICAgICB0aGlzLnBvc2l0aW9uLm5leHQueSA9IFkgKyB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vVG8gaGlkZSB0aGUgd2luZG93IGVsZW1lbnQgd2UgbmVlZCB0byBzZXQgaXQgdG9wOiAtMTAwJSBpbiBzY3NzLFxuICAgICAgLy9zbyB3ZSBsYXRlciBuZWVkIHRvIGNhbGN1bGF0ZSBldmVyeXRoaW5nICsgaW5uZXJIZWlnaHRcbiAgICAgIHN3aXRjaCAocG9zaXRpb25TdHJbMV0pIHtcbiAgICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgICB0aGlzLnBvc2l0aW9uLm5leHQueSA9IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgICAgIHRoaXMucG9zaXRpb24ubmV4dC55ID1cbiAgICAgICAgICAgIHdpbmRvdy5pbm5lckhlaWdodCArXG4gICAgICAgICAgICAod2luZG93LmlubmVySGVpZ2h0IC8gMiAtIHRoaXMuc2l6ZS5oZWlnaHQuY3VycmVudCAvIDIpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgICAgdGhpcy5wb3NpdGlvbi5uZXh0LnkgPVxuICAgICAgICAgICAgd2luZG93LmlubmVySGVpZ2h0ICtcbiAgICAgICAgICAgICh3aW5kb3cuaW5uZXJIZWlnaHQgLSB0aGlzLnNpemUuaGVpZ2h0LmN1cnJlbnQpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhpcy5wb3NpdGlvbi5uZXh0LnkgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5wb3NpdGlvbi5jdXJyZW50ID0gdGhpcy5wb3NpdGlvbi5uZXh0O1xuICB9XG5cbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gIC8vICAgICAgIFN0eWxlICAgICAgICAvL1xuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgLy8gICAgICAgUnVsZXMgICAgICAgIC8vXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIGxvYWRSdWxlcygpIHtcbiAgICAvL01pbmltaXphYmxlP1xuICAgIGlmICghdGhpcy5ydWxlcy5taW5pbWl6YWJsZSkge1xuICAgICAgdGhpcy5zZXRTdHlsZSh0aGlzLmNvbXBvbmVudEVsZW1lbnQsICctLW1pbmltaXplQnV0dG9uJywgJ25vbmUnKTtcbiAgICB9XG5cbiAgICAvL01heGltaXphYmxlP1xuICAgIGlmICghdGhpcy5ydWxlcy5tYXhpbWl6YWJsZSkge1xuICAgICAgdGhpcy5zZXRTdHlsZSh0aGlzLmNvbXBvbmVudEVsZW1lbnQsICctLW1heGltaXplQnV0dG9uJywgJ25vbmUnKTtcbiAgICB9XG5cbiAgICAvL0Nsb3NhYmxlP1xuICAgIGlmICghdGhpcy5ydWxlcy5jbG9zYWJsZSkge1xuICAgICAgdGhpcy5zZXRTdHlsZSh0aGlzLmNvbXBvbmVudEVsZW1lbnQsICctLWNsb3NlQnV0dG9uJywgJ25vbmUnKTtcbiAgICB9XG5cbiAgICAvL1Jlc2l6YWJsZT9cbiAgICBpZiAodGhpcy5ydWxlcy5kaXNhYmxlUmVzaXplKSB7XG4gICAgICB0aGlzLnNldFN0eWxlKHRoaXMuY29tcG9uZW50RWxlbWVudCwgJy0tY3Vyc29yTicsICdhdXRvJyk7XG4gICAgICB0aGlzLnNldFN0eWxlKHRoaXMuY29tcG9uZW50RWxlbWVudCwgJy0tY3Vyc29yTkUnLCAnYXV0bycpO1xuICAgICAgdGhpcy5zZXRTdHlsZSh0aGlzLmNvbXBvbmVudEVsZW1lbnQsICctLWN1cnNvckUnLCAnYXV0bycpO1xuICAgICAgdGhpcy5zZXRTdHlsZSh0aGlzLmNvbXBvbmVudEVsZW1lbnQsICctLWN1cnNvclNFJywgJ2F1dG8nKTtcbiAgICAgIHRoaXMuc2V0U3R5bGUodGhpcy5jb21wb25lbnRFbGVtZW50LCAnLS1jdXJzb3JTJywgJ2F1dG8nKTtcbiAgICAgIHRoaXMuc2V0U3R5bGUodGhpcy5jb21wb25lbnRFbGVtZW50LCAnLS1jdXJzb3JTVycsICdhdXRvJyk7XG4gICAgICB0aGlzLnNldFN0eWxlKHRoaXMuY29tcG9uZW50RWxlbWVudCwgJy0tY3Vyc29yVycsICdhdXRvJyk7XG4gICAgICB0aGlzLnNldFN0eWxlKHRoaXMuY29tcG9uZW50RWxlbWVudCwgJy0tY3Vyc29yTlcnLCAnYXV0bycpO1xuICAgIH1cbiAgfVxuXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAvLyAgICAgIENvbnRyb2xzICAgICAgLy9cbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgbWluaW1pemUoKSB7XG4gICAgLy9UT0RPXG4gIH1cblxuICBtYXhpbWl6ZSgpIHtcbiAgICBpZiAodGhpcy5ydWxlcy5tYXhpbWl6YWJsZSkge1xuICAgICAgaWYgKHRoaXMuc3RhdGUubWF4aW1pemVkID09IGZhbHNlKSB7XG4gICAgICAgIC8vU2F2aW5nIHZhbHVlIGZvciBsYXRlclxuICAgICAgICB0aGlzLnNpemUuaGVpZ2h0LnByZXZpb3VzID0gdGhpcy5zaXplLmhlaWdodC5jdXJyZW50O1xuICAgICAgICB0aGlzLnNpemUud2lkdGgucHJldmlvdXMgPSB0aGlzLnNpemUud2lkdGguY3VycmVudDtcblxuICAgICAgICB0aGlzLnNpemUuaGVpZ2h0LmN1cnJlbnQgPSAxMDA7XG4gICAgICAgIHRoaXMuc2l6ZS5oZWlnaHQudW5pdCA9ICd2aCc7XG4gICAgICAgIHRoaXMuc2l6ZS53aWR0aC5jdXJyZW50ID0gMTAwO1xuICAgICAgICB0aGlzLnNpemUud2lkdGgudW5pdCA9ICd2dyc7XG5cbiAgICAgICAgdGhpcy5wb3NpdGlvbi5jdXJyZW50ID0geyB4OiAwLCB5OiB3aW5kb3cuaW5uZXJIZWlnaHQgfTtcblxuICAgICAgICB0aGlzLnN0YXRlLm1heGltaXplZCA9IHRydWU7XG4gICAgICAgIHRoaXMucnVsZXMuZGlzYWJsZVJlc2l6ZSA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvL1Jlc3RvcmluZyB3aW5kb3cgc2l6ZVxuICAgICAgICB0aGlzLnNpemUuaGVpZ2h0LmN1cnJlbnQgPSB0aGlzLnNpemUuaGVpZ2h0LnByZXZpb3VzO1xuICAgICAgICB0aGlzLnNpemUuaGVpZ2h0LnVuaXQgPSAncHgnO1xuICAgICAgICB0aGlzLnNpemUud2lkdGguY3VycmVudCA9IHRoaXMuc2l6ZS53aWR0aC5wcmV2aW91cztcbiAgICAgICAgdGhpcy5zaXplLndpZHRoLnVuaXQgPSAncHgnO1xuXG4gICAgICAgIHRoaXMucG9zaXRpb24uY3VycmVudCA9IHRoaXMucG9zaXRpb24ubmV4dDtcblxuICAgICAgICB0aGlzLnN0YXRlLm1heGltaXplZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJ1bGVzLmRpc2FibGVSZXNpemUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvL1doZW4gbWF4aW1pemVkIGFuZCB0aGVuIGRyYWdnZWQgdGhlIHdpbmRvdyBkZW1heGltaXplc1xuICAvL2FuZCBwdXRzIGl0c2VsZiBhbGlnbmVkIHdpdGggdGhlIG1vdXNlIHBvc2l0aW9uXG4gIGRlbWF4aW1pemUoKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUubWF4aW1pemVkID09IHRydWUpIHtcbiAgICAgIHRoaXMucG9zaXRpb24ubmV4dCA9IHtcbiAgICAgICAgeDogdGhpcy5tb3VzZVBvcy54IC0gdGhpcy5zaXplLndpZHRoLmN1cnJlbnQgLyAyLFxuICAgICAgICB5OiB0aGlzLm1vdXNlUG9zLnkgKyB3aW5kb3cuaW5uZXJIZWlnaHQgLSAyMCxcbiAgICAgIH07XG4gICAgICB0aGlzLm1heGltaXplKCk7XG4gICAgfVxuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgdGhpcy5jb21wb25lbnRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQucmVtb3ZlKCk7XG4gIH1cblxuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgLy8gUmVzaXplICYgbW92ZW1lbnQgIC8vXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIHN0b3JlTW91c2VQb3MoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICB0aGlzLm1vdXNlUG9zID0ge1xuICAgICAgeDogZXZlbnQueCxcbiAgICAgIHk6IGV2ZW50LnksXG4gICAgfTtcbiAgfVxuXG4gIC8vU2V0cyBzb21lIHZhcmlhYmxlcyB3aGVuIHRoZSByZXNpemUgZHJhZyBzdGFydHMsIHdlIHVzZSB0aGVtIGxhdGVyXG4gIHN0YXJ0UmVzaXplKCkge1xuICAgIHRoaXMuc2l6ZS5oZWlnaHQucHJldmlvdXMgPSB0aGlzLnNpemUuaGVpZ2h0LmN1cnJlbnQ7XG4gICAgdGhpcy5zaXplLndpZHRoLnByZXZpb3VzID0gdGhpcy5zaXplLndpZHRoLmN1cnJlbnQ7XG4gIH1cblxuICByZXNpemUoZHJhZ0V2ZW50OiBDZGtEcmFnTW92ZSwgZGlyZWN0aW9uOiBzdHJpbmcpIHtcbiAgICBsZXQgZGlyZWN0aW9uU3BsaXQ6IHN0cmluZ1tdID0gW2RpcmVjdGlvbi5jaGFyQXQoMCksIGRpcmVjdGlvbi5jaGFyQXQoMSldO1xuXG4gICAgdGhpcy5hbmNob3IgPSBkcmFnRXZlbnQuc291cmNlLmdldEZyZWVEcmFnUG9zaXRpb24oKTtcblxuICAgIGRpcmVjdGlvblNwbGl0LmZvckVhY2goZGlyID0+IHtcbiAgICAgIHRoaXMucmVzaXplRGlyZWN0aW9uKGRpcik7XG4gICAgfSk7XG5cbiAgICAvL1Jlc2V0IGFuY2hvciBwb3NpdGlvblxuICAgIHN3aXRjaCAoZGlyZWN0aW9uKSB7XG4gICAgICBjYXNlICduJzpcbiAgICAgICAgdGhpcy5jZGtBbmNob3JzLm4gPSB7IHg6IDAsIHk6IDAgfTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ25lJzpcbiAgICAgICAgdGhpcy5jZGtBbmNob3JzLm4gPSB7IHg6IDAsIHk6IDAgfTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2UnOlxuICAgICAgICB0aGlzLmNka0FuY2hvcnMuZSA9IHsgeDogMCwgeTogMCB9O1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnc2UnOlxuICAgICAgICB0aGlzLmNka0FuY2hvcnMuc2UgPSB7IHg6IDAsIHk6IDAgfTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3MnOlxuICAgICAgICB0aGlzLmNka0FuY2hvcnMucyA9IHsgeDogMCwgeTogMCB9O1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnc3cnOlxuICAgICAgICB0aGlzLmNka0FuY2hvcnMuc3cgPSB7IHg6IDAsIHk6IDAgfTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3cnOlxuICAgICAgICB0aGlzLmNka0FuY2hvcnMudyA9IHsgeDogMCwgeTogMCB9O1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnbncnOlxuICAgICAgICB0aGlzLmNka0FuY2hvcnMubncgPSB7IHg6IDAsIHk6IDAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmVzaXplRGlyZWN0aW9uKGRpcmVjdGlvbjogc3RyaW5nKSB7XG4gICAgdGhpcy5wb3NpdGlvbi5yZXNpemUgPSB0aGlzLnBvc2l0aW9uLm5leHQ7XG5cbiAgICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgICAgY2FzZSAnbic6XG4gICAgICAgIC8vQ2hlY2tzIHRoYXQgdGhlIG5ldyBwb3NpdGlvbiBhbmQgZGltZXNpb25zIHByb2R1Y2UgYSBtaW5IZWlnaHQgbG93ZXIgdGhhbiB0aGUgcmVxdWlyZWRcbiAgICAgICAgaWYgKHRoaXMuc2l6ZS5oZWlnaHQucHJldmlvdXMgLSB0aGlzLmFuY2hvci55ID49IHRoaXMubWluSGVpZ2h0KSB7XG4gICAgICAgICAgdGhpcy5wb3NpdGlvbi5yZXNpemUgPSB7XG4gICAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLnJlc2l6ZS54LFxuICAgICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi5uZXh0LnkgKyB0aGlzLmFuY2hvci55LFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICB0aGlzLnNpemUuaGVpZ2h0LmN1cnJlbnQgPSB0aGlzLnNpemUuaGVpZ2h0LnByZXZpb3VzIC0gdGhpcy5hbmNob3IueTtcbiAgICAgICAgICB0aGlzLnNpemUuaGVpZ2h0LmN1cnJlbnQgPSB0aGlzLmNsYW1wSGVpZ2h0KFxuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5zaXplLmhlaWdodC5jdXJyZW50LFxuICAgICAgICAgICAgdGhpcy5taW5IZWlnaHRcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgdGhpcy5wb3NpdGlvbi5jdXJyZW50ID0ge1xuICAgICAgICAgICAgeDogdGhpcy5wb3NpdGlvbi5jdXJyZW50LngsXG4gICAgICAgICAgICB5OiB0aGlzLnBvc2l0aW9uLnJlc2l6ZS55LFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2UnOlxuICAgICAgICB0aGlzLnNpemUud2lkdGguY3VycmVudCA9IHRoaXMuc2l6ZS53aWR0aC5wcmV2aW91cyArIHRoaXMuYW5jaG9yLng7XG4gICAgICAgIHRoaXMuc2l6ZS53aWR0aC5jdXJyZW50ID0gdGhpcy5jbGFtcFdpZHRoKFxuICAgICAgICAgIHRoaXMuY29tcG9uZW50RWxlbWVudCxcbiAgICAgICAgICB0aGlzLnNpemUud2lkdGguY3VycmVudCxcbiAgICAgICAgICB0aGlzLm1pbldpZHRoXG4gICAgICAgICk7XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3MnOlxuICAgICAgICB0aGlzLnNpemUuaGVpZ2h0LmN1cnJlbnQgPSB0aGlzLnNpemUuaGVpZ2h0LnByZXZpb3VzICsgdGhpcy5hbmNob3IueTtcbiAgICAgICAgdGhpcy5zaXplLmhlaWdodC5jdXJyZW50ID0gdGhpcy5jbGFtcEhlaWdodChcbiAgICAgICAgICB0aGlzLmNvbXBvbmVudEVsZW1lbnQsXG4gICAgICAgICAgdGhpcy5zaXplLmhlaWdodC5jdXJyZW50LFxuICAgICAgICAgIHRoaXMubWluSGVpZ2h0XG4gICAgICAgICk7XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3cnOlxuICAgICAgICAvL0NoZWNrcyB0aGF0IHRoZSBuZXcgcG9zaXRpb24gYW5kIGRpbWVzaW9ucyBwcm9kdWNlIGEgbWluSGVpZ2h0IGxvd2VyIHRoYW4gdGhlIHJlcXVpcmVkXG4gICAgICAgIGlmICh0aGlzLnNpemUud2lkdGgucHJldmlvdXMgLSB0aGlzLmFuY2hvci54ID49IHRoaXMubWluV2lkdGgpIHtcbiAgICAgICAgICB0aGlzLnBvc2l0aW9uLnJlc2l6ZSA9IHtcbiAgICAgICAgICAgIHg6IHRoaXMucG9zaXRpb24ubmV4dC54ICsgdGhpcy5hbmNob3IueCxcbiAgICAgICAgICAgIHk6IHRoaXMucG9zaXRpb24ucmVzaXplLnksXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHRoaXMuc2l6ZS53aWR0aC5jdXJyZW50ID0gdGhpcy5zaXplLndpZHRoLnByZXZpb3VzIC0gdGhpcy5hbmNob3IueDtcbiAgICAgICAgICB0aGlzLnNpemUud2lkdGguY3VycmVudCA9IHRoaXMuY2xhbXBXaWR0aChcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50RWxlbWVudCxcbiAgICAgICAgICAgIHRoaXMuc2l6ZS53aWR0aC5jdXJyZW50LFxuICAgICAgICAgICAgdGhpcy5taW5XaWR0aFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICB0aGlzLnBvc2l0aW9uLmN1cnJlbnQgPSB7XG4gICAgICAgICAgICB4OiB0aGlzLnBvc2l0aW9uLnJlc2l6ZS54LFxuICAgICAgICAgICAgeTogdGhpcy5wb3NpdGlvbi5jdXJyZW50LnksXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBlbmRSZXNpemUoKSB7XG4gICAgdGhpcy5wb3NpdGlvbi5uZXh0ID0gdGhpcy5wb3NpdGlvbi5jdXJyZW50O1xuICB9XG5cbiAgLy9XaGVuIHJlbGVhc2luZyB0aGUgb3Mtd2luZG93IHRoZSB1c2VyIG1heSBsZWF2ZSBpdCBvdXRzaWRlIG9mIHRoZSBicm93c2VyIHdpbmRvd1xuICAvL3doaWNoIHdvdWxkIG1ha2UgaXQgaW1wb3NpYmxlIHRvIGludGVyYWN0IHdpdGggdGhlIGNvbXBvbmVudCBhZ2FpbixcbiAgLy90aGlzIG1ha2VzIHRoZSB3aW5kb3cgJ2JvdW5jZScgYmFjayBpbnRvIHNpZ2h0XG4gIGNvcnJlY3RFbmRQb3NpdGlvbihldmVudDogQ2RrRHJhZ0VuZCkge1xuICAgIHRoaXMucG9zaXRpb24ubmV4dCA9IGV2ZW50LnNvdXJjZS5nZXRGcmVlRHJhZ1Bvc2l0aW9uKCk7XG5cbiAgICAvL0ZpeCBmb3IgWSBwb3NpdGlvbiwgdGhlIHdpbmRvdy1iYXIgd2lsbCBhbHdheXMgYmUgdmlzaWJsZVxuICAgIGlmICh0aGlzLnBvc2l0aW9uLm5leHQueSA8IHdpbmRvdy5pbm5lckhlaWdodCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi5uZXh0LnkgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gICAgfSBlbHNlIGlmICh0aGlzLnBvc2l0aW9uLm5leHQueSA+IHdpbmRvdy5pbm5lckhlaWdodCAqIDIgLSA0MCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi5uZXh0LnkgPSB3aW5kb3cuaW5uZXJIZWlnaHQgKiAyIC0gNDA7XG4gICAgfVxuXG4gICAgLy9GaXggZm9yIFggcG9zaXRpb24sIGEgcXVhcnRlciBvZiB0aGUgd2luZG93IHdpbGwgYWx3YXlzIGJlIHZpc2libGVcbiAgICBpZiAodGhpcy5wb3NpdGlvbi5uZXh0LnggPCAtKCh0aGlzLnNpemUud2lkdGguY3VycmVudCAvIDQpICogMykpIHtcbiAgICAgIHRoaXMucG9zaXRpb24ubmV4dC54ID0gLSgodGhpcy5zaXplLndpZHRoLmN1cnJlbnQgLyA0KSAqIDMpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0aGlzLnBvc2l0aW9uLm5leHQueCA+XG4gICAgICB3aW5kb3cuaW5uZXJXaWR0aCAtIHRoaXMuc2l6ZS53aWR0aC5jdXJyZW50IC8gNFxuICAgICkge1xuICAgICAgdGhpcy5wb3NpdGlvbi5uZXh0LnggPSB3aW5kb3cuaW5uZXJXaWR0aCAtIHRoaXMuc2l6ZS53aWR0aC5jdXJyZW50IC8gNDtcbiAgICB9XG5cbiAgICB0aGlzLnBvc2l0aW9uLmN1cnJlbnQgPSB0aGlzLnBvc2l0aW9uLm5leHQ7XG4gIH1cblxuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgLy8gIE90aGVyIHVzZXIgaW50ZXJhY3Rpb24gIC8vXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIC8vV2hlbiBhIHdpbmRvdyBpcyBjbGlja2VkIHdlIHdhbnQgdG8gY2hhbmdlIGl0J3Mgei1pbmRleCB2YWx1ZSBhbmQgYXBwbHkgc29tZSBzdHlsZXNcbiAgZm9jdXMoKSB7XG4gICAgLy9XZSBnZXQgdGhlIGN1cnJlbnQgZ2xvYmFsIHotaW5kZXhcbiAgICB0aGlzLnBvc2l0aW9uLnpJbmRleC5uZXh0ID0gdGhpcy5nbG9iYWxDb25maWdTZXJ2aWNlLmdldFpJbmRleCgpO1xuXG4gICAgLy9UaGlzIHdpbGwgYmUgdW5lcXVhbCBpZiBhbm90aGVyIHdpbmRvdyBoYXMgYmVlbiBmb2N1c2VkIG9uXG4gICAgaWYgKHRoaXMucG9zaXRpb24uekluZGV4LmN1cnJlbnQgIT0gdGhpcy5wb3NpdGlvbi56SW5kZXgubmV4dCkge1xuICAgICAgdGhpcy5wb3NpdGlvbi56SW5kZXgubmV4dCsrO1xuICAgICAgdGhpcy5wb3NpdGlvbi56SW5kZXguY3VycmVudCA9IHRoaXMucG9zaXRpb24uekluZGV4Lm5leHQ7XG5cbiAgICAgIC8vVXBkYXRpbmcgZ2xvYmFsIHotaW5kZXhcbiAgICAgIHRoaXMuZ2xvYmFsQ29uZmlnU2VydmljZS5zZXRaSW5kZXgodGhpcy5wb3NpdGlvbi56SW5kZXguY3VycmVudCk7XG4gICAgfVxuXG4gICAgLy9BZnRlciB0aGF0IHdlIHJlbW92ZSB0aGUgJ2ZvY3VzZWQnIGNsYXNzIGZyb20gYWxsIHRoZSB3aW5kb3dzXG4gICAgbGV0IGZvY3VzZWQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdmb2N1c2VkJyk7XG4gICAgbGV0IGk6IG51bWJlciA9IDA7XG4gICAgd2hpbGUgKGkgPCBmb2N1c2VkLmxlbmd0aCkge1xuICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhmb2N1c2VkW2ldLCAnZm9jdXNlZCcpO1xuICAgICAgaSsrO1xuICAgIH1cblxuICAgIC8vV2UgYWRkIHRoZSAnZm9jdXNlZCcgY2xhc3MgdG8gdGhlIGN1cnJlbnQgd2luZG93XG4gICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyhcbiAgICAgIHRoaXMuY29tcG9uZW50RWxlbWVudC5uYXRpdmVFbGVtZW50LmZpcnN0Q2hpbGQsXG4gICAgICAnZm9jdXNlZCdcbiAgICApO1xuICB9XG59XG4iXX0=