UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

296 lines (294 loc) 35.8 kB
import { __decorate } from "tslib"; /** * 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 { normalizePassiveListenerOptions } from '@angular/cdk/platform'; import { DOCUMENT, NgClass, NgIf, NgStyle, NgTemplateOutlet } from '@angular/common'; import { booleanAttribute, ChangeDetectionStrategy, Component, EventEmitter, Inject, Input, numberAttribute, Output, ViewChild, ViewEncapsulation } from '@angular/core'; import { fromEvent, Subject } from 'rxjs'; import { takeUntil, throttleTime } from 'rxjs/operators'; import { NzAffixModule } from 'ng-zorro-antd/affix'; import { WithConfig } from 'ng-zorro-antd/core/config'; import { numberAttributeWithZeroFallback } from 'ng-zorro-antd/core/util'; import { getOffsetTop } from './util'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd/core/config"; import * as i2 from "ng-zorro-antd/core/services"; import * as i3 from "@angular/cdk/platform"; import * as i4 from "ng-zorro-antd/affix"; const VISIBLE_CLASSNAME = 'ant-anchor-ink-ball-visible'; const NZ_CONFIG_MODULE_NAME = 'anchor'; const sharpMatcherRegx = /#([^#]+)$/; const passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: true }); export class NzAnchorComponent { constructor(doc, nzConfigService, scrollSrv, cdr, platform, zone, renderer) { this.doc = doc; this.nzConfigService = nzConfigService; this.scrollSrv = scrollSrv; this.cdr = cdr; this.platform = platform; this.zone = zone; this.renderer = renderer; this._nzModuleName = NZ_CONFIG_MODULE_NAME; this.nzAffix = true; this.nzShowInkInFixed = false; this.nzBounds = 5; this.nzOffsetTop = undefined; this.nzTargetOffset = undefined; this.nzDirection = 'vertical'; this.nzClick = new EventEmitter(); this.nzChange = new EventEmitter(); this.nzScroll = new EventEmitter(); this.visible = false; this.wrapperStyle = { 'max-height': '100vh' }; this.links = []; this.animating = false; this.destroy$ = new Subject(); } registerLink(link) { this.links.push(link); } unregisterLink(link) { this.links.splice(this.links.indexOf(link), 1); } getContainer() { return this.container || window; } ngAfterViewInit() { this.registerScrollEvent(); } ngOnDestroy() { clearTimeout(this.handleScrollTimeoutID); this.destroy$.next(true); this.destroy$.complete(); } registerScrollEvent() { if (!this.platform.isBrowser) { return; } this.destroy$.next(true); this.zone.runOutsideAngular(() => { fromEvent(this.getContainer(), 'scroll', passiveEventListenerOptions) .pipe(throttleTime(50), takeUntil(this.destroy$)) .subscribe(() => this.handleScroll()); }); // Browser would maintain the scrolling position when refreshing. // So we have to delay calculation in avoid of getting a incorrect result. this.handleScrollTimeoutID = setTimeout(() => this.handleScroll()); } handleScroll() { if (typeof document === 'undefined' || this.animating) { return; } const sections = []; const offsetTop = this.nzTargetOffset ? this.nzTargetOffset : this.nzOffsetTop || 0; const scope = offsetTop + this.nzBounds; this.links.forEach(comp => { const sharpLinkMatch = sharpMatcherRegx.exec(comp.nzHref.toString()); if (!sharpLinkMatch) { return; } const target = this.doc.getElementById(sharpLinkMatch[1]); if (target) { const top = getOffsetTop(target, this.getContainer()); if (top < scope) { sections.push({ top, comp }); } } }); this.visible = !!sections.length; if (!this.visible) { this.clearActive(); this.cdr.detectChanges(); } else { const maxSection = sections.reduce((prev, curr) => (curr.top > prev.top ? curr : prev)); this.handleActive(maxSection.comp); } this.setVisible(); } clearActive() { this.links.forEach(i => { i.unsetActive(); }); } setActive(comp) { const originalActiveLink = this.activeLink; const targetComp = (this.nzCurrentAnchor && this.links.find(n => n.nzHref === this.nzCurrentAnchor)) || comp; if (!targetComp) return; targetComp.setActive(); const linkNode = targetComp.getLinkTitleElement(); if (this.nzDirection === 'vertical') { this.ink.nativeElement.style.top = `${linkNode.offsetTop + linkNode.clientHeight / 2 - 4.5}px`; } else { this.ink.nativeElement.style.left = `${linkNode.offsetLeft + linkNode.clientWidth / 2}px`; } this.activeLink = (comp || targetComp).nzHref; if (originalActiveLink !== this.activeLink) { this.nzChange.emit(this.activeLink); } } handleActive(comp) { this.clearActive(); this.setActive(comp); this.visible = true; this.setVisible(); this.nzScroll.emit(comp); } setVisible() { if (this.ink) { const visible = this.visible; if (visible) { this.renderer.addClass(this.ink.nativeElement, VISIBLE_CLASSNAME); } else { this.renderer.removeClass(this.ink.nativeElement, VISIBLE_CLASSNAME); } } } handleScrollTo(linkComp) { const el = this.doc.querySelector(linkComp.nzHref); if (!el) { return; } this.animating = true; const containerScrollTop = this.scrollSrv.getScroll(this.getContainer()); const elOffsetTop = getOffsetTop(el, this.getContainer()); let targetScrollTop = containerScrollTop + elOffsetTop; targetScrollTop -= this.nzTargetOffset !== undefined ? this.nzTargetOffset : this.nzOffsetTop || 0; this.scrollSrv.scrollTo(this.getContainer(), targetScrollTop, { callback: () => { this.animating = false; this.handleActive(linkComp); } }); this.nzClick.emit(linkComp.nzHref); } ngOnChanges(changes) { const { nzOffsetTop, nzContainer, nzCurrentAnchor } = changes; if (nzOffsetTop) { this.wrapperStyle = { 'max-height': `calc(100vh - ${this.nzOffsetTop}px)` }; } if (nzContainer) { const container = this.nzContainer; this.container = typeof container === 'string' ? this.doc.querySelector(container) : container; this.registerScrollEvent(); } if (nzCurrentAnchor) { this.setActive(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NzAnchorComponent, deps: [{ token: DOCUMENT }, { token: i1.NzConfigService }, { token: i2.NzScrollService }, { token: i0.ChangeDetectorRef }, { token: i3.Platform }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: NzAnchorComponent, isStandalone: true, selector: "nz-anchor", inputs: { nzAffix: ["nzAffix", "nzAffix", booleanAttribute], nzShowInkInFixed: ["nzShowInkInFixed", "nzShowInkInFixed", booleanAttribute], nzBounds: ["nzBounds", "nzBounds", numberAttribute], nzOffsetTop: ["nzOffsetTop", "nzOffsetTop", numberAttributeWithZeroFallback], nzTargetOffset: ["nzTargetOffset", "nzTargetOffset", numberAttributeWithZeroFallback], nzContainer: "nzContainer", nzCurrentAnchor: "nzCurrentAnchor", nzDirection: "nzDirection" }, outputs: { nzClick: "nzClick", nzChange: "nzChange", nzScroll: "nzScroll" }, viewQueries: [{ propertyName: "ink", first: true, predicate: ["ink"], descendants: true }], exportAs: ["nzAnchor"], usesOnChanges: true, ngImport: i0, template: ` @if (nzAffix) { <nz-affix [nzOffsetTop]="nzOffsetTop" [nzTarget]="container"> <ng-template [ngTemplateOutlet]="content"></ng-template> </nz-affix> } @else { <ng-template [ngTemplateOutlet]="content"></ng-template> } <ng-template #content> <div class="ant-anchor-wrapper" [ngClass]="{ 'ant-anchor-wrapper-horizontal': nzDirection === 'horizontal' }" [ngStyle]="wrapperStyle" > <div class="ant-anchor" [ngClass]="{ 'ant-anchor-fixed': !nzAffix && !nzShowInkInFixed }"> <div class="ant-anchor-ink"> <div class="ant-anchor-ink-ball" #ink></div> </div> <ng-content></ng-content> </div> </div> </ng-template> `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: NzAffixModule }, { kind: "component", type: i4.NzAffixComponent, selector: "nz-affix", inputs: ["nzTarget", "nzOffsetTop", "nzOffsetBottom"], outputs: ["nzChange"], exportAs: ["nzAffix"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } __decorate([ WithConfig() ], NzAnchorComponent.prototype, "nzShowInkInFixed", void 0); __decorate([ WithConfig() ], NzAnchorComponent.prototype, "nzBounds", void 0); __decorate([ WithConfig() ], NzAnchorComponent.prototype, "nzOffsetTop", void 0); __decorate([ WithConfig() ], NzAnchorComponent.prototype, "nzTargetOffset", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NzAnchorComponent, decorators: [{ type: Component, args: [{ selector: 'nz-anchor', exportAs: 'nzAnchor', preserveWhitespaces: false, standalone: true, imports: [NgClass, NgIf, NgStyle, NgTemplateOutlet, NzAffixModule], template: ` @if (nzAffix) { <nz-affix [nzOffsetTop]="nzOffsetTop" [nzTarget]="container"> <ng-template [ngTemplateOutlet]="content"></ng-template> </nz-affix> } @else { <ng-template [ngTemplateOutlet]="content"></ng-template> } <ng-template #content> <div class="ant-anchor-wrapper" [ngClass]="{ 'ant-anchor-wrapper-horizontal': nzDirection === 'horizontal' }" [ngStyle]="wrapperStyle" > <div class="ant-anchor" [ngClass]="{ 'ant-anchor-fixed': !nzAffix && !nzShowInkInFixed }"> <div class="ant-anchor-ink"> <div class="ant-anchor-ink-ball" #ink></div> </div> <ng-content></ng-content> </div> </div> </ng-template> `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: i1.NzConfigService }, { type: i2.NzScrollService }, { type: i0.ChangeDetectorRef }, { type: i3.Platform }, { type: i0.NgZone }, { type: i0.Renderer2 }], propDecorators: { ink: [{ type: ViewChild, args: ['ink', { static: false }] }], nzAffix: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzShowInkInFixed: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzBounds: [{ type: Input, args: [{ transform: numberAttribute }] }], nzOffsetTop: [{ type: Input, args: [{ transform: numberAttributeWithZeroFallback }] }], nzTargetOffset: [{ type: Input, args: [{ transform: numberAttributeWithZeroFallback }] }], nzContainer: [{ type: Input }], nzCurrentAnchor: [{ type: Input }], nzDirection: [{ type: Input }], nzClick: [{ type: Output }], nzChange: [{ type: Output }], nzScroll: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5jaG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvYW5jaG9yL2FuY2hvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBRSwrQkFBK0IsRUFBWSxNQUFNLHVCQUF1QixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRixPQUFPLEVBRUwsZ0JBQWdCLEVBQ2hCLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBRUwsZUFBZSxFQUdmLE1BQU0sRUFHTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3BELE9BQU8sRUFBZ0MsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFHckYsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHMUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQzs7Ozs7O0FBT3RDLE1BQU0saUJBQWlCLEdBQUcsNkJBQTZCLENBQUM7QUFDeEQsTUFBTSxxQkFBcUIsR0FBZ0IsUUFBUSxDQUFDO0FBQ3BELE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDO0FBRXJDLE1BQU0sMkJBQTJCLEdBQUcsK0JBQStCLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQW1DdkYsTUFBTSxPQUFPLGlCQUFp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LENBQUM7b0JBQ2xFLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1QlQ7b0JBQ0QsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7b0JBQ3JDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO2lCQUNoRDs7MEJBNENJLE1BQU07MkJBQUMsUUFBUTt5TUF4QzJCLEdBQUc7c0JBQS9DLFNBQVM7dUJBQUMsS0FBSyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFFSyxPQUFPO3NCQUE5QyxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFO2dCQUl0QyxnQkFBZ0I7c0JBRmYsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRTtnQkFNdEMsUUFBUTtzQkFGUCxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRTtnQkFNckMsV0FBVztzQkFGVixLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLCtCQUErQixFQUFFO2dCQU1yRCxjQUFjO3NCQUZiLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsK0JBQStCLEVBQUU7Z0JBSTVDLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVhLE9BQU87c0JBQXpCLE1BQU07Z0JBQ1ksUUFBUTtzQkFBMUIsTUFBTTtnQkFDWSxRQUFRO3NCQUExQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgbm9ybWFsaXplUGFzc2l2ZUxpc3RlbmVyT3B0aW9ucywgUGxhdGZvcm0gfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHsgRE9DVU1FTlQsIE5nQ2xhc3MsIE5nSWYsIE5nU3R5bGUsIE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgYm9vbGVhbkF0dHJpYnV0ZSxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBudW1iZXJBdHRyaWJ1dGUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFJlbmRlcmVyMixcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZyb21FdmVudCwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsLCB0aHJvdHRsZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE56QWZmaXhNb2R1bGUgfSBmcm9tICduZy16b3Jyby1hbnRkL2FmZml4JztcbmltcG9ydCB7IE56Q29uZmlnS2V5LCBOekNvbmZpZ1NlcnZpY2UsIFdpdGhDb25maWcgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvY29uZmlnJztcbmltcG9ydCB7IE56U2Nyb2xsU2VydmljZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBOZ1N0eWxlSW50ZXJmYWNlLCBOekRpcmVjdGlvblZIVHlwZSwgTnpTYWZlQW55IH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcbmltcG9ydCB7IG51bWJlckF0dHJpYnV0ZVdpdGhaZXJvRmFsbGJhY2sgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdXRpbCc7XG5cbmltcG9ydCB7IE56QW5jaG9yTGlua0NvbXBvbmVudCB9IGZyb20gJy4vYW5jaG9yLWxpbmsuY29tcG9uZW50JztcbmltcG9ydCB7IGdldE9mZnNldFRvcCB9IGZyb20gJy4vdXRpbCc7XG5cbmludGVyZmFjZSBTZWN0aW9uIHtcbiAgY29tcDogTnpBbmNob3JMaW5rQ29tcG9uZW50O1xuICB0b3A6IG51bWJlcjtcbn1cblxuY29uc3QgVklTSUJMRV9DTEFTU05BTUUgPSAnYW50LWFuY2hvci1pbmstYmFsbC12aXNpYmxlJztcbmNvbnN0IE5aX0NPTkZJR19NT0RVTEVfTkFNRTogTnpDb25maWdLZXkgPSAnYW5jaG9yJztcbmNvbnN0IHNoYXJwTWF0Y2hlclJlZ3ggPSAvIyhbXiNdKykkLztcblxuY29uc3QgcGFzc2l2ZUV2ZW50TGlzdGVuZXJPcHRpb25zID0gbm9ybWFsaXplUGFzc2l2ZUxpc3RlbmVyT3B0aW9ucyh7IHBhc3NpdmU6IHRydWUgfSk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ256LWFuY2hvcicsXG4gIGV4cG9ydEFzOiAnbnpBbmNob3InLFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW05nQ2xhc3MsIE5nSWYsIE5nU3R5bGUsIE5nVGVtcGxhdGVPdXRsZXQsIE56QWZmaXhNb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIEBpZiAobnpBZmZpeCkge1xuICAgICAgPG56LWFmZml4IFtuek9mZnNldFRvcF09XCJuek9mZnNldFRvcFwiIFtuelRhcmdldF09XCJjb250YWluZXJcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRlbnRcIj48L25nLXRlbXBsYXRlPlxuICAgICAgPC9uei1hZmZpeD5cbiAgICB9IEBlbHNlIHtcbiAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250ZW50XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICB9XG5cbiAgICA8bmctdGVtcGxhdGUgI2NvbnRlbnQ+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiYW50LWFuY2hvci13cmFwcGVyXCJcbiAgICAgICAgW25nQ2xhc3NdPVwieyAnYW50LWFuY2hvci13cmFwcGVyLWhvcml6b250YWwnOiBuekRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnIH1cIlxuICAgICAgICBbbmdTdHlsZV09XCJ3cmFwcGVyU3R5bGVcIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LWFuY2hvclwiIFtuZ0NsYXNzXT1cInsgJ2FudC1hbmNob3ItZml4ZWQnOiAhbnpBZmZpeCAmJiAhbnpTaG93SW5rSW5GaXhlZCB9XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFudC1hbmNob3ItaW5rXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LWFuY2hvci1pbmstYmFsbFwiICNpbms+PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIGAsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIE56QW5jaG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95LCBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMge1xuICByZWFkb25seSBfbnpNb2R1bGVOYW1lOiBOekNvbmZpZ0tleSA9IE5aX0NPTkZJR19NT0RVTEVfTkFNRTtcblxuICBAVmlld0NoaWxkKCdpbmsnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHJpdmF0ZSBpbmshOiBFbGVtZW50UmVmO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBuekFmZml4ID0gdHJ1ZTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSlcbiAgQFdpdGhDb25maWcoKVxuICBuelNob3dJbmtJbkZpeGVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUgfSlcbiAgQFdpdGhDb25maWcoKVxuICBuekJvdW5kczogbnVtYmVyID0gNTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IG51bWJlckF0dHJpYnV0ZVdpdGhaZXJvRmFsbGJhY2sgfSlcbiAgQFdpdGhDb25maWc8bnVtYmVyPigpXG4gIG56T2Zmc2V0VG9wPzogbnVtYmVyID0gdW5kZWZpbmVkO1xuXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogbnVtYmVyQXR0cmlidXRlV2l0aFplcm9GYWxsYmFjayB9KVxuICBAV2l0aENvbmZpZzxudW1iZXI+KClcbiAgbnpUYXJnZXRPZmZzZXQ/OiBudW1iZXIgPSB1bmRlZmluZWQ7XG5cbiAgQElucHV0KCkgbnpDb250YWluZXI/OiBzdHJpbmcgfCBIVE1MRWxlbWVudDtcbiAgQElucHV0KCkgbnpDdXJyZW50QW5jaG9yPzogc3RyaW5nO1xuICBASW5wdXQoKSBuekRpcmVjdGlvbjogTnpEaXJlY3Rpb25WSFR5cGUgPSAndmVydGljYWwnO1xuXG4gIEBPdXRwdXQoKSByZWFkb25seSBuekNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBuekNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpTY3JvbGwgPSBuZXcgRXZlbnRFbWl0dGVyPE56QW5jaG9yTGlua0NvbXBvbmVudD4oKTtcblxuICB2aXNpYmxlID0gZmFsc2U7XG4gIHdyYXBwZXJTdHlsZTogTmdTdHlsZUludGVyZmFjZSA9IHsgJ21heC1oZWlnaHQnOiAnMTAwdmgnIH07XG5cbiAgY29udGFpbmVyPzogSFRNTEVsZW1lbnQgfCBXaW5kb3c7XG4gIGFjdGl2ZUxpbms/OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBsaW5rczogTnpBbmNob3JMaW5rQ29tcG9uZW50W10gPSBbXTtcbiAgcHJpdmF0ZSBhbmltYXRpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PGJvb2xlYW4+KCk7XG4gIHByaXZhdGUgaGFuZGxlU2Nyb2xsVGltZW91dElEPzogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2M6IE56U2FmZUFueSxcbiAgICBwdWJsaWMgbnpDb25maWdTZXJ2aWNlOiBOekNvbmZpZ1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBzY3JvbGxTcnY6IE56U2Nyb2xsU2VydmljZSxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBwbGF0Zm9ybTogUGxhdGZvcm0sXG4gICAgcHJpdmF0ZSB6b25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyXG4gICkge31cblxuICByZWdpc3RlckxpbmsobGluazogTnpBbmNob3JMaW5rQ29tcG9uZW50KTogdm9pZCB7XG4gICAgdGhpcy5saW5rcy5wdXNoKGxpbmspO1xuICB9XG5cbiAgdW5yZWdpc3RlckxpbmsobGluazogTnpBbmNob3JMaW5rQ29tcG9uZW50KTogdm9pZCB7XG4gICAgdGhpcy5saW5rcy5zcGxpY2UodGhpcy5saW5rcy5pbmRleE9mKGxpbmspLCAxKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29udGFpbmVyKCk6IEhUTUxFbGVtZW50IHwgV2luZG93IHtcbiAgICByZXR1cm4gdGhpcy5jb250YWluZXIgfHwgd2luZG93O1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVnaXN0ZXJTY3JvbGxFdmVudCgpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGFuZGxlU2Nyb2xsVGltZW91dElEKTtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQodHJ1ZSk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3RlclNjcm9sbEV2ZW50KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wbGF0Zm9ybS5pc0Jyb3dzZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KHRydWUpO1xuICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBmcm9tRXZlbnQodGhpcy5nZXRDb250YWluZXIoKSwgJ3Njcm9sbCcsIDxBZGRFdmVudExpc3RlbmVyT3B0aW9ucz5wYXNzaXZlRXZlbnRMaXN0ZW5lck9wdGlvbnMpXG4gICAgICAgIC5waXBlKHRocm90dGxlVGltZSg1MCksIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLmhhbmRsZVNjcm9sbCgpKTtcbiAgICB9KTtcbiAgICAvLyBCcm93c2VyIHdvdWxkIG1haW50YWluIHRoZSBzY3JvbGxpbmcgcG9zaXRpb24gd2hlbiByZWZyZXNoaW5nLlxuICAgIC8vIFNvIHdlIGhhdmUgdG8gZGVsYXkgY2FsY3VsYXRpb24gaW4gYXZvaWQgb2YgZ2V0dGluZyBhIGluY29ycmVjdCByZXN1bHQuXG4gICAgdGhpcy5oYW5kbGVTY3JvbGxUaW1lb3V0SUQgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuaGFuZGxlU2Nyb2xsKCkpO1xuICB9XG5cbiAgaGFuZGxlU2Nyb2xsKCk6IHZvaWQge1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMuYW5pbWF0aW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc2VjdGlvbnM6IFNlY3Rpb25bXSA9IFtdO1xuICAgIGNvbnN0IG9mZnNldFRvcCA9IHRoaXMubnpUYXJnZXRPZmZzZXQgPyB0aGlzLm56VGFyZ2V0T2Zmc2V0IDogdGhpcy5uek9mZnNldFRvcCB8fCAwO1xuICAgIGNvbnN0IHNjb3BlID0gb2Zmc2V0VG9wICsgdGhpcy5uekJvdW5kcztcbiAgICB0aGlzLmxpbmtzLmZvckVhY2goY29tcCA9PiB7XG4gICAgICBjb25zdCBzaGFycExpbmtNYXRjaCA9IHNoYXJwTWF0Y2hlclJlZ3guZXhlYyhjb21wLm56SHJlZi50b1N0cmluZygpKTtcbiAgICAgIGlmICghc2hhcnBMaW5rTWF0Y2gpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5kb2MuZ2V0RWxlbWVudEJ5SWQoc2hhcnBMaW5rTWF0Y2hbMV0pO1xuICAgICAgaWYgKHRhcmdldCkge1xuICAgICAgICBjb25zdCB0b3AgPSBnZXRPZmZzZXRUb3AodGFyZ2V0LCB0aGlzLmdldENvbnRhaW5lcigpKTtcbiAgICAgICAgaWYgKHRvcCA8IHNjb3BlKSB7XG4gICAgICAgICAgc2VjdGlvbnMucHVzaCh7XG4gICAgICAgICAgICB0b3AsXG4gICAgICAgICAgICBjb21wXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMudmlzaWJsZSA9ICEhc2VjdGlvbnMubGVuZ3RoO1xuICAgIGlmICghdGhpcy52aXNpYmxlKSB7XG4gICAgICB0aGlzLmNsZWFyQWN0aXZlKCk7XG4gICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG1heFNlY3Rpb24gPSBzZWN0aW9ucy5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IChjdXJyLnRvcCA+IHByZXYudG9wID8gY3VyciA6IHByZXYpKTtcbiAgICAgIHRoaXMuaGFuZGxlQWN0aXZlKG1heFNlY3Rpb24uY29tcCk7XG4gICAgfVxuICAgIHRoaXMuc2V0VmlzaWJsZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhckFjdGl2ZSgpOiB2b2lkIHtcbiAgICB0aGlzLmxpbmtzLmZvckVhY2goaSA9PiB7XG4gICAgICBpLnVuc2V0QWN0aXZlKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldEFjdGl2ZShjb21wPzogTnpBbmNob3JMaW5rQ29tcG9uZW50KTogdm9pZCB7XG4gICAgY29uc3Qgb3JpZ2luYWxBY3RpdmVMaW5rID0gdGhpcy5hY3RpdmVMaW5rO1xuICAgIGNvbnN0IHRhcmdldENvbXAgPSAodGhpcy5uekN1cnJlbnRBbmNob3IgJiYgdGhpcy5saW5rcy5maW5kKG4gPT4gbi5uekhyZWYgPT09IHRoaXMubnpDdXJyZW50QW5jaG9yKSkgfHwgY29tcDtcbiAgICBpZiAoIXRhcmdldENvbXApIHJldHVybjtcblxuICAgIHRhcmdldENvbXAuc2V0QWN0aXZlKCk7XG4gICAgY29uc3QgbGlua05vZGUgPSB0YXJnZXRDb21wLmdldExpbmtUaXRsZUVsZW1lbnQoKTtcbiAgICBpZiAodGhpcy5uekRpcmVjdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy5pbmsubmF0aXZlRWxlbWVudC5zdHlsZS50b3AgPSBgJHtsaW5rTm9kZS5vZmZzZXRUb3AgKyBsaW5rTm9kZS5jbGllbnRIZWlnaHQgLyAyIC0gNC41fXB4YDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pbmsubmF0aXZlRWxlbWVudC5zdHlsZS5sZWZ0ID0gYCR7bGlua05vZGUub2Zmc2V0TGVmdCArIGxpbmtOb2RlLmNsaWVudFdpZHRoIC8gMn1weGA7XG4gICAgfVxuICAgIHRoaXMuYWN0aXZlTGluayA9IChjb21wIHx8IHRhcmdldENvbXApLm56SHJlZjtcbiAgICBpZiAob3JpZ2luYWxBY3RpdmVMaW5rICE9PSB0aGlzLmFjdGl2ZUxpbmspIHtcbiAgICAgIHRoaXMubnpDaGFuZ2UuZW1pdCh0aGlzLmFjdGl2ZUxpbmspO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQWN0aXZlKGNvbXA6IE56QW5jaG9yTGlua0NvbXBvbmVudCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJBY3RpdmUoKTtcbiAgICB0aGlzLnNldEFjdGl2ZShjb21wKTtcbiAgICB0aGlzLnZpc2libGUgPSB0cnVlO1xuICAgIHRoaXMuc2V0VmlzaWJsZSgpO1xuICAgIHRoaXMubnpTY3JvbGwuZW1pdChjb21wKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0VmlzaWJsZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pbmspIHtcbiAgICAgIGNvbnN0IHZpc2libGUgPSB0aGlzLnZpc2libGU7XG4gICAgICBpZiAodmlzaWJsZSkge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuaW5rLm5hdGl2ZUVsZW1lbnQsIFZJU0lCTEVfQ0xBU1NOQU1FKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy5pbmsubmF0aXZlRWxlbWVudCwgVklTSUJMRV9DTEFTU05BTUUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGhhbmRsZVNjcm9sbFRvKGxpbmtDb21wOiBOekFuY2hvckxpbmtDb21wb25lbnQpOiB2b2lkIHtcbiAgICBjb25zdCBlbCA9IHRoaXMuZG9jLnF1ZXJ5U2VsZWN0b3IobGlua0NvbXAubnpIcmVmKTtcbiAgICBpZiAoIWVsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5hbmltYXRpbmcgPSB0cnVlO1xuICAgIGNvbnN0IGNvbnRhaW5lclNjcm9sbFRvcCA9IHRoaXMuc2Nyb2xsU3J2LmdldFNjcm9sbCh0aGlzLmdldENvbnRhaW5lcigpKTtcbiAgICBjb25zdCBlbE9mZnNldFRvcCA9IGdldE9mZnNldFRvcChlbCwgdGhpcy5nZXRDb250YWluZXIoKSk7XG4gICAgbGV0IHRhcmdldFNjcm9sbFRvcCA9IGNvbnRhaW5lclNjcm9sbFRvcCArIGVsT2Zmc2V0VG9wO1xuICAgIHRhcmdldFNjcm9sbFRvcCAtPSB0aGlzLm56VGFyZ2V0T2Zmc2V0ICE9PSB1bmRlZmluZWQgPyB0aGlzLm56VGFyZ2V0T2Zmc2V0IDogdGhpcy5uek9mZnNldFRvcCB8fCAwO1xuICAgIHRoaXMuc2Nyb2xsU3J2LnNjcm9sbFRvKHRoaXMuZ2V0Q29udGFpbmVyKCksIHRhcmdldFNjcm9sbFRvcCwge1xuICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgdGhpcy5hbmltYXRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5oYW5kbGVBY3RpdmUobGlua0NvbXApO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMubnpDbGljay5lbWl0KGxpbmtDb21wLm56SHJlZik7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3QgeyBuek9mZnNldFRvcCwgbnpDb250YWluZXIsIG56Q3VycmVudEFuY2hvciB9ID0gY2hhbmdlcztcbiAgICBpZiAobnpPZmZzZXRUb3ApIHtcbiAgICAgIHRoaXMud3JhcHBlclN0eWxlID0ge1xuICAgICAgICAnbWF4LWhlaWdodCc6IGBjYWxjKDEwMHZoIC0gJHt0aGlzLm56T2Zmc2V0VG9wfXB4KWBcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChuekNvbnRhaW5lcikge1xuICAgICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5uekNvbnRhaW5lcjtcbiAgICAgIHRoaXMuY29udGFpbmVyID0gdHlwZW9mIGNvbnRhaW5lciA9PT0gJ3N0cmluZycgPyB0aGlzLmRvYy5xdWVyeVNlbGVjdG9yKGNvbnRhaW5lcikgOiBjb250YWluZXI7XG4gICAgICB0aGlzLnJlZ2lzdGVyU2Nyb2xsRXZlbnQoKTtcbiAgICB9XG4gICAgaWYgKG56Q3VycmVudEFuY2hvcikge1xuICAgICAgdGhpcy5zZXRBY3RpdmUoKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==