@alfresco/adf-content-services
Version:
Alfresco ADF content services
133 lines • 35.4 kB
JavaScript
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component, inject, Input, ViewEncapsulation } from '@angular/core';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { SearchFacetFiltersService } from '../../services/search-facet-filters.service';
import { TranslationService } from '@alfresco/adf-core';
import { Subject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { TranslateModule } from '@ngx-translate/core';
import { FormsModule } from '@angular/forms';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/material/button";
import * as i3 from "@angular/material/icon";
import * as i4 from "@angular/material/form-field";
import * as i5 from "@angular/material/input";
import * as i6 from "@ngx-translate/core";
import * as i7 from "@angular/forms";
import * as i8 from "@angular/material/checkbox";
export class SearchFacetFieldComponent {
constructor() {
this.queryBuilder = inject(SearchQueryBuilderService);
this.searchFacetFiltersService = inject(SearchFacetFiltersService);
this.translationService = inject(TranslationService);
this.displayValue$ = new Subject();
}
get canUpdateOnChange() {
return this.field.settings?.allowUpdateOnChange ?? true;
}
onToggleBucket(event, field, bucket) {
if (event && bucket) {
if (event.checked) {
this.selectFacetBucket(field, bucket);
}
else {
this.unselectFacetBucket(field, bucket);
}
}
}
selectFacetBucket(field, bucket) {
if (bucket) {
bucket.checked = true;
this.queryBuilder.addUserFacetBucket(field.field, bucket);
this.searchFacetFiltersService.updateSelectedBuckets();
if (this.canUpdateOnChange) {
this.updateDisplayValue();
this.queryBuilder.update();
}
}
}
unselectFacetBucket(field, bucket) {
if (bucket) {
bucket.checked = false;
this.queryBuilder.removeUserFacetBucket(field.field, bucket);
this.searchFacetFiltersService.updateSelectedBuckets();
if (this.canUpdateOnChange) {
this.updateDisplayValue();
this.queryBuilder.update();
}
}
}
canResetSelectedBuckets(field) {
if (field?.buckets) {
return field.buckets.items.some((bucket) => bucket.checked);
}
return false;
}
resetSelectedBuckets(field) {
if (field?.buckets) {
for (const bucket of field.buckets.items) {
bucket.checked = false;
this.queryBuilder.removeUserFacetBucket(field.field, bucket);
}
this.searchFacetFiltersService.updateSelectedBuckets();
if (this.canUpdateOnChange) {
this.queryBuilder.update();
}
}
}
getBucketCountDisplay(bucket) {
return bucket.count === null ? '' : `(${bucket.count})`;
}
updateDisplayValue() {
if (!this.field.buckets?.items) {
this.displayValue$.next('');
}
else {
const displayValue = this.field.buckets?.items
?.filter((item) => item.checked)
.map((item) => this.translationService.instant(item.display || item.label))
.join(', ');
this.displayValue$.next(displayValue);
}
}
reset() {
this.resetSelectedBuckets(this.field);
this.updateDisplayValue();
this.queryBuilder.update();
}
submitValues() {
this.updateDisplayValue();
this.queryBuilder.update();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SearchFacetFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: SearchFacetFieldComponent, isStandalone: true, selector: "adf-search-facet-field", inputs: { field: "field" }, ngImport: i0, template: "<div class=\"adf-search-filter-facet\">\n <div class=\"adf-facet-result-filter\">\n <div class=\"adf-facet-search-container\">\n <button mat-icon-button class=\"adf-facet-search-icon\" tabindex=\"-1\">\n <mat-icon class=\"adf-search-field-icon\">search</mat-icon>\n </button>\n <mat-form-field class=\"adf-facet-search-field\" subscriptSizing=\"dynamic\">\n <input\n matInput\n placeholder=\"{{ 'SEARCH.FILTER.ACTIONS.SEARCH' | translate }}\"\n [attr.data-automation-id]=\"'facet-result-filter-' + field.label\"\n [(ngModel)]=\"field.buckets.filterText\"\n />\n <button\n *ngIf=\"field.buckets.filterText\"\n matSuffix\n mat-icon-button\n [attr.title]=\"'SEARCH.FILTER.BUTTONS.CLEAR' | translate\"\n (click)=\"field.buckets.filterText = ''\"\n >\n <mat-icon role=\"button\" [attr.aria-label]=\"'SEARCH.FILTER.BUTTONS.CLEAR' | translate\">clear</mat-icon>\n </button>\n </mat-form-field>\n </div>\n </div>\n\n <div class=\"adf-checklist\">\n <mat-checkbox\n *ngFor=\"let bucket of field.buckets\"\n [checked]=\"bucket.checked\"\n [attr.data-automation-id]=\"'checkbox-' + field.label + '-' + (bucket.display || bucket.label)\"\n (change)=\"onToggleBucket($event, field, bucket)\"\n class=\"adf-search-filter-facet-checkbox\"\n >\n <div\n title=\"{{ bucket.display || bucket.label | translate }} {{ getBucketCountDisplay(bucket) }}\"\n class=\"adf-facet-label\"\n [class.adf-search-filter-facet-checkbox-checked]=\"bucket.checked\"\n >\n {{ bucket.display || bucket.label | translate }} {{ getBucketCountDisplay(bucket) }}\n </div>\n </mat-checkbox>\n </div>\n\n <div class=\"adf-facet-buttons\" *ngIf=\"field.buckets.fitsPage && !field.settings?.hideDefaultAction\">\n <button *ngIf=\"canResetSelectedBuckets(field)\" mat-button color=\"primary\" (click)=\"resetSelectedBuckets(field)\">\n {{ 'SEARCH.FILTER.ACTIONS.CLEAR-ALL' | translate }}\n </button>\n </div>\n\n <div class=\"adf-facet-buttons\" *ngIf=\"!field.buckets.fitsPage\">\n <button\n mat-icon-button\n *ngIf=\"canResetSelectedBuckets(field)\"\n title=\"{{ 'SEARCH.FILTER.ACTIONS.CLEAR-ALL' | translate }}\"\n (click)=\"resetSelectedBuckets(field)\"\n >\n <mat-icon>clear</mat-icon>\n </button>\n <button\n mat-icon-button\n *ngIf=\"field.buckets.canShowLessItems\"\n (click)=\"field.buckets.showLessItems()\"\n title=\"{{ 'SEARCH.FILTER.ACTIONS.SHOW-LESS' | translate }}\"\n >\n <mat-icon>keyboard_arrow_up</mat-icon>\n </button>\n <button\n mat-icon-button\n *ngIf=\"field.buckets.canShowMoreItems\"\n (click)=\"field.buckets.showMoreItems()\"\n title=\"{{ 'SEARCH.FILTER.ACTIONS.SHOW-MORE' | translate }}\"\n >\n <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n </div>\n</div>\n", styles: [".adf-search-filter-facet .adf-checklist{display:flex;flex-direction:column;max-height:180px;padding:5px 0;overflow-y:auto}.adf-search-filter-facet .adf-checklist .adf-search-filter-facet-checkbox{margin:5px}.adf-search-filter-facet .adf-checklist .adf-search-filter-facet-checkbox .adf-search-filter-facet-checkbox-checked{font-weight:700}.adf-search-filter-facet .adf-facet-result-filter{padding-bottom:16px}.adf-search-filter-facet .adf-facet-result-filter .adf-facet-search-container{border-radius:6px;background:var(--theme-background-color);display:flex;height:32px}.adf-search-filter-facet .adf-facet-result-filter .adf-facet-search-container .adf-facet-search-icon{width:27px;margin-top:-3px}.adf-search-filter-facet .adf-facet-result-filter .adf-facet-search-container .adf-facet-search-icon .adf-search-field-icon{font-size:var(--theme-subheading-1-font-size)}.adf-search-filter-facet .adf-facet-result-filter .adf-facet-search-container .adf-facet-search-field{padding:2px;flex:1;margin-top:-16px;font-size:var(--theme-body-1-font-size);line-height:24px;letter-spacing:.25px}.adf-search-filter-facet .adf-facet-buttons{text-align:right}.adf-search-filter-facet .adf-facet-buttons button{text-transform:uppercase}.adf-search-filter-facet .adf-facet-buttons--topSpace{padding-top:15px}.adf-search-filter-facet .adf-facet-label{color:var(--adf-theme-foreground-text-color-054)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i8.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SearchFacetFieldComponent, decorators: [{
type: Component,
args: [{ selector: 'adf-search-facet-field', standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatFormFieldModule, MatInputModule, TranslateModule, FormsModule, MatCheckboxModule], encapsulation: ViewEncapsulation.None, template: "<div class=\"adf-search-filter-facet\">\n <div class=\"adf-facet-result-filter\">\n <div class=\"adf-facet-search-container\">\n <button mat-icon-button class=\"adf-facet-search-icon\" tabindex=\"-1\">\n <mat-icon class=\"adf-search-field-icon\">search</mat-icon>\n </button>\n <mat-form-field class=\"adf-facet-search-field\" subscriptSizing=\"dynamic\">\n <input\n matInput\n placeholder=\"{{ 'SEARCH.FILTER.ACTIONS.SEARCH' | translate }}\"\n [attr.data-automation-id]=\"'facet-result-filter-' + field.label\"\n [(ngModel)]=\"field.buckets.filterText\"\n />\n <button\n *ngIf=\"field.buckets.filterText\"\n matSuffix\n mat-icon-button\n [attr.title]=\"'SEARCH.FILTER.BUTTONS.CLEAR' | translate\"\n (click)=\"field.buckets.filterText = ''\"\n >\n <mat-icon role=\"button\" [attr.aria-label]=\"'SEARCH.FILTER.BUTTONS.CLEAR' | translate\">clear</mat-icon>\n </button>\n </mat-form-field>\n </div>\n </div>\n\n <div class=\"adf-checklist\">\n <mat-checkbox\n *ngFor=\"let bucket of field.buckets\"\n [checked]=\"bucket.checked\"\n [attr.data-automation-id]=\"'checkbox-' + field.label + '-' + (bucket.display || bucket.label)\"\n (change)=\"onToggleBucket($event, field, bucket)\"\n class=\"adf-search-filter-facet-checkbox\"\n >\n <div\n title=\"{{ bucket.display || bucket.label | translate }} {{ getBucketCountDisplay(bucket) }}\"\n class=\"adf-facet-label\"\n [class.adf-search-filter-facet-checkbox-checked]=\"bucket.checked\"\n >\n {{ bucket.display || bucket.label | translate }} {{ getBucketCountDisplay(bucket) }}\n </div>\n </mat-checkbox>\n </div>\n\n <div class=\"adf-facet-buttons\" *ngIf=\"field.buckets.fitsPage && !field.settings?.hideDefaultAction\">\n <button *ngIf=\"canResetSelectedBuckets(field)\" mat-button color=\"primary\" (click)=\"resetSelectedBuckets(field)\">\n {{ 'SEARCH.FILTER.ACTIONS.CLEAR-ALL' | translate }}\n </button>\n </div>\n\n <div class=\"adf-facet-buttons\" *ngIf=\"!field.buckets.fitsPage\">\n <button\n mat-icon-button\n *ngIf=\"canResetSelectedBuckets(field)\"\n title=\"{{ 'SEARCH.FILTER.ACTIONS.CLEAR-ALL' | translate }}\"\n (click)=\"resetSelectedBuckets(field)\"\n >\n <mat-icon>clear</mat-icon>\n </button>\n <button\n mat-icon-button\n *ngIf=\"field.buckets.canShowLessItems\"\n (click)=\"field.buckets.showLessItems()\"\n title=\"{{ 'SEARCH.FILTER.ACTIONS.SHOW-LESS' | translate }}\"\n >\n <mat-icon>keyboard_arrow_up</mat-icon>\n </button>\n <button\n mat-icon-button\n *ngIf=\"field.buckets.canShowMoreItems\"\n (click)=\"field.buckets.showMoreItems()\"\n title=\"{{ 'SEARCH.FILTER.ACTIONS.SHOW-MORE' | translate }}\"\n >\n <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n </div>\n</div>\n", styles: [".adf-search-filter-facet .adf-checklist{display:flex;flex-direction:column;max-height:180px;padding:5px 0;overflow-y:auto}.adf-search-filter-facet .adf-checklist .adf-search-filter-facet-checkbox{margin:5px}.adf-search-filter-facet .adf-checklist .adf-search-filter-facet-checkbox .adf-search-filter-facet-checkbox-checked{font-weight:700}.adf-search-filter-facet .adf-facet-result-filter{padding-bottom:16px}.adf-search-filter-facet .adf-facet-result-filter .adf-facet-search-container{border-radius:6px;background:var(--theme-background-color);display:flex;height:32px}.adf-search-filter-facet .adf-facet-result-filter .adf-facet-search-container .adf-facet-search-icon{width:27px;margin-top:-3px}.adf-search-filter-facet .adf-facet-result-filter .adf-facet-search-container .adf-facet-search-icon .adf-search-field-icon{font-size:var(--theme-subheading-1-font-size)}.adf-search-filter-facet .adf-facet-result-filter .adf-facet-search-container .adf-facet-search-field{padding:2px;flex:1;margin-top:-16px;font-size:var(--theme-body-1-font-size);line-height:24px;letter-spacing:.25px}.adf-search-filter-facet .adf-facet-buttons{text-align:right}.adf-search-filter-facet .adf-facet-buttons button{text-transform:uppercase}.adf-search-filter-facet .adf-facet-buttons--topSpace{padding-top:15px}.adf-search-filter-facet .adf-facet-label{color:var(--adf-theme-foreground-text-color-054)}\n"] }]
}], propDecorators: { field: [{
type: Input,
args: [{ required: true }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLWZhY2V0LWZpZWxkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYi9jb250ZW50LXNlcnZpY2VzL3NyYy9saWIvc2VhcmNoL2NvbXBvbmVudHMvc2VhcmNoLWZhY2V0LWZpZWxkL3NlYXJjaC1mYWNldC1maWVsZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWIvY29udGVudC1zZXJ2aWNlcy9zcmMvbGliL3NlYXJjaC9jb21wb25lbnRzL3NlYXJjaC1mYWNldC1maWVsZC9zZWFyY2gtZmFjZXQtZmllbGQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTVFLE9BQU8sRUFBcUIsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVsRixPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUN4RixPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUV4RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFP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QUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRCxZQUFZO1FBQ1IsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUMvQixDQUFDOzhHQTdGUSx5QkFBeUI7a0dBQXpCLHlCQUF5Qiw4R0MxQ3RDLDAyR0E2RUEsbTZDRHhDYyxZQUFZLCtQQUFFLGVBQWUsd1VBQUUsYUFBYSxtTEFBRSxrQkFBa0IsMFdBQUUsY0FBYywwV0FBRSxlQUFlLDJGQUFFLFdBQVcsOG1CQUFFLGlCQUFpQjs7MkZBS2xJLHlCQUF5QjtrQkFSckMsU0FBUzsrQkFDSSx3QkFBd0IsY0FDdEIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsaUJBQWlCLENBQUMsaUJBRzdILGlCQUFpQixDQUFDLElBQUk7OEJBUXJDLEtBQUs7c0JBREosS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgwqkgMjAwNS0yMDI1IEh5bGFuZCBTb2Z0d2FyZSwgSW5jLiBhbmQgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IENvbXBvbmVudCwgaW5qZWN0LCBJbnB1dCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZhY2V0RmllbGQgfSBmcm9tICcuLi8uLi9tb2RlbHMvZmFjZXQtZmllbGQuaW50ZXJmYWNlJztcbmltcG9ydCB7IE1hdENoZWNrYm94Q2hhbmdlLCBNYXRDaGVja2JveE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NoZWNrYm94JztcbmltcG9ydCB7IEZhY2V0RmllbGRCdWNrZXQgfSBmcm9tICcuLi8uLi9tb2RlbHMvZmFjZXQtZmllbGQtYnVja2V0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBTZWFyY2hRdWVyeUJ1aWxkZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvc2VhcmNoLXF1ZXJ5LWJ1aWxkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBTZWFyY2hGYWNldEZpbHRlcnNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvc2VhcmNoLWZhY2V0LWZpbHRlcnMuc2VydmljZSc7XG5pbXBvcnQgeyBGYWNldFdpZGdldCB9IGZyb20gJy4uLy4uL21vZGVscy9mYWNldC13aWRnZXQuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRyYW5zbGF0aW9uU2VydmljZSB9IGZyb20gJ0BhbGZyZXNjby9hZGYtY29yZSc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBUcmFuc2xhdGVNb2R1bGUgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2FkZi1zZWFyY2gtZmFjZXQtZmllbGQnLFxuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgTWF0QnV0dG9uTW9kdWxlLCBNYXRJY29uTW9kdWxlLCBNYXRGb3JtRmllbGRNb2R1bGUsIE1hdElucHV0TW9kdWxlLCBUcmFuc2xhdGVNb2R1bGUsIEZvcm1zTW9kdWxlLCBNYXRDaGVja2JveE1vZHVsZV0sXG4gICAgdGVtcGxhdGVVcmw6ICcuL3NlYXJjaC1mYWNldC1maWVsZC5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vc2VhcmNoLWZhY2V0LWZpZWxkLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBTZWFyY2hGYWNldEZpZWxkQ29tcG9uZW50IGltcGxlbWVudHMgRmFjZXRXaWRnZXQge1xuICAgIHByaXZhdGUgcXVlcnlCdWlsZGVyID0gaW5qZWN0KFNlYXJjaFF1ZXJ5QnVpbGRlclNlcnZpY2UpO1xuICAgIHByaXZhdGUgc2VhcmNoRmFjZXRGaWx0ZXJzU2VydmljZSA9IGluamVjdChTZWFyY2hGYWNldEZpbHRlcnNTZXJ2aWNlKTtcbiAgICBwcml2YXRlIHRyYW5zbGF0aW9uU2VydmljZSA9IGluamVjdChUcmFuc2xhdGlvblNlcnZpY2UpO1xuXG4gICAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSlcbiAgICBmaWVsZDogRmFjZXRGaWVsZDtcblxuICAgIGRpc3BsYXlWYWx1ZSQ6IFN1YmplY3Q8c3RyaW5nPiA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcblxuICAgIGdldCBjYW5VcGRhdGVPbkNoYW5nZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmllbGQuc2V0dGluZ3M/LmFsbG93VXBkYXRlT25DaGFuZ2UgPz8gdHJ1ZTtcbiAgICB9XG5cbiAgICBvblRvZ2dsZUJ1Y2tldChldmVudDogTWF0Q2hlY2tib3hDaGFuZ2UsIGZpZWxkOiBGYWNldEZpZWxkLCBidWNrZXQ6IEZhY2V0RmllbGRCdWNrZXQpIHtcbiAgICAgICAgaWYgKGV2ZW50ICYmIGJ1Y2tldCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdEZhY2V0QnVja2V0KGZpZWxkLCBidWNrZXQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVuc2VsZWN0RmFjZXRCdWNrZXQoZmllbGQsIGJ1Y2tldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZWxlY3RGYWNldEJ1Y2tldChmaWVsZDogRmFjZXRGaWVsZCwgYnVja2V0OiBGYWNldEZpZWxkQnVja2V0KSB7XG4gICAgICAgIGlmIChidWNrZXQpIHtcbiAgICAgICAgICAgIGJ1Y2tldC5jaGVja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMucXVlcnlCdWlsZGVyLmFkZFVzZXJGYWNldEJ1Y2tldChmaWVsZC5maWVsZCwgYnVja2V0KTtcbiAgICAgICAgICAgIHRoaXMuc2VhcmNoRmFjZXRGaWx0ZXJzU2VydmljZS51cGRhdGVTZWxlY3RlZEJ1Y2tldHMoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmNhblVwZGF0ZU9uQ2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVEaXNwbGF5VmFsdWUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnF1ZXJ5QnVpbGRlci51cGRhdGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVuc2VsZWN0RmFjZXRCdWNrZXQoZmllbGQ6IEZhY2V0RmllbGQsIGJ1Y2tldDogRmFjZXRGaWVsZEJ1Y2tldCkge1xuICAgICAgICBpZiAoYnVja2V0KSB7XG4gICAgICAgICAgICBidWNrZXQuY2hlY2tlZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5xdWVyeUJ1aWxkZXIucmVtb3ZlVXNlckZhY2V0QnVja2V0KGZpZWxkLmZpZWxkLCBidWNrZXQpO1xuICAgICAgICAgICAgdGhpcy5zZWFyY2hGYWNldEZpbHRlcnNTZXJ2aWNlLnVwZGF0ZVNlbGVjdGVkQnVja2V0cygpO1xuICAgICAgICAgICAgaWYgKHRoaXMuY2FuVXBkYXRlT25DaGFuZ2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZURpc3BsYXlWYWx1ZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMucXVlcnlCdWlsZGVyLnVwZGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2FuUmVzZXRTZWxlY3RlZEJ1Y2tldHMoZmllbGQ6IEZhY2V0RmllbGQpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKGZpZWxkPy5idWNrZXRzKSB7XG4gICAgICAgICAgICByZXR1cm4gZmllbGQuYnVja2V0cy5pdGVtcy5zb21lKChidWNrZXQpID0+IGJ1Y2tldC5jaGVja2VkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmVzZXRTZWxlY3RlZEJ1Y2tldHMoZmllbGQ6IEZhY2V0RmllbGQpIHtcbiAgICAgICAgaWYgKGZpZWxkPy5idWNrZXRzKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGJ1Y2tldCBvZiBmaWVsZC5idWNrZXRzLml0ZW1zKSB7XG4gICAgICAgICAgICAgICAgYnVja2V0LmNoZWNrZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLnF1ZXJ5QnVpbGRlci5yZW1vdmVVc2VyRmFjZXRCdWNrZXQoZmllbGQuZmllbGQsIGJ1Y2tldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNlYXJjaEZhY2V0RmlsdGVyc1NlcnZpY2UudXBkYXRlU2VsZWN0ZWRCdWNrZXRzKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jYW5VcGRhdGVPbkNoYW5nZSkge1xuICAgICAgICAgICAgICAgIHRoaXMucXVlcnlCdWlsZGVyLnVwZGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0QnVja2V0Q291bnREaXNwbGF5KGJ1Y2tldDogRmFjZXRGaWVsZEJ1Y2tldCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBidWNrZXQuY291bnQgPT09IG51bGwgPyAnJyA6IGAoJHtidWNrZXQuY291bnR9KWA7XG4gICAgfVxuXG4gICAgdXBkYXRlRGlzcGxheVZhbHVlKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuZmllbGQuYnVja2V0cz8uaXRlbXMpIHtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheVZhbHVlJC5uZXh0KCcnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGRpc3BsYXlWYWx1ZSA9IHRoaXMuZmllbGQuYnVja2V0cz8uaXRlbXNcbiAgICAgICAgICAgICAgICA/LmZpbHRlcigoaXRlbSkgPT4gaXRlbS5jaGVja2VkKVxuICAgICAgICAgICAgICAgIC5tYXAoKGl0ZW0pID0+IHRoaXMudHJhbnNsYXRpb25TZXJ2aWNlLmluc3RhbnQoaXRlbS5kaXNwbGF5IHx8IGl0ZW0ubGFiZWwpKVxuICAgICAgICAgICAgICAgIC5qb2luKCcsICcpO1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5VmFsdWUkLm5leHQoZGlzcGxheVZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlc2V0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnJlc2V0U2VsZWN0ZWRCdWNrZXRzKHRoaXMuZmllbGQpO1xuICAgICAgICB0aGlzLnVwZGF0ZURpc3BsYXlWYWx1ZSgpO1xuICAgICAgICB0aGlzLnF1ZXJ5QnVpbGRlci51cGRhdGUoKTtcbiAgICB9XG5cbiAgICBzdWJtaXRWYWx1ZXMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMudXBkYXRlRGlzcGxheVZhbHVlKCk7XG4gICAgICAgIHRoaXMucXVlcnlCdWlsZGVyLnVwZGF0ZSgpO1xuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJhZGYtc2VhcmNoLWZpbHRlci1mYWNldFwiPlxuICAgIDxkaXYgY2xhc3M9XCJhZGYtZmFjZXQtcmVzdWx0LWZpbHRlclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYWRmLWZhY2V0LXNlYXJjaC1jb250YWluZXJcIj5cbiAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNsYXNzPVwiYWRmLWZhY2V0LXNlYXJjaC1pY29uXCIgdGFiaW5kZXg9XCItMVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImFkZi1zZWFyY2gtZmllbGQtaWNvblwiPnNlYXJjaDwvbWF0LWljb24+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImFkZi1mYWNldC1zZWFyY2gtZmllbGRcIiBzdWJzY3JpcHRTaXppbmc9XCJkeW5hbWljXCI+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3sgJ1NFQVJDSC5GSUxURVIuQUNUSU9OUy5TRUFSQ0gnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgICAgICAgICAgW2F0dHIuZGF0YS1hdXRvbWF0aW9uLWlkXT1cIidmYWNldC1yZXN1bHQtZmlsdGVyLScgKyBmaWVsZC5sYWJlbFwiXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZmllbGQuYnVja2V0cy5maWx0ZXJUZXh0XCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJmaWVsZC5idWNrZXRzLmZpbHRlclRleHRcIlxuICAgICAgICAgICAgICAgICAgICBtYXRTdWZmaXhcbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLnRpdGxlXT1cIidTRUFSQ0guRklMVEVSLkJVVFRPTlMuQ0xFQVInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImZpZWxkLmJ1Y2tldHMuZmlsdGVyVGV4dCA9ICcnXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiByb2xlPVwiYnV0dG9uXCIgW2F0dHIuYXJpYS1sYWJlbF09XCInU0VBUkNILkZJTFRFUi5CVVRUT05TLkNMRUFSJyB8IHRyYW5zbGF0ZVwiPmNsZWFyPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImFkZi1jaGVja2xpc3RcIj5cbiAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IGJ1Y2tldCBvZiBmaWVsZC5idWNrZXRzXCJcbiAgICAgICAgICAgIFtjaGVja2VkXT1cImJ1Y2tldC5jaGVja2VkXCJcbiAgICAgICAgICAgIFthdHRyLmRhdGEtYXV0b21hdGlvbi1pZF09XCInY2hlY2tib3gtJyArIGZpZWxkLmxhYmVsICsgJy0nICsgKGJ1Y2tldC5kaXNwbGF5IHx8IGJ1Y2tldC5sYWJlbClcIlxuICAgICAgICAgICAgKGNoYW5nZSk9XCJvblRvZ2dsZUJ1Y2tldCgkZXZlbnQsIGZpZWxkLCBidWNrZXQpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiYWRmLXNlYXJjaC1maWx0ZXItZmFjZXQtY2hlY2tib3hcIlxuICAgICAgICA+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBidWNrZXQuZGlzcGxheSB8fCBidWNrZXQubGFiZWwgfCB0cmFuc2xhdGUgfX0ge3sgZ2V0QnVja2V0Q291bnREaXNwbGF5KGJ1Y2tldCkgfX1cIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYWRmLWZhY2V0LWxhYmVsXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuYWRmLXNlYXJjaC1maWx0ZXItZmFjZXQtY2hlY2tib3gtY2hlY2tlZF09XCJidWNrZXQuY2hlY2tlZFwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAge3sgYnVja2V0LmRpc3BsYXkgfHwgYnVja2V0LmxhYmVsIHwgdHJhbnNsYXRlIH19IHt7IGdldEJ1Y2tldENvdW50RGlzcGxheShidWNrZXQpIH19XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiYWRmLWZhY2V0LWJ1dHRvbnNcIiAqbmdJZj1cImZpZWxkLmJ1Y2tldHMuZml0c1BhZ2UgJiYgIWZpZWxkLnNldHRpbmdzPy5oaWRlRGVmYXVsdEFjdGlvblwiPlxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiY2FuUmVzZXRTZWxlY3RlZEJ1Y2tldHMoZmllbGQpXCIgbWF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwicmVzZXRTZWxlY3RlZEJ1Y2tldHMoZmllbGQpXCI+XG4gICAgICAgICAgICB7eyAnU0VBUkNILkZJTFRFUi5BQ1RJT05TLkNMRUFSLUFMTCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiYWRmLWZhY2V0LWJ1dHRvbnNcIiAqbmdJZj1cIiFmaWVsZC5idWNrZXRzLmZpdHNQYWdlXCI+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJjYW5SZXNldFNlbGVjdGVkQnVja2V0cyhmaWVsZClcIlxuICAgICAgICAgICAgdGl0bGU9XCJ7eyAnU0VBUkNILkZJTFRFUi5BQ1RJT05TLkNMRUFSLUFMTCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgKGNsaWNrKT1cInJlc2V0U2VsZWN0ZWRCdWNrZXRzKGZpZWxkKVwiXG4gICAgICAgID5cbiAgICAgICAgICAgIDxtYXQtaWNvbj5jbGVhcjwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiZmllbGQuYnVja2V0cy5jYW5TaG93TGVzc0l0ZW1zXCJcbiAgICAgICAgICAgIChjbGljayk9XCJmaWVsZC5idWNrZXRzLnNob3dMZXNzSXRlbXMoKVwiXG4gICAgICAgICAgICB0aXRsZT1cInt7ICdTRUFSQ0guRklMVEVSLkFDVElPTlMuU0hPVy1MRVNTJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgID5cbiAgICAgICAgICAgIDxtYXQtaWNvbj5rZXlib2FyZF9hcnJvd191cDwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiZmllbGQuYnVja2V0cy5jYW5TaG93TW9yZUl0ZW1zXCJcbiAgICAgICAgICAgIChjbGljayk9XCJmaWVsZC5idWNrZXRzLnNob3dNb3JlSXRlbXMoKVwiXG4gICAgICAgICAgICB0aXRsZT1cInt7ICdTRUFSQ0guRklMVEVSLkFDVElPTlMuU0hPVy1NT1JFJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgID5cbiAgICAgICAgICAgIDxtYXQtaWNvbj5rZXlib2FyZF9hcnJvd19kb3duPC9tYXQtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==