UNPKG

carbon-components-angular

Version:
309 lines 34.9 kB
import { Component, Input, EventEmitter, Output, HostBinding, HostListener, ViewChild } from "@angular/core"; import { NG_VALUE_ACCESSOR } from "@angular/forms"; import * as i0 from "@angular/core"; import * as i1 from "carbon-components-angular/i18n"; import * as i2 from "@angular/common"; import * as i3 from "carbon-components-angular/icon"; /** * Get started with importing the module: * * ```typescript * import { SearchModule } from 'carbon-components-angular'; * ``` * * [See demo](../../?path=/story/components-search--basic) */ export class Search { /** * Creates an instance of `Search`. * @param i18n The i18n translations. */ constructor(elementRef, i18n) { this.elementRef = elementRef; this.i18n = i18n; /** * @deprecated since v5 - Use `cdsLayer` directive instead * `light` or `dark` search theme. */ this.theme = "dark"; /** * Size of the search field. */ this.size = "md"; /** * Set to `true` for a disabled search input. */ this.disabled = false; /** * Set to `true` for a toolbar search component. */ this.toolbar = false; /** * Set to `true` to make the search component expandable. * `expandable` would override `toolbar` property behaviours. */ this.expandable = false; /** * Set to `true` for a loading search component. */ this.skeleton = false; /** * Set to `true` to expand the toolbar search component. */ this.active = false; /** * Specifies whether the search component is used in the table toolbar. */ this.tableSearch = false; /** * The unique id for the search component. */ this.id = `search-${Search.searchCount}`; /** * Sets the value attribute on the `input` element. */ this.value = ""; /** * Sets the autocomplete attribute on the `input` element. * For reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#Values */ this.autocomplete = "on"; /** * Sets the text inside the `label` tag. */ this.label = this.i18n.get().SEARCH.LABEL; /** * Sets the placeholder attribute on the `input` element. */ this.placeholder = this.i18n.get().SEARCH.PLACEHOLDER; /** * Used to set the `title` attribute of the clear button. */ this.clearButtonTitle = this.i18n.get().SEARCH.CLEAR_BUTTON; /** * Title for the search trigger */ this.searchTitle = ""; /** * Emits an event when value is changed. */ this.valueChange = new EventEmitter(); this.open = new EventEmitter(); /** * Emits an event when the clear button is clicked. */ this.clear = new EventEmitter(); /** * Emits an event on enter. */ this.search = new EventEmitter(); /** * Sets `true` when composing text via IME. */ this.isComposing = false; /** * Called when search input is blurred. Needed to properly implement `ControlValueAccessor`. */ this.onTouched = () => { }; /** * Method set in `registerOnChange` to propagate changes back to the form. */ this.propagateChange = (_) => { }; Search.searchCount++; } get containerClass() { return !(this.toolbar || this.expandable); } /** * This is the initial value set to the component * @param value The input value. */ writeValue(value) { this.value = value; } /** * Sets a method in order to propagate changes back to the form. */ registerOnChange(fn) { this.propagateChange = fn; } /** * Registers a callback to be triggered when the control has been touched. * @param fn Callback to be triggered when the search input is touched. */ registerOnTouched(fn) { this.onTouched = fn; } /** * Called when text is written in the input. * @param search The input text. */ onSearch(search) { if (this.isComposing) { // check for IME use return; } this.value = search; this.doValueChange(); } /** * Called on enter. */ onEnter() { this.search.emit(this.value); } /** * Called when clear button is clicked. */ clearSearch() { this.value = ""; this.clear.emit(); this.propagateChange(this.value); } doValueChange() { this.valueChange.emit(this.value); this.propagateChange(this.value); } openSearch() { this.active = true; this.open.emit(this.active); setTimeout(() => this.inputRef.nativeElement.focus()); } keyDown(event) { if (this.toolbar || this.expandable) { if (event.key === "Escape") { if (this.value === "") { this.active = false; this.open.emit(this.active); } } else if (event.key === "Enter") { this.openSearch(); } } if (event.key === "Escape") { if (this.value !== "") { this.clearSearch(); } } } focusOut(event) { this.onTouched(); if ((this.expandable || this.toolbar) && this.inputRef && this.inputRef.nativeElement.value === "" && !this.elementRef.nativeElement.contains(event.relatedTarget)) { this.active = false; this.open.emit(this.active); } } focusIn(event) { this.onTouched(); // set input focus if search icon get focus from tab key press event. if ((this.expandable || this.toolbar) && this.inputRef && !event.relatedTarget && !this.elementRef.nativeElement.contains(event.relatedTarget)) { this.openSearch(); } } /** * Called when using IME composition. */ compositionStart(event) { this.isComposing = true; } /** * Called when IME composition finishes. */ compositionEnd(event) { this.isComposing = false; this.onSearch(this.value + event.data); } } /** * Variable used for creating unique ids for search components. */ Search.searchCount = 0; Search.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Search, deps: [{ token: i0.ElementRef }, { token: i1.I18n }], target: i0.ɵɵFactoryTarget.Component }); Search.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Search, selector: "cds-search, ibm-search", inputs: { theme: "theme", size: "size", disabled: "disabled", toolbar: "toolbar", expandable: "expandable", skeleton: "skeleton", active: "active", tableSearch: "tableSearch", name: "name", id: "id", required: "required", value: "value", autocomplete: "autocomplete", label: "label", placeholder: "placeholder", clearButtonTitle: "clearButtonTitle", searchTitle: "searchTitle", ariaLabel: "ariaLabel" }, outputs: { valueChange: "valueChange", open: "open", clear: "clear", search: "search" }, host: { listeners: { "keydown": "keyDown($event)", "focusout": "focusOut($event)", "focusin": "focusIn($event)", "compositionstart": "compositionStart($event)", "compositionend": "compositionEnd($event)" }, properties: { "class.cds--form-item": "this.containerClass" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: Search, multi: true } ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div\n\tclass=\"cds--search\"\n\t[ngClass]=\"{\n\t\t'cds--search--sm': size === 'sm',\n\t\t'cds--search--md': size === 'md',\n\t\t'cds--search--lg': size === 'lg',\n\t\t'cds--search--light': theme === 'light',\n\t\t'cds--skeleton': skeleton,\n\t\t'cds--search--expandable': expandable && !tableSearch,\n\t\t'cds--search--expanded': expandable && !tableSearch && active,\n\t\t'cds--toolbar-search': toolbar && !expandable,\n\t\t'cds--toolbar-search--active': toolbar && !expandable && active,\n\t\t'cds--toolbar-search-container-persistent': tableSearch && !expandable,\n\t\t'cds--toolbar-search-container-expandable': tableSearch && expandable,\n\t\t'cds--toolbar-search-container-active': tableSearch && expandable && active\n\t}\"\n\trole=\"search\"\n\t[attr.aria-label]=\"ariaLabel\"\n\t(click)=\"openSearch()\">\n\t<label class=\"cds--label\" [for]=\"id\">{{label}}</label>\n\n\t<div *ngIf=\"skeleton; else enableInput\" class=\"cds--search-input\"></div>\n\t<ng-template #enableInput>\n\t\t<input\n\t\t\t#input\n\t\t\tclass=\"cds--search-input\"\n\t\t\t[type]=\"tableSearch || !toolbar ? 'text' : 'search'\"\n\t\t\t[id]=\"id\"\n\t\t\t[value]=\"value\"\n\t\t\t[autocomplete]=\"autocomplete\"\n\t\t\t[placeholder]=\"placeholder\"\n\t\t\t[disabled]=\"disabled\"\n\t\t\t[required]=\"required\"\n\t\t\t(input)=\"onSearch($event.target.value)\"\n\t\t\t(keyup.enter)=\"onEnter()\"/>\n\t\t<button\n\t\t\t*ngIf=\"!tableSearch && toolbar\"\n\t\t\tclass=\"cds--toolbar-search__btn\"\n\t\t\t(click)=\"openSearch()\"\n\t\t\taria-label=\"Open search\">\n\t\t\t<svg cdsIcon=\"search\" size=\"16\" class=\"cds--search-magnifier-icon\"></svg>\n\t\t</button>\n\t\t<svg\n\t\t\tcdsIcon=\"search\"\n\t\t\t*ngIf=\"tableSearch || !toolbar\"\n\t\t\tclass=\"cds--search-magnifier-icon\"\n\t\t\tsize=\"16\">\n\t\t</svg>\n\t</ng-template>\n\n\t<button\n\t\t*ngIf=\"tableSearch || !toolbar\"\n\t\tclass=\"cds--search-close\"\n\t\t[ngClass]=\"{\n\t\t\t'cds--search-close--hidden': !value || value.length === 0\n\t\t}\"\n\t\t[title]=\"clearButtonTitle\"\n\t\t(click)=\"clearSearch()\">\n\t\t<span class=\"cds--visually-hidden\">{{ clearButtonTitle }}</span>\n\t\t<svg cdsIcon=\"close\" size=\"16\"></svg>\n\t</button>\n</div>\n", dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Search, decorators: [{ type: Component, args: [{ selector: "cds-search, ibm-search", providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: Search, multi: true } ], template: "<div\n\tclass=\"cds--search\"\n\t[ngClass]=\"{\n\t\t'cds--search--sm': size === 'sm',\n\t\t'cds--search--md': size === 'md',\n\t\t'cds--search--lg': size === 'lg',\n\t\t'cds--search--light': theme === 'light',\n\t\t'cds--skeleton': skeleton,\n\t\t'cds--search--expandable': expandable && !tableSearch,\n\t\t'cds--search--expanded': expandable && !tableSearch && active,\n\t\t'cds--toolbar-search': toolbar && !expandable,\n\t\t'cds--toolbar-search--active': toolbar && !expandable && active,\n\t\t'cds--toolbar-search-container-persistent': tableSearch && !expandable,\n\t\t'cds--toolbar-search-container-expandable': tableSearch && expandable,\n\t\t'cds--toolbar-search-container-active': tableSearch && expandable && active\n\t}\"\n\trole=\"search\"\n\t[attr.aria-label]=\"ariaLabel\"\n\t(click)=\"openSearch()\">\n\t<label class=\"cds--label\" [for]=\"id\">{{label}}</label>\n\n\t<div *ngIf=\"skeleton; else enableInput\" class=\"cds--search-input\"></div>\n\t<ng-template #enableInput>\n\t\t<input\n\t\t\t#input\n\t\t\tclass=\"cds--search-input\"\n\t\t\t[type]=\"tableSearch || !toolbar ? 'text' : 'search'\"\n\t\t\t[id]=\"id\"\n\t\t\t[value]=\"value\"\n\t\t\t[autocomplete]=\"autocomplete\"\n\t\t\t[placeholder]=\"placeholder\"\n\t\t\t[disabled]=\"disabled\"\n\t\t\t[required]=\"required\"\n\t\t\t(input)=\"onSearch($event.target.value)\"\n\t\t\t(keyup.enter)=\"onEnter()\"/>\n\t\t<button\n\t\t\t*ngIf=\"!tableSearch && toolbar\"\n\t\t\tclass=\"cds--toolbar-search__btn\"\n\t\t\t(click)=\"openSearch()\"\n\t\t\taria-label=\"Open search\">\n\t\t\t<svg cdsIcon=\"search\" size=\"16\" class=\"cds--search-magnifier-icon\"></svg>\n\t\t</button>\n\t\t<svg\n\t\t\tcdsIcon=\"search\"\n\t\t\t*ngIf=\"tableSearch || !toolbar\"\n\t\t\tclass=\"cds--search-magnifier-icon\"\n\t\t\tsize=\"16\">\n\t\t</svg>\n\t</ng-template>\n\n\t<button\n\t\t*ngIf=\"tableSearch || !toolbar\"\n\t\tclass=\"cds--search-close\"\n\t\t[ngClass]=\"{\n\t\t\t'cds--search-close--hidden': !value || value.length === 0\n\t\t}\"\n\t\t[title]=\"clearButtonTitle\"\n\t\t(click)=\"clearSearch()\">\n\t\t<span class=\"cds--visually-hidden\">{{ clearButtonTitle }}</span>\n\t\t<svg cdsIcon=\"close\" size=\"16\"></svg>\n\t</button>\n</div>\n" }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.I18n }]; }, propDecorators: { containerClass: [{ type: HostBinding, args: ["class.cds--form-item"] }], theme: [{ type: Input }], size: [{ type: Input }], disabled: [{ type: Input }], toolbar: [{ type: Input }], expandable: [{ type: Input }], skeleton: [{ type: Input }], active: [{ type: Input }], tableSearch: [{ type: Input }], name: [{ type: Input }], id: [{ type: Input }], required: [{ type: Input }], value: [{ type: Input }], autocomplete: [{ type: Input }], label: [{ type: Input }], placeholder: [{ type: Input }], clearButtonTitle: [{ type: Input }], searchTitle: [{ type: Input }], ariaLabel: [{ type: Input }], valueChange: [{ type: Output }], open: [{ type: Output }], clear: [{ type: Output }], search: [{ type: Output }], inputRef: [{ type: ViewChild, args: ["input"] }], keyDown: [{ type: HostListener, args: ["keydown", ["$event"]] }], focusOut: [{ type: HostListener, args: ["focusout", ["$event"]] }], focusIn: [{ type: HostListener, args: ["focusin", ["$event"]] }], compositionStart: [{ type: HostListener, args: ["compositionstart", ["$event"]] }], compositionEnd: [{ type: HostListener, args: ["compositionend", ["$event"]] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZWFyY2gvc2VhcmNoLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3NyYy9zZWFyY2gvc2VhcmNoLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTixTQUFTLEVBQ1QsS0FBSyxFQUNMLFlBQVksRUFDWixNQUFNLEVBQ04sV0FBVyxFQUVYLFlBQVksRUFDWixTQUFTLEVBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGlCQUFpQixFQUF3QixNQUFNLGdCQUFnQixDQUFDOzs7OztBQUd6RTs7Ozs7Ozs7R0FRRztBQVlILE1BQU0sT0FBTyxNQUFNO0lBNEdsQjs7O09BR0c7SUFDSCxZQUFzQixVQUFzQixFQUFZLElBQVU7UUFBNUMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUFZLFNBQUksR0FBSixJQUFJLENBQU07UUF0R2xFOzs7V0FHRztRQUNNLFVBQUssR0FBcUIsTUFBTSxDQUFDO1FBRTFDOztXQUVHO1FBQ00sU0FBSSxHQUF1QixJQUFJLENBQUM7UUFFekM7O1dBRUc7UUFDTSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQzFCOztXQUVHO1FBQ00sWUFBTyxHQUFHLEtBQUssQ0FBQztRQUN6Qjs7O1dBR0c7UUFDTSxlQUFVLEdBQUcsS0FBSyxDQUFDO1FBQzVCOztXQUVHO1FBQ00sYUFBUSxHQUFHLEtBQUssQ0FBQztRQUMxQjs7V0FFRztRQUNNLFdBQU0sR0FBRyxLQUFLLENBQUM7UUFDeEI7O1dBRUc7UUFDTSxnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUs3Qjs7V0FFRztRQUNNLE9BQUUsR0FBRyxVQUFVLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUs3Qzs7V0FFRztRQUNNLFVBQUssR0FBRyxFQUFFLENBQUM7UUFDcEI7OztXQUdHO1FBQ00saUJBQVksR0FBRyxJQUFJLENBQUM7UUFDN0I7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c0JBQW5CLEtBQUs7Z0JBSUcsSUFBSTtzQkFBWixLQUFLO2dCQUlHLEVBQUU7c0JBQVYsS0FBSztnQkFJRyxRQUFRO3NCQUFoQixLQUFLO2dCQUlHLEtBQUs7c0JBQWIsS0FBSztnQkFLRyxZQUFZO3NCQUFwQixLQUFLO2dCQUlHLEtBQUs7c0JBQWIsS0FBSztnQkFJRyxXQUFXO3NCQUFuQixLQUFLO2dCQUlHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFJRyxXQUFXO3NCQUFuQixLQUFLO2dCQUlHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBSUksV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxJQUFJO3NCQUFiLE1BQU07Z0JBSUcsS0FBSztzQkFBZCxNQUFNO2dCQUlHLE1BQU07c0JBQWYsTUFBTTtnQkFFYSxRQUFRO3NCQUEzQixTQUFTO3VCQUFDLE9BQU87Z0JBd0ZsQixPQUFPO3NCQUROLFlBQVk7dUJBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQXFCbkMsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFhcEMsT0FBTztzQkFETixZQUFZO3VCQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFlbkMsZ0JBQWdCO3NCQURmLFlBQVk7dUJBQUMsa0JBQWtCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBUzVDLGNBQWM7c0JBRGIsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0SW5wdXQsXG5cdEV2ZW50RW1pdHRlcixcblx0T3V0cHV0LFxuXHRIb3N0QmluZGluZyxcblx0RWxlbWVudFJlZixcblx0SG9zdExpc3RlbmVyLFxuXHRWaWV3Q2hpbGRcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IE5HX1ZBTFVFX0FDQ0VTU09SLCBDb250cm9sVmFsdWVBY2Nlc3NvciB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHsgSTE4biB9IGZyb20gXCJjYXJib24tY29tcG9uZW50cy1hbmd1bGFyL2kxOG5cIjtcblxuLyoqXG4gKiBHZXQgc3RhcnRlZCB3aXRoIGltcG9ydGluZyB0aGUgbW9kdWxlOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFNlYXJjaE1vZHVsZSB9IGZyb20gJ2NhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXInO1xuICogYGBgXG4gKlxuICogW1NlZSBkZW1vXSguLi8uLi8/cGF0aD0vc3RvcnkvY29tcG9uZW50cy1zZWFyY2gtLWJhc2ljKVxuICovXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6IFwiY2RzLXNlYXJjaCwgaWJtLXNlYXJjaFwiLFxuXHR0ZW1wbGF0ZVVybDogXCJzZWFyY2guY29tcG9uZW50Lmh0bWxcIixcblx0cHJvdmlkZXJzOiBbXG5cdFx0e1xuXHRcdFx0cHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG5cdFx0XHR1c2VFeGlzdGluZzogU2VhcmNoLFxuXHRcdFx0bXVsdGk6IHRydWVcblx0XHR9XG5cdF1cbn0pXG5leHBvcnQgY2xhc3MgU2VhcmNoIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuXHQvKipcblx0ICogVmFyaWFibGUgdXNlZCBmb3IgY3JlYXRpbmcgdW5pcXVlIGlkcyBmb3Igc2VhcmNoIGNvbXBvbmVudHMuXG5cdCAqL1xuXHRzdGF0aWMgc2VhcmNoQ291bnQgPSAwO1xuXG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tZm9ybS1pdGVtXCIpIGdldCBjb250YWluZXJDbGFzcygpIHtcblx0XHRyZXR1cm4gISh0aGlzLnRvb2xiYXIgfHwgdGhpcy5leHBhbmRhYmxlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAZGVwcmVjYXRlZCBzaW5jZSB2NSAtIFVzZSBgY2RzTGF5ZXJgIGRpcmVjdGl2ZSBpbnN0ZWFkXG5cdCAqIGBsaWdodGAgb3IgYGRhcmtgIHNlYXJjaCB0aGVtZS5cblx0ICovXG5cdEBJbnB1dCgpIHRoZW1lOiBcImxpZ2h0XCIgfCBcImRhcmtcIiA9IFwiZGFya1wiO1xuXG5cdC8qKlxuXHQgKiBTaXplIG9mIHRoZSBzZWFyY2ggZmllbGQuXG5cdCAqL1xuXHRASW5wdXQoKSBzaXplOiBcInNtXCIgfCBcIm1kXCIgfCBcImxnXCIgPSBcIm1kXCI7XG5cblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgZm9yIGEgZGlzYWJsZWQgc2VhcmNoIGlucHV0LlxuXHQgKi9cblx0QElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgZm9yIGEgdG9vbGJhciBzZWFyY2ggY29tcG9uZW50LlxuXHQgKi9cblx0QElucHV0KCkgdG9vbGJhciA9IGZhbHNlO1xuXHQvKipcblx0ICogU2V0IHRvIGB0cnVlYCB0byBtYWtlIHRoZSBzZWFyY2ggY29tcG9uZW50IGV4cGFuZGFibGUuXG5cdCAqIGBleHBhbmRhYmxlYCB3b3VsZCBvdmVycmlkZSBgdG9vbGJhcmAgcHJvcGVydHkgYmVoYXZpb3Vycy5cblx0ICovXG5cdEBJbnB1dCgpIGV4cGFuZGFibGUgPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgZm9yIGEgbG9hZGluZyBzZWFyY2ggY29tcG9uZW50LlxuXHQgKi9cblx0QElucHV0KCkgc2tlbGV0b24gPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgdG8gZXhwYW5kIHRoZSB0b29sYmFyIHNlYXJjaCBjb21wb25lbnQuXG5cdCAqL1xuXHRASW5wdXQoKSBhY3RpdmUgPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNwZWNpZmllcyB3aGV0aGVyIHRoZSBzZWFyY2ggY29tcG9uZW50IGlzIHVzZWQgaW4gdGhlIHRhYmxlIHRvb2xiYXIuXG5cdCAqL1xuXHRASW5wdXQoKSB0YWJsZVNlYXJjaCA9IGZhbHNlO1xuXHQvKipcblx0ICogU2V0cyB0aGUgbmFtZSBhdHRyaWJ1dGUgb24gdGhlIGBpbnB1dGAgZWxlbWVudC5cblx0ICovXG5cdEBJbnB1dCgpIG5hbWU6IHN0cmluZztcblx0LyoqXG5cdCAqIFRoZSB1bmlxdWUgaWQgZm9yIHRoZSBzZWFyY2ggY29tcG9uZW50LlxuXHQgKi9cblx0QElucHV0KCkgaWQgPSBgc2VhcmNoLSR7U2VhcmNoLnNlYXJjaENvdW50fWA7XG5cdC8qKlxuXHQgKiBSZWZsZWN0cyB0aGUgcmVxdWlyZWQgYXR0cmlidXRlIG9mIHRoZSBgaW5wdXRgIGVsZW1lbnQuXG5cdCAqL1xuXHRASW5wdXQoKSByZXF1aXJlZDogYm9vbGVhbjtcblx0LyoqXG5cdCAqIFNldHMgdGhlIHZhbHVlIGF0dHJpYnV0ZSBvbiB0aGUgYGlucHV0YCBlbGVtZW50LlxuXHQgKi9cblx0QElucHV0KCkgdmFsdWUgPSBcIlwiO1xuXHQvKipcblx0ICogU2V0cyB0aGUgYXV0b2NvbXBsZXRlIGF0dHJpYnV0ZSBvbiB0aGUgYGlucHV0YCBlbGVtZW50LlxuXHQgKiBGb3IgcmVmZXJlbmNlOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0F0dHJpYnV0ZXMvYXV0b2NvbXBsZXRlI1ZhbHVlc1xuXHQgKi9cblx0QElucHV0KCkgYXV0b2NvbXBsZXRlID0gXCJvblwiO1xuXHQvKipcblx0ICogU2V0cyB0aGUgdGV4dCBpbnNpZGUgdGhlIGBsYWJlbGAgdGFnLlxuXHQgKi9cblx0QElucHV0KCkgbGFiZWwgPSB0aGlzLmkxOG4uZ2V0KCkuU0VBUkNILkxBQkVMO1xuXHQvKipcblx0ICogU2V0cyB0aGUgcGxhY2Vob2xkZXIgYXR0cmlidXRlIG9uIHRoZSBgaW5wdXRgIGVsZW1lbnQuXG5cdCAqL1xuXHRASW5wdXQoKSBwbGFjZWhvbGRlciA9IHRoaXMuaTE4bi5nZXQoKS5TRUFSQ0guUExBQ0VIT0xERVI7XG5cdC8qKlxuXHQgKiBVc2VkIHRvIHNldCB0aGUgYHRpdGxlYCBhdHRyaWJ1dGUgb2YgdGhlIGNsZWFyIGJ1dHRvbi5cblx0ICovXG5cdEBJbnB1dCgpIGNsZWFyQnV0dG9uVGl0bGUgPSB0aGlzLmkxOG4uZ2V0KCkuU0VBUkNILkNMRUFSX0JVVFRPTjtcblx0LyoqXG5cdCAqIFRpdGxlIGZvciB0aGUgc2VhcmNoIHRyaWdnZXJcblx0ICovXG5cdEBJbnB1dCgpIHNlYXJjaFRpdGxlID0gXCJcIjtcblx0LyoqXG5cdCAqIFNldHMgdGhlIGFyaWEgbGFiZWwgb24gdGhlIGBkaXZgIGVsZW1lbnQgd2l0aCB0aGUgYHNlYXJjaGAgcm9sZS5cblx0ICovXG5cdEBJbnB1dCgpIGFyaWFMYWJlbDogc3RyaW5nO1xuXHQvKipcblx0ICogRW1pdHMgYW4gZXZlbnQgd2hlbiB2YWx1ZSBpcyBjaGFuZ2VkLlxuXHQgKi9cblx0QE91dHB1dCgpIHZhbHVlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cdEBPdXRwdXQoKSBvcGVuID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXHQvKipcblx0ICogRW1pdHMgYW4gZXZlbnQgd2hlbiB0aGUgY2xlYXIgYnV0dG9uIGlzIGNsaWNrZWQuXG5cdCAqL1xuXHRAT3V0cHV0KCkgY2xlYXIgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cdC8qKlxuXHQgKiBFbWl0cyBhbiBldmVudCBvbiBlbnRlci5cblx0ICovXG5cdEBPdXRwdXQoKSBzZWFyY2ggPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuXHRAVmlld0NoaWxkKFwiaW5wdXRcIikgaW5wdXRSZWY6IEVsZW1lbnRSZWY7XG5cblx0LyoqXG5cdCAqIFNldHMgYHRydWVgIHdoZW4gY29tcG9zaW5nIHRleHQgdmlhIElNRS5cblx0ICovXG5cdHByb3RlY3RlZCBpc0NvbXBvc2luZyA9IGZhbHNlO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGBTZWFyY2hgLlxuXHQgKiBAcGFyYW0gaTE4biBUaGUgaTE4biB0cmFuc2xhdGlvbnMuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgZWxlbWVudFJlZjogRWxlbWVudFJlZiwgcHJvdGVjdGVkIGkxOG46IEkxOG4pIHtcblx0XHRTZWFyY2guc2VhcmNoQ291bnQrKztcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGlzIGlzIHRoZSBpbml0aWFsIHZhbHVlIHNldCB0byB0aGUgY29tcG9uZW50XG5cdCAqIEBwYXJhbSB2YWx1ZSBUaGUgaW5wdXQgdmFsdWUuXG5cdCAqL1xuXHRwdWJsaWMgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KSB7XG5cdFx0dGhpcy52YWx1ZSA9IHZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgYSBtZXRob2QgaW4gb3JkZXIgdG8gcHJvcGFnYXRlIGNoYW5nZXMgYmFjayB0byB0aGUgZm9ybS5cblx0ICovXG5cdHB1YmxpYyByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpIHtcblx0XHR0aGlzLnByb3BhZ2F0ZUNoYW5nZSA9IGZuO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlZ2lzdGVycyBhIGNhbGxiYWNrIHRvIGJlIHRyaWdnZXJlZCB3aGVuIHRoZSBjb250cm9sIGhhcyBiZWVuIHRvdWNoZWQuXG5cdCAqIEBwYXJhbSBmbiBDYWxsYmFjayB0byBiZSB0cmlnZ2VyZWQgd2hlbiB0aGUgc2VhcmNoIGlucHV0IGlzIHRvdWNoZWQuXG5cdCAqL1xuXHRwdWJsaWMgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSkge1xuXHRcdHRoaXMub25Ub3VjaGVkID0gZm47XG5cdH1cblxuXHQvKipcblx0ICogQ2FsbGVkIHdoZW4gc2VhcmNoIGlucHV0IGlzIGJsdXJyZWQuIE5lZWRlZCB0byBwcm9wZXJseSBpbXBsZW1lbnQgYENvbnRyb2xWYWx1ZUFjY2Vzc29yYC5cblx0ICovXG5cdG9uVG91Y2hlZDogKCkgPT4gYW55ID0gKCkgPT4ge307XG5cblx0LyoqXG5cdCAqIE1ldGhvZCBzZXQgaW4gYHJlZ2lzdGVyT25DaGFuZ2VgIHRvIHByb3BhZ2F0ZSBjaGFuZ2VzIGJhY2sgdG8gdGhlIGZvcm0uXG5cdCAqL1xuXHRwcm9wYWdhdGVDaGFuZ2UgPSAoXzogYW55KSA9PiB7fTtcblxuXHQvKipcblx0ICogQ2FsbGVkIHdoZW4gdGV4dCBpcyB3cml0dGVuIGluIHRoZSBpbnB1dC5cblx0ICogQHBhcmFtIHNlYXJjaCBUaGUgaW5wdXQgdGV4dC5cblx0ICovXG5cdG9uU2VhcmNoKHNlYXJjaDogc3RyaW5nKSB7XG5cdFx0aWYgKHRoaXMuaXNDb21wb3NpbmcpIHsgLy8gY2hlY2sgZm9yIElNRSB1c2Vcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy52YWx1ZSA9IHNlYXJjaDtcblx0XHR0aGlzLmRvVmFsdWVDaGFuZ2UoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDYWxsZWQgb24gZW50ZXIuXG5cdCAqL1xuXHRvbkVudGVyKCkge1xuXHRcdHRoaXMuc2VhcmNoLmVtaXQodGhpcy52YWx1ZSk7XG5cdH1cblxuXHQvKipcblx0ICogQ2FsbGVkIHdoZW4gY2xlYXIgYnV0dG9uIGlzIGNsaWNrZWQuXG5cdCAqL1xuXHRjbGVhclNlYXJjaCgpOiB2b2lkIHtcblx0XHR0aGlzLnZhbHVlID0gXCJcIjtcblx0XHR0aGlzLmNsZWFyLmVtaXQoKTtcblx0XHR0aGlzLnByb3BhZ2F0ZUNoYW5nZSh0aGlzLnZhbHVlKTtcblx0fVxuXG5cdGRvVmFsdWVDaGFuZ2UoKSB7XG5cdFx0dGhpcy52YWx1ZUNoYW5nZS5lbWl0KHRoaXMudmFsdWUpO1xuXHRcdHRoaXMucHJvcGFnYXRlQ2hhbmdlKHRoaXMudmFsdWUpO1xuXHR9XG5cblx0b3BlblNlYXJjaCgpIHtcblx0XHR0aGlzLmFjdGl2ZSA9IHRydWU7XG5cdFx0dGhpcy5vcGVuLmVtaXQodGhpcy5hY3RpdmUpO1xuXHRcdHNldFRpbWVvdXQoKCkgPT4gdGhpcy5pbnB1dFJlZi5uYXRpdmVFbGVtZW50LmZvY3VzKCkpO1xuXHR9XG5cblx0QEhvc3RMaXN0ZW5lcihcImtleWRvd25cIiwgW1wiJGV2ZW50XCJdKVxuXHRrZXlEb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG5cdFx0aWYgKHRoaXMudG9vbGJhciB8fCB0aGlzLmV4cGFuZGFibGUpIHtcblx0XHRcdGlmIChldmVudC5rZXkgPT09IFwiRXNjYXBlXCIpIHtcblx0XHRcdFx0aWYgKHRoaXMudmFsdWUgPT09IFwiXCIpIHtcblx0XHRcdFx0XHR0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuXHRcdFx0XHRcdHRoaXMub3Blbi5lbWl0KHRoaXMuYWN0aXZlKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIGlmIChldmVudC5rZXkgPT09IFwiRW50ZXJcIikge1xuXHRcdFx0XHR0aGlzLm9wZW5TZWFyY2goKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZXZlbnQua2V5ID09PSBcIkVzY2FwZVwiKSB7XG5cdFx0XHRpZiAodGhpcy52YWx1ZSAhPT0gXCJcIikge1xuXHRcdFx0XHR0aGlzLmNsZWFyU2VhcmNoKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0QEhvc3RMaXN0ZW5lcihcImZvY3Vzb3V0XCIsIFtcIiRldmVudFwiXSlcblx0Zm9jdXNPdXQoZXZlbnQpIHtcblx0XHR0aGlzLm9uVG91Y2hlZCgpO1xuXHRcdGlmICgodGhpcy5leHBhbmRhYmxlIHx8IHRoaXMudG9vbGJhcikgJiZcblx0XHRcdHRoaXMuaW5wdXRSZWYgJiZcblx0XHRcdHRoaXMuaW5wdXRSZWYubmF0aXZlRWxlbWVudC52YWx1ZSA9PT0gXCJcIiAmJlxuXHRcdFx0ISh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCkuY29udGFpbnMoZXZlbnQucmVsYXRlZFRhcmdldCkpIHtcblx0XHRcdHRoaXMuYWN0aXZlID0gZmFsc2U7XG5cdFx0XHR0aGlzLm9wZW4uZW1pdCh0aGlzLmFjdGl2ZSk7XG5cdFx0fVxuXHR9XG5cblx0QEhvc3RMaXN0ZW5lcihcImZvY3VzaW5cIiwgW1wiJGV2ZW50XCJdKVxuXHRmb2N1c0luKGV2ZW50KSB7XG5cdFx0dGhpcy5vblRvdWNoZWQoKTtcblx0XHQvLyBzZXQgaW5wdXQgZm9jdXMgaWYgc2VhcmNoIGljb24gZ2V0IGZvY3VzIGZyb20gdGFiIGtleSBwcmVzcyBldmVudC5cblx0XHRpZiAoKHRoaXMuZXhwYW5kYWJsZSB8fCB0aGlzLnRvb2xiYXIpICYmXG5cdFx0XHR0aGlzLmlucHV0UmVmICYmICFldmVudC5yZWxhdGVkVGFyZ2V0ICYmXG5cdFx0XHQhKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50KS5jb250YWlucyhldmVudC5yZWxhdGVkVGFyZ2V0KSApIHtcblx0XHRcdHRoaXMub3BlblNlYXJjaCgpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDYWxsZWQgd2hlbiB1c2luZyBJTUUgY29tcG9zaXRpb24uXG5cdCAqL1xuXHRASG9zdExpc3RlbmVyKFwiY29tcG9zaXRpb25zdGFydFwiLCBbXCIkZXZlbnRcIl0pXG5cdGNvbXBvc2l0aW9uU3RhcnQoZXZlbnQpIHtcblx0XHR0aGlzLmlzQ29tcG9zaW5nID0gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDYWxsZWQgd2hlbiBJTUUgY29tcG9zaXRpb24gZmluaXNoZXMuXG5cdCAqL1xuXHRASG9zdExpc3RlbmVyKFwiY29tcG9zaXRpb25lbmRcIiwgW1wiJGV2ZW50XCJdKVxuXHRjb21wb3NpdGlvbkVuZChldmVudCkge1xuXHRcdHRoaXMuaXNDb21wb3NpbmcgPSBmYWxzZTtcblx0XHR0aGlzLm9uU2VhcmNoKHRoaXMudmFsdWUgKyBldmVudC5kYXRhKTtcblx0fVxufVxuIiwiPGRpdlxuXHRjbGFzcz1cImNkcy0tc2VhcmNoXCJcblx0W25nQ2xhc3NdPVwie1xuXHRcdCdjZHMtLXNlYXJjaC0tc20nOiBzaXplID09PSAnc20nLFxuXHRcdCdjZHMtLXNlYXJjaC0tbWQnOiBzaXplID09PSAnbWQnLFxuXHRcdCdjZHMtLXNlYXJjaC0tbGcnOiBzaXplID09PSAnbGcnLFxuXHRcdCdjZHMtLXNlYXJjaC0tbGlnaHQnOiB0aGVtZSA9PT0gJ2xpZ2h0Jyxcblx0XHQnY2RzLS1za2VsZXRvbic6IHNrZWxldG9uLFxuXHRcdCdjZHMtLXNlYXJjaC0tZXhwYW5kYWJsZSc6IGV4cGFuZGFibGUgJiYgIXRhYmxlU2VhcmNoLFxuXHRcdCdjZHMtLXNlYXJjaC0tZXhwYW5kZWQnOiBleHBhbmRhYmxlICYmICF0YWJsZVNlYXJjaCAmJiBhY3RpdmUsXG5cdFx0J2Nkcy0tdG9vbGJhci1zZWFyY2gnOiB0b29sYmFyICYmICFleHBhbmRhYmxlLFxuXHRcdCdjZHMtLXRvb2xiYXItc2VhcmNoLS1hY3RpdmUnOiB0b29sYmFyICYmICFleHBhbmRhYmxlICYmIGFjdGl2ZSxcblx0XHQnY2RzLS10b29sYmFyLXNlYXJjaC1jb250YWluZXItcGVyc2lzdGVudCc6IHRhYmxlU2VhcmNoICYmICFleHBhbmRhYmxlLFxuXHRcdCdjZHMtLXRvb2xiYXItc2VhcmNoLWNvbnRhaW5lci1leHBhbmRhYmxlJzogdGFibGVTZWFyY2ggJiYgZXhwYW5kYWJsZSxcblx0XHQnY2RzLS10b29sYmFyLXNlYXJjaC1jb250YWluZXItYWN0aXZlJzogdGFibGVTZWFyY2ggJiYgZXhwYW5kYWJsZSAmJiBhY3RpdmVcblx0fVwiXG5cdHJvbGU9XCJzZWFyY2hcIlxuXHRbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbFwiXG5cdChjbGljayk9XCJvcGVuU2VhcmNoKClcIj5cblx0PGxhYmVsIGNsYXNzPVwiY2RzLS1sYWJlbFwiIFtmb3JdPVwiaWRcIj57e2xhYmVsfX08L2xhYmVsPlxuXG5cdDxkaXYgKm5nSWY9XCJza2VsZXRvbjsgZWxzZSBlbmFibGVJbnB1dFwiIGNsYXNzPVwiY2RzLS1zZWFyY2gtaW5wdXRcIj48L2Rpdj5cblx0PG5nLXRlbXBsYXRlICNlbmFibGVJbnB1dD5cblx0XHQ8aW5wdXRcblx0XHRcdCNpbnB1dFxuXHRcdFx0Y2xhc3M9XCJjZHMtLXNlYXJjaC1pbnB1dFwiXG5cdFx0XHRbdHlwZV09XCJ0YWJsZVNlYXJjaCB8fCAhdG9vbGJhciA/ICd0ZXh0JyA6ICdzZWFyY2gnXCJcblx0XHRcdFtpZF09XCJpZFwiXG5cdFx0XHRbdmFsdWVdPVwidmFsdWVcIlxuXHRcdFx0W2F1dG9jb21wbGV0ZV09XCJhdXRvY29tcGxldGVcIlxuXHRcdFx0W3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcblx0XHRcdFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG5cdFx0XHRbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuXHRcdFx0KGlucHV0KT1cIm9uU2VhcmNoKCRldmVudC50YXJnZXQudmFsdWUpXCJcblx0XHRcdChrZXl1cC5lbnRlcik9XCJvbkVudGVyKClcIi8+XG5cdFx0PGJ1dHRvblxuXHRcdFx0Km5nSWY9XCIhdGFibGVTZWFyY2ggJiYgdG9vbGJhclwiXG5cdFx0XHRjbGFzcz1cImNkcy0tdG9vbGJhci1zZWFyY2hfX2J0blwiXG5cdFx0XHQoY2xpY2spPVwib3BlblNlYXJjaCgpXCJcblx0XHRcdGFyaWEtbGFiZWw9XCJPcGVuIHNlYXJjaFwiPlxuXHRcdFx0PHN2ZyBjZHNJY29uPVwic2VhcmNoXCIgc2l6ZT1cIjE2XCIgY2xhc3M9XCJjZHMtLXNlYXJjaC1tYWduaWZpZXItaWNvblwiPjwvc3ZnPlxuXHRcdDwvYnV0dG9uPlxuXHRcdDxzdmdcblx0XHRcdGNkc0ljb249XCJzZWFyY2hcIlxuXHRcdFx0Km5nSWY9XCJ0YWJsZVNlYXJjaCB8fCAhdG9vbGJhclwiXG5cdFx0XHRjbGFzcz1cImNkcy0tc2VhcmNoLW1hZ25pZmllci1pY29uXCJcblx0XHRcdHNpemU9XCIxNlwiPlxuXHRcdDwvc3ZnPlxuXHQ8L25nLXRlbXBsYXRlPlxuXG5cdDxidXR0b25cblx0XHQqbmdJZj1cInRhYmxlU2VhcmNoIHx8ICF0b29sYmFyXCJcblx0XHRjbGFzcz1cImNkcy0tc2VhcmNoLWNsb3NlXCJcblx0XHRbbmdDbGFzc109XCJ7XG5cdFx0XHQnY2RzLS1zZWFyY2gtY2xvc2UtLWhpZGRlbic6ICF2YWx1ZSB8fCB2YWx1ZS5sZW5ndGggPT09IDBcblx0XHR9XCJcblx0XHRbdGl0bGVdPVwiY2xlYXJCdXR0b25UaXRsZVwiXG5cdFx0KGNsaWNrKT1cImNsZWFyU2VhcmNoKClcIj5cblx0XHQ8c3BhbiBjbGFzcz1cImNkcy0tdmlzdWFsbHktaGlkZGVuXCI+e3sgY2xlYXJCdXR0b25UaXRsZSB9fTwvc3Bhbj5cblx0XHQ8c3ZnIGNkc0ljb249XCJjbG9zZVwiIHNpemU9XCIxNlwiPjwvc3ZnPlxuXHQ8L2J1dHRvbj5cbjwvZGl2PlxuIl19