UNPKG

ng-zorro-antd

Version:

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

476 lines (474 loc) 67.5 kB
import { DOWN_ARROW, ENTER, ESCAPE, LEFT_ARROW, RIGHT_ARROW, TAB, UP_ARROW } from '@angular/cdk/keycodes'; import { ConnectionPositionPair, OverlayConfig } from '@angular/cdk/overlay'; import { TemplatePortal } from '@angular/cdk/portal'; import { DOCUMENT, NgTemplateOutlet } from '@angular/common'; import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EventEmitter, Input, Output, TemplateRef, ViewChild, ViewChildren, booleanAttribute, inject } from '@angular/core'; import { Observable, Subscription, fromEvent, merge, of as observableOf } from 'rxjs'; import { distinctUntilChanged, map, startWith, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators'; import { NzFormNoStatusService, NzFormPatchModule, NzFormStatusService } from 'ng-zorro-antd/core/form'; import { DEFAULT_MENTION_BOTTOM_POSITIONS, DEFAULT_MENTION_TOP_POSITIONS } from 'ng-zorro-antd/core/overlay'; import { NzDestroyService } from 'ng-zorro-antd/core/services'; import { getCaretCoordinates, getMentions, getStatusClassNames } from 'ng-zorro-antd/core/util'; import { NzEmptyModule } from 'ng-zorro-antd/empty'; import { NzIconModule } from 'ng-zorro-antd/icon'; import { NZ_MENTION_CONFIG } from './config'; import { NzMentionSuggestionDirective } from './mention-suggestions'; import { NzMentionService } from './mention.service'; import * as i0 from "@angular/core"; import * as i1 from "@angular/cdk/bidi"; import * as i2 from "@angular/cdk/overlay"; import * as i3 from "./mention.service"; import * as i4 from "ng-zorro-antd/core/services"; import * as i5 from "ng-zorro-antd/icon"; import * as i6 from "ng-zorro-antd/empty"; import * as i7 from "ng-zorro-antd/core/form"; export class NzMentionComponent { set suggestionChild(value) { if (value) { this.suggestionTemplate = value; } } get triggerNativeElement() { return this.trigger.el.nativeElement; } get focusItemElement() { const itemArr = this.items?.toArray(); if (itemArr && itemArr[this.activeIndex]) { return itemArr[this.activeIndex].nativeElement; } return null; } constructor(ngZone, directionality, cdr, overlay, viewContainerRef, elementRef, renderer, nzMentionService, destroy$) { this.ngZone = ngZone; this.directionality = directionality; this.cdr = cdr; this.overlay = overlay; this.viewContainerRef = viewContainerRef; this.elementRef = elementRef; this.renderer = renderer; this.nzMentionService = nzMentionService; this.destroy$ = destroy$; this.nzValueWith = value => value; this.nzPrefix = '@'; this.nzLoading = false; this.nzNotFoundContent = '无匹配结果,轻敲空格完成输入'; this.nzPlacement = 'bottom'; this.nzSuggestions = []; this.nzStatus = ''; this.nzOnSelect = new EventEmitter(); this.nzOnSearchChange = new EventEmitter(); this.isOpen = false; this.filteredSuggestions = []; this.suggestionTemplate = null; this.activeIndex = -1; this.dir = 'ltr'; // status this.prefixCls = 'ant-mentions'; this.statusCls = {}; this.status = ''; this.hasFeedback = false; this.previousValue = null; this.cursorMention = null; this.overlayRef = null; this.document = inject(DOCUMENT); this.nzFormStatusService = inject(NzFormStatusService, { optional: true }); this.nzFormNoStatusService = inject(NzFormNoStatusService, { optional: true }); } ngOnInit() { this.nzFormStatusService?.formStatusChanges .pipe(distinctUntilChanged((pre, cur) => { return pre.status === cur.status && pre.hasFeedback === cur.hasFeedback; }), withLatestFrom(this.nzFormNoStatusService ? this.nzFormNoStatusService.noFormStatus : observableOf(false)), map(([{ status, hasFeedback }, noStatus]) => ({ status: noStatus ? '' : status, hasFeedback })), takeUntil(this.destroy$)) .subscribe(({ status, hasFeedback }) => { this.setStatusStyles(status, hasFeedback); }); this.nzMentionService.triggerChanged().subscribe(trigger => { this.trigger = trigger; this.bindTriggerEvents(); this.closeDropdown(); this.overlayRef = null; }); this.dir = this.directionality.value; this.directionality.change?.pipe(takeUntil(this.destroy$)).subscribe((direction) => { this.dir = direction; }); } ngOnChanges(changes) { const { nzSuggestions, nzStatus } = changes; if (nzSuggestions) { if (this.isOpen) { this.previousValue = null; this.activeIndex = -1; this.resetDropdown(false); } } if (nzStatus) { this.setStatusStyles(this.nzStatus, this.hasFeedback); } } ngAfterViewInit() { this.items.changes .pipe(startWith(this.items), switchMap(() => { const items = this.items.toArray(); // Caretaker note: we explicitly should call `subscribe()` within the root zone. // `runOutsideAngular(() => fromEvent(...))` will just create an observable within the root zone, // but `addEventListener` is called when the `fromEvent` is subscribed. return new Observable(subscriber => this.ngZone.runOutsideAngular(() => merge(...items.map(item => fromEvent(item.nativeElement, 'mousedown'))).subscribe(subscriber))); })) .subscribe(event => { event.preventDefault(); }); } ngOnDestroy() { this.closeDropdown(); } closeDropdown() { if (this.overlayRef && this.overlayRef.hasAttached()) { this.overlayRef.detach(); this.overlayOutsideClickSubscription.unsubscribe(); this.isOpen = false; this.cdr.markForCheck(); } } openDropdown() { this.attachOverlay(); this.isOpen = true; this.cdr.markForCheck(); } getMentions() { return this.trigger ? getMentions(this.trigger.value, this.nzPrefix) : []; } selectSuggestion(suggestion) { const value = this.nzValueWith(suggestion); this.trigger.insertMention({ mention: value, startPos: this.cursorMentionStart, endPos: this.cursorMentionEnd }); this.nzOnSelect.emit(suggestion); this.closeDropdown(); this.activeIndex = -1; } handleInput(event) { const target = event.target; this.trigger.onChange(target.value); this.trigger.value = target.value; this.resetDropdown(); } handleKeydown(event) { const keyCode = event.keyCode; if (this.isOpen && keyCode === ENTER && this.activeIndex !== -1 && this.filteredSuggestions.length) { this.selectSuggestion(this.filteredSuggestions[this.activeIndex]); event.preventDefault(); } else if (keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW) { this.resetDropdown(); event.stopPropagation(); } else { if (this.isOpen && (keyCode === TAB || keyCode === ESCAPE)) { this.closeDropdown(); return; } if (this.isOpen && keyCode === UP_ARROW) { this.setPreviousItemActive(); event.preventDefault(); event.stopPropagation(); } if (this.isOpen && keyCode === DOWN_ARROW) { this.setNextItemActive(); event.preventDefault(); event.stopPropagation(); } } } handleClick() { this.resetDropdown(); } bindTriggerEvents() { this.trigger.onInput.subscribe((e) => this.handleInput(e)); this.trigger.onKeydown.subscribe((e) => this.handleKeydown(e)); this.trigger.onClick.subscribe(() => this.handleClick()); } suggestionsFilter(value, emit) { const suggestions = value.substring(1); /** * Should always emit (nzOnSearchChange) when value empty * * @[something]... @[empty]... @[empty] * ^ ^ ^ * preValue preValue (should emit) */ if (this.previousValue === value && value !== this.cursorMention[0]) { return; } this.previousValue = value; if (emit) { this.nzOnSearchChange.emit({ value: this.cursorMention.substring(1), prefix: this.cursorMention[0] }); } const searchValue = suggestions.toLowerCase(); this.filteredSuggestions = this.nzSuggestions.filter(suggestion => this.nzValueWith(suggestion).toLowerCase().includes(searchValue)); } resetDropdown(emit = true) { this.resetCursorMention(); if (typeof this.cursorMention !== 'string' || !this.canOpen()) { this.closeDropdown(); return; } this.suggestionsFilter(this.cursorMention, emit); const activeIndex = this.filteredSuggestions.indexOf(this.cursorMention.substring(1)); this.activeIndex = activeIndex >= 0 ? activeIndex : 0; this.openDropdown(); } setNextItemActive() { this.activeIndex = this.activeIndex + 1 <= this.filteredSuggestions.length - 1 ? this.activeIndex + 1 : 0; this.cdr.markForCheck(); this.scrollToFocusItem(); } setPreviousItemActive() { this.activeIndex = this.activeIndex - 1 < 0 ? this.filteredSuggestions.length - 1 : this.activeIndex - 1; this.cdr.markForCheck(); this.scrollToFocusItem(); } scrollToFocusItem() { if (this.focusItemElement) { this.focusItemElement.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' }); } } canOpen() { const element = this.triggerNativeElement; return !element.readOnly && !element.disabled; } resetCursorMention() { const value = this.triggerNativeElement.value.replace(/[\r\n]/g, NZ_MENTION_CONFIG.split) || ''; const selectionStart = this.triggerNativeElement.selectionStart; const prefix = typeof this.nzPrefix === 'string' ? [this.nzPrefix] : this.nzPrefix; let i = prefix.length; while (i >= 0) { const startPos = value.lastIndexOf(prefix[i], selectionStart); const endPos = value.indexOf(NZ_MENTION_CONFIG.split, selectionStart) > -1 ? value.indexOf(NZ_MENTION_CONFIG.split, selectionStart) : value.length; const mention = value.substring(startPos, endPos); if ((startPos > 0 && value[startPos - 1] !== NZ_MENTION_CONFIG.split) || startPos < 0 || mention.includes(prefix[i], 1) || mention.includes(NZ_MENTION_CONFIG.split)) { this.cursorMention = null; this.cursorMentionStart = -1; this.cursorMentionEnd = -1; } else { this.cursorMention = mention; this.cursorMentionStart = startPos; this.cursorMentionEnd = endPos; return; } i--; } } updatePositions() { const coordinates = getCaretCoordinates(this.triggerNativeElement, this.cursorMentionStart); const top = coordinates.top - this.triggerNativeElement.getBoundingClientRect().height - this.triggerNativeElement.scrollTop + (this.nzPlacement === 'bottom' ? coordinates.height - 6 : -6); const left = coordinates.left - this.triggerNativeElement.scrollLeft; this.positionStrategy.withDefaultOffsetX(left).withDefaultOffsetY(top); if (this.nzPlacement === 'bottom') { this.positionStrategy.withPositions([...DEFAULT_MENTION_BOTTOM_POSITIONS]); } if (this.nzPlacement === 'top') { this.positionStrategy.withPositions([...DEFAULT_MENTION_TOP_POSITIONS]); } this.positionStrategy.apply(); } subscribeOverlayOutsideClick() { const canCloseDropdown = (event) => { const clickTarget = event.target; return (this.isOpen && clickTarget !== this.trigger.el.nativeElement && !this.overlayRef?.overlayElement.contains(clickTarget)); }; const subscription = new Subscription(); subscription.add(this.overlayRef.outsidePointerEvents().subscribe(event => canCloseDropdown(event) && this.closeDropdown())); subscription.add(this.ngZone.runOutsideAngular(() => fromEvent(this.document, 'touchend').subscribe(event => canCloseDropdown(event) && this.ngZone.run(() => this.closeDropdown())))); return subscription; } attachOverlay() { if (!this.overlayRef) { this.portal = new TemplatePortal(this.suggestionsTemp, this.viewContainerRef); this.overlayRef = this.overlay.create(this.getOverlayConfig()); } if (this.overlayRef && !this.overlayRef.hasAttached()) { this.overlayRef.attach(this.portal); this.overlayOutsideClickSubscription = this.subscribeOverlayOutsideClick(); } this.updatePositions(); } getOverlayConfig() { return new OverlayConfig({ positionStrategy: this.getOverlayPosition(), scrollStrategy: this.overlay.scrollStrategies.reposition(), disposeOnNavigation: true }); } getOverlayPosition() { const positions = [ new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }), new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' }) ]; this.positionStrategy = this.overlay .position() .flexibleConnectedTo(this.trigger.el) .withPositions(positions) .withFlexibleDimensions(false) .withPush(false); return this.positionStrategy; } setStatusStyles(status, hasFeedback) { // set inner status this.status = status; this.hasFeedback = hasFeedback; this.cdr.markForCheck(); // render status if nzStatus is set this.statusCls = getStatusClassNames(this.prefixCls, status, hasFeedback); Object.keys(this.statusCls).forEach(status => { if (this.statusCls[status]) { this.renderer.addClass(this.elementRef.nativeElement, status); } else { this.renderer.removeClass(this.elementRef.nativeElement, status); } }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzMentionComponent, deps: [{ token: i0.NgZone }, { token: i1.Directionality }, { token: i0.ChangeDetectorRef }, { token: i2.Overlay }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i3.NzMentionService }, { token: i4.NzDestroyService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.2", type: NzMentionComponent, isStandalone: true, selector: "nz-mention", inputs: { nzValueWith: "nzValueWith", nzPrefix: "nzPrefix", nzLoading: ["nzLoading", "nzLoading", booleanAttribute], nzNotFoundContent: "nzNotFoundContent", nzPlacement: "nzPlacement", nzSuggestions: "nzSuggestions", nzStatus: "nzStatus" }, outputs: { nzOnSelect: "nzOnSelect", nzOnSearchChange: "nzOnSearchChange" }, host: { properties: { "class.ant-mentions-rtl": "dir === 'rtl'" }, classAttribute: "ant-mentions" }, providers: [NzMentionService, NzDestroyService], queries: [{ propertyName: "suggestionChild", first: true, predicate: NzMentionSuggestionDirective, descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "suggestionsTemp", first: true, predicate: TemplateRef, descendants: true }, { propertyName: "items", predicate: ["items"], descendants: true, read: ElementRef }], exportAs: ["nzMention"], usesOnChanges: true, ngImport: i0, template: ` <ng-content></ng-content> <ng-template #suggestions> <div class="ant-mentions-dropdown"> <ul class="ant-mentions-dropdown-menu" role="menu" tabindex="0"> @for (suggestion of filteredSuggestions; track suggestion) { <li #items class="ant-mentions-dropdown-menu-item" role="menuitem" tabindex="-1" [class.ant-mentions-dropdown-menu-item-active]="$index === activeIndex" [class.ant-mentions-dropdown-menu-item-selected]="$index === activeIndex" (click)="selectSuggestion(suggestion)" > @if (suggestionTemplate) { <ng-container *ngTemplateOutlet="suggestionTemplate; context: { $implicit: suggestion }" /> } @else { {{ nzValueWith(suggestion) }} } </li> } @if (filteredSuggestions.length === 0) { <li class="ant-mentions-dropdown-menu-item ant-mentions-dropdown-menu-item-disabled"> @if (nzLoading) { <span><span nz-icon nzType="loading"></span></span> } @else { <span> <nz-embed-empty nzComponentName="select" [specificContent]="nzNotFoundContent!" /> </span> } </li> } </ul> </div> </ng-template> @if (hasFeedback && !!status) { <nz-form-item-feedback-icon class="ant-mentions-suffix" [status]="status" /> } `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i5.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzEmptyModule }, { kind: "component", type: i6.NzEmbedEmptyComponent, selector: "nz-embed-empty", inputs: ["nzComponentName", "specificContent"], exportAs: ["nzEmbedEmpty"] }, { kind: "ngmodule", type: NzFormPatchModule }, { kind: "component", type: i7.NzFormItemFeedbackIconComponent, selector: "nz-form-item-feedback-icon", inputs: ["status"], exportAs: ["nzFormFeedbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzMentionComponent, decorators: [{ type: Component, args: [{ selector: 'nz-mention', exportAs: 'nzMention', template: ` <ng-content></ng-content> <ng-template #suggestions> <div class="ant-mentions-dropdown"> <ul class="ant-mentions-dropdown-menu" role="menu" tabindex="0"> @for (suggestion of filteredSuggestions; track suggestion) { <li #items class="ant-mentions-dropdown-menu-item" role="menuitem" tabindex="-1" [class.ant-mentions-dropdown-menu-item-active]="$index === activeIndex" [class.ant-mentions-dropdown-menu-item-selected]="$index === activeIndex" (click)="selectSuggestion(suggestion)" > @if (suggestionTemplate) { <ng-container *ngTemplateOutlet="suggestionTemplate; context: { $implicit: suggestion }" /> } @else { {{ nzValueWith(suggestion) }} } </li> } @if (filteredSuggestions.length === 0) { <li class="ant-mentions-dropdown-menu-item ant-mentions-dropdown-menu-item-disabled"> @if (nzLoading) { <span><span nz-icon nzType="loading"></span></span> } @else { <span> <nz-embed-empty nzComponentName="select" [specificContent]="nzNotFoundContent!" /> </span> } </li> } </ul> </div> </ng-template> @if (hasFeedback && !!status) { <nz-form-item-feedback-icon class="ant-mentions-suffix" [status]="status" /> } `, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, providers: [NzMentionService, NzDestroyService], host: { class: 'ant-mentions', '[class.ant-mentions-rtl]': `dir === 'rtl'` }, imports: [NgTemplateOutlet, NzIconModule, NzEmptyModule, NzFormPatchModule], standalone: true }] }], ctorParameters: () => [{ type: i0.NgZone }, { type: i1.Directionality }, { type: i0.ChangeDetectorRef }, { type: i2.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i3.NzMentionService }, { type: i4.NzDestroyService }], propDecorators: { nzValueWith: [{ type: Input }], nzPrefix: [{ type: Input }], nzLoading: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzNotFoundContent: [{ type: Input }], nzPlacement: [{ type: Input }], nzSuggestions: [{ type: Input }], nzStatus: [{ type: Input }], nzOnSelect: [{ type: Output }], nzOnSearchChange: [{ type: Output }], suggestionsTemp: [{ type: ViewChild, args: [TemplateRef, { static: false }] }], items: [{ type: ViewChildren, args: ['items', { read: ElementRef }] }], suggestionChild: [{ type: ContentChild, args: [NzMentionSuggestionDirective, { static: false, read: TemplateRef }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL21lbnRpb24vbWVudGlvbi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzFHLE9BQU8sRUFDTCxzQkFBc0IsRUFHdEIsYUFBYSxFQUdkLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM3RCxPQUFPLEVBRUwsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osVUFBVSxFQUNWLFlBQVksRUFDWixLQUFLLEVBS0wsTUFBTSxFQUlOLFdBQVcsRUFDWCxTQUFTLEVBQ1QsWUFBWSxFQUVaLGdCQUFnQixFQUNoQixNQUFNLEVBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFNUcsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGlCQUFpQixFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDeEcsT0FBTyxFQUFFLGdDQUFnQyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0csT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1B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QUMsTUFBTTtvQkFDL0MsU0FBUyxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUM7b0JBQy9DLElBQUksRUFBRTt3QkFDSixLQUFLLEVBQUUsY0FBYzt3QkFDckIsMEJBQTBCLEVBQUUsZUFBZTtxQkFDNUM7b0JBQ0QsT0FBTyxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQztvQkFDM0UsVUFBVSxFQUFFLElBQUk7aUJBQ2pCOzRTQUVVLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDa0MsU0FBUztzQkFBaEQsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRTtnQkFDN0IsaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNhLFVBQVU7c0JBQTVCLE1BQU07Z0JBQ1ksZ0JBQWdCO3NCQUFsQyxNQUFNO2dCQUdvQyxlQUFlO3NCQUF6RCxTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBRXpDLEtBQUs7c0JBREosWUFBWTt1QkFBQyxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO2dCQUl2QyxlQUFlO3NCQURsQixZQUFZO3VCQUFDLDRCQUE0QixFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgRGlyZWN0aW9uLCBEaXJlY3Rpb25hbGl0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7IERPV05fQVJST1csIEVOVEVSLCBFU0NBUEUsIExFRlRfQVJST1csIFJJR0hUX0FSUk9XLCBUQUIsIFVQX0FSUk9XIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7XG4gIENvbm5lY3Rpb25Qb3NpdGlvblBhaXIsXG4gIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneSxcbiAgT3ZlcmxheSxcbiAgT3ZlcmxheUNvbmZpZyxcbiAgT3ZlcmxheVJlZixcbiAgUG9zaXRpb25TdHJhdGVneVxufSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQgeyBUZW1wbGF0ZVBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHsgRE9DVU1FTlQsIE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgUmVuZGVyZXIyLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3Q2hpbGRyZW4sXG4gIFZpZXdDb250YWluZXJSZWYsXG4gIGJvb2xlYW5BdHRyaWJ1dGUsXG4gIGluamVjdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YnNjcmlwdGlvbiwgZnJvbUV2ZW50LCBtZXJnZSwgb2YgYXMgb2JzZXJ2YWJsZU9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgbWFwLCBzdGFydFdpdGgsIHN3aXRjaE1hcCwgdGFrZVVudGlsLCB3aXRoTGF0ZXN0RnJvbSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTnpGb3JtTm9TdGF0dXNTZXJ2aWNlLCBOekZvcm1QYXRjaE1vZHVsZSwgTnpGb3JtU3RhdHVzU2VydmljZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9mb3JtJztcbmltcG9ydCB7IERFRkFVTFRfTUVOVElPTl9CT1RUT01fUE9TSVRJT05TLCBERUZBVUxUX01FTlRJT05fVE9QX1BPU0lUSU9OUyB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9vdmVybGF5JztcbmltcG9ydCB7IE56RGVzdHJveVNlcnZpY2UgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvc2VydmljZXMnO1xuaW1wb3J0IHsgTmdDbGFzc0ludGVyZmFjZSwgTnpTYWZlQW55LCBOelN0YXR1cywgTnpWYWxpZGF0ZVN0YXR1cyB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyBnZXRDYXJldENvb3JkaW5hdGVzLCBnZXRNZW50aW9ucywgZ2V0U3RhdHVzQ2xhc3NOYW1lcyB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS91dGlsJztcbmltcG9ydCB7IE56RW1wdHlNb2R1bGUgfSBmcm9tICduZy16b3Jyby1hbnRkL2VtcHR5JztcbmltcG9ydCB7IE56SWNvbk1vZHVsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvaWNvbic7XG5cbmltcG9ydCB7IE5aX01FTlRJT05fQ09ORklHIH0gZnJvbSAnLi9jb25maWcnO1xuaW1wb3J0IHsgTnpNZW50aW9uU3VnZ2VzdGlvbkRpcmVjdGl2ZSB9IGZyb20gJy4vbWVudGlvbi1zdWdnZXN0aW9ucyc7XG5pbXBvcnQgeyBOek1lbnRpb25UcmlnZ2VyRGlyZWN0aXZlIH0gZnJvbSAnLi9tZW50aW9uLXRyaWdnZXInO1xuaW1wb3J0IHsgTnpNZW50aW9uU2VydmljZSB9IGZyb20gJy4vbWVudGlvbi5zZXJ2aWNlJztcblxuZXhwb3J0IGludGVyZmFjZSBNZW50aW9uT25TZWFyY2hUeXBlcyB7XG4gIHZhbHVlOiBzdHJpbmc7XG4gIHByZWZpeDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1lbnRpb24ge1xuICBzdGFydFBvczogbnVtYmVyO1xuICBlbmRQb3M6IG51bWJlcjtcbiAgbWVudGlvbjogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBNZW50aW9uUGxhY2VtZW50ID0gJ3RvcCcgfCAnYm90dG9tJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbnotbWVudGlvbicsXG4gIGV4cG9ydEFzOiAnbnpNZW50aW9uJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgPG5nLXRlbXBsYXRlICNzdWdnZXN0aW9ucz5cbiAgICAgIDxkaXYgY2xhc3M9XCJhbnQtbWVudGlvbnMtZHJvcGRvd25cIj5cbiAgICAgICAgPHVsIGNsYXNzPVwiYW50LW1lbnRpb25zLWRyb3Bkb3duLW1lbnVcIiByb2xlPVwibWVudVwiIHRhYmluZGV4PVwiMFwiPlxuICAgICAgICAgIEBmb3IgKHN1Z2dlc3Rpb24gb2YgZmlsdGVyZWRTdWdnZXN0aW9uczsgdHJhY2sgc3VnZ2VzdGlvbikge1xuICAgICAgICAgICAgPGxpXG4gICAgICAgICAgICAgICNpdGVtc1xuICAgICAgICAgICAgICBjbGFzcz1cImFudC1tZW50aW9ucy1kcm9wZG93bi1tZW51LWl0ZW1cIlxuICAgICAgICAgICAgICByb2xlPVwibWVudWl0ZW1cIlxuICAgICAgICAgICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICAgICAgW2NsYXNzLmFudC1tZW50aW9ucy1kcm9wZG93bi1tZW51LWl0ZW0tYWN0aXZlXT1cIiRpbmRleCA9PT0gYWN0aXZlSW5kZXhcIlxuICAgICAgICAgICAgICBbY2xhc3MuYW50LW1lbnRpb25zLWRyb3Bkb3duLW1lbnUtaXRlbS1zZWxlY3RlZF09XCIkaW5kZXggPT09IGFjdGl2ZUluZGV4XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFN1Z2dlc3Rpb24oc3VnZ2VzdGlvbilcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICBAaWYgKHN1Z2dlc3Rpb25UZW1wbGF0ZSkge1xuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzdWdnZXN0aW9uVGVtcGxhdGU7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBzdWdnZXN0aW9uIH1cIiAvPlxuICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICB7eyBuelZhbHVlV2l0aChzdWdnZXN0aW9uKSB9fVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgIH1cblxuICAgICAgICAgIEBpZiAoZmlsdGVyZWRTdWdnZXN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIDxsaSBjbGFzcz1cImFudC1tZW50aW9ucy1kcm9wZG93bi1tZW51LWl0ZW0gYW50LW1lbnRpb25zLWRyb3Bkb3duLW1lbnUtaXRlbS1kaXNhYmxlZFwiPlxuICAgICAgICAgICAgICBAaWYgKG56TG9hZGluZykge1xuICAgICAgICAgICAgICAgIDxzcGFuPjxzcGFuIG56LWljb24gbnpUeXBlPVwibG9hZGluZ1wiPjwvc3Bhbj48L3NwYW4+XG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICAgICAgPG56LWVtYmVkLWVtcHR5IG56Q29tcG9uZW50TmFtZT1cInNlbGVjdFwiIFtzcGVjaWZpY0NvbnRlbnRdPVwibnpOb3RGb3VuZENvbnRlbnQhXCIgLz5cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgfVxuICAgICAgICA8L3VsPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgICBAaWYgKGhhc0ZlZWRiYWNrICYmICEhc3RhdHVzKSB7XG4gICAgICA8bnotZm9ybS1pdGVtLWZlZWRiYWNrLWljb24gY2xhc3M9XCJhbnQtbWVudGlvbnMtc3VmZml4XCIgW3N0YXR1c109XCJzdGF0dXNcIiAvPlxuICAgIH1cbiAgYCxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtOek1lbnRpb25TZXJ2aWNlLCBOekRlc3Ryb3lTZXJ2aWNlXSxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnYW50LW1lbnRpb25zJyxcbiAgICAnW2NsYXNzLmFudC1tZW50aW9ucy1ydGxdJzogYGRpciA9PT0gJ3J0bCdgXG4gIH0sXG4gIGltcG9ydHM6IFtOZ1RlbXBsYXRlT3V0bGV0LCBOekljb25Nb2R1bGUsIE56RW1wdHlNb2R1bGUsIE56Rm9ybVBhdGNoTW9kdWxlXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZVxufSlcbmV4cG9ydCBjbGFzcyBOek1lbnRpb25Db21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgbnpWYWx1ZVdpdGg6ICh2YWx1ZTogTnpTYWZlQW55KSA9PiBzdHJpbmcgPSB2YWx1ZSA9PiB2YWx1ZTtcbiAgQElucHV0KCkgbnpQcmVmaXg6IHN0cmluZyB8IHN0cmluZ1tdID0gJ0AnO1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgbnpMb2FkaW5nID0gZmFsc2U7XG4gIEBJbnB1dCgpIG56Tm90Rm91bmRDb250ZW50OiBzdHJpbmcgPSAn5peg5Yy56YWN57uT5p6c77yM6L275pWy56m65qC85a6M5oiQ6L6T5YWlJztcbiAgQElucHV0KCkgbnpQbGFjZW1lbnQ6IE1lbnRpb25QbGFjZW1lbnQgPSAnYm90dG9tJztcbiAgQElucHV0KCkgbnpTdWdnZXN0aW9uczogTnpTYWZlQW55W10gPSBbXTtcbiAgQElucHV0KCkgbnpTdGF0dXM6IE56U3RhdHVzID0gJyc7XG4gIEBPdXRwdXQoKSByZWFkb25seSBuek9uU2VsZWN0OiBFdmVudEVtaXR0ZXI8TnpTYWZlQW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IG56T25TZWFyY2hDaGFuZ2U6IEV2ZW50RW1pdHRlcjxNZW50aW9uT25TZWFyY2hUeXBlcz4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgdHJpZ2dlciE6IE56TWVudGlvblRyaWdnZXJEaXJlY3RpdmU7XG4gIEBWaWV3Q2hpbGQoVGVtcGxhdGVSZWYsIHsgc3RhdGljOiBmYWxzZSB9KSBzdWdnZXN0aW9uc1RlbXA/OiBUZW1wbGF0ZVJlZjx2b2lkPjtcbiAgQFZpZXdDaGlsZHJlbignaXRlbXMnLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSlcbiAgaXRlbXMhOiBRdWVyeUxpc3Q8RWxlbWVudFJlZj47XG5cbiAgQENvbnRlbnRDaGlsZChOek1lbnRpb25TdWdnZXN0aW9uRGlyZWN0aXZlLCB7IHN0YXRpYzogZmFsc2UsIHJlYWQ6IFRlbXBsYXRlUmVmIH0pXG4gIHNldCBzdWdnZXN0aW9uQ2hpbGQodmFsdWU6IFRlbXBsYXRlUmVmPHsgJGltcGxpY2l0OiBOelNhZmVBbnkgfT4pIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuc3VnZ2VzdGlvblRlbXBsYXRlID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgaXNPcGVuID0gZmFsc2U7XG4gIGZpbHRlcmVkU3VnZ