ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
432 lines • 36.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: affix.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { __decorate, __metadata } from "tslib";
/**
* @license
* Copyright Alibaba.com All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { Platform } from '@angular/cdk/platform';
import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Inject, Input, NgZone, Output, Renderer2, ViewChild, ViewEncapsulation } from '@angular/core';
import { NzConfigService, WithConfig } from 'ng-zorro-antd/core/config';
import { NzScrollService } from 'ng-zorro-antd/core/services';
import { getStyleAsText, InputNumber, shallowEqual } from 'ng-zorro-antd/core/util';
import { fromEvent, merge, ReplaySubject, Subject, Subscription } from 'rxjs';
import { auditTime, map, takeUntil } from 'rxjs/operators';
import { AffixRespondEvents } from './respond-events';
import { getTargetRect } from './utils';
/** @type {?} */
const NZ_CONFIG_COMPONENT_NAME = 'affix';
/** @type {?} */
const NZ_AFFIX_CLS_PREFIX = 'ant-affix';
/** @type {?} */
const NZ_AFFIX_DEFAULT_SCROLL_TIME = 20;
export class NzAffixComponent {
/**
* @param {?} el
* @param {?} doc
* @param {?} nzConfigService
* @param {?} scrollSrv
* @param {?} ngZone
* @param {?} platform
* @param {?} renderer
*/
constructor(el, doc, nzConfigService, scrollSrv, ngZone, platform, renderer) {
this.nzConfigService = nzConfigService;
this.scrollSrv = scrollSrv;
this.ngZone = ngZone;
this.platform = platform;
this.renderer = renderer;
this.nzChange = new EventEmitter();
this.positionChangeSubscription = Subscription.EMPTY;
this.offsetChanged$ = new ReplaySubject(1);
this.destroy$ = new Subject();
// The wrapper would stay at the original position as a placeholder.
this.placeholderNode = el.nativeElement;
this.document = doc;
}
/**
* @private
* @return {?}
*/
get target() {
/** @type {?} */
const el = this.nzTarget;
return (typeof el === 'string' ? this.document.querySelector(el) : el) || window;
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
const { nzOffsetBottom, nzOffsetTop, nzTarget } = changes;
if (nzOffsetBottom || nzOffsetTop) {
this.offsetChanged$.next();
}
if (nzTarget) {
this.registerListeners();
}
}
/**
* @return {?}
*/
ngAfterViewInit() {
this.registerListeners();
}
/**
* @return {?}
*/
ngOnDestroy() {
this.removeListeners();
}
/**
* @private
* @return {?}
*/
registerListeners() {
this.removeListeners();
this.positionChangeSubscription = this.ngZone.runOutsideAngular((/**
* @return {?}
*/
() => {
return merge(...Object.keys(AffixRespondEvents).map((/**
* @param {?} evName
* @return {?}
*/
evName => fromEvent(this.target, evName))), this.offsetChanged$.pipe(takeUntil(this.destroy$), map((/**
* @return {?}
*/
() => ({})))))
.pipe(auditTime(NZ_AFFIX_DEFAULT_SCROLL_TIME))
.subscribe((/**
* @param {?} e
* @return {?}
*/
e => this.updatePosition((/** @type {?} */ (e)))));
}));
this.timeout = setTimeout((/**
* @return {?}
*/
() => this.updatePosition((/** @type {?} */ ({})))));
}
/**
* @private
* @return {?}
*/
removeListeners() {
clearTimeout(this.timeout);
this.positionChangeSubscription.unsubscribe();
this.destroy$.next();
this.destroy$.complete();
}
/**
* @param {?} element
* @param {?} target
* @return {?}
*/
getOffset(element, target) {
/** @type {?} */
const elemRect = element.getBoundingClientRect();
/** @type {?} */
const targetRect = getTargetRect((/** @type {?} */ (target)));
/** @type {?} */
const scrollTop = this.scrollSrv.getScroll(target, true);
/** @type {?} */
const scrollLeft = this.scrollSrv.getScroll(target, false);
/** @type {?} */
const docElem = this.document.body;
/** @type {?} */
const clientTop = docElem.clientTop || 0;
/** @type {?} */
const clientLeft = docElem.clientLeft || 0;
return {
top: elemRect.top - targetRect.top + scrollTop - clientTop,
left: elemRect.left - targetRect.left + scrollLeft - clientLeft,
width: elemRect.width,
height: elemRect.height
};
}
/**
* @private
* @param {?} e
* @param {?=} affixStyle
* @return {?}
*/
setAffixStyle(e, affixStyle) {
/** @type {?} */
const originalAffixStyle = this.affixStyle;
/** @type {?} */
const isWindow = this.target === window;
if (e.type === 'scroll' && originalAffixStyle && affixStyle && isWindow) {
return;
}
if (shallowEqual(originalAffixStyle, affixStyle)) {
return;
}
/** @type {?} */
const fixed = !!affixStyle;
/** @type {?} */
const wrapEl = this.fixedEl.nativeElement;
this.renderer.setStyle(wrapEl, 'cssText', getStyleAsText(affixStyle));
this.affixStyle = affixStyle;
if (fixed) {
wrapEl.classList.add(NZ_AFFIX_CLS_PREFIX);
}
else {
wrapEl.classList.remove(NZ_AFFIX_CLS_PREFIX);
}
if ((affixStyle && !originalAffixStyle) || (!affixStyle && originalAffixStyle)) {
this.nzChange.emit(fixed);
}
}
/**
* @private
* @param {?=} placeholderStyle
* @return {?}
*/
setPlaceholderStyle(placeholderStyle) {
/** @type {?} */
const originalPlaceholderStyle = this.placeholderStyle;
if (shallowEqual(placeholderStyle, originalPlaceholderStyle)) {
return;
}
this.renderer.setStyle(this.placeholderNode, 'cssText', getStyleAsText(placeholderStyle));
this.placeholderStyle = placeholderStyle;
}
/**
* @private
* @param {?} e
* @return {?}
*/
syncPlaceholderStyle(e) {
if (!this.affixStyle) {
return;
}
this.renderer.setStyle(this.placeholderNode, 'cssText', '');
this.placeholderStyle = undefined;
/** @type {?} */
const styleObj = {
width: this.placeholderNode.offsetWidth,
height: this.fixedEl.nativeElement.offsetHeight
};
this.setAffixStyle(e, Object.assign(Object.assign({}, this.affixStyle), styleObj));
this.setPlaceholderStyle(styleObj);
}
/**
* @param {?} e
* @return {?}
*/
updatePosition(e) {
if (!this.platform.isBrowser) {
return;
}
/** @type {?} */
const targetNode = this.target;
/** @type {?} */
let offsetTop = this.nzOffsetTop;
/** @type {?} */
const scrollTop = this.scrollSrv.getScroll(targetNode, true);
/** @type {?} */
const elemOffset = this.getOffset(this.placeholderNode, (/** @type {?} */ (targetNode)));
/** @type {?} */
const fixedNode = this.fixedEl.nativeElement;
/** @type {?} */
const elemSize = {
width: fixedNode.offsetWidth,
height: fixedNode.offsetHeight
};
/** @type {?} */
const offsetMode = {
top: false,
bottom: false
};
// Default to `offsetTop=0`.
if (typeof offsetTop !== 'number' && typeof this.nzOffsetBottom !== 'number') {
offsetMode.top = true;
offsetTop = 0;
}
else {
offsetMode.top = typeof offsetTop === 'number';
offsetMode.bottom = typeof this.nzOffsetBottom === 'number';
}
/** @type {?} */
const targetRect = getTargetRect((/** @type {?} */ (targetNode)));
/** @type {?} */
const targetInnerHeight = ((/** @type {?} */ (targetNode))).innerHeight || ((/** @type {?} */ (targetNode))).clientHeight;
if (scrollTop >= elemOffset.top - ((/** @type {?} */ (offsetTop))) && offsetMode.top) {
/** @type {?} */
const width = elemOffset.width;
/** @type {?} */
const top = targetRect.top + ((/** @type {?} */ (offsetTop)));
this.setAffixStyle(e, {
position: 'fixed',
top,
left: targetRect.left + elemOffset.left,
width
});
this.setPlaceholderStyle({
width,
height: elemSize.height
});
}
else if (scrollTop <= elemOffset.top + elemSize.height + ((/** @type {?} */ (this.nzOffsetBottom))) - targetInnerHeight && offsetMode.bottom) {
/** @type {?} */
const targetBottomOffset = targetNode === window ? 0 : window.innerHeight - (/** @type {?} */ (targetRect.bottom));
/** @type {?} */
const width = elemOffset.width;
this.setAffixStyle(e, {
position: 'fixed',
bottom: targetBottomOffset + ((/** @type {?} */ (this.nzOffsetBottom))),
left: targetRect.left + elemOffset.left,
width
});
this.setPlaceholderStyle({
width,
height: elemOffset.height
});
}
else {
if (e.type === AffixRespondEvents.resize &&
this.affixStyle &&
this.affixStyle.position === 'fixed' &&
this.placeholderNode.offsetWidth) {
this.setAffixStyle(e, Object.assign(Object.assign({}, this.affixStyle), { width: this.placeholderNode.offsetWidth }));
}
else {
this.setAffixStyle(e);
}
this.setPlaceholderStyle();
}
if (e.type === 'resize') {
this.syncPlaceholderStyle(e);
}
}
}
NzAffixComponent.decorators = [
{ type: Component, args: [{
selector: 'nz-affix',
exportAs: 'nzAffix',
template: `
<div #fixedEl>
<ng-content></ng-content>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
}] }
];
/** @nocollapse */
NzAffixComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
{ type: NzConfigService },
{ type: NzScrollService },
{ type: NgZone },
{ type: Platform },
{ type: Renderer2 }
];
NzAffixComponent.propDecorators = {
fixedEl: [{ type: ViewChild, args: ['fixedEl', { static: true },] }],
nzTarget: [{ type: Input }],
nzOffsetTop: [{ type: Input }],
nzOffsetBottom: [{ type: Input }],
nzChange: [{ type: Output }]
};
__decorate([
WithConfig(NZ_CONFIG_COMPONENT_NAME, null),
InputNumber(),
__metadata("design:type", Object)
], NzAffixComponent.prototype, "nzOffsetTop", void 0);
__decorate([
WithConfig(NZ_CONFIG_COMPONENT_NAME, null),
InputNumber(),
__metadata("design:type", Object)
], NzAffixComponent.prototype, "nzOffsetBottom", void 0);
if (false) {
/** @type {?} */
NzAffixComponent.ngAcceptInputType_nzOffsetTop;
/** @type {?} */
NzAffixComponent.ngAcceptInputType_nzOffsetBottom;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.fixedEl;
/** @type {?} */
NzAffixComponent.prototype.nzTarget;
/** @type {?} */
NzAffixComponent.prototype.nzOffsetTop;
/** @type {?} */
NzAffixComponent.prototype.nzOffsetBottom;
/** @type {?} */
NzAffixComponent.prototype.nzChange;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.placeholderNode;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.affixStyle;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.placeholderStyle;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.positionChangeSubscription;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.offsetChanged$;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.destroy$;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.timeout;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.document;
/** @type {?} */
NzAffixComponent.prototype.nzConfigService;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.scrollSrv;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.ngZone;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.platform;
/**
* @type {?}
* @private
*/
NzAffixComponent.prototype.renderer;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWZmaXguY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctem9ycm8tYW50ZC9hZmZpeC8iLCJzb3VyY2VzIjpbImFmZml4LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBUUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2pELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBRUwsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUdOLE1BQU0sRUFDTixTQUFTLEVBRVQsU0FBUyxFQUNULGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUU5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVwRixPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM5RSxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsYUFBYSxFQUFjLE1BQU0sU0FBUyxDQUFDOztNQUU5Qyx3QkFBd0IsR0FBRyxPQUFPOztNQUNsQyxtQkFBbUIsR0FBRyxXQUFXOztNQUNqQyw0QkFBNEIsR0FBRyxFQUFFO0FBYXZDLE1BQU0sT0FBTyxnQkFBZ0I7Ozs7Ozs7Ozs7SUFtQzNCLFlBQ0UsRUFBYyxFQUNJLEdB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USxFQUFFLFVBQVU7Z0JBQ3BCLFFBQVEsRUFBRSxTQUFTO2dCQUNuQixRQUFRLEVBQUU7Ozs7R0FJVDtnQkFDRCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtnQkFDL0MsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7YUFDdEM7Ozs7WUF0Q0MsVUFBVTs0Q0E0RVAsTUFBTSxTQUFDLFFBQVE7WUEvRFgsZUFBZTtZQUNmLGVBQWU7WUFWdEIsTUFBTTtZQVZDLFFBQVE7WUFjZixTQUFTOzs7c0JBbUNSLFNBQVMsU0FBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO3VCQUVyQyxLQUFLOzBCQUVMLEtBQUs7NkJBS0wsS0FBSzt1QkFLTCxNQUFNOztBQVBQO0lBRkMsVUFBVSxDQUFnQix3QkFBd0IsRUFBRSxJQUFJLENBQUM7SUFDekQsV0FBVyxFQUFFOztxREFDYTtBQUszQjtJQUZDLFVBQVUsQ0FBZ0Isd0JBQXdCLEVBQUUsSUFBSSxDQUFDO0lBQ3pELFdBQVcsRUFBRTs7d0RBQ2dCOzs7SUFmOUIsK0NBQWtEOztJQUNsRCxrREFBcUQ7Ozs7O0lBRXJELG1DQUFvRjs7SUFFcEYsb0NBQTZDOztJQUU3Qyx1Q0FHMkI7O0lBRTNCLDBDQUc4Qjs7SUFFOUIsb0NBQTBEOzs7OztJQUUxRCwyQ0FBOEM7Ozs7O0lBRTlDLHNDQUFzQzs7Ozs7SUFDdEMsNENBQTRDOzs7OztJQUM1QyxzREFBc0U7Ozs7O0lBQ3RFLDBDQUE4Qzs7Ozs7SUFDOUMsb0NBQXVDOzs7OztJQUN2QyxtQ0FBeUI7Ozs7O0lBQ3pCLG9DQUEyQjs7SUFVekIsMkNBQXVDOzs7OztJQUN2QyxxQ0FBa0M7Ozs7O0lBQ2xDLGtDQUFzQjs7Ozs7SUFDdEIsb0NBQTBCOzs7OztJQUMxQixvQ0FBMkIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgQWxpYmFiYS5jb20gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFJlbmRlcmVyMixcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE56Q29uZmlnU2VydmljZSwgV2l0aENvbmZpZyB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9jb25maWcnO1xuaW1wb3J0IHsgTnpTY3JvbGxTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3NlcnZpY2VzJztcbmltcG9ydCB7IE5nU3R5bGVJbnRlcmZhY2UsIE51bWJlcklucHV0LCBOelNhZmVBbnkgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgZ2V0U3R5bGVBc1RleHQsIElucHV0TnVtYmVyLCBzaGFsbG93RXF1YWwgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdXRpbCc7XG5cbmltcG9ydCB7IGZyb21FdmVudCwgbWVyZ2UsIFJlcGxheVN1YmplY3QsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgYXVkaXRUaW1lLCBtYXAsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgQWZmaXhSZXNwb25kRXZlbnRzIH0gZnJvbSAnLi9yZXNwb25kLWV2ZW50cyc7XG5pbXBvcnQgeyBnZXRUYXJnZXRSZWN0LCBTaW1wbGVSZWN0IH0gZnJvbSAnLi91dGlscyc7XG5cbmNvbnN0IE5aX0NPTkZJR19DT01QT05FTlRfTkFNRSA9ICdhZmZpeCc7XG5jb25zdCBOWl9BRkZJWF9DTFNfUFJFRklYID0gJ2FudC1hZmZpeCc7XG5jb25zdCBOWl9BRkZJWF9ERUZBVUxUX1NDUk9MTF9USU1FID0gMjA7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ256LWFmZml4JyxcbiAgZXhwb3J0QXM6ICduekFmZml4JyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2ICNmaXhlZEVsPlxuICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgIDwvZGl2PlxuICBgLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBOekFmZml4Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpPZmZzZXRUb3A6IE51bWJlcklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpPZmZzZXRCb3R0b206IE51bWJlcklucHV0O1xuXG4gIEBWaWV3Q2hpbGQoJ2ZpeGVkRWwnLCB7IHN0YXRpYzogdHJ1ZSB9KSBwcml2YXRlIGZpeGVkRWw6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIEBJbnB1dCgpIG56VGFyZ2V0OiBzdHJpbmcgfCBFbGVtZW50IHwgV2luZG93O1xuXG4gIEBJbnB1dCgpXG4gIEBXaXRoQ29uZmlnPG51bWJlciB8IG51bGw+KE5aX0NPTkZJR19DT01QT05FTlRfTkFNRSwgbnVsbClcbiAgQElucHV0TnVtYmVyKClcbiAgbnpPZmZzZXRUb3A6IG51bGwgfCBudW1iZXI7XG5cbiAgQElucHV0KClcbiAgQFdpdGhDb25maWc8bnVtYmVyIHwgbnVsbD4oTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FLCBudWxsKVxuICBASW5wdXROdW1iZXIoKVxuICBuek9mZnNldEJvdHRvbTogbnVsbCB8IG51bWJlcjtcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBwbGFjZWhvbGRlck5vZGU6IEhUTUxFbGVtZW50O1xuXG4gIHByaXZhdGUgYWZmaXhTdHlsZT86IE5nU3R5bGVJbnRlcmZhY2U7XG4gIHByaXZhdGUgcGxhY2Vob2xkZXJTdHlsZT86IE5nU3R5bGVJbnRlcmZhY2U7XG4gIHByaXZhdGUgcG9zaXRpb25DaGFuZ2VTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IFN1YnNjcmlwdGlvbi5FTVBUWTtcbiAgcHJpdmF0ZSBvZmZzZXRDaGFuZ2VkJCA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSB0aW1lb3V0PzogbnVtYmVyO1xuICBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudDtcblxuICBwcml2YXRlIGdldCB0YXJnZXQoKTogRWxlbWVudCB8IFdpbmRvdyB7XG4gICAgY29uc3QgZWwgPSB0aGlzLm56VGFyZ2V0O1xuICAgIHJldHVybiAodHlwZW9mIGVsID09PSAnc3RyaW5nJyA/IHRoaXMuZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbCkgOiBlbCkgfHwgd2luZG93O1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWw6IEVsZW1lbnRSZWYsXG4gICAgQEluamVjdChET0NVTUVOVCkgZG9jOiBOelNhZmVBbnksXG4gICAgcHVibGljIG56Q29uZmlnU2VydmljZTogTnpDb25maWdTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2Nyb2xsU3J2OiBOelNjcm9sbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIHBsYXRmb3JtOiBQbGF0Zm9ybSxcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjJcbiAgKSB7XG4gICAgLy8gVGhlIHdyYXBwZXIgd291bGQgc3RheSBhdCB0aGUgb3JpZ2luYWwgcG9zaXRpb24gYXMgYSBwbGFjZWhvbGRlci5cbiAgICB0aGlzLnBsYWNlaG9sZGVyTm9kZSA9IGVsLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5kb2N1bWVudCA9IGRvYztcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCB7IG56T2Zmc2V0Qm90dG9tLCBuek9mZnNldFRvcCwgbnpUYXJnZXQgfSA9IGNoYW5nZXM7XG5cbiAgICBpZiAobnpPZmZzZXRCb3R0b20gfHwgbnpPZmZzZXRUb3ApIHtcbiAgICAgIHRoaXMub2Zmc2V0Q2hhbmdlZCQubmV4dCgpO1xuICAgIH1cbiAgICBpZiAobnpUYXJnZXQpIHtcbiAgICAgIHRoaXMucmVnaXN0ZXJMaXN0ZW5lcnMoKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZWdpc3Rlckxpc3RlbmVycygpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcnMoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVnaXN0ZXJMaXN0ZW5lcnMoKTogdm9pZCB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnBvc2l0aW9uQ2hhbmdlU3Vic2NyaXB0aW9uID0gdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgcmV0dXJuIG1lcmdlKFxuICAgICAgICAuLi5PYmplY3Qua2V5cyhBZmZpeFJlc3BvbmRFdmVudHMpLm1hcChldk5hbWUgPT4gZnJvbUV2ZW50KHRoaXMudGFyZ2V0LCBldk5hbWUpKSxcbiAgICAgICAgdGhpcy5vZmZzZXRDaGFuZ2VkJC5waXBlKFxuICAgICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSxcbiAgICAgICAgICBtYXAoKCkgPT4gKHt9KSlcbiAgICAgICAgKVxuICAgICAgKVxuICAgICAgICAucGlwZShhdWRpdFRpbWUoTlpfQUZGSVhfREVGQVVMVF9TQ1JPTExfVElNRSkpXG4gICAgICAgIC5zdWJzY3JpYmUoZSA9PiB0aGlzLnVwZGF0ZVBvc2l0aW9uKGUgYXMgRXZlbnQpKTtcbiAgICB9KTtcbiAgICB0aGlzLnRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMudXBkYXRlUG9zaXRpb24oe30gYXMgRXZlbnQpKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlTGlzdGVuZXJzKCk6IHZvaWQge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpO1xuICAgIHRoaXMucG9zaXRpb25DaGFuZ2VTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBnZXRPZmZzZXQoZWxlbWVudDogRWxlbWVudCwgdGFyZ2V0OiBFbGVtZW50IHwgV2luZG93IHwgdW5kZWZpbmVkKTogU2ltcGxlUmVjdCB7XG4gICAgY29uc3QgZWxlbVJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHRhcmdldFJlY3QgPSBnZXRUYXJnZXRSZWN0KHRhcmdldCEpO1xuXG4gICAgY29uc3Qgc2Nyb2xsVG9wID0gdGhpcy5zY3JvbGxTcnYuZ2V0U2Nyb2xsKHRhcmdldCwgdHJ1ZSk7XG4gICAgY29uc3Qgc2Nyb2xsTGVmdCA9IHRoaXMuc2Nyb2xsU3J2LmdldFNjcm9sbCh0YXJnZXQsIGZhbHNlKTtcblxuICAgIGNvbnN0IGRvY0VsZW0gPSB0aGlzLmRvY3VtZW50LmJvZHk7XG4gICAgY29uc3QgY2xpZW50VG9wID0gZG9jRWxlbS5jbGllbnRUb3AgfHwgMDtcbiAgICBjb25zdCBjbGllbnRMZWZ0ID0gZG9jRWxlbS5jbGllbnRMZWZ0IHx8IDA7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG9wOiBlbGVtUmVjdC50b3AgLSB0YXJnZXRSZWN0LnRvcCArIHNjcm9sbFRvcCAtIGNsaWVudFRvcCxcbiAgICAgIGxlZnQ6IGVsZW1SZWN0LmxlZnQgLSB0YXJnZXRSZWN0LmxlZnQgKyBzY3JvbGxMZWZ0IC0gY2xpZW50TGVmdCxcbiAgICAgIHdpZHRoOiBlbGVtUmVjdC53aWR0aCxcbiAgICAgIGhlaWdodDogZWxlbVJlY3QuaGVpZ2h0XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0QWZmaXhTdHlsZShlOiBFdmVudCwgYWZmaXhTdHlsZT86IE5nU3R5bGVJbnRlcmZhY2UpOiB2b2lkIHtcbiAgICBjb25zdCBvcmlnaW5hbEFmZml4U3R5bGUgPSB0aGlzLmFmZml4U3R5bGU7XG4gICAgY29uc3QgaXNXaW5kb3cgPSB0aGlzLnRhcmdldCA9PT0gd2luZG93O1xuICAgIGlmIChlLnR5cGUgPT09ICdzY3JvbGwnICYmIG9yaWdpbmFsQWZmaXhTdHlsZSAmJiBhZmZpeFN0eWxlICYmIGlzV2luZG93KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChzaGFsbG93RXF1YWwob3JpZ2luYWxBZmZpeFN0eWxlLCBhZmZpeFN0eWxlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGZpeGVkID0gISFhZmZpeFN0eWxlO1xuICAgIGNvbnN0IHdyYXBFbCA9IHRoaXMuZml4ZWRFbC5uYXRpdmVFbGVtZW50O1xuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUod3JhcEVsLCAnY3NzVGV4dCcsIGdldFN0eWxlQXNUZXh0KGFmZml4U3R5bGUpKTtcbiAgICB0aGlzLmFmZml4U3R5bGUgPSBhZmZpeFN0eWxlO1xuICAgIGlmIChmaXhlZCkge1xuICAgICAgd3JhcEVsLmNsYXNzTGlzdC5hZGQoTlpfQUZGSVhfQ0xTX1BSRUZJWCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdyYXBFbC5jbGFzc0xpc3QucmVtb3ZlKE5aX0FGRklYX0NMU19QUkVGSVgpO1xuICAgIH1cblxuICAgIGlmICgoYWZmaXhTdHlsZSAmJiAhb3JpZ2luYWxBZmZpeFN0eWxlKSB8fCAoIWFmZml4U3R5bGUgJiYgb3JpZ2luYWxBZmZpeFN0eWxlKSkge1xuICAgICAgdGhpcy5uekNoYW5nZS5lbWl0KGZpeGVkKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldFBsYWNlaG9sZGVyU3R5bGUocGxhY2Vob2xkZXJTdHlsZT86IE5nU3R5bGVJbnRlcmZhY2UpOiB2b2lkIHtcbiAgICBjb25zdCBvcmlnaW5hbFBsYWNlaG9sZGVyU3R5bGUgPSB0aGlzLnBsYWNlaG9sZGVyU3R5bGU7XG4gICAgaWYgKHNoYWxsb3dFcXVhbChwbGFjZWhvbGRlclN0eWxlLCBvcmlnaW5hbFBsYWNlaG9sZGVyU3R5bGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5wbGFjZWhvbGRlck5vZGUsICdjc3NUZXh0JywgZ2V0U3R5bGVBc1RleHQocGxhY2Vob2xkZXJTdHlsZSkpO1xuICAgIHRoaXMucGxhY2Vob2xkZXJTdHlsZSA9IHBsYWNlaG9sZGVyU3R5bGU7XG4gIH1cblxuICBwcml2YXRlIHN5bmNQbGFjZWhvbGRlclN0eWxlKGU6IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmFmZml4U3R5bGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLnBsYWNlaG9sZGVyTm9kZSwgJ2Nzc1RleHQnLCAnJyk7XG4gICAgdGhpcy5wbGFjZWhvbGRlclN0eWxlID0gdW5kZWZpbmVkO1xuICAgIGNvbnN0IHN0eWxlT2JqID0ge1xuICAgICAgd2lkdGg6IHRoaXMucGxhY2Vob2xkZXJOb2RlLm9mZnNldFdpZHRoLFxuICAgICAgaGVpZ2h0OiB0aGlzLmZpeGVkRWwubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHRcbiAgICB9O1xuICAgIHRoaXMuc2V0QWZmaXhTdHlsZShlLCB7XG4gICAgICAuLi50aGlzLmFmZml4U3R5bGUsXG4gICAgICAuLi5zdHlsZU9ialxuICAgIH0pO1xuICAgIHRoaXMuc2V0UGxhY2Vob2xkZXJTdHlsZShzdHlsZU9iaik7XG4gIH1cblxuICB1cGRhdGVQb3NpdGlvbihlOiBFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wbGF0Zm9ybS5pc0Jyb3dzZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB0YXJnZXROb2RlID0gdGhpcy50YXJnZXQ7XG4gICAgbGV0IG9mZnNldFRvcCA9IHRoaXMubnpPZmZzZXRUb3A7XG4gICAgY29uc3Qgc2Nyb2xsVG9wID0gdGhpcy5zY3JvbGxTcnYuZ2V0U2Nyb2xsKHRhcmdldE5vZGUsIHRydWUpO1xuICAgIGNvbnN0IGVsZW1PZmZzZXQgPSB0aGlzLmdldE9mZnNldCh0aGlzLnBsYWNlaG9sZGVyTm9kZSwgdGFyZ2V0Tm9kZSEpO1xuICAgIGNvbnN0IGZpeGVkTm9kZSA9IHRoaXMuZml4ZWRFbC5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IGVsZW1TaXplID0ge1xuICAgICAgd2lkdGg6IGZpeGVkTm9kZS5vZmZzZXRXaWR0aCxcbiAgICAgIGhlaWdodDogZml4ZWROb2RlLm9mZnNldEhlaWdodFxuICAgIH07XG4gICAgY29uc3Qgb2Zmc2V0TW9kZSA9IHtcbiAgICAgIHRvcDogZmFsc2UsXG4gICAgICBib3R0b206IGZhbHNlXG4gICAgfTtcbiAgICAvLyBEZWZhdWx0IHRvIGBvZmZzZXRUb3A9MGAuXG4gICAgaWYgKHR5cGVvZiBvZmZzZXRUb3AgIT09ICdudW1iZXInICYmIHR5cGVvZiB0aGlzLm56T2Zmc2V0Qm90dG9tICE9PSAnbnVtYmVyJykge1xuICAgICAgb2Zmc2V0TW9kZS50b3AgPSB0cnVlO1xuICAgICAgb2Zmc2V0VG9wID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgb2Zmc2V0TW9kZS50b3AgPSB0eXBlb2Ygb2Zmc2V0VG9wID09PSAnbnVtYmVyJztcbiAgICAgIG9mZnNldE1vZGUuYm90dG9tID0gdHlwZW9mIHRoaXMubnpPZmZzZXRCb3R0b20gPT09ICdudW1iZXInO1xuICAgIH1cbiAgICBjb25zdCB0YXJnZXRSZWN0ID0gZ2V0VGFyZ2V0UmVjdCh0YXJnZXROb2RlIGFzIFdpbmRvdyk7XG4gICAgY29uc3QgdGFyZ2V0SW5uZXJIZWlnaHQgPSAodGFyZ2V0Tm9kZSBhcyBXaW5kb3cpLmlubmVySGVpZ2h0IHx8ICh0YXJnZXROb2RlIGFzIEhUTUxFbGVtZW50KS5jbGllbnRIZWlnaHQ7XG4gICAgaWYgKHNjcm9sbFRvcCA+PSBlbGVtT2Zmc2V0LnRvcCAtIChvZmZzZXRUb3AgYXMgbnVtYmVyKSAmJiBvZmZzZXRNb2RlLnRvcCkge1xuICAgICAgY29uc3Qgd2lkdGggPSBlbGVtT2Zmc2V0LndpZHRoO1xuICAgICAgY29uc3QgdG9wID0gdGFyZ2V0UmVjdC50b3AgKyAob2Zmc2V0VG9wIGFzIG51bWJlcik7XG4gICAgICB0aGlzLnNldEFmZml4U3R5bGUoZSwge1xuICAgICAgICBwb3NpdGlvbjogJ2ZpeGVkJyxcbiAgICAgICAgdG9wLFxuICAgICAgICBsZWZ0OiB0YXJnZXRSZWN0LmxlZnQgKyBlbGVtT2Zmc2V0LmxlZnQsXG4gICAgICAgIHdpZHRoXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2V0UGxhY2Vob2xkZXJTdHlsZSh7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGVsZW1TaXplLmhlaWdodFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChzY3JvbGxUb3AgPD0gZWxlbU9mZnNldC50b3AgKyBlbGVtU2l6ZS5oZWlnaHQgKyAodGhpcy5uek9mZnNldEJvdHRvbSBhcyBudW1iZXIpIC0gdGFyZ2V0SW5uZXJIZWlnaHQgJiYgb2Zmc2V0TW9kZS5ib3R0b20pIHtcbiAgICAgIGNvbnN0IHRhcmdldEJvdHRvbU9mZnNldCA9IHRhcmdldE5vZGUgPT09IHdpbmRvdyA/IDAgOiB3aW5kb3cuaW5uZXJIZWlnaHQgLSB0YXJnZXRSZWN0LmJvdHRvbSE7XG4gICAgICBjb25zdCB3aWR0aCA9IGVsZW1PZmZzZXQud2lkdGg7XG4gICAgICB0aGlzLnNldEFmZml4U3R5bGUoZSwge1xuICAgICAgICBwb3NpdGlvbjogJ2ZpeGVkJyxcbiAgICAgICAgYm90dG9tOiB0YXJnZXRCb3R0b21PZmZzZXQgKyAodGhpcy5uek9mZnNldEJvdHRvbSBhcyBudW1iZXIpLFxuICAgICAgICBsZWZ0OiB0YXJnZXRSZWN0LmxlZnQgKyBlbGVtT2Zmc2V0LmxlZnQsXG4gICAgICAgIHdpZHRoXG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2V0UGxhY2Vob2xkZXJTdHlsZSh7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGVsZW1PZmZzZXQuaGVpZ2h0XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKFxuICAgICAgICBlLnR5cGUgPT09IEFmZml4UmVzcG9uZEV2ZW50cy5yZXNpemUgJiZcbiAgICAgICAgdGhpcy5hZmZpeFN0eWxlICYmXG4gICAgICAgIHRoaXMuYWZmaXhTdHlsZS5wb3NpdGlvbiA9PT0gJ2ZpeGVkJyAmJlxuICAgICAgICB0aGlzLnBsYWNlaG9sZGVyTm9kZS5vZmZzZXRXaWR0aFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuc2V0QWZmaXhTdHlsZShlLCB7XG4gICAgICAgICAgLi4udGhpcy5hZmZpeFN0eWxlLFxuICAgICAgICAgIHdpZHRoOiB0aGlzLnBsYWNlaG9sZGVyTm9kZS5vZmZzZXRXaWR0aFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0QWZmaXhTdHlsZShlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0UGxhY2Vob2xkZXJTdHlsZSgpO1xuICAgIH1cblxuICAgIGlmIChlLnR5cGUgPT09ICdyZXNpemUnKSB7XG4gICAgICB0aGlzLnN5bmNQbGFjZWhvbGRlclN0eWxlKGUpO1xuICAgIH1cbiAgfVxufVxuIl19