@knora/search
Version:
Knora ui module: search
205 lines • 29.2 kB
JavaScript
import * as tslib_1 from "tslib";
import { Component, EventEmitter, Inject, Input, Output, QueryList, ViewChild, ViewChildren } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { ApiResponseError, KnoraApiConnection, OntologiesMetadata, OntologyMetadata, ReadResource } from '@knora/api';
import { GravsearchGenerationService, KnoraApiConnectionToken, OntologyCacheService, OntologyInformation, Properties, PropertyWithValue, ResourceClass } from '@knora/core';
import { SelectResourceClassComponent } from './select-resource-class/select-resource-class.component';
/**
* The extended search allows you to filter by project, by source type (resource class), or by the metadata (properties) of source types. Each filter can be standalone or combined. The metadata field can be precisely filtered with criteria such as "contains", "like", "equals to", "exists" or in case of a date value with "before" or "after". In addition, for a metadata field that is connected to another source type, it's possible to filter by this second source type. If you are looking for the source type "Photograph" with the metadata field "Photographer", which is connected to source type "Person", you can search for photograph(s) taken by person(s) who is born before February 1970. The result of this request will be an intersection of the two source types.
*/
let ExtendedSearchComponent = class ExtendedSearchComponent {
constructor(fb, knoraApiConnection, _route, _router, _cacheService, _gravSearchService) {
this.fb = fb;
this.knoraApiConnection = knoraApiConnection;
this._route = _route;
this._router = _router;
this._cacheService = _cacheService;
this._gravSearchService = _gravSearchService;
/**
* @param {boolean} toggleExtendedSearchForm Trigger toggle for extended search form.
*/
this.toggleExtendedSearchForm = new EventEmitter();
/**
* @param {string} gravsearch Send the gravsearch query back.
*/
this.gravsearch = new EventEmitter();
// all available ontologies
this.ontologies = [];
// properties specified by the user
this.activeProperties = [];
// resource classes for the selected ontology
this.resourceClasses = [];
this.result = [new ReadResource()];
// form validation status
this.formValid = false;
}
ngOnInit() {
// parent form is empty, it gets passed to the child components
this.form = this.fb.group({});
// if form status changes, re-run validation
this.form.statusChanges.subscribe((data) => {
this.formValid = this.validateForm();
// console.log(this.form);
});
// initialize ontologies to be used for the ontologies selection in the search form
this.initializeOntologies();
}
/**
* @ignore
* Add a property to the search form.
* @returns void
*/
addProperty() {
this.activeProperties.push(true);
}
/**
* @ignore
* Remove the last property from the search form.
* @returns void
*/
removeProperty() {
this.activeProperties.splice(-1, 1);
}
/**
* @ignore
* Gets all available ontologies for the search form.
* @returns void
*/
initializeOntologies() {
this.knoraApiConnection.v2.onto.getOntologiesMetadata().subscribe((response) => {
this.ontologies = response.ontologies;
}, (error) => {
console.error(error);
});
}
/**
* @ignore
* Once an ontology has been selected, gets its classes and properties.
* The classes and properties will be made available to the user for selection.
*
* @param ontologyIri Iri of the ontology chosen by the user.
* @returns void
*/
getResourceClassesAndPropertiesForOntology(ontologyIri) {
// reset active resource class definition
this.activeResourceClass = undefined;
// reset specified properties
this.activeProperties = [];
this.activeOntology = ontologyIri;
this._cacheService.getEntityDefinitionsForOntologies([ontologyIri]).subscribe((ontoInfo) => {
this.resourceClasses = ontoInfo.getResourceClassesAsArray(true);
this.properties = ontoInfo.getProperties();
});
}
/**
* @ignore
* Once a resource class has been selected, gets its properties.
* The properties will be made available to the user for selection.
*
* @param resourceClassIri
* @returns void
*/
getPropertiesForResourceClass(resourceClassIri) {
// reset specified properties
this.activeProperties = [];
// if the client undoes the selection of a resource class, use the active ontology as a fallback
if (resourceClassIri === null) {
this.getResourceClassesAndPropertiesForOntology(this.activeOntology);
}
else {
this._cacheService.getResourceClassDefinitions([resourceClassIri]).subscribe((ontoInfo) => {
this.properties = ontoInfo.getProperties();
this.activeResourceClass = ontoInfo.getResourceClasses()[resourceClassIri];
});
}
}
/**
* @ignore
* Validates form and returns its status (boolean).
*/
validateForm() {
// check that either a resource class is selected or at least one property is specified
return this.form.valid &&
(this.propertyComponents.length > 0 || (this.resourceClassComponent !== undefined && this.resourceClassComponent.getResourceClassSelected() !== false));
}
/**
* @ignore
* Resets the form (selected resource class and specified properties) preserving the active ontology.
*/
resetForm() {
if (this.activeOntology !== undefined) {
this.getResourceClassesAndPropertiesForOntology(this.activeOntology);
}
}
/**
* @ignore
* Creates a GravSearch query with the given form values and calls the extended search route.
*/
submit() {
if (!this.formValid)
return; // check that from is valid
const resClassOption = this.resourceClassComponent.getResourceClassSelected();
let resClass;
if (resClassOption !== false) {
resClass = resClassOption;
}
const properties = this.propertyComponents.map((propComp) => {
return propComp.getPropertySelectedWithValue();
});
const gravsearch = this._gravSearchService.createGravsearchQuery(properties, resClass, 0);
if (this.route) {
this._router.navigate([this.route + '/extended/', gravsearch], { relativeTo: this._route });
}
else {
this.gravsearch.emit(gravsearch);
}
// toggle extended search form
this.toggleExtendedSearchForm.emit(true);
}
};
ExtendedSearchComponent.ctorParameters = () => [
{ type: FormBuilder, decorators: [{ type: Inject, args: [FormBuilder,] }] },
{ type: KnoraApiConnection, decorators: [{ type: Inject, args: [KnoraApiConnectionToken,] }] },
{ type: ActivatedRoute },
{ type: Router },
{ type: OntologyCacheService },
{ type: GravsearchGenerationService }
];
tslib_1.__decorate([
Input(),
tslib_1.__metadata("design:type", Object)
], ExtendedSearchComponent.prototype, "route", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", Object)
], ExtendedSearchComponent.prototype, "toggleExtendedSearchForm", void 0);
tslib_1.__decorate([
Output(),
tslib_1.__metadata("design:type", Object)
], ExtendedSearchComponent.prototype, "gravsearch", void 0);
tslib_1.__decorate([
ViewChild('resourceClass', { static: false }),
tslib_1.__metadata("design:type", SelectResourceClassComponent)
], ExtendedSearchComponent.prototype, "resourceClassComponent", void 0);
tslib_1.__decorate([
ViewChildren('property'),
tslib_1.__metadata("design:type", QueryList)
], ExtendedSearchComponent.prototype, "propertyComponents", void 0);
ExtendedSearchComponent = tslib_1.__decorate([
Component({
selector: 'kui-extended-search',
template: "<form [formGroup]=\"form\" (ngSubmit)=\"submit()\" class=\"kui-form-content\">\n\n <div>\n <kui-select-ontology *ngIf=\"ontologies.length > 0\" [formGroup]=\"form\" [ontologies]=\"ontologies\"\n (ontologySelected)=\"getResourceClassesAndPropertiesForOntology($event)\"></kui-select-ontology>\n </div>\n\n <div class=\"select-resource-class\" *ngIf=\"resourceClasses?.length > 0\">\n <kui-select-resource-class #resourceClass [formGroup]=\"form\" [resourceClasses]=\"resourceClasses\"\n (resourceClassSelectedEvent)=\"getPropertiesForResourceClass($event)\">\n </kui-select-resource-class>\n </div>\n\n <div class=\"select-property\" *ngIf=\"properties !== undefined\">\n <div *ngFor=\"let prop of activeProperties; let i = index\">\n\n <kui-select-property #property [activeResourceClass]=\"activeResourceClass\" [formGroup]=\"form\" [index]=\"i\"\n [properties]=\"properties\"></kui-select-property>\n\n </div>\n </div>\n\n\n <div class=\"select-property buttons\">\n <button mat-mini-fab class=\"property-button add-property-button\" color=\"primary\" type=\"button\"\n (click)=\"addProperty()\" [disabled]=\"activeOntology === undefined || activeProperties.length >= 4\">\n <mat-icon aria-label=\"add a property\">add</mat-icon>\n </button>\n\n <button mat-mini-fab class=\"property-button remove-property-button\" color=\"primary\" type=\"button\"\n (click)=\"removeProperty()\" [disabled]=\"activeProperties.length == 0\">\n <mat-icon aria-label=\"remove property\">remove</mat-icon>\n </button>\n </div>\n\n <!-- <div>\n <button mat-icon-button type=\"button\" (click)=\"resetForm()\" [disabled]=\"this.activeOntology === undefined\">\n <mat-icon aria-label=\"reset query form\">clear</mat-icon>\n </button>\n\n <button mat-icon-button type=\"submit\" [disabled]=\"!formValid\">\n <mat-icon aria-label=\"submit query\">send</mat-icon>\n </button>\n </div> -->\n\n <div class=\"kui-form-action\">\n <button class=\"reset\" mat-button type=\"button\" (click)=\"resetForm()\" [disabled]=\"this.activeOntology === undefined\">\n Reset\n </button>\n <span class=\"fill-remaining-space\"></span>\n <button class=\"extended-search-button\" mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"!formValid\">\n Search\n </button>\n </div>\n\n</form>\n",
styles: [".select-resource-class{margin-left:8px}.select-property{margin-left:16px}.select-property .property-button{margin:0 12px 64px 0}"]
}),
tslib_1.__param(0, Inject(FormBuilder)),
tslib_1.__param(1, Inject(KnoraApiConnectionToken)),
tslib_1.__metadata("design:paramtypes", [FormBuilder,
KnoraApiConnection,
ActivatedRoute,
Router,
OntologyCacheService,
GravsearchGenerationService])
], ExtendedSearchComponent);
export { ExtendedSearchComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZW5kZWQtc2VhcmNoLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Brbm9yYS9zZWFyY2gvIiwic291cmNlcyI6WyJsaWIvZXh0ZW5kZWQtc2VhcmNoL2V4dGVuZGVkLXNlYXJjaC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNILE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3RILE9BQU8sRUFBRSwyQkFBMkIsRUFBRSx1QkFBdUIsRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRzVLLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBRXZHOztHQUVHO0FBTUgsSUFBYSx1QkFBdUIsR0FBcEMsTUFBYSx1QkFBdUI7SUFpRGhDLFlBQ2lDLEVBQWUsRUFDSCxrQkFBc0MsRUFDdkUsTUFBc0IsRUFDdEIsT0FBZSxFQUNmLGFBQW1DLEVBQ25DLGtCQUErQztRQUwxQixPQUFFLEdBQUYsRUFBRSxDQUFhO1FBQ0gsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN2RSxXQUFNLEdBQU4sTUFBTSxDQUFnQjtRQUN0QixZQUFPLEdBQVAsT0FBTyxDQUFRO1FBQ2Ysa0JBQWEsR0FBYixhQUFhLENBQXNCO1FBQ25D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Q0FEQyxXQUFXO1FBQ2lCLGtCQUFrQjtRQUMvRCxjQUFjO1FBQ2IsTUFBTTtRQUNBLG9CQUFvQjtRQUNmLDJCQUEyQjtHQXZEbEQsdUJBQXVCLENBaU9uQztTQWpPWSx1QkFBdUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5qZWN0LCBJbnB1dCwgT25Jbml0LCBPdXRwdXQsIFF1ZXJ5TGlzdCwgVmlld0NoaWxkLCBWaWV3Q2hpbGRyZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IEFwaVJlc3BvbnNlRXJyb3IsIEtub3JhQXBpQ29ubmVjdGlvbiwgT250b2xvZ2llc01ldGFkYXRhLCBPbnRvbG9neU1ldGFkYXRhLCBSZWFkUmVzb3VyY2UgfSBmcm9tICdAa25vcmEvYXBpJztcbmltcG9ydCB7IEdyYXZzZWFyY2hHZW5lcmF0aW9uU2VydmljZSwgS25vcmFBcGlDb25uZWN0aW9uVG9rZW4sIE9udG9sb2d5Q2FjaGVTZXJ2aWNlLCBPbnRvbG9neUluZm9ybWF0aW9uLCBQcm9wZXJ0aWVzLCBQcm9wZXJ0eVdpdGhWYWx1ZSwgUmVzb3VyY2VDbGFzcyB9IGZyb20gJ0Brbm9yYS9jb3JlJztcblxuaW1wb3J0IHsgU2VsZWN0UHJvcGVydHlDb21wb25lbnQgfSBmcm9tICcuL3NlbGVjdC1wcm9wZXJ0eS9zZWxlY3QtcHJvcGVydHkuY29tcG9uZW50JztcbmltcG9ydCB7IFNlbGVjdFJlc291cmNlQ2xhc3NDb21wb25lbnQgfSBmcm9tICcuL3NlbGVjdC1yZXNvdXJjZS1jbGFzcy9zZWxlY3QtcmVzb3VyY2UtY2xhc3MuY29tcG9uZW50JztcblxuLyoqXG4gKiBUaGUgZXh0ZW5kZWQgc2VhcmNoIGFsbG93cyB5b3UgdG8gZmlsdGVyIGJ5IHByb2plY3QsIGJ5IHNvdXJjZSB0eXBlIChyZXNvdXJjZSBjbGFzcyksIG9yIGJ5IHRoZSBtZXRhZGF0YSAocHJvcGVydGllcykgb2Ygc291cmNlIHR5cGVzLiBFYWNoIGZpbHRlciBjYW4gYmUgc3RhbmRhbG9uZSBvciBjb21iaW5lZC4gVGhlIG1ldGFkYXRhIGZpZWxkIGNhbiBiZSBwcmVjaXNlbHkgZmlsdGVyZWQgd2l0aCBjcml0ZXJpYSBzdWNoIGFzIFwiY29udGFpbnNcIiwgXCJsaWtlXCIsIFwiZXF1YWxzIHRvXCIsIFwiZXhpc3RzXCIgb3IgaW4gY2FzZSBvZiBhIGRhdGUgdmFsdWUgd2l0aCBcImJlZm9yZVwiIG9yIFwiYWZ0ZXJcIi4gSW4gYWRkaXRpb24sIGZvciBhIG1ldGFkYXRhIGZpZWxkIHRoYXQgaXMgY29ubmVjdGVkIHRvIGFub3RoZXIgc291cmNlIHR5cGUsIGl0J3MgcG9zc2libGUgdG8gZmlsdGVyIGJ5IHRoaXMgc2Vjb25kIHNvdXJjZSB0eXBlLiBJZiB5b3UgYXJlIGxvb2tpbmcgZm9yIHRoZSBzb3VyY2UgdHlwZSBcIlBob3RvZ3JhcGhcIiB3aXRoIHRoZSBtZXRhZGF0YSBmaWVsZCBcIlBob3RvZ3JhcGhlclwiLCB3aGljaCBpcyBjb25uZWN0ZWQgdG8gc291cmNlIHR5cGUgXCJQZXJzb25cIiwgeW91IGNhbiBzZWFyY2ggZm9yIHBob3RvZ3JhcGgocykgdGFrZW4gYnkgcGVyc29uKHMpIHdobyBpcyBib3JuIGJlZm9yZSBGZWJydWFyeSAxOTcwLiBUaGUgcmVzdWx0IG9mIHRoaXMgcmVxdWVzdCB3aWxsIGJlIGFuIGludGVyc2VjdGlvbiBvZiB0aGUgdHdvIHNvdXJjZSB0eXBlcy5cbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdrdWktZXh0ZW5kZWQtc2VhcmNoJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vZXh0ZW5kZWQtc2VhcmNoLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9leHRlbmRlZC1zZWFyY2guY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBFeHRlbmRlZFNlYXJjaENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gIHtzdHJpbmd9IHJvdXRlIFJvdXRlIHRvIG5hdmlnYXRlIGFmdGVyIHNlYXJjaC4gVGhpcyByb3V0ZSBwYXRoIHNob3VsZCBjb250YWluIGEgY29tcG9uZW50IGZvciBzZWFyY2ggcmVzdWx0cy5cbiAgICAgKi9cbiAgICBASW5wdXQoKSByb3V0ZT87XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gIHtib29sZWFufSB0b2dnbGVFeHRlbmRlZFNlYXJjaEZvcm0gVHJpZ2dlciB0b2dnbGUgZm9yIGV4dGVuZGVkIHNlYXJjaCBmb3JtLlxuICAgICAqL1xuICAgIEBPdXRwdXQoKSB0b2dnbGVFeHRlbmRlZFNlYXJjaEZvcm0gPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gIHtzdHJpbmd9IGdyYXZzZWFyY2ggU2VuZCB0aGUgZ3JhdnNlYXJjaCBxdWVyeSBiYWNrLlxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBncmF2c2VhcmNoID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgICAvLyBhbGwgYXZhaWxhYmxlIG9udG9sb2dpZXNcbiAgICBvbnRvbG9naWVzOiBPbnRvbG9neU1ldGFkYXRhW10gPSBbXTtcblxuICAgIC8vIG9udG9sb2d5IGNob3NlbiBieSB0aGUgdXNlclxuICAgIGFjdGl2ZU9udG9sb2d5OiBzdHJpbmc7XG5cbiAgICAvLyBwcm9wZXJ0aWVzIHNwZWNpZmllZCBieSB0aGUgdXNlclxuICAgIGFjdGl2ZVByb3BlcnRpZXM6IGJvb2xlYW5bXSA9IFtdO1xuXG4gICAgLy8gcmVzb3VyY2UgY2xhc3NlcyBmb3IgdGhlIHNlbGVjdGVkIG9udG9sb2d5XG4gICAgcmVzb3VyY2VDbGFzc2VzOiBBcnJheTxSZXNvdXJjZUNsYXNzPiA9IFtdO1xuXG4gICAgLy8gZGVmaW5pdGlvbiBvZiB0aGUgc2VsZWN0ZWQgcmVzb3VyY2UgY2xhc3MsIGlmIHNldC5cbiAgICBhY3RpdmVSZXNvdXJjZUNsYXNzOiBSZXNvdXJjZUNsYXNzO1xuXG4gICAgLy8gcHJvcGVydGllcyBmb3IgdGhlIHNlbGVjdGVkIG9udG9sb2d5IG9yIHNlbGVjdGVkIHJlc291cmNlIGNsYXNzXG4gICAgcHJvcGVydGllczogUHJvcGVydGllcztcblxuICAgIHJlc3VsdDogUmVhZFJlc291cmNlW10gPSBbbmV3IFJlYWRSZXNvdXJjZSgpXTtcblxuICAgIC8vIHJlZmVyZW5jZSB0byB0aGUgY29tcG9uZW50IHRoYXQgY29udHJvbHMgdGhlIHJlc291cmNlIGNsYXNzIHNlbGVjdGlvblxuICAgIEBWaWV3Q2hpbGQoJ3Jlc291cmNlQ2xhc3MnLCB7IHN0YXRpYzogZmFsc2UgfSkgcmVzb3VyY2VDbGFzc0NvbXBvbmVudDogU2VsZWN0UmVzb3VyY2VDbGFzc0NvbXBvbmVudDtcblxuICAgIC8vIHJlZmVyZW5jZSB0byB0aGUgY29tcG9uZW50IGNvbnRyb2xsaW5nIHRoZSBwcm9wZXJ0eSBzZWxlY3Rpb25cbiAgICBAVmlld0NoaWxkcmVuKCdwcm9wZXJ0eScpIHByb3BlcnR5Q29tcG9uZW50czogUXVlcnlMaXN0PFNlbGVjdFByb3BlcnR5Q29tcG9uZW50PjtcblxuICAgIC8vIEZvcm1Hcm91cCAodXNlZCBhcyBwYXJlbnQgZm9yIGNoaWxkIGNvbXBvbmVudHMpXG4gICAgZm9ybTogRm9ybUdyb3VwO1xuXG4gICAgLy8gZm9ybSB2YWxpZGF0aW9uIHN0YXR1c1xuICAgIGZvcm1WYWxpZCA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIEBJbmplY3QoRm9ybUJ1aWxkZXIpIHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxuICAgICAgICBASW5qZWN0KEtub3JhQXBpQ29ubmVjdGlvblRva2VuKSBwcml2YXRlIGtub3JhQXBpQ29ubmVjdGlvbjogS25vcmFBcGlDb25uZWN0aW9uLFxuICAgICAgICBwcml2YXRlIF9yb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgIHByaXZhdGUgX3JvdXRlcjogUm91dGVyLFxuICAgICAgICBwcml2YXRlIF9jYWNoZVNlcnZpY2U6IE9udG9sb2d5Q2FjaGVTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIF9ncmF2U2VhcmNoU2VydmljZTogR3JhdnNlYXJjaEdlbmVyYXRpb25TZXJ2aWNlKSB7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKSB7XG5cbiAgICAgICAgLy8gcGFyZW50IGZvcm0gaXMgZW1wdHksIGl0IGdldHMgcGFzc2VkIHRvIHRoZSBjaGlsZCBjb21wb25lbnRzXG4gICAgICAgIHRoaXMuZm9ybSA9IHRoaXMuZmIuZ3JvdXAoe30pO1xuXG4gICAgICAgIC8vIGlmIGZvcm0gc3RhdHVzIGNoYW5nZXMsIHJlLXJ1biB2YWxpZGF0aW9uXG4gICAgICAgIHRoaXMuZm9ybS5zdGF0dXNDaGFuZ2VzLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWQgPSB0aGlzLnZhbGlkYXRlRm9ybSgpO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy5mb3JtKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gaW5pdGlhbGl6ZSBvbnRvbG9naWVzIHRvIGJlIHVzZWQgZm9yIHRoZSBvbnRvbG9naWVzIHNlbGVjdGlvbiBpbiB0aGUgc2VhcmNoIGZvcm1cbiAgICAgICAgdGhpcy5pbml0aWFsaXplT250b2xvZ2llcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBBZGQgYSBwcm9wZXJ0eSB0byB0aGUgc2VhcmNoIGZvcm0uXG4gICAgICogQHJldHVybnMgdm9pZFxuICAgICAqL1xuICAgIGFkZFByb3BlcnR5KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmFjdGl2ZVByb3BlcnRpZXMucHVzaCh0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogUmVtb3ZlIHRoZSBsYXN0IHByb3BlcnR5IGZyb20gdGhlIHNlYXJjaCBmb3JtLlxuICAgICAqIEByZXR1cm5zIHZvaWRcbiAgICAgKi9cbiAgICByZW1vdmVQcm9wZXJ0eSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5hY3RpdmVQcm9wZXJ0aWVzLnNwbGljZSgtMSwgMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqIEdldHMgYWxsIGF2YWlsYWJsZSBvbnRvbG9naWVzIGZvciB0aGUgc2VhcmNoIGZvcm0uXG4gICAgICogQHJldHVybnMgdm9pZFxuICAgICAqL1xuICAgIGluaXRpYWxpemVPbnRvbG9naWVzKCk6IHZvaWQge1xuXG4gICAgICAgIHRoaXMua25vcmFBcGlDb25uZWN0aW9uLnYyLm9udG8uZ2V0T250b2xvZ2llc01ldGFkYXRhKCkuc3Vic2NyaWJlKFxuICAgICAgICAgICAgKHJlc3BvbnNlOiBPbnRvbG9naWVzTWV0YWRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLm9udG9sb2dpZXMgPSByZXNwb25zZS5vbnRvbG9naWVzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnJvcjogQXBpUmVzcG9uc2VFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqIE9uY2UgYW4gb250b2xvZ3kgaGFzIGJlZW4gc2VsZWN0ZWQsIGdldHMgaXRzIGNsYXNzZXMgYW5kIHByb3BlcnRpZXMuXG4gICAgICogVGhlIGNsYXNzZXMgYW5kIHByb3BlcnRpZXMgd2lsbCBiZSBtYWRlIGF2YWlsYWJsZSB0byB0aGUgdXNlciBmb3Igc2VsZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIG9udG9sb2d5SXJpIElyaSBvZiB0aGUgb250b2xvZ3kgY2hvc2VuIGJ5IHRoZSB1c2VyLlxuICAgICAqIEByZXR1cm5zIHZvaWRcbiAgICAgKi9cbiAgICBnZXRSZXNvdXJjZUNsYXNzZXNBbmRQcm9wZXJ0aWVzRm9yT250b2xvZ3kob250b2xvZ3lJcmk6IHN0cmluZyk6IHZvaWQge1xuXG4gICAgICAgIC8vIHJlc2V0IGFjdGl2ZSByZXNvdXJjZSBjbGFzcyBkZWZpbml0aW9uXG4gICAgICAgIHRoaXMuYWN0aXZlUmVzb3VyY2VDbGFzcyA9IHVuZGVmaW5lZDtcblxuICAgICAgICAvLyByZXNldCBzcGVjaWZpZWQgcHJvcGVydGllc1xuICAgICAgICB0aGlzLmFjdGl2ZVByb3BlcnRpZXMgPSBbXTtcblxuICAgICAgICB0aGlzLmFjdGl2ZU9udG9sb2d5ID0gb250b2xvZ3lJcmk7XG5cbiAgICAgICAgdGhpcy5fY2FjaGVTZXJ2aWNlLmdldEVudGl0eURlZmluaXRpb25zRm9yT250b2xvZ2llcyhbb250b2xvZ3lJcmldKS5zdWJzY3JpYmUoXG4gICAgICAgICAgICAob250b0luZm86IE9udG9sb2d5SW5mb3JtYXRpb24pID0+IHtcblxuICAgICAgICAgICAgICAgIHRoaXMucmVzb3VyY2VDbGFzc2VzID0gb250b0luZm8uZ2V0UmVzb3VyY2VDbGFzc2VzQXNBcnJheSh0cnVlKTtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBvbnRvSW5mby5nZXRQcm9wZXJ0aWVzKCk7XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBPbmNlIGEgcmVzb3VyY2UgY2xhc3MgaGFzIGJlZW4gc2VsZWN0ZWQsIGdldHMgaXRzIHByb3BlcnRpZXMuXG4gICAgICogVGhlIHByb3BlcnRpZXMgd2lsbCBiZSBtYWRlIGF2YWlsYWJsZSB0byB0aGUgdXNlciBmb3Igc2VsZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIHJlc291cmNlQ2xhc3NJcmlcbiAgICAgKiBAcmV0dXJucyB2b2lkXG4gICAgICovXG4gICAgZ2V0UHJvcGVydGllc0ZvclJlc291cmNlQ2xhc3MocmVzb3VyY2VDbGFzc0lyaTogc3RyaW5nKTogdm9pZCB7XG5cbiAgICAgICAgLy8gcmVzZXQgc3BlY2lmaWVkIHByb3BlcnRpZXNcbiAgICAgICAgdGhpcy5hY3RpdmVQcm9wZXJ0aWVzID0gW107XG5cbiAgICAgICAgLy8gaWYgdGhlIGNsaWVudCB1bmRvZXMgdGhlIHNlbGVjdGlvbiBvZiBhIHJlc291cmNlIGNsYXNzLCB1c2UgdGhlIGFjdGl2ZSBvbnRvbG9neSBhcyBhIGZhbGxiYWNrXG4gICAgICAgIGlmIChyZXNvdXJjZUNsYXNzSXJpID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmdldFJlc291cmNlQ2xhc3Nlc0FuZFByb3BlcnRpZXNGb3JPbnRvbG9neSh0aGlzLmFjdGl2ZU9udG9sb2d5KTtcbiAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgdGhpcy5fY2FjaGVTZXJ2aWNlLmdldFJlc291cmNlQ2xhc3NEZWZpbml0aW9ucyhbcmVzb3VyY2VDbGFzc0lyaV0pLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgICAob250b0luZm86IE9udG9sb2d5SW5mb3JtYXRpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gb250b0luZm8uZ2V0UHJvcGVydGllcygpO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlUmVzb3VyY2VDbGFzcyA9IG9udG9JbmZvLmdldFJlc291cmNlQ2xhc3NlcygpW3Jlc291cmNlQ2xhc3NJcmldO1xuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcblxuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogVmFsaWRhdGVzIGZvcm0gYW5kIHJldHVybnMgaXRzIHN0YXR1cyAoYm9vbGVhbikuXG4gICAgICovXG4gICAgcHJpdmF0ZSB2YWxpZGF0ZUZvcm0oKSB7XG5cbiAgICAgICAgLy8gY2hlY2sgdGhhdCBlaXRoZXIgYSByZXNvdXJjZSBjbGFzcyBpcyBzZWxlY3RlZCBvciBhdCBsZWFzdCBvbmUgcHJvcGVydHkgaXMgc3BlY2lmaWVkXG4gICAgICAgIHJldHVybiB0aGlzLmZvcm0udmFsaWQgJiZcbiAgICAgICAgICAgICh0aGlzLnByb3BlcnR5Q29tcG9uZW50cy5sZW5ndGggPiAwIHx8ICh0aGlzLnJlc291cmNlQ2xhc3NDb21wb25lbnQgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnJlc291cmNlQ2xhc3NDb21wb25lbnQuZ2V0UmVzb3VyY2VDbGFzc1NlbGVjdGVkKCkgIT09IGZhbHNlKSk7XG5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogUmVzZXRzIHRoZSBmb3JtIChzZWxlY3RlZCByZXNvdXJjZSBjbGFzcyBhbmQgc3BlY2lmaWVkIHByb3BlcnRpZXMpIHByZXNlcnZpbmcgdGhlIGFjdGl2ZSBvbnRvbG9neS5cbiAgICAgKi9cbiAgICByZXNldEZvcm0oKSB7XG4gICAgICAgIGlmICh0aGlzLmFjdGl2ZU9udG9sb2d5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVzb3VyY2VDbGFzc2VzQW5kUHJvcGVydGllc0Zvck9udG9sb2d5KHRoaXMuYWN0aXZlT250b2xvZ3kpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICogQ3JlYXRlcyBhIEdyYXZTZWFyY2ggcXVlcnkgd2l0aCB0aGUgZ2l2ZW4gZm9ybSB2YWx1ZXMgYW5kIGNhbGxzIHRoZSBleHRlbmRlZCBzZWFyY2ggcm91dGUuXG4gICAgICovXG4gICAgc3VibWl0KCkge1xuXG4gICAgICAgIGlmICghdGhpcy5mb3JtVmFsaWQpIHJldHVybjsgLy8gY2hlY2sgdGhhdCBmcm9tIGlzIHZhbGlkXG5cbiAgICAgICAgY29uc3QgcmVzQ2xhc3NPcHRpb24gPSB0aGlzLnJlc291cmNlQ2xhc3NDb21wb25lbnQuZ2V0UmVzb3VyY2VDbGFzc1NlbGVjdGVkKCk7XG5cbiAgICAgICAgbGV0IHJlc0NsYXNzO1xuXG4gICAgICAgIGlmIChyZXNDbGFzc09wdGlvbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJlc0NsYXNzID0gcmVzQ2xhc3NPcHRpb247XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcm9wZXJ0aWVzOiBQcm9wZXJ0eVdpdGhWYWx1ZVtdID0gdGhpcy5wcm9wZXJ0eUNvbXBvbmVudHMubWFwKFxuICAgICAgICAgICAgKHByb3BDb21wKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3BDb21wLmdldFByb3BlcnR5U2VsZWN0ZWRXaXRoVmFsdWUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBncmF2c2VhcmNoID0gdGhpcy5fZ3JhdlNlYXJjaFNlcnZpY2UuY3JlYXRlR3JhdnNlYXJjaFF1ZXJ5KHByb3BlcnRpZXMsIHJlc0NsYXNzLCAwKTtcblxuICAgICAgICBpZiAodGhpcy5yb3V0ZSkge1xuICAgICAgICAgICAgdGhpcy5fcm91dGVyLm5hdmlnYXRlKFt0aGlzLnJvdXRlICsgJy9leHRlbmRlZC8nLCBncmF2c2VhcmNoXSwgeyByZWxhdGl2ZVRvOiB0aGlzLl9yb3V0ZSB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ3JhdnNlYXJjaC5lbWl0KGdyYXZzZWFyY2gpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdG9nZ2xlIGV4dGVuZGVkIHNlYXJjaCBmb3JtXG4gICAgICAgIHRoaXMudG9nZ2xlRXh0ZW5kZWRTZWFyY2hGb3JtLmVtaXQodHJ1ZSk7XG5cbiAgICB9XG5cbn1cbiJdfQ==