UNPKG

@ux-aspects/ux-aspects

Version:

Open source user interface framework for building modern, responsive, mobile big data applications

199 lines 30.2 kB
import { animate, state, style, transition, trigger } from '@angular/animations'; import { isPlatformServer } from '@angular/common'; import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EventEmitter, HostListener, inject, Input, Output, PLATFORM_ID, Renderer2 } from '@angular/core'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { ColorService } from '../../services/color/color.service'; import { ToolbarSearchButtonDirective } from './toolbar-search-button.directive'; import { ToolbarSearchFieldDirective } from './toolbar-search-field.directive'; import * as i0 from "@angular/core"; export class ToolbarSearchComponent { constructor() { this._platformId = inject(PLATFORM_ID); this._elementRef = inject(ElementRef); this._colorService = inject(ColorService); this._renderer = inject(Renderer2); /** The direction in which the search box will expand. If the search button is aligned to the right edge of the container, specify left. */ this.direction = 'right'; /** Whether the color scheme is inverted. For use when the component is hosted on a dark background, e.g. the masthead. */ this.inverse = false; /** Indicate whether or not the search field should always be expanded */ this.alwaysExpanded = false; /** Emitted when the expanded state changes */ this.expandedChange = new EventEmitter(); /** * Emitted when a search query has been submitted, either by pressing enter when the search field has focus, or by clicking the search button * when the search field contains text. The event contains the search text. */ this.search = new EventEmitter(); /** Store the CSS position value as this may change to absolute */ this._position = 'relative'; /** Store the active background color */ this._backgroundColor = 'transparent'; /** Store the expanded state */ this._expanded = false; /** Unsubscribe from all subscriptions on component destroy */ this._onDestroy = new Subject(); } /** Whether the input field is visible. Use this to collapse or expand the control in response to other events. */ set expanded(value) { this._expanded = value; this.expandedChange.emit(this.expanded); if (this.expanded) { // Set focus on the input when expanded this.field.focus(); } else { // Clear text when contracted this.field.clear(); // Remove focus (works around an IE issue where the caret remains visible) this.field.blur(); } } get expanded() { return this.alwaysExpanded || this._expanded; } /* * The background color of the component. Color names from the Color Palette can be used here. * Specify this when a transparent background would cause display issues, such as background items showing through the search field. */ set background(value) { this._backgroundColor = this._colorService.resolve(value) || 'transparent'; } /** Return the correct animation based on the expanded state */ get _expandedAnimation() { return { value: this.expanded ? 'expanded' : 'collapsed', params: { initialWidth: this.button.width + 'px' } }; } ngAfterContentInit() { // Subscribe to the submitted event on the input field, triggering the search event this.field.submitted.pipe(takeUntil(this._onDestroy)).subscribe((text) => this.search.emit(text)); // Subscribe to cancel events coming from the input field this.field.cancel.pipe(takeUntil(this._onDestroy)).subscribe(() => this.expanded = false); // Subscribe to the button click event this.button.clicked.pipe(takeUntil(this._onDestroy)).subscribe(() => { this.expanded && this.field.text ? this.search.emit(this.field.text) : this.expanded = !this.expanded; }); // Create placeholder element to avoid changing layout when switching to position: absolute // If the platform is a server we dont want to do this as we can't access getComputedStyle if (!isPlatformServer(this._platformId)) { this.createPlaceholder(); } } ngOnDestroy() { this._onDestroy.next(); this._onDestroy.complete(); /** * We programmatically created the placeholder node so Angular is not aware of its existence * so we must manually destroy it otherwise the reference will be retained. * Note, the `destroyNode` function may be null or undefined as mentioned in the * Angular API docs (https://angular.io/api/core/Renderer2#destroyNode) so * we must check that the function is available before attempting to call it */ if (this._placeholder && this._renderer && this._renderer.destroyNode) { this._renderer.destroyNode(this._placeholder); } } animationStart(event) { if (event.toState === 'expanded') { this._position = 'absolute'; this.setPlaceholderVisible(true); } } animationDone(event) { if (event.toState === 'collapsed') { this._position = 'relative'; this.setPlaceholderVisible(false); } } /** Programmatically create a placeholder element */ createPlaceholder() { // Create invisible div with the same dimensions this._placeholder = this._renderer.createElement('div'); this._renderer.setStyle(this._placeholder, 'display', 'none'); this._renderer.setStyle(this._placeholder, 'width', this.button.width + 'px'); this._renderer.setStyle(this._placeholder, 'visibility', 'hidden'); this.setPlaceholderHeight(); // Add as a sibling this._renderer.insertBefore(this._elementRef.nativeElement.parentNode, this._placeholder, this._elementRef.nativeElement); } /** Update the display state of the placeholder node */ setPlaceholderVisible(isVisible) { if (!this._placeholder) { return; } // Recalculate the height since the layout might not be complete when initially created. if (isVisible) { this.setPlaceholderHeight(); } this._renderer.setStyle(this._placeholder, 'display', isVisible ? 'inline-block' : 'none'); } /** Set the placeholder height to match the height of this component. */ setPlaceholderHeight() { const { height } = getComputedStyle(this._elementRef.nativeElement); this._renderer.setStyle(this._placeholder, 'height', height); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ToolbarSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: ToolbarSearchComponent, selector: "ux-toolbar-search", inputs: { direction: "direction", inverse: "inverse", alwaysExpanded: "alwaysExpanded", expanded: "expanded", background: "background" }, outputs: { expandedChange: "expandedChange", search: "search" }, host: { listeners: { "@expanded.start": "animationStart($event)", "@expanded.done": "animationDone($event)" }, properties: { "class.expanded": "expanded", "class.left": "direction === \"left\"", "class.right": "direction === \"right\"", "class.inverse": "inverse", "style.position": "_position", "style.background-color": "_backgroundColor", "@expanded": "_expandedAnimation" } }, queries: [{ propertyName: "field", first: true, predicate: ToolbarSearchFieldDirective, descendants: true, static: true }, { propertyName: "button", first: true, predicate: ToolbarSearchButtonDirective, descendants: true }], ngImport: i0, template: '<ng-content></ng-content>', isInline: true, animations: [ trigger('expanded', [ state('collapsed', style({ width: '{{initialWidth}}' }), { params: { initialWidth: '30px' } }), state('expanded', style({ width: '100%' })), transition('collapsed <=> expanded', [animate('0.3s ease-out')]) ]) ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ToolbarSearchComponent, decorators: [{ type: Component, args: [{ selector: 'ux-toolbar-search', template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, animations: [ trigger('expanded', [ state('collapsed', style({ width: '{{initialWidth}}' }), { params: { initialWidth: '30px' } }), state('expanded', style({ width: '100%' })), transition('collapsed <=> expanded', [animate('0.3s ease-out')]) ]) ], host: { '[class.expanded]': 'expanded', '[class.left]': 'direction === "left"', '[class.right]': 'direction === "right"', '[class.inverse]': 'inverse', '[style.position]': '_position', '[style.background-color]': '_backgroundColor', '[@expanded]': '_expandedAnimation' } }] }], propDecorators: { direction: [{ type: Input }], inverse: [{ type: Input }], alwaysExpanded: [{ type: Input }], expanded: [{ type: Input }], background: [{ type: Input }], expandedChange: [{ type: Output }], search: [{ type: Output }], field: [{ type: ContentChild, args: [ToolbarSearchFieldDirective, { static: true }] }], button: [{ type: ContentChild, args: [ToolbarSearchButtonDirective, { static: false }] }], animationStart: [{ type: HostListener, args: ['@expanded.start', ['$event']] }], animationDone: [{ type: HostListener, args: ['@expanded.done', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbGJhci1zZWFyY2guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdG9vbGJhci1zZWFyY2gvdG9vbGJhci1zZWFyY2guY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQWtCLEtBQUssRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFBb0IsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JNLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNqRixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQzs7QUEwQi9FLE1BQU0sT0FBTyxzQkFBc0I7SUF4Qm5DO1FBeUJxQixnQkFBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUVsQyxnQkFBVyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUVqQyxrQkFBYSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVyQyxjQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRS9DLDJJQUEySTtRQUNsSSxjQUFTLEdBQXFCLE9BQU8s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QVU7d0JBQzlCLGNBQWMsRUFBRSxzQkFBc0I7d0JBQ3RDLGVBQWUsRUFBRSx1QkFBdUI7d0JBQ3hDLGlCQUFpQixFQUFFLFNBQVM7d0JBQzVCLGtCQUFrQixFQUFFLFdBQVc7d0JBQy9CLDBCQUEwQixFQUFFLGtCQUFrQjt3QkFDOUMsYUFBYSxFQUFFLG9CQUFvQjtxQkFDdEM7aUJBQ0o7OEJBV1ksU0FBUztzQkFBakIsS0FBSztnQkFHRyxPQUFPO3NCQUFmLEtBQUs7Z0JBR0csY0FBYztzQkFBdEIsS0FBSztnQkFJRixRQUFRO3NCQURYLEtBQUs7Z0JBMkJGLFVBQVU7c0JBRGIsS0FBSztnQkFNSSxjQUFjO3NCQUF2QixNQUFNO2dCQU1HLE1BQU07c0JBQWYsTUFBTTtnQkFhc0QsS0FBSztzQkFBakUsWUFBWTt1QkFBQywyQkFBMkIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBR0ksTUFBTTtzQkFBcEUsWUFBWTt1QkFBQyw0QkFBNEIsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBcUQ3RCxjQUFjO3NCQURiLFlBQVk7dUJBQUMsaUJBQWlCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBUzNDLGFBQWE7c0JBRFosWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGFuaW1hdGUsIEFuaW1hdGlvbkV2ZW50LCBzdGF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIHRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQWZ0ZXJDb250ZW50SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgQ29udGVudENoaWxkLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIEhvc3RMaXN0ZW5lciwgaW5qZWN0LCBJbnB1dCwgT25EZXN0cm95LCBPdXRwdXQsIFBMQVRGT1JNX0lELCBSZW5kZXJlcjIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENvbG9yU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2NvbG9yL2NvbG9yLnNlcnZpY2UnO1xuaW1wb3J0IHsgVG9vbGJhclNlYXJjaEJ1dHRvbkRpcmVjdGl2ZSB9IGZyb20gJy4vdG9vbGJhci1zZWFyY2gtYnV0dG9uLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBUb29sYmFyU2VhcmNoRmllbGREaXJlY3RpdmUgfSBmcm9tICcuL3Rvb2xiYXItc2VhcmNoLWZpZWxkLmRpcmVjdGl2ZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAndXgtdG9vbGJhci1zZWFyY2gnLFxuICAgIHRlbXBsYXRlOiAnPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PicsXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgYW5pbWF0aW9uczogW1xuICAgICAgICB0cmlnZ2VyKCdleHBhbmRlZCcsIFtcbiAgICAgICAgICAgIHN0YXRlKCdjb2xsYXBzZWQnLFxuICAgICAgICAgICAgICAgIHN0eWxlKHsgd2lkdGg6ICd7e2luaXRpYWxXaWR0aH19JyB9KSxcbiAgICAgICAgICAgICAgICB7IHBhcmFtczogeyBpbml0aWFsV2lkdGg6ICczMHB4JyB9IH1cbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBzdGF0ZSgnZXhwYW5kZWQnLCBzdHlsZSh7IHdpZHRoOiAnMTAwJScgfSkpLFxuICAgICAgICAgICAgdHJhbnNpdGlvbignY29sbGFwc2VkIDw9PiBleHBhbmRlZCcsIFthbmltYXRlKCcwLjNzIGVhc2Utb3V0JyldKVxuICAgICAgICBdKVxuICAgIF0sXG4gICAgaG9zdDoge1xuICAgICAgICAnW2NsYXNzLmV4cGFuZGVkXSc6ICdleHBhbmRlZCcsXG4gICAgICAgICdbY2xhc3MubGVmdF0nOiAnZGlyZWN0aW9uID09PSBcImxlZnRcIicsXG4gICAgICAgICdbY2xhc3MucmlnaHRdJzogJ2RpcmVjdGlvbiA9PT0gXCJyaWdodFwiJyxcbiAgICAgICAgJ1tjbGFzcy5pbnZlcnNlXSc6ICdpbnZlcnNlJyxcbiAgICAgICAgJ1tzdHlsZS5wb3NpdGlvbl0nOiAnX3Bvc2l0aW9uJyxcbiAgICAgICAgJ1tzdHlsZS5iYWNrZ3JvdW5kLWNvbG9yXSc6ICdfYmFja2dyb3VuZENvbG9yJyxcbiAgICAgICAgJ1tAZXhwYW5kZWRdJzogJ19leHBhbmRlZEFuaW1hdGlvbidcbiAgICB9XG59KVxuZXhwb3J0IGNsYXNzIFRvb2xiYXJTZWFyY2hDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3BsYXRmb3JtSWQgPSBpbmplY3QoUExBVEZPUk1fSUQpO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBfZWxlbWVudFJlZiA9IGluamVjdChFbGVtZW50UmVmKTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NvbG9yU2VydmljZSA9IGluamVjdChDb2xvclNlcnZpY2UpO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcmVuZGVyZXIgPSBpbmplY3QoUmVuZGVyZXIyKTtcblxuICAgIC8qKiBUaGUgZGlyZWN0aW9uIGluIHdoaWNoIHRoZSBzZWFyY2ggYm94IHdpbGwgZXhwYW5kLiBJZiB0aGUgc2VhcmNoIGJ1dHRvbiBpcyBhbGlnbmVkIHRvIHRoZSByaWdodCBlZGdlIG9mIHRoZSBjb250YWluZXIsIHNwZWNpZnkgbGVmdC4gKi9cbiAgICBASW5wdXQoKSBkaXJlY3Rpb246ICdsZWZ0JyB8ICdyaWdodCcgPSAncmlnaHQnO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIGNvbG9yIHNjaGVtZSBpcyBpbnZlcnRlZC4gRm9yIHVzZSB3aGVuIHRoZSBjb21wb25lbnQgaXMgaG9zdGVkIG9uIGEgZGFyayBiYWNrZ3JvdW5kLCBlLmcuIHRoZSBtYXN0aGVhZC4gKi9cbiAgICBASW5wdXQoKSBpbnZlcnNlID0gZmFsc2U7XG5cbiAgICAvKiogSW5kaWNhdGUgd2hldGhlciBvciBub3QgdGhlIHNlYXJjaCBmaWVsZCBzaG91bGQgYWx3YXlzIGJlIGV4cGFuZGVkICovXG4gICAgQElucHV0KCkgYWx3YXlzRXhwYW5kZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBXaGV0aGVyIHRoZSBpbnB1dCBmaWVsZCBpcyB2aXNpYmxlLiBVc2UgdGhpcyB0byBjb2xsYXBzZSBvciBleHBhbmQgdGhlIGNvbnRyb2wgaW4gcmVzcG9uc2UgdG8gb3RoZXIgZXZlbnRzLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgc2V0IGV4cGFuZGVkKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuX2V4cGFuZGVkID0gdmFsdWU7XG5cbiAgICAgICAgdGhpcy5leHBhbmRlZENoYW5nZS5lbWl0KHRoaXMuZXhwYW5kZWQpO1xuXG4gICAgICAgIGlmICh0aGlzLmV4cGFuZGVkKSB7XG4gICAgICAgICAgICAvLyBTZXQgZm9jdXMgb24gdGhlIGlucHV0IHdoZW4gZXhwYW5kZWRcbiAgICAgICAgICAgIHRoaXMuZmllbGQuZm9jdXMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIENsZWFyIHRleHQgd2hlbiBjb250cmFjdGVkXG4gICAgICAgICAgICB0aGlzLmZpZWxkLmNsZWFyKCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBmb2N1cyAod29ya3MgYXJvdW5kIGFuIElFIGlzc3VlIHdoZXJlIHRoZSBjYXJldCByZW1haW5zIHZpc2libGUpXG4gICAgICAgICAgICB0aGlzLmZpZWxkLmJsdXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBleHBhbmRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWx3YXlzRXhwYW5kZWQgfHwgdGhpcy5fZXhwYW5kZWQ7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBUaGUgYmFja2dyb3VuZCBjb2xvciBvZiB0aGUgY29tcG9uZW50LiBDb2xvciBuYW1lcyBmcm9tIHRoZSBDb2xvciBQYWxldHRlIGNhbiBiZSB1c2VkIGhlcmUuXG4gICAgICogU3BlY2lmeSB0aGlzIHdoZW4gYSB0cmFuc3BhcmVudCBiYWNrZ3JvdW5kIHdvdWxkIGNhdXNlIGRpc3BsYXkgaXNzdWVzLCBzdWNoIGFzIGJhY2tncm91bmQgaXRlbXMgc2hvd2luZyB0aHJvdWdoIHRoZSBzZWFyY2ggZmllbGQuXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBzZXQgYmFja2dyb3VuZCh2YWx1ZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX2JhY2tncm91bmRDb2xvciA9IHRoaXMuX2NvbG9yU2VydmljZS5yZXNvbHZlKHZhbHVlKSB8fCAndHJhbnNwYXJlbnQnO1xuICAgIH1cblxuICAgIC8qKiBFbWl0dGVkIHdoZW4gdGhlIGV4cGFuZGVkIHN0YXRlIGNoYW5nZXMgKi9cbiAgICBAT3V0cHV0KCkgZXhwYW5kZWRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIHdoZW4gYSBzZWFyY2ggcXVlcnkgaGFzIGJlZW4gc3VibWl0dGVkLCBlaXRoZXIgYnkgcHJlc3NpbmcgZW50ZXIgd2hlbiB0aGUgc2VhcmNoIGZpZWxkIGhhcyBmb2N1cywgb3IgYnkgY2xpY2tpbmcgdGhlIHNlYXJjaCBidXR0b25cbiAgICAgKiB3aGVuIHRoZSBzZWFyY2ggZmllbGQgY29udGFpbnMgdGV4dC4gVGhlIGV2ZW50IGNvbnRhaW5zIHRoZSBzZWFyY2ggdGV4dC5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgc2VhcmNoID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgICAvKiogUmV0dXJuIHRoZSBjb3JyZWN0IGFuaW1hdGlvbiBiYXNlZCBvbiB0aGUgZXhwYW5kZWQgc3RhdGUgKi9cbiAgICBnZXQgX2V4cGFuZGVkQW5pbWF0aW9uKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsdWU6IHRoaXMuZXhwYW5kZWQgPyAnZXhwYW5kZWQnIDogJ2NvbGxhcHNlZCcsXG4gICAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgICAgICBpbml0aWFsV2lkdGg6IHRoaXMuYnV0dG9uLndpZHRoICsgJ3B4J1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKiBBY2Nlc3MgdGhlIGlucHV0IGZpZWxkIGVsZW1lbnQgKi9cbiAgICBAQ29udGVudENoaWxkKFRvb2xiYXJTZWFyY2hGaWVsZERpcmVjdGl2ZSwgeyBzdGF0aWM6IHRydWUgfSkgZmllbGQ6IFRvb2xiYXJTZWFyY2hGaWVsZERpcmVjdGl2ZTtcblxuICAgIC8qKiBBY2Nlc3MgdGhlIHNlYXJjaCBidXR0b24gZWxlbWVudCAqL1xuICAgIEBDb250ZW50Q2hpbGQoVG9vbGJhclNlYXJjaEJ1dHRvbkRpcmVjdGl2ZSwgeyBzdGF0aWM6IGZhbHNlIH0pIGJ1dHRvbjogVG9vbGJhclNlYXJjaEJ1dHRvbkRpcmVjdGl2ZTtcblxuICAgIC8qKiBTdG9yZSB0aGUgQ1NTIHBvc2l0aW9uIHZhbHVlIGFzIHRoaXMgbWF5IGNoYW5nZSB0byBhYnNvbHV0ZSAqL1xuICAgIF9wb3NpdGlvbjogc3RyaW5nID0gJ3JlbGF0aXZlJztcblxuICAgIC8qKiBTdG9yZSB0aGUgYWN0aXZlIGJhY2tncm91bmQgY29sb3IgKi9cbiAgICBfYmFja2dyb3VuZENvbG9yOiBzdHJpbmcgPSAndHJhbnNwYXJlbnQnO1xuXG4gICAgLyoqIFN0b3JlIHRoZSBleHBhbmRlZCBzdGF0ZSAqL1xuICAgIHByaXZhdGUgX2V4cGFuZGVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKiogU3RvcmUgdGhlIHByb2dyYW1tYXRpY2FsbHkgY3JlYXRlZCBwbGFjZWhvbGRlciBlbGVtZW50ICovXG4gICAgcHJpdmF0ZSBfcGxhY2Vob2xkZXI6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqIFVuc3Vic2NyaWJlIGZyb20gYWxsIHN1YnNjcmlwdGlvbnMgb24gY29tcG9uZW50IGRlc3Ryb3kgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgICAgICAvLyBTdWJzY3JpYmUgdG8gdGhlIHN1Ym1pdHRlZCBldmVudCBvbiB0aGUgaW5wdXQgZmllbGQsIHRyaWdnZXJpbmcgdGhlIHNlYXJjaCBldmVudFxuICAgICAgICB0aGlzLmZpZWxkLnN1Ym1pdHRlZC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKS5zdWJzY3JpYmUoKHRleHQ6IHN0cmluZykgPT4gdGhpcy5zZWFyY2guZW1pdCh0ZXh0KSk7XG5cbiAgICAgICAgLy8gU3Vic2NyaWJlIHRvIGNhbmNlbCBldmVudHMgY29taW5nIGZyb20gdGhlIGlucHV0IGZpZWxkXG4gICAgICAgIHRoaXMuZmllbGQuY2FuY2VsLnBpcGUodGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSkpLnN1YnNjcmliZSgoKSA9PiB0aGlzLmV4cGFuZGVkID0gZmFsc2UpO1xuXG4gICAgICAgIC8vIFN1YnNjcmliZSB0byB0aGUgYnV0dG9uIGNsaWNrIGV2ZW50XG4gICAgICAgIHRoaXMuYnV0dG9uLmNsaWNrZWQucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZXhwYW5kZWQgJiYgdGhpcy5maWVsZC50ZXh0ID8gdGhpcy5zZWFyY2guZW1pdCh0aGlzLmZpZWxkLnRleHQpIDogdGhpcy5leHBhbmRlZCA9ICF0aGlzLmV4cGFuZGVkO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDcmVhdGUgcGxhY2Vob2xkZXIgZWxlbWVudCB0byBhdm9pZCBjaGFuZ2luZyBsYXlvdXQgd2hlbiBzd2l0Y2hpbmcgdG8gcG9zaXRpb246IGFic29sdXRlXG4gICAgICAgIC8vIElmIHRoZSBwbGF0Zm9ybSBpcyBhIHNlcnZlciB3ZSBkb250IHdhbnQgdG8gZG8gdGhpcyBhcyB3ZSBjYW4ndCBhY2Nlc3MgZ2V0Q29tcHV0ZWRTdHlsZVxuICAgICAgICBpZiAoIWlzUGxhdGZvcm1TZXJ2ZXIodGhpcy5fcGxhdGZvcm1JZCkpIHtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlUGxhY2Vob2xkZXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9vbkRlc3Ryb3kubmV4dCgpO1xuICAgICAgICB0aGlzLl9vbkRlc3Ryb3kuY29tcGxldGUoKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogV2UgcHJvZ3JhbW1hdGljYWxseSBjcmVhdGVkIHRoZSBwbGFjZWhvbGRlciBub2RlIHNvIEFuZ3VsYXIgaXMgbm90IGF3YXJlIG9mIGl0cyBleGlzdGVuY2VcbiAgICAgICAgICogc28gd2UgbXVzdCBtYW51YWxseSBkZXN0cm95IGl0IG90aGVyd2lzZSB0aGUgcmVmZXJlbmNlIHdpbGwgYmUgcmV0YWluZWQuXG4gICAgICAgICAqIE5vdGUsIHRoZSBgZGVzdHJveU5vZGVgIGZ1bmN0aW9uIG1heSBiZSBudWxsIG9yIHVuZGVmaW5lZCBhcyBtZW50aW9uZWQgaW4gdGhlXG4gICAgICAgICAqIEFuZ3VsYXIgQVBJIGRvY3MgKGh0dHBzOi8vYW5ndWxhci5pby9hcGkvY29yZS9SZW5kZXJlcjIjZGVzdHJveU5vZGUpIHNvXG4gICAgICAgICAqIHdlIG11c3QgY2hlY2sgdGhhdCB0aGUgZnVuY3Rpb24gaXMgYXZhaWxhYmxlIGJlZm9yZSBhdHRlbXB0aW5nIHRvIGNhbGwgaXRcbiAgICAgICAgICovXG4gICAgICAgIGlmICh0aGlzLl9wbGFjZWhvbGRlciAmJiB0aGlzLl9yZW5kZXJlciAmJiB0aGlzLl9yZW5kZXJlci5kZXN0cm95Tm9kZSkge1xuICAgICAgICAgICAgdGhpcy5fcmVuZGVyZXIuZGVzdHJveU5vZGUodGhpcy5fcGxhY2Vob2xkZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignQGV4cGFuZGVkLnN0YXJ0JywgWyckZXZlbnQnXSlcbiAgICBhbmltYXRpb25TdGFydChldmVudDogQW5pbWF0aW9uRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKGV2ZW50LnRvU3RhdGUgPT09ICdleHBhbmRlZCcpIHtcbiAgICAgICAgICAgIHRoaXMuX3Bvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgICAgIHRoaXMuc2V0UGxhY2Vob2xkZXJWaXNpYmxlKHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignQGV4cGFuZGVkLmRvbmUnLCBbJyRldmVudCddKVxuICAgIGFuaW1hdGlvbkRvbmUoZXZlbnQ6IEFuaW1hdGlvbkV2ZW50KTogdm9pZCB7XG4gICAgICAgIGlmIChldmVudC50b1N0YXRlID09PSAnY29sbGFwc2VkJykge1xuICAgICAgICAgICAgdGhpcy5fcG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgICAgICAgICAgdGhpcy5zZXRQbGFjZWhvbGRlclZpc2libGUoZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFByb2dyYW1tYXRpY2FsbHkgY3JlYXRlIGEgcGxhY2Vob2xkZXIgZWxlbWVudCAqL1xuICAgIHByaXZhdGUgY3JlYXRlUGxhY2Vob2xkZXIoKTogdm9pZCB7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGludmlzaWJsZSBkaXYgd2l0aCB0aGUgc2FtZSBkaW1lbnNpb25zXG4gICAgICAgIHRoaXMuX3BsYWNlaG9sZGVyID0gdGhpcy5fcmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLnNldFN0eWxlKHRoaXMuX3BsYWNlaG9sZGVyLCAnZGlzcGxheScsICdub25lJyk7XG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLnNldFN0eWxlKHRoaXMuX3BsYWNlaG9sZGVyLCAnd2lkdGgnLCB0aGlzLmJ1dHRvbi53aWR0aCArICdweCcpO1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5zZXRTdHlsZSh0aGlzLl9wbGFjZWhvbGRlciwgJ3Zpc2liaWxpdHknLCAnaGlkZGVuJyk7XG4gICAgICAgIHRoaXMuc2V0UGxhY2Vob2xkZXJIZWlnaHQoKTtcblxuICAgICAgICAvLyBBZGQgYXMgYSBzaWJsaW5nXG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLmluc2VydEJlZm9yZSh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucGFyZW50Tm9kZSwgdGhpcy5fcGxhY2Vob2xkZXIsIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgLyoqIFVwZGF0ZSB0aGUgZGlzcGxheSBzdGF0ZSBvZiB0aGUgcGxhY2Vob2xkZXIgbm9kZSAqL1xuICAgIHByaXZhdGUgc2V0UGxhY2Vob2xkZXJWaXNpYmxlKGlzVmlzaWJsZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuX3BsYWNlaG9sZGVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWNhbGN1bGF0ZSB0aGUgaGVpZ2h0IHNpbmNlIHRoZSBsYXlvdXQgbWlnaHQgbm90IGJlIGNvbXBsZXRlIHdoZW4gaW5pdGlhbGx5IGNyZWF0ZWQuXG4gICAgICAgIGlmIChpc1Zpc2libGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0UGxhY2Vob2xkZXJIZWlnaHQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLnNldFN0eWxlKHRoaXMuX3BsYWNlaG9sZGVyLCAnZGlzcGxheScsIGlzVmlzaWJsZSA/ICdpbmxpbmUtYmxvY2snIDogJ25vbmUnKTtcbiAgICB9XG5cbiAgICAvKiogU2V0IHRoZSBwbGFjZWhvbGRlciBoZWlnaHQgdG8gbWF0Y2ggdGhlIGhlaWdodCBvZiB0aGlzIGNvbXBvbmVudC4gKi9cbiAgICBwcml2YXRlIHNldFBsYWNlaG9sZGVySGVpZ2h0KCk6IHZvaWQge1xuICAgICAgICBjb25zdCB7IGhlaWdodCB9ID0gZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5zZXRTdHlsZSh0aGlzLl9wbGFjZWhvbGRlciwgJ2hlaWdodCcsIGhlaWdodCk7XG4gICAgfVxufVxuIl19