@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
177 lines • 31.8 kB
JavaScript
import { VerticalAlignment, HorizontalAlignment, Util } from '../services/overlay/utilities';
import { fadeOut, fadeIn } from '../animations/main';
import { isIE } from '../core/utils';
import { BaseFitPositionStrategy } from '../services/overlay/position/base-fit-position-strategy';
/** @hidden @internal */
export class SelectPositioningStrategy extends BaseFitPositionStrategy {
constructor(select, settings) {
super();
this.select = select;
this._selectDefaultSettings = {
horizontalDirection: HorizontalAlignment.Right,
verticalDirection: VerticalAlignment.Bottom,
horizontalStartPoint: HorizontalAlignment.Left,
verticalStartPoint: VerticalAlignment.Top,
openAnimation: fadeIn,
closeAnimation: fadeOut
};
// Global variables required for cases of !initialCall (page scroll/overlay repositionAll)
this.global_yOffset = 0;
this.global_xOffset = 0;
this.global_styles = {};
this.settings = Object.assign({}, this._selectDefaultSettings, settings);
}
/** @inheritdoc */
position(contentElement, size, document, initialCall) {
const rects = super.calculateElementRectangles(contentElement);
// selectFit obj, to be used for both cases of initialCall and !initialCall(page scroll/overlay repositionAll)
const selectFit = {
verticalOffset: this.global_yOffset,
horizontalOffset: this.global_xOffset,
targetRect: rects.targetRect,
contentElementRect: rects.elementRect,
styles: this.global_styles,
scrollContainer: this.select.scrollContainer,
scrollContainerRect: this.select.scrollContainer.getBoundingClientRect()
};
if (initialCall) {
// Fill in the required selectFit object properties.
selectFit.viewPortRect = Util.getViewportRect(document);
selectFit.itemElement = this.getInteractionItemElement();
selectFit.itemRect = selectFit.itemElement.getBoundingClientRect();
// Calculate input and selected item elements style related variables
selectFit.styles = this.calculateStyles(selectFit);
selectFit.scrollAmount = this.calculateScrollAmount(selectFit);
// Calculate how much to offset the overlay container.
this.calculateYoffset(selectFit);
this.calculateXoffset(selectFit);
super.updateViewPortFit(selectFit);
// container does not fit in viewPort and is out on Top or Bottom
if (selectFit.fitVertical.back < 0 || selectFit.fitVertical.forward < 0) {
this.fitInViewport(contentElement, selectFit);
}
this.select.scrollContainer.scrollTop = selectFit.scrollAmount;
}
this.setStyles(contentElement, selectFit);
}
/**
* Calculate selected item scroll position.
*/
calculateScrollAmount(selectFit) {
const itemElementRect = selectFit.itemRect;
const scrollContainer = selectFit.scrollContainer;
const scrollContainerRect = selectFit.scrollContainerRect;
const scrollDelta = scrollContainerRect.top - itemElementRect.top;
let scrollPosition = scrollContainer.scrollTop - scrollDelta;
const dropDownHeight = scrollContainer.clientHeight;
scrollPosition -= dropDownHeight / 2;
scrollPosition += itemElementRect.height / 2;
return Math.round(Math.min(Math.max(0, scrollPosition), scrollContainer.scrollHeight - scrollContainerRect.height));
}
/**
* Position the items outer container so selected item text is positioned over input text and if header
* And/OR footer - both header/footer are visible
* @param selectFit selectFit to use for computation.
*/
fitInViewport(contentElement, selectFit) {
const footer = selectFit.scrollContainerRect.bottom - selectFit.contentElementRect.bottom;
const header = selectFit.scrollContainerRect.top - selectFit.contentElementRect.top;
const lastItemFitSize = selectFit.targetRect.bottom + selectFit.styles.itemTextToInputTextDiff - footer;
const firstItemFitSize = selectFit.targetRect.top - selectFit.styles.itemTextToInputTextDiff - header;
// out of viewPort on Top
if (selectFit.fitVertical.back < 0) {
const possibleScrollAmount = selectFit.scrollContainer.scrollHeight -
selectFit.scrollContainerRect.height - selectFit.scrollAmount;
if (possibleScrollAmount + selectFit.fitVertical.back > 0 && firstItemFitSize > selectFit.viewPortRect.top) {
selectFit.scrollAmount -= selectFit.fitVertical.back;
selectFit.verticalOffset -= selectFit.fitVertical.back;
this.global_yOffset = selectFit.verticalOffset;
}
else {
selectFit.verticalOffset = 0;
this.global_yOffset = 0;
}
// out of viewPort on Bottom
}
else if (selectFit.fitVertical.forward < 0) {
if (selectFit.scrollAmount + selectFit.fitVertical.forward > 0 && lastItemFitSize < selectFit.viewPortRect.bottom) {
selectFit.scrollAmount += selectFit.fitVertical.forward;
selectFit.verticalOffset += selectFit.fitVertical.forward;
this.global_yOffset = selectFit.verticalOffset;
}
else {
selectFit.verticalOffset = -selectFit.contentElementRect.height + selectFit.targetRect.height;
this.global_yOffset = selectFit.verticalOffset;
}
}
}
/**
* Sets element's style which effectively positions the provided element
* @param element Element to position
* @param selectFit selectFit to use for computation.
* @param initialCall should be true if this is the initial call to the position method calling setStyles
*/
setStyles(contentElement, selectFit) {
super.setStyle(contentElement, selectFit.targetRect, selectFit.contentElementRect, selectFit);
contentElement.style.width = `${selectFit.styles.contentElementNewWidth}px`; // manage container based on paddings?
this.global_styles.contentElementNewWidth = selectFit.styles.contentElementNewWidth;
}
/**
* Calculate the necessary input and selected item styles to be used for positioning item text over input text.
* Calculate & Set default items container width.
* @param selectFit selectFit to use for computation.
*/
calculateStyles(selectFit) {
const styles = {};
const inputElementStyles = window.getComputedStyle(this.settings.target);
const itemElementStyles = window.getComputedStyle(selectFit.itemElement);
const numericInputFontSize = parseFloat(inputElementStyles.fontSize);
const numericItemFontSize = parseFloat(itemElementStyles.fontSize);
const inputTextToInputTop = (selectFit.targetRect.bottom - selectFit.targetRect.top - numericInputFontSize) / 2;
const itemTextToItemTop = (selectFit.itemRect.height - numericItemFontSize) / 2;
// Adjust for input top padding
const negateInputPaddings = (parseFloat(inputElementStyles.paddingTop) -
parseFloat(inputElementStyles.paddingBottom)) / 2;
styles.itemTextToInputTextDiff = Math.round(itemTextToItemTop - inputTextToInputTop + negateInputPaddings);
const numericLeftPadding = parseFloat(itemElementStyles.paddingLeft);
const numericTextIndent = parseFloat(itemElementStyles.textIndent);
styles.itemTextPadding = numericLeftPadding;
styles.itemTextIndent = numericTextIndent;
// 24 is the input's toggle ddl icon width
styles.contentElementNewWidth = selectFit.targetRect.width + 24 + numericLeftPadding * 2;
return styles;
}
/**
* Obtain the selected item if there is such one or otherwise use the first one
*/
getInteractionItemElement() {
let itemElement;
if (this.select.selectedItem) {
itemElement = this.select.selectedItem.element.nativeElement;
// D.P. Feb 22 2019, #3921 Force item scroll before measuring in IE11, due to base scrollToItem delay
if (isIE()) {
this.select.scrollContainer.scrollTop = this.select.calculateScrollPosition(this.select.selectedItem);
}
}
else {
itemElement = this.select.getFirstItemElement();
}
return itemElement;
}
/**
* Calculate how much to offset the overlay container for Y-axis.
*/
calculateYoffset(selectFit) {
selectFit.verticalOffset = -(selectFit.itemRect.top - selectFit.contentElementRect.top +
selectFit.styles.itemTextToInputTextDiff - selectFit.scrollAmount);
this.global_yOffset = selectFit.verticalOffset;
}
/**
* Calculate how much to offset the overlay container for X-axis.
*/
calculateXoffset(selectFit) {
selectFit.horizontalOffset = selectFit.styles.itemTextIndent - selectFit.styles.itemTextPadding;
this.global_xOffset = selectFit.horizontalOffset;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LXBvc2l0aW9uaW5nLXN0cmF0ZWd5LmpzIiwic291cmNlUm9vdCI6Im5nOi8vaWduaXRldWktYW5ndWxhci8iLCJzb3VyY2VzIjpbImxpYi9zZWxlY3Qvc2VsZWN0LXBvc2l0aW9uaW5nLXN0cmF0ZWd5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxtQkFBbUIsRUFBMEIsSUFBSSxFQUFpQixNQUFNLCtCQUErQixDQUFDO0FBRXBJLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFckQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNyQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx5REFBeUQsQ0FBQztBQUVsRyx3QkFBd0I7QUFDeEIsTUFBTSxPQUFPLHlCQUEwQixTQUFRLHVCQUF1QjtJQWNsRSxZQUFtQixNQUFxQixFQUFFLFFBQTJCO1FBQ2pFLEtBQUssRUFBRSxDQUFDO1FBRE8sV0FBTSxHQUFOLE1BQU0sQ0FBZTtRQVpoQywyQkFBc0IsR0FBRztZQUM3QixtQkFBbUIsRUFBRSxtQkFBbUIsQ0FBQyxLQUFLO1lBQzlDLGlCQUFpQixFQUFFLGlCQUFpQixDQUFDLE1BQU07WUFDM0Msb0JBQW9CLEVBQUUsbUJBQW1CLENBQUMsSUFBSTtZQUM5QyxrQkFBa0IsRUFBRSxpQkFBaUIsQ0FBQyxHQUFHO1lBQ3pDLGFBQWEsRUFBRSxNQUFNO1lBQ3JCLGNBQWMsRUFBRSxPQUFPO1NBQzFCLENBQUM7UUFVRiwwRkFBMEY7UUFDbEYsbUJBQWMsR0FBRyxDQUFDLENBQUM7UUFDbkIsbUJBQWMsR0FBRyxDQUFDLENBQUM7UUFDbkIsa0JBQWEsR0FBaUIsRUFBRSxDQUFDO1FBTnJDLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixFQUFFLFFBQVEsQ0FBQyxDQUFDO0lB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aEcsSUFBSSxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUMsZ0JBQWdCLENBQUM7SUFDckQsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVmVydGljYWxBbGlnbm1lbnQsIEhvcml6b250YWxBbGlnbm1lbnQsIFBvc2l0aW9uU2V0dGluZ3MsIFNpemUsIFV0aWwsIENvbm5lY3RlZEZpdCAgfSBmcm9tICcuLi9zZXJ2aWNlcy9vdmVybGF5L3V0aWxpdGllcyc7XG5pbXBvcnQgeyBJUG9zaXRpb25TdHJhdGVneSB9IGZyb20gJy4uL3NlcnZpY2VzL292ZXJsYXkvcG9zaXRpb24nO1xuaW1wb3J0IHsgZmFkZU91dCwgZmFkZUluIH0gZnJvbSAnLi4vYW5pbWF0aW9ucy9tYWluJztcbmltcG9ydCB7IElneFNlbGVjdEJhc2UgfSBmcm9tICcuL3NlbGVjdC5jb21tb24nO1xuaW1wb3J0IHsgaXNJRSB9IGZyb20gJy4uL2NvcmUvdXRpbHMnO1xuaW1wb3J0IHsgQmFzZUZpdFBvc2l0aW9uU3RyYXRlZ3kgfSBmcm9tICcuLi9zZXJ2aWNlcy9vdmVybGF5L3Bvc2l0aW9uL2Jhc2UtZml0LXBvc2l0aW9uLXN0cmF0ZWd5JztcblxuLyoqIEBoaWRkZW4gQGludGVybmFsICovXG5leHBvcnQgY2xhc3MgU2VsZWN0UG9zaXRpb25pbmdTdHJhdGVneSBleHRlbmRzIEJhc2VGaXRQb3NpdGlvblN0cmF0ZWd5IGltcGxlbWVudHMgSVBvc2l0aW9uU3RyYXRlZ3kge1xuXG4gICAgcHJpdmF0ZSBfc2VsZWN0RGVmYXVsdFNldHRpbmdzID0ge1xuICAgICAgICBob3Jpem9udGFsRGlyZWN0aW9uOiBIb3Jpem9udGFsQWxpZ25tZW50LlJpZ2h0LFxuICAgICAgICB2ZXJ0aWNhbERpcmVjdGlvbjogVmVydGljYWxBbGlnbm1lbnQuQm90dG9tLFxuICAgICAgICBob3Jpem9udGFsU3RhcnRQb2ludDogSG9yaXpvbnRhbEFsaWdubWVudC5MZWZ0LFxuICAgICAgICB2ZXJ0aWNhbFN0YXJ0UG9pbnQ6IFZlcnRpY2FsQWxpZ25tZW50LlRvcCxcbiAgICAgICAgb3BlbkFuaW1hdGlvbjogZmFkZUluLFxuICAgICAgICBjbG9zZUFuaW1hdGlvbjogZmFkZU91dFxuICAgIH07XG5cbiAgICAvKiogQGluaGVyaXRkb2MgKi9cbiAgICBwdWJsaWMgc2V0dGluZ3M6IFBvc2l0aW9uU2V0dGluZ3M7XG5cbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgc2VsZWN0OiBJZ3hTZWxlY3RCYXNlLCBzZXR0aW5ncz86IFBvc2l0aW9uU2V0dGluZ3MpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5zZXR0aW5ncyA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuX3NlbGVjdERlZmF1bHRTZXR0aW5ncywgc2V0dGluZ3MpO1xuICAgIH1cblxuICAgIC8vIEdsb2JhbCB2YXJpYWJsZXMgcmVxdWlyZWQgZm9yIGNhc2VzIG9mICFpbml0aWFsQ2FsbCAocGFnZSBzY3JvbGwvb3ZlcmxheSByZXBvc2l0aW9uQWxsKVxuICAgIHByaXZhdGUgZ2xvYmFsX3lPZmZzZXQgPSAwO1xuICAgIHByaXZhdGUgZ2xvYmFsX3hPZmZzZXQgPSAwO1xuICAgIHByaXZhdGUgZ2xvYmFsX3N0eWxlczogU2VsZWN0U3R5bGVzID0ge307XG5cbiAgICAvKiogQGluaGVyaXRkb2MgKi9cbiAgICBwb3NpdGlvbihjb250ZW50RWxlbWVudDogSFRNTEVsZW1lbnQsIHNpemU6IFNpemUsIGRvY3VtZW50PzogRG9jdW1lbnQsIGluaXRpYWxDYWxsPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBjb25zdCByZWN0cyA9IHN1cGVyLmNhbGN1bGF0ZUVsZW1lbnRSZWN0YW5nbGVzKGNvbnRlbnRFbGVtZW50KTtcbiAgICAgICAgLy8gc2VsZWN0Rml0IG9iaiwgdG8gYmUgdXNlZCBmb3IgYm90aCBjYXNlcyBvZiBpbml0aWFsQ2FsbCBhbmQgIWluaXRpYWxDYWxsKHBhZ2Ugc2Nyb2xsL292ZXJsYXkgcmVwb3NpdGlvbkFsbClcbiAgICAgICAgY29uc3Qgc2VsZWN0Rml0OiBTZWxlY3RGaXQgPSB7XG4gICAgICAgICAgICB2ZXJ0aWNhbE9mZnNldDogdGhpcy5nbG9iYWxfeU9mZnNldCxcbiAgICAgICAgICAgIGhvcml6b250YWxPZmZzZXQ6IHRoaXMuZ2xvYmFsX3hPZmZzZXQsXG4gICAgICAgICAgICB0YXJnZXRSZWN0OiByZWN0cy50YXJnZXRSZWN0LFxuICAgICAgICAgICAgY29udGVudEVsZW1lbnRSZWN0OiByZWN0cy5lbGVtZW50UmVjdCxcbiAgICAgICAgICAgIHN0eWxlczogdGhpcy5nbG9iYWxfc3R5bGVzLFxuICAgICAgICAgICAgc2Nyb2xsQ29udGFpbmVyOiB0aGlzLnNlbGVjdC5zY3JvbGxDb250YWluZXIsXG4gICAgICAgICAgICBzY3JvbGxDb250YWluZXJSZWN0OiB0aGlzLnNlbGVjdC5zY3JvbGxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoaW5pdGlhbENhbGwpIHtcbiAgICAgICAgICAgIC8vIEZpbGwgaW4gdGhlIHJlcXVpcmVkIHNlbGVjdEZpdCBvYmplY3QgcHJvcGVydGllcy5cbiAgICAgICAgICAgIHNlbGVjdEZpdC52aWV3UG9ydFJlY3QgPSBVdGlsLmdldFZpZXdwb3J0UmVjdChkb2N1bWVudCk7XG4gICAgICAgICAgICBzZWxlY3RGaXQuaXRlbUVsZW1lbnQgPSB0aGlzLmdldEludGVyYWN0aW9uSXRlbUVsZW1lbnQoKTtcbiAgICAgICAgICAgIHNlbGVjdEZpdC5pdGVtUmVjdCA9IHNlbGVjdEZpdC5pdGVtRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIGlucHV0IGFuZCBzZWxlY3RlZCBpdGVtIGVsZW1lbnRzIHN0eWxlIHJlbGF0ZWQgdmFyaWFibGVzXG4gICAgICAgICAgICBzZWxlY3RGaXQuc3R5bGVzID0gdGhpcy5jYWxjdWxhdGVTdHlsZXMoc2VsZWN0Rml0KTtcblxuICAgICAgICAgICAgc2VsZWN0Rml0LnNjcm9sbEFtb3VudCA9IHRoaXMuY2FsY3VsYXRlU2Nyb2xsQW1vdW50KHNlbGVjdEZpdCk7XG4gICAgICAgICAgICAvLyBDYWxjdWxhdGUgaG93IG11Y2ggdG8gb2Zmc2V0IHRoZSBvdmVybGF5IGNvbnRhaW5lci5cbiAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlWW9mZnNldChzZWxlY3RGaXQpO1xuICAgICAgICAgICAgdGhpcy5jYWxjdWxhdGVYb2Zmc2V0KHNlbGVjdEZpdCk7XG5cbiAgICAgICAgICAgIHN1cGVyLnVwZGF0ZVZpZXdQb3J0Rml0KHNlbGVjdEZpdCk7XG4gICAgICAgICAgICAvLyBjb250YWluZXIgZG9lcyBub3QgZml0IGluIHZpZXdQb3J0IGFuZCBpcyBvdXQgb24gVG9wIG9yIEJvdHRvbVxuICAgICAgICAgICAgaWYgKHNlbGVjdEZpdC5maXRWZXJ0aWNhbC5iYWNrIDwgMCB8fCBzZWxlY3RGaXQuZml0VmVydGljYWwuZm9yd2FyZCA8IDAgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maXRJblZpZXdwb3J0KGNvbnRlbnRFbGVtZW50LCBzZWxlY3RGaXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZWxlY3Quc2Nyb2xsQ29udGFpbmVyLnNjcm9sbFRvcCA9IHNlbGVjdEZpdC5zY3JvbGxBbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdHlsZXMoY29udGVudEVsZW1lbnQsIHNlbGVjdEZpdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlIHNlbGVjdGVkIGl0ZW0gc2Nyb2xsIHBvc2l0aW9uLlxuICAgICAqL1xuICAgIHByaXZhdGUgY2FsY3VsYXRlU2Nyb2xsQW1vdW50KHNlbGVjdEZpdDogU2VsZWN0Rml0KTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgaXRlbUVsZW1lbnRSZWN0ID0gc2VsZWN0Rml0Lml0ZW1SZWN0O1xuICAgICAgICBjb25zdCBzY3JvbGxDb250YWluZXIgPSBzZWxlY3RGaXQuc2Nyb2xsQ29udGFpbmVyO1xuICAgICAgICBjb25zdCBzY3JvbGxDb250YWluZXJSZWN0ID0gc2VsZWN0Rml0LnNjcm9sbENvbnRhaW5lclJlY3Q7XG4gICAgICAgIGNvbnN0IHNjcm9sbERlbHRhID0gc2Nyb2xsQ29udGFpbmVyUmVjdC50b3AgLSBpdGVtRWxlbWVudFJlY3QudG9wO1xuICAgICAgICBsZXQgc2Nyb2xsUG9zaXRpb24gPSBzY3JvbGxDb250YWluZXIuc2Nyb2xsVG9wIC0gc2Nyb2xsRGVsdGE7XG5cbiAgICAgICAgY29uc3QgZHJvcERvd25IZWlnaHQgPSBzY3JvbGxDb250YWluZXIuY2xpZW50SGVpZ2h0O1xuICAgICAgICBzY3JvbGxQb3NpdGlvbiAtPSBkcm9wRG93bkhlaWdodCAvIDI7XG4gICAgICAgIHNjcm9sbFBvc2l0aW9uICs9IGl0ZW1FbGVtZW50UmVjdC5oZWlnaHQgLyAyO1xuXG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKE1hdGgubWluKE1hdGgubWF4KDAsIHNjcm9sbFBvc2l0aW9uKSwgc2Nyb2xsQ29udGFpbmVyLnNjcm9sbEhlaWdodCAtIHNjcm9sbENvbnRhaW5lclJlY3QuaGVpZ2h0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUG9zaXRpb24gdGhlIGl0ZW1zIG91dGVyIGNvbnRhaW5lciBzbyBzZWxlY3RlZCBpdGVtIHRleHQgaXMgcG9zaXRpb25lZCBvdmVyIGlucHV0IHRleHQgYW5kIGlmIGhlYWRlclxuICAgICAqIEFuZC9PUiBmb290ZXIgLSBib3RoIGhlYWRlci9mb290ZXIgYXJlIHZpc2libGVcbiAgICAgKiBAcGFyYW0gc2VsZWN0Rml0IHNlbGVjdEZpdCB0byB1c2UgZm9yIGNvbXB1dGF0aW9uLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBmaXRJblZpZXdwb3J0KGNvbnRlbnRFbGVtZW50OiBIVE1MRWxlbWVudCwgc2VsZWN0Rml0OiBTZWxlY3RGaXQpIHtcbiAgICAgICAgY29uc3QgZm9vdGVyID0gc2VsZWN0Rml0LnNjcm9sbENvbnRhaW5lclJlY3QuYm90dG9tIC0gc2VsZWN0Rml0LmNvbnRlbnRFbGVtZW50UmVjdC5ib3R0b207XG4gICAgICAgIGNvbnN0IGhlYWRlciA9IHNlbGVjdEZpdC5zY3JvbGxDb250YWluZXJSZWN0LnRvcCAtIHNlbGVjdEZpdC5jb250ZW50RWxlbWVudFJlY3QudG9wO1xuICAgICAgICBjb25zdCBsYXN0SXRlbUZpdFNpemUgPSBzZWxlY3RGaXQudGFyZ2V0UmVjdC5ib3R0b20gKyBzZWxlY3RGaXQuc3R5bGVzLml0ZW1UZXh0VG9JbnB1dFRleHREaWZmIC0gZm9vdGVyO1xuICAgICAgICBjb25zdCBmaXJzdEl0ZW1GaXRTaXplID0gc2VsZWN0Rml0LnRhcmdldFJlY3QudG9wIC0gc2VsZWN0Rml0LnN0eWxlcy5pdGVtVGV4dFRvSW5wdXRUZXh0RGlmZiAtIGhlYWRlcjtcbiAgICAgICAgLy8gb3V0IG9mIHZpZXdQb3J0IG9uIFRvcFxuICAgICAgICBpZiAoc2VsZWN0Rml0LmZpdFZlcnRpY2FsLmJhY2sgPCAwKSB7XG4gICAgICAgICAgICBjb25zdCBwb3NzaWJsZVNjcm9sbEFtb3VudCA9IHNlbGVjdEZpdC5zY3JvbGxDb250YWluZXIuc2Nyb2xsSGVpZ2h0IC1cbiAgICAgICAgICAgICAgICBzZWxlY3RGaXQuc2Nyb2xsQ29udGFpbmVyUmVjdC5oZWlnaHQgLSBzZWxlY3RGaXQuc2Nyb2xsQW1vdW50O1xuICAgICAgICAgICAgaWYgKHBvc3NpYmxlU2Nyb2xsQW1vdW50ICsgc2VsZWN0Rml0LmZpdFZlcnRpY2FsLmJhY2sgPiAwICYmIGZpcnN0SXRlbUZpdFNpemUgPiBzZWxlY3RGaXQudmlld1BvcnRSZWN0LnRvcCkge1xuICAgICAgICAgICAgICAgIHNlbGVjdEZpdC5zY3JvbGxBbW91bnQgLT0gc2VsZWN0Rml0LmZpdFZlcnRpY2FsLmJhY2s7XG4gICAgICAgICAgICAgICAgc2VsZWN0Rml0LnZlcnRpY2FsT2Zmc2V0IC09IHNlbGVjdEZpdC5maXRWZXJ0aWNhbC5iYWNrO1xuICAgICAgICAgICAgICAgIHRoaXMuZ2xvYmFsX3lPZmZzZXQgPSBzZWxlY3RGaXQudmVydGljYWxPZmZzZXQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNlbGVjdEZpdC52ZXJ0aWNhbE9mZnNldCA9IDAgO1xuICAgICAgICAgICAgICAgIHRoaXMuZ2xvYmFsX3lPZmZzZXQgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAvLyBvdXQgb2Ygdmlld1BvcnQgb24gQm90dG9tXG4gICAgICAgIH0gZWxzZSBpZiAoc2VsZWN0Rml0LmZpdFZlcnRpY2FsLmZvcndhcmQgPCAwKSB7XG4gICAgICAgICAgICBpZiAoc2VsZWN0Rml0LnNjcm9sbEFtb3VudCArIHNlbGVjdEZpdC5maXRWZXJ0aWNhbC5mb3J3YXJkID4gMCAmJiBsYXN0SXRlbUZpdFNpemUgPCBzZWxlY3RGaXQudmlld1BvcnRSZWN0LmJvdHRvbSkge1xuICAgICAgICAgICAgICAgIHNlbGVjdEZpdC5zY3JvbGxBbW91bnQgKz0gc2VsZWN0Rml0LmZpdFZlcnRpY2FsLmZvcndhcmQ7XG4gICAgICAgICAgICAgICAgc2VsZWN0Rml0LnZlcnRpY2FsT2Zmc2V0ICs9IHNlbGVjdEZpdC5maXRWZXJ0aWNhbC5mb3J3YXJkO1xuICAgICAgICAgICAgICAgIHRoaXMuZ2xvYmFsX3lPZmZzZXQgPSBzZWxlY3RGaXQudmVydGljYWxPZmZzZXQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNlbGVjdEZpdC52ZXJ0aWNhbE9mZnNldCA9IC1zZWxlY3RGaXQuY29udGVudEVsZW1lbnRSZWN0LmhlaWdodCArIHNlbGVjdEZpdC50YXJnZXRSZWN0LmhlaWdodDtcbiAgICAgICAgICAgICAgICB0aGlzLmdsb2JhbF95T2Zmc2V0ID0gc2VsZWN0Rml0LnZlcnRpY2FsT2Zmc2V0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBlbGVtZW50J3Mgc3R5bGUgd2hpY2ggZWZmZWN0aXZlbHkgcG9zaXRpb25zIHRoZSBwcm92aWRlZCBlbGVtZW50XG4gICAgICogQHBhcmFtIGVsZW1lbnQgRWxlbWVudCB0byBwb3NpdGlvblxuICAgICAqIEBwYXJhbSBzZWxlY3RGaXQgc2VsZWN0Rml0IHRvIHVzZSBmb3IgY29tcHV0YXRpb24uXG4gICAgICogQHBhcmFtIGluaXRpYWxDYWxsIHNob3VsZCBiZSB0cnVlIGlmIHRoaXMgaXMgdGhlIGluaXRpYWwgY2FsbCB0byB0aGUgcG9zaXRpb24gbWV0aG9kIGNhbGxpbmcgc2V0U3R5bGVzXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHNldFN0eWxlcyhjb250ZW50RWxlbWVudDogSFRNTEVsZW1lbnQsIHNlbGVjdEZpdDogU2VsZWN0Rml0KSB7XG4gICAgICAgIHN1cGVyLnNldFN0eWxlKGNvbnRlbnRFbGVtZW50LCBzZWxlY3RGaXQudGFyZ2V0UmVjdCwgc2VsZWN0Rml0LmNvbnRlbnRFbGVtZW50UmVjdCwgc2VsZWN0Rml0KTtcbiAgICAgICAgY29udGVudEVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHtzZWxlY3RGaXQuc3R5bGVzLmNvbnRlbnRFbGVtZW50TmV3V2lkdGh9cHhgOyAvLyBtYW5hZ2UgY29udGFpbmVyIGJhc2VkIG9uIHBhZGRpbmdzP1xuICAgICAgICB0aGlzLmdsb2JhbF9zdHlsZXMuY29udGVudEVsZW1lbnROZXdXaWR0aCA9IHNlbGVjdEZpdC5zdHlsZXMuY29udGVudEVsZW1lbnROZXdXaWR0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgdGhlIG5lY2Vzc2FyeSBpbnB1dCBhbmQgc2VsZWN0ZWQgaXRlbSBzdHlsZXMgdG8gYmUgdXNlZCBmb3IgcG9zaXRpb25pbmcgaXRlbSB0ZXh0IG92ZXIgaW5wdXQgdGV4dC5cbiAgICAgKiBDYWxjdWxhdGUgJiBTZXQgZGVmYXVsdCBpdGVtcyBjb250YWluZXIgd2lkdGguXG4gICAgICogQHBhcmFtIHNlbGVjdEZpdCBzZWxlY3RGaXQgdG8gdXNlIGZvciBjb21wdXRhdGlvbi5cbiAgICAgKi9cbiAgICBwcml2YXRlIGNhbGN1bGF0ZVN0eWxlcyhzZWxlY3RGaXQ6IFNlbGVjdEZpdCk6IFNlbGVjdFN0eWxlcyAge1xuICAgICAgICBjb25zdCBzdHlsZXM6IFNlbGVjdFN0eWxlcyA9IHt9O1xuICAgICAgICBjb25zdCBpbnB1dEVsZW1lbnRTdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnNldHRpbmdzLnRhcmdldCBhcyBFbGVtZW50KTtcbiAgICAgICAgY29uc3QgaXRlbUVsZW1lbnRTdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShzZWxlY3RGaXQuaXRlbUVsZW1lbnQpO1xuICAgICAgICBjb25zdCBudW1lcmljSW5wdXRGb250U2l6ZSA9IHBhcnNlRmxvYXQoaW5wdXRFbGVtZW50U3R5bGVzLmZvbnRTaXplKTtcbiAgICAgICAgY29uc3QgbnVtZXJpY0l0ZW1Gb250U2l6ZSA9IHBhcnNlRmxvYXQoaXRlbUVsZW1lbnRTdHlsZXMuZm9udFNpemUpO1xuICAgICAgICBjb25zdCBpbnB1dFRleHRUb0lucHV0VG9wID0gKHNlbGVjdEZpdC50YXJnZXRSZWN0LmJvdHRvbSAtIHNlbGVjdEZpdC50YXJnZXRSZWN0LnRvcCAtIG51bWVyaWNJbnB1dEZvbnRTaXplKSAvIDI7XG4gICAgICAgIGNvbnN0IGl0ZW1UZXh0VG9JdGVtVG9wID0gKHNlbGVjdEZpdC5pdGVtUmVjdC5oZWlnaHQgLSBudW1lcmljSXRlbUZvbnRTaXplKSAvIDI7XG4gICAgICAgICAvLyBBZGp1c3QgZm9yIGlucHV0IHRvcCBwYWRkaW5nXG4gICAgICAgIGNvbnN0IG5lZ2F0ZUlucHV0UGFkZGluZ3MgPSAoXG4gICAgICAgICAgICAgICAgcGFyc2VGbG9hdChpbnB1dEVsZW1lbnRTdHlsZXMucGFkZGluZ1RvcCkgLVxuICAgICAgICAgICAgICAgIHBhcnNlRmxvYXQoaW5wdXRFbGVtZW50U3R5bGVzLnBhZGRpbmdCb3R0b20pXG4gICAgICAgICAgICApIC8gMjtcbiAgICAgICAgc3R5bGVzLml0ZW1UZXh0VG9JbnB1dFRleHREaWZmID0gTWF0aC5yb3VuZChpdGVtVGV4dFRvSXRlbVRvcCAtIGlucHV0VGV4dFRvSW5wdXRUb3AgKyBuZWdhdGVJbnB1dFBhZGRpbmdzKTtcblxuICAgICAgICBjb25zdCBudW1lcmljTGVmdFBhZGRpbmcgPSBwYXJzZUZsb2F0KGl0ZW1FbGVtZW50U3R5bGVzLnBhZGRpbmdMZWZ0KTtcbiAgICAgICAgY29uc3QgbnVtZXJpY1RleHRJbmRlbnQgPSBwYXJzZUZsb2F0KGl0ZW1FbGVtZW50U3R5bGVzLnRleHRJbmRlbnQpO1xuXG4gICAgICAgIHN0eWxlcy5pdGVtVGV4dFBhZGRpbmcgPSBudW1lcmljTGVmdFBhZGRpbmc7XG4gICAgICAgIHN0eWxlcy5pdGVtVGV4dEluZGVudCA9IG51bWVyaWNUZXh0SW5kZW50O1xuICAgICAgICAvLyAyNCBpcyB0aGUgaW5wdXQncyB0b2dnbGUgZGRsIGljb24gd2lkdGhcbiAgICAgICAgc3R5bGVzLmNvbnRlbnRFbGVtZW50TmV3V2lkdGggPSBzZWxlY3RGaXQudGFyZ2V0UmVjdC53aWR0aCArIDI0ICsgbnVtZXJpY0xlZnRQYWRkaW5nICogMjtcblxuICAgICAgICByZXR1cm4gc3R5bGVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9idGFpbiB0aGUgc2VsZWN0ZWQgaXRlbSBpZiB0aGVyZSBpcyBzdWNoIG9uZSBvciBvdGhlcndpc2UgdXNlIHRoZSBmaXJzdCBvbmVcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0SW50ZXJhY3Rpb25JdGVtRWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGxldCBpdGVtRWxlbWVudDtcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0LnNlbGVjdGVkSXRlbSkge1xuICAgICAgICAgICAgaXRlbUVsZW1lbnQgPSB0aGlzLnNlbGVjdC5zZWxlY3RlZEl0ZW0uZWxlbWVudC5uYXRpdmVFbGVtZW50O1xuICAgICAgICAgICAgLy8gRC5QLiBGZWIgMjIgMjAxOSwgIzM5MjEgRm9yY2UgaXRlbSBzY3JvbGwgYmVmb3JlIG1lYXN1cmluZyBpbiBJRTExLCBkdWUgdG8gYmFzZSBzY3JvbGxUb0l0ZW0gZGVsYXlcbiAgICAgICAgICAgIGlmIChpc0lFKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdC5zY3JvbGxDb250YWluZXIuc2Nyb2xsVG9wID0gdGhpcy5zZWxlY3QuY2FsY3VsYXRlU2Nyb2xsUG9zaXRpb24odGhpcy5zZWxlY3Quc2VsZWN0ZWRJdGVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGl0ZW1FbGVtZW50ID0gdGhpcy5zZWxlY3QuZ2V0Rmlyc3RJdGVtRWxlbWVudCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpdGVtRWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgaG93IG11Y2ggdG8gb2Zmc2V0IHRoZSBvdmVybGF5IGNvbnRhaW5lciBmb3IgWS1heGlzLlxuICAgICAqL1xuICAgIHByaXZhdGUgY2FsY3VsYXRlWW9mZnNldChzZWxlY3RGaXQ6IFNlbGVjdEZpdCkge1xuICAgICAgICBzZWxlY3RGaXQudmVydGljYWxPZmZzZXQgPSAtKHNlbGVjdEZpdC5pdGVtUmVjdC50b3AgLSBzZWxlY3RGaXQuY29udGVudEVsZW1lbnRSZWN0LnRvcCArXG4gICAgICAgICAgICBzZWxlY3RGaXQuc3R5bGVzLml0ZW1UZXh0VG9JbnB1dFRleHREaWZmIC0gc2VsZWN0Rml0LnNjcm9sbEFtb3VudCk7XG4gICAgICAgIHRoaXMuZ2xvYmFsX3lPZmZzZXQgPSBzZWxlY3RGaXQudmVydGljYWxPZmZzZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlIGhvdyBtdWNoIHRvIG9mZnNldCB0aGUgb3ZlcmxheSBjb250YWluZXIgZm9yIFgtYXhpcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIGNhbGN1bGF0ZVhvZmZzZXQoc2VsZWN0Rml0OiBTZWxlY3RGaXQpIHtcbiAgICAgICAgc2VsZWN0Rml0Lmhvcml6b250YWxPZmZzZXQgPSBzZWxlY3RGaXQuc3R5bGVzLml0ZW1UZXh0SW5kZW50IC0gc2VsZWN0Rml0LnN0eWxlcy5pdGVtVGV4dFBhZGRpbmc7XG4gICAgICAgIHRoaXMuZ2xvYmFsX3hPZmZzZXQgPSBzZWxlY3RGaXQuaG9yaXpvbnRhbE9mZnNldDtcbiAgICB9XG59XG5cbi8qKiBAaGlkZGVuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlbGVjdEZpdCBleHRlbmRzIENvbm5lY3RlZEZpdCB7XG4gICAgaXRlbUVsZW1lbnQ/OiBIVE1MRWxlbWVudDtcbiAgICBzY3JvbGxDb250YWluZXI6IEhUTUxFbGVtZW50O1xuICAgIHNjcm9sbENvbnRhaW5lclJlY3Q6IENsaWVudFJlY3Q7XG4gICAgaXRlbVJlY3Q/OiBDbGllbnRSZWN0O1xuICAgIHN0eWxlcz86IFNlbGVjdFN0eWxlcztcbiAgICBzY3JvbGxBbW91bnQ/OiBudW1iZXI7XG59XG5cbi8qKiBAaGlkZGVuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlbGVjdFN0eWxlcyB7XG4gICAgaXRlbVRleHRQYWRkaW5nPzogbnVtYmVyO1xuICAgIGl0ZW1UZXh0SW5kZW50PzogbnVtYmVyO1xuICAgIGl0ZW1UZXh0VG9JbnB1dFRleHREaWZmPzogbnVtYmVyO1xuICAgIGNvbnRlbnRFbGVtZW50TmV3V2lkdGg/OiBudW1iZXI7XG4gICAgbnVtZXJpY0xlZnRQYWRkaW5nPzogbnVtYmVyO1xufVxuIl19