@knora/core
Version:
Knora ui module: core
176 lines • 33.3 kB
JavaScript
import * as tslib_1 from "tslib";
import { Injectable } from '@angular/core';
import { Constants } from '@knora/api';
import { KnoraConstants, KnoraSchema } from '../../declarations/api/knora-constants';
import { ExtendedSearchParams, SearchParamsService } from './search-params.service';
import * as i0 from "@angular/core";
import * as i1 from "./search-params.service";
/**
* @deprecated Use new service from `@knora/api` (github:dasch-swiss/knora-api-js-lib) instead
*
* Create GravSearch queries from provided parameters.
*/
var GravsearchGenerationService = /** @class */ (function () {
function GravsearchGenerationService(_searchParamsService) {
this._searchParamsService = _searchParamsService;
}
GravsearchGenerationService_1 = GravsearchGenerationService;
/**
* @deprecated since v10.0.0
*
* Will be replaced by `@knora/api` (github:knora-api-js-lib)
*
* Generates a Gravsearch query from the provided arguments.
*
* @param {PropertyWithValue[]} properties the properties specified by the user.
* @param {string} [mainResourceClassOption] the class of the main resource, if specified.
* @param {number} offset the offset to be used (nth page of results).
* @returns string - a KnarQL query string.
*/
GravsearchGenerationService.prototype.createGravsearchQuery = function (properties, mainResourceClassOption, offset) {
if (offset === void 0) { offset = 0; }
// class restriction for the resource searched for
var mainResourceClass = '';
// if given, create the class restriction for the main resource
if (mainResourceClassOption !== undefined) {
mainResourceClass = "?mainRes a <" + mainResourceClassOption + "> .";
}
// criteria for the order by statement
var orderByCriteria = [];
// statements to be returned in query results
var returnStatements = [];
// loop over given properties and create statements and filters from them
var props = properties.map(function (propWithVal, index) {
// represents the object of a statement
var propValue;
if (!propWithVal.property.isLinkProperty || propWithVal.valueLiteral.comparisonOperator.getClassName() === 'Exists') {
// it is not a linking property, create a variable for the value (to be used by a subsequent FILTER)
// OR the comparison operator Exists is used in which case we do not need to specify the object any further
propValue = "?propVal" + index;
}
else {
// it is a linking property and the comparison operator is not Exists, use its IRI
propValue = propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex);
}
// generate statement
var statement = "?mainRes <" + propWithVal.property.id + "> " + propValue + " .";
// check if it is a linking property that has to be wrapped in a FILTER NOT EXISTS (comparison operator NOT_EQUALS) to negate it
if (propWithVal.property.isLinkProperty && propWithVal.valueLiteral.comparisonOperator.getClassName() === 'NotEquals') {
// do not include statement in results, because the query checks for the absence of this statement
statement = "FILTER NOT EXISTS {\n" + statement + "\n\n\n}";
}
else {
// TODO: check if statement should be returned returned in results (Boolean flag from checkbox)
returnStatements.push(statement);
statement = "\n" + statement + "\n\n\n";
}
// generate restricting expression (e.g., a FILTER) if comparison operator is not Exists
var restriction = '';
// only create a FILTER if the comparison operator is not EXISTS and it is not a linking property
if (!propWithVal.property.isLinkProperty && propWithVal.valueLiteral.comparisonOperator.getClassName() !== 'Exists') {
// generate variable for value literal
var propValueLiteral = propValue + "Literal";
if (propWithVal.valueLiteral.comparisonOperator.getClassName() === 'Like') {
// generate statement to value literal
restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propValueLiteral + '\n';
// use regex function for LIKE
restriction += "FILTER regex(" + propValueLiteral + ", " + propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex) + ", \"i\")";
}
else if (propWithVal.valueLiteral.comparisonOperator.getClassName() === 'Match') {
// generate statement to value literal
restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propValueLiteral + '\n';
// use contains function for MATCH
restriction += "FILTER <" + KnoraConstants.MatchFunction + ">(" + propValueLiteral + ", " + propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex) + ")";
}
else if (propWithVal.property.objectType === Constants.DateValue) {
// handle date property
restriction = "FILTER(knora-api:toSimpleDate(" + propValue + ") " + propWithVal.valueLiteral.comparisonOperator.type + " " + propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex) + ")";
}
else if (propWithVal.property.objectType === Constants.ListValue) {
// handle list node
restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex) + '\n';
// check for comparison operator "not equals"
if (propWithVal.valueLiteral.comparisonOperator.getClassName() === 'NotEquals') {
restriction = "FILTER NOT EXISTS {\n " + restriction + "\n }";
}
}
else {
// generate statement to value literal
restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propValueLiteral + '\n';
// generate filter expression
restriction += "FILTER(" + propValueLiteral + " " + propWithVal.valueLiteral.comparisonOperator.type + " " + propWithVal.valueLiteral.value.toSparql(KnoraSchema.complex) + ")";
}
}
// check if current value is a sort criterion
if (propWithVal.isSortCriterion)
orderByCriteria.push(propValue);
return statement + "\n" + restriction + "\n";
});
var orderByStatement = '';
if (orderByCriteria.length > 0) {
orderByStatement = "\nORDER BY " + orderByCriteria.join(' ') + "\n";
}
// template of the Gravsearch query with dynamic components
var gravsearchTemplate = "\nPREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>\nCONSTRUCT {\n\n?mainRes knora-api:isMainResource true .\n\n" + returnStatements.join('\n') + "\n\n} WHERE {\n\n?mainRes a knora-api:Resource .\n\n" + mainResourceClass + "\n\n" + props.join('') + "\n\n}\n" + orderByStatement;
// offset component of the Gravsearch query
var offsetTemplate = "\nOFFSET " + offset + "\n";
// function that generates the same KnarQL query with the given offset
var generateGravsearchQueryWithCustomOffset = function (localOffset) {
var offsetCustomTemplate = "\nOFFSET " + localOffset + "\n";
return gravsearchTemplate + offsetCustomTemplate;
};
if (offset === 0) {
// store the function so another KnarQL query can be created with an increased offset
this._searchParamsService.changeSearchParamsMsg(new ExtendedSearchParams(generateGravsearchQueryWithCustomOffset));
}
return gravsearchTemplate + offsetTemplate;
};
var GravsearchGenerationService_1;
/**
* @ignore
*
* Map of complex knora-api value types to simple ones.
* Use computed property name: http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer.
*/
GravsearchGenerationService.typeConversionComplexToSimple = {
'http://api.knora.org/ontology/knora-api/v2#IntValue': Constants.XsdInteger,
'http://api.knora.org/ontology/knora-api/v2#DecimalValue': Constants.XsdDecimal,
'http://api.knora.org/ontology/knora-api/v2#BooleanValue': Constants.XsdBoolean,
'http://api.knora.org/ontology/knora-api/v2#TextValue': Constants.XsdString,
'http://api.knora.org/ontology/knora-api/v2#UriValue': Constants.XsdAnyUri,
'http://api.knora.org/ontology/knora-api/v2#DateValue': KnoraConstants.dateSimple,
'http://api.knora.org/ontology/knora-api/v2#IntervalValue': KnoraConstants.intervalSimple,
'http://api.knora.org/ontology/knora-api/v2#GeomValue': KnoraConstants.geomSimple,
'http://api.knora.org/ontology/knora-api/v2#ColorValue': KnoraConstants.colorSimple,
'http://api.knora.org/ontology/knora-api/v2#GeonameValue': KnoraConstants.geonameSimple,
'http://api.knora.org/ontology/knora-api/v2#StillImageFileValue': KnoraConstants.fileSimple,
'http://api.knora.org/ontology/knora-api/v2#FileValue': KnoraConstants.fileSimple,
'http://api.knora.org/ontology/knora-api/v2#MovingImageFileValue': KnoraConstants.fileSimple,
'http://api.knora.org/ontology/knora-api/v2#DDDFileValue': KnoraConstants.fileSimple,
'http://api.knora.org/ontology/knora-api/v2#AudioFileValue': KnoraConstants.fileSimple,
'http://api.knora.org/ontology/knora-api/v2#DocumentFileValue': KnoraConstants.fileSimple,
'http://api.knora.org/ontology/knora-api/v2#TextFileValue': KnoraConstants.fileSimple,
'http://api.knora.org/ontology/knora-api/v2#ListValue': KnoraConstants.listNodeSimple
};
GravsearchGenerationService.complexTypeToProp = {
'http://api.knora.org/ontology/knora-api/v2#IntValue': Constants.IntValueAsInt,
'http://api.knora.org/ontology/knora-api/v2#DecimalValue': Constants.DecimalValueAsDecimal,
'http://api.knora.org/ontology/knora-api/v2#BooleanValue': Constants.BooleanValueAsBoolean,
'http://api.knora.org/ontology/knora-api/v2#TextValue': Constants.ValueAsString,
'http://api.knora.org/ontology/knora-api/v2#UriValue': Constants.UriValueAsUri,
'http://api.knora.org/ontology/knora-api/v2#ListValue': Constants.ListValueAsListNode
};
GravsearchGenerationService.ctorParameters = function () { return [
{ type: SearchParamsService }
]; };
GravsearchGenerationService.ngInjectableDef = i0.ɵɵdefineInjectable({ factory: function GravsearchGenerationService_Factory() { return new GravsearchGenerationService(i0.ɵɵinject(i1.SearchParamsService)); }, token: GravsearchGenerationService, providedIn: "root" });
GravsearchGenerationService = GravsearchGenerationService_1 = tslib_1.__decorate([
Injectable({
providedIn: 'root'
}),
tslib_1.__metadata("design:paramtypes", [SearchParamsService])
], GravsearchGenerationService);
return GravsearchGenerationService;
}());
export { GravsearchGenerationService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3Jhdi1zZWFyY2guc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Brbm9yYS9jb3JlLyIsInNvdXJjZXMiOlsibGliL3NlcnZpY2VzL3YyL2dyYXYtc2VhcmNoLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV2QyxPQUFPLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBR3JGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDOzs7QUFFcEY7Ozs7R0FJRztBQUlIO0lBc0NJLHFDQUFvQixvQkFBeUM7UUFBekMseUJBQW9CLEdBQXBCLG9CQUFvQixDQUFxQjtJQUFJLENBQUM7b0NBdEN6RCwyQkFBMkI7SUF3Q3BDOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsMkRBQXFCLEdBQXJCLFVBQXNCLFVBQStCLEVBQUUsdUJBQWdDLEVBQUUsTUFBa0I7UUFBbEIsdUJBQUEsRUFBQSxVQUFrQjtRQUV2RyxrREFBa0Q7UUFDbEQsSUFBSSxpQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFFM0IsK0RBQStEO1FBQy9ELElBQUksdUJBQXVCLEtBQUssU0FBUyxFQUFFO1lBQ3ZDLGlCQUFpQixHQUFHLGlCQUFlLHVCQUF1QixRQUFLLENBQUM7U0FDbkU7UUFFRCxzQ0FBc0M7UUFDdEMsSUFBTSxlQUFlLEdBQUcsRUFBRSxDQUFDO1FBRTNCLDZDQUE2QztRQUM3QyxJQUFNLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztRQUU1Qix5RUFBeUU7UUFDekUsSUFBTSxLQUFLLEdBQWEsVUFBVSxDQUFDLEdBQUcsQ0FDbEMsVUFBQyxXQUE4QixFQUFFLEtBQWE7WUFFMUMsdUNBQXVDO1lBQ3ZDLElBQUksU0FBUyxDQUFDO1lBQ2QsSUFBSSxDQUFDLFdBQVcs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aUUsRUFBRSxjQUFjLENBQUMsVUFBVTtRQUM1Rix5REFBeUQsRUFBRSxjQUFjLENBQUMsVUFBVTtRQUNwRiwyREFBMkQsRUFBRSxjQUFjLENBQUMsVUFBVTtRQUN0Riw4REFBOEQsRUFBRSxjQUFjLENBQUMsVUFBVTtRQUN6RiwwREFBMEQsRUFBRSxjQUFjLENBQUMsVUFBVTtRQUNyRixzREFBc0QsRUFBRSxjQUFjLENBQUMsY0FBYztLQUN4RixDQUFDO0lBRVksNkNBQWlCLEdBQUc7UUFDOUIscURBQXFELEVBQUUsU0FBUyxDQUFDLGFBQWE7UUFDOUUseURBQXlELEVBQUUsU0FBUyxDQUFDLHFCQUFxQjtRQUMxRix5REFBeUQsRUFBRSxTQUFTLENBQUMscUJBQXFCO1FBQzFGLHNEQUFzRCxFQUFFLFNBQVMsQ0FBQyxhQUFhO1FBQy9FLHFEQUFxRCxFQUFFLFNBQVMsQ0FBQyxhQUFhO1FBQzlFLHNEQUFzRCxFQUFFLFNBQVMsQ0FBQyxtQkFBbUI7S0FDeEYsQ0FBQzs7Z0JBRXdDLG1CQUFtQjs7O0lBdENwRCwyQkFBMkI7UUFIdkMsVUFBVSxDQUFDO1lBQ1IsVUFBVSxFQUFFLE1BQU07U0FDckIsQ0FBQztpREF1QzRDLG1CQUFtQjtPQXRDcEQsMkJBQTJCLENBME12QztzQ0ExTkQ7Q0EwTkMsQUExTUQsSUEwTUM7U0ExTVksMkJBQTJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29uc3RhbnRzIH0gZnJvbSAnQGtub3JhL2FwaSc7XG5cbmltcG9ydCB7IEtub3JhQ29uc3RhbnRzLCBLbm9yYVNjaGVtYSB9IGZyb20gJy4uLy4uL2RlY2xhcmF0aW9ucy9hcGkva25vcmEtY29uc3RhbnRzJztcbmltcG9ydCB7IFByb3BlcnR5V2l0aFZhbHVlIH0gZnJvbSAnLi4vLi4vZGVjbGFyYXRpb25zL2FwaS9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBFeHRlbmRlZFNlYXJjaFBhcmFtcywgU2VhcmNoUGFyYW1zU2VydmljZSB9IGZyb20gJy4vc2VhcmNoLXBhcmFtcy5zZXJ2aWNlJztcblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgbmV3IHNlcnZpY2UgZnJvbSBgQGtub3JhL2FwaWAgKGdpdGh1YjpkYXNjaC1zd2lzcy9rbm9yYS1hcGktanMtbGliKSBpbnN0ZWFkXG4gKlxuICogQ3JlYXRlIEdyYXZTZWFyY2ggcXVlcmllcyBmcm9tIHByb3ZpZGVkIHBhcmFtZXRlcnMuXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgR3JhdnNlYXJjaEdlbmVyYXRpb25TZXJ2aWNlIHtcblxuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKlxuICAgICAqIE1hcCBvZiBjb21wbGV4IGtub3JhLWFwaSB2YWx1ZSB0eXBlcyB0byBzaW1wbGUgb25lcy5cbiAgICAgKiBVc2UgY29tcHV0ZWQgcHJvcGVydHkgbmFtZTogaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC1pbml0aWFsaXplci5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHR5cGVDb252ZXJzaW9uQ29tcGxleFRvU2ltcGxlID0ge1xuICAgICAgICAnaHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyI0ludFZhbHVlJzogQ29uc3RhbnRzLlhzZEludGVnZXIsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjRGVjaW1hbFZhbHVlJzogQ29uc3RhbnRzLlhzZERlY2ltYWwsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjQm9vbGVhblZhbHVlJzogQ29uc3RhbnRzLlhzZEJvb2xlYW4sXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjVGV4dFZhbHVlJzogQ29uc3RhbnRzLlhzZFN0cmluZyxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNVcmlWYWx1ZSc6IENvbnN0YW50cy5Yc2RBbnlVcmksXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjRGF0ZVZhbHVlJzogS25vcmFDb25zdGFudHMuZGF0ZVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNJbnRlcnZhbFZhbHVlJzogS25vcmFDb25zdGFudHMuaW50ZXJ2YWxTaW1wbGUsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjR2VvbVZhbHVlJzogS25vcmFDb25zdGFudHMuZ2VvbVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNDb2xvclZhbHVlJzogS25vcmFDb25zdGFudHMuY29sb3JTaW1wbGUsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjR2VvbmFtZVZhbHVlJzogS25vcmFDb25zdGFudHMuZ2VvbmFtZVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNTdGlsbEltYWdlRmlsZVZhbHVlJzogS25vcmFDb25zdGFudHMuZmlsZVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNGaWxlVmFsdWUnOiBLbm9yYUNvbnN0YW50cy5maWxlU2ltcGxlLFxuICAgICAgICAnaHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyI01vdmluZ0ltYWdlRmlsZVZhbHVlJzogS25vcmFDb25zdGFudHMuZmlsZVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNERERGaWxlVmFsdWUnOiBLbm9yYUNvbnN0YW50cy5maWxlU2ltcGxlLFxuICAgICAgICAnaHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyI0F1ZGlvRmlsZVZhbHVlJzogS25vcmFDb25zdGFudHMuZmlsZVNpbXBsZSxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNEb2N1bWVudEZpbGVWYWx1ZSc6IEtub3JhQ29uc3RhbnRzLmZpbGVTaW1wbGUsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjVGV4dEZpbGVWYWx1ZSc6IEtub3JhQ29uc3RhbnRzLmZpbGVTaW1wbGUsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjTGlzdFZhbHVlJzogS25vcmFDb25zdGFudHMubGlzdE5vZGVTaW1wbGVcbiAgICB9O1xuXG4gICAgcHVibGljIHN0YXRpYyBjb21wbGV4VHlwZVRvUHJvcCA9IHtcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNJbnRWYWx1ZSc6IENvbnN0YW50cy5JbnRWYWx1ZUFzSW50LFxuICAgICAgICAnaHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyI0RlY2ltYWxWYWx1ZSc6IENvbnN0YW50cy5EZWNpbWFsVmFsdWVBc0RlY2ltYWwsXG4gICAgICAgICdodHRwOi8vYXBpLmtub3JhLm9yZy9vbnRvbG9neS9rbm9yYS1hcGkvdjIjQm9vbGVhblZhbHVlJzogQ29uc3RhbnRzLkJvb2xlYW5WYWx1ZUFzQm9vbGVhbixcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNUZXh0VmFsdWUnOiBDb25zdGFudHMuVmFsdWVBc1N0cmluZyxcbiAgICAgICAgJ2h0dHA6Ly9hcGkua25vcmEub3JnL29udG9sb2d5L2tub3JhLWFwaS92MiNVcmlWYWx1ZSc6IENvbnN0YW50cy5VcmlWYWx1ZUFzVXJpLFxuICAgICAgICAnaHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyI0xpc3RWYWx1ZSc6IENvbnN0YW50cy5MaXN0VmFsdWVBc0xpc3ROb2RlXG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX3NlYXJjaFBhcmFtc1NlcnZpY2U6IFNlYXJjaFBhcmFtc1NlcnZpY2UpIHsgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWQgc2luY2UgdjEwLjAuMFxuICAgICAqXG4gICAgICogV2lsbCBiZSByZXBsYWNlZCBieSBgQGtub3JhL2FwaWAgKGdpdGh1Yjprbm9yYS1hcGktanMtbGliKVxuICAgICAqXG4gICAgICogR2VuZXJhdGVzIGEgR3JhdnNlYXJjaCBxdWVyeSBmcm9tIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1Byb3BlcnR5V2l0aFZhbHVlW119IHByb3BlcnRpZXMgdGhlIHByb3BlcnRpZXMgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbbWFpblJlc291cmNlQ2xhc3NPcHRpb25dIHRoZSBjbGFzcyBvZiB0aGUgbWFpbiByZXNvdXJjZSwgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgdGhlIG9mZnNldCB0byBiZSB1c2VkIChudGggcGFnZSBvZiByZXN1bHRzKS5cbiAgICAgKiBAcmV0dXJucyBzdHJpbmcgLSBhIEtuYXJRTCBxdWVyeSBzdHJpbmcuXG4gICAgICovXG4gICAgY3JlYXRlR3JhdnNlYXJjaFF1ZXJ5KHByb3BlcnRpZXM6IFByb3BlcnR5V2l0aFZhbHVlW10sIG1haW5SZXNvdXJjZUNsYXNzT3B0aW9uPzogc3RyaW5nLCBvZmZzZXQ6IG51bWJlciA9IDApOiBzdHJpbmcge1xuXG4gICAgICAgIC8vIGNsYXNzIHJlc3RyaWN0aW9uIGZvciB0aGUgcmVzb3VyY2Ugc2VhcmNoZWQgZm9yXG4gICAgICAgIGxldCBtYWluUmVzb3VyY2VDbGFzcyA9ICcnO1xuXG4gICAgICAgIC8vIGlmIGdpdmVuLCBjcmVhdGUgdGhlIGNsYXNzIHJlc3RyaWN0aW9uIGZvciB0aGUgbWFpbiByZXNvdXJjZVxuICAgICAgICBpZiAobWFpblJlc291cmNlQ2xhc3NPcHRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbWFpblJlc291cmNlQ2xhc3MgPSBgP21haW5SZXMgYSA8JHttYWluUmVzb3VyY2VDbGFzc09wdGlvbn0+IC5gO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY3JpdGVyaWEgZm9yIHRoZSBvcmRlciBieSBzdGF0ZW1lbnRcbiAgICAgICAgY29uc3Qgb3JkZXJCeUNyaXRlcmlhID0gW107XG5cbiAgICAgICAgLy8gc3RhdGVtZW50cyB0byBiZSByZXR1cm5lZCBpbiBxdWVyeSByZXN1bHRzXG4gICAgICAgIGNvbnN0IHJldHVyblN0YXRlbWVudHMgPSBbXTtcblxuICAgICAgICAvLyBsb29wIG92ZXIgZ2l2ZW4gcHJvcGVydGllcyBhbmQgY3JlYXRlIHN0YXRlbWVudHMgYW5kIGZpbHRlcnMgZnJvbSB0aGVtXG4gICAgICAgIGNvbnN0IHByb3BzOiBzdHJpbmdbXSA9IHByb3BlcnRpZXMubWFwKFxuICAgICAgICAgICAgKHByb3BXaXRoVmFsOiBQcm9wZXJ0eVdpdGhWYWx1ZSwgaW5kZXg6IG51bWJlcikgPT4ge1xuXG4gICAgICAgICAgICAgICAgLy8gcmVwcmVzZW50cyB0aGUgb2JqZWN0IG9mIGEgc3RhdGVtZW50XG4gICAgICAgICAgICAgICAgbGV0IHByb3BWYWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAoIXByb3BXaXRoVmFsLnByb3BlcnR5LmlzTGlua1Byb3BlcnR5IHx8IHByb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC5jb21wYXJpc29uT3BlcmF0b3IuZ2V0Q2xhc3NOYW1lKCkgPT09ICdFeGlzdHMnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGl0IGlzIG5vdCBhIGxpbmtpbmcgcHJvcGVydHksIGNyZWF0ZSBhIHZhcmlhYmxlIGZvciB0aGUgdmFsdWUgKHRvIGJlIHVzZWQgYnkgYSBzdWJzZXF1ZW50IEZJTFRFUilcbiAgICAgICAgICAgICAgICAgICAgLy8gT1IgdGhlIGNvbXBhcmlzb24gb3BlcmF0b3IgRXhpc3RzIGlzIHVzZWQgaW4gd2hpY2ggY2FzZSB3ZSBkbyBub3QgbmVlZCB0byBzcGVjaWZ5IHRoZSBvYmplY3QgYW55IGZ1cnRoZXJcbiAgICAgICAgICAgICAgICAgICAgcHJvcFZhbHVlID0gYD9wcm9wVmFsJHtpbmRleH1gO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGl0IGlzIGEgbGlua2luZyBwcm9wZXJ0eSBhbmQgdGhlIGNvbXBhcmlzb24gb3BlcmF0b3IgaXMgbm90IEV4aXN0cywgdXNlIGl0cyBJUklcbiAgICAgICAgICAgICAgICAgICAgcHJvcFZhbHVlID0gcHJvcFdpdGhWYWwudmFsdWVMaXRlcmFsLnZhbHVlLnRvU3BhcnFsKEtub3JhU2NoZW1hLmNvbXBsZXgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIGdlbmVyYXRlIHN0YXRlbWVudFxuICAgICAgICAgICAgICAgIGxldCBzdGF0ZW1lbnQ6IHN0cmluZyA9IGA/bWFpblJlcyA8JHtwcm9wV2l0aFZhbC5wcm9wZXJ0eS5pZH0+ICR7cHJvcFZhbHVlfSAuYDtcblxuICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGl0IGlzIGEgbGlua2luZyBwcm9wZXJ0eSB0aGF0IGhhcyB0byBiZSB3cmFwcGVkIGluIGEgRklMVEVSIE5PVCBFWElTVFMgKGNvbXBhcmlzb24gb3BlcmF0b3IgTk9UX0VRVUFMUykgdG8gbmVnYXRlIGl0XG4gICAgICAgICAgICAgICAgaWYgKHByb3BXaXRoVmFsLnByb3BlcnR5LmlzTGlua1Byb3BlcnR5ICYmIHByb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC5jb21wYXJpc29uT3BlcmF0b3IuZ2V0Q2xhc3NOYW1lKCkgPT09ICdOb3RFcXVhbHMnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBpbmNsdWRlIHN0YXRlbWVudCBpbiByZXN1bHRzLCBiZWNhdXNlIHRoZSBxdWVyeSBjaGVja3MgZm9yIHRoZSBhYnNlbmNlIG9mIHRoaXMgc3RhdGVtZW50XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudCA9IGBGSUxURVIgTk9UIEVYSVNUUyB7XG4ke3N0YXRlbWVudH1cblxuXG59YDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBjaGVjayBpZiBzdGF0ZW1lbnQgc2hvdWxkIGJlIHJldHVybmVkIHJldHVybmVkIGluIHJlc3VsdHMgKEJvb2xlYW4gZmxhZyBmcm9tIGNoZWNrYm94KVxuICAgICAgICAgICAgICAgICAgICByZXR1cm5TdGF0ZW1lbnRzLnB1c2goc3RhdGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50ID0gYFxuJHtzdGF0ZW1lbnR9XG5cblxuYDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBnZW5lcmF0ZSByZXN0cmljdGluZyBleHByZXNzaW9uIChlLmcuLCBhIEZJTFRFUikgaWYgY29tcGFyaXNvbiBvcGVyYXRvciBpcyBub3QgRXhpc3RzXG4gICAgICAgICAgICAgICAgbGV0IHJlc3RyaWN0aW9uOiBzdHJpbmcgPSAnJztcbiAgICAgICAgICAgICAgICAvLyBvbmx5IGNyZWF0ZSBhIEZJTFRFUiBpZiB0aGUgY29tcGFyaXNvbiBvcGVyYXRvciBpcyBub3QgRVhJU1RTIGFuZCBpdCBpcyBub3QgYSBsaW5raW5nIHByb3BlcnR5XG4gICAgICAgICAgICAgICAgaWYgKCFwcm9wV2l0aFZhbC5wcm9wZXJ0eS5pc0xpbmtQcm9wZXJ0eSAmJiBwcm9wV2l0aFZhbC52YWx1ZUxpdGVyYWwuY29tcGFyaXNvbk9wZXJhdG9yLmdldENsYXNzTmFtZSgpICE9PSAnRXhpc3RzJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBnZW5lcmF0ZSB2YXJpYWJsZSBmb3IgdmFsdWUgbGl0ZXJhbFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9wVmFsdWVMaXRlcmFsID0gYCR7cHJvcFZhbHVlfUxpdGVyYWxgO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wV2l0aFZhbC52YWx1ZUxpdGVyYWwuY29tcGFyaXNvbk9wZXJhdG9yLmdldENsYXNzTmFtZSgpID09PSAnTGlrZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdlbmVyYXRlIHN0YXRlbWVudCB0byB2YWx1ZSBsaXRlcmFsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN0cmljdGlvbiA9IGAke3Byb3BWYWx1ZX0gPCR7R3JhdnNlYXJjaEdlbmVyYXRpb25TZXJ2aWNlLmNvbXBsZXhUeXBlVG9Qcm9wW3Byb3BXaXRoVmFsLnByb3BlcnR5Lm9iamVjdFR5cGVdfT4gJHtwcm9wVmFsdWVMaXRlcmFsfWAgKyAnXFxuJztcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZSByZWdleCBmdW5jdGlvbiBmb3IgTElLRVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3Rpb24gKz0gYEZJTFRFUiByZWdleCgke3Byb3BWYWx1ZUxpdGVyYWx9LCAke3Byb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC52YWx1ZS50b1NwYXJxbChLbm9yYVNjaGVtYS5jb21wbGV4KX0sIFwiaVwiKWA7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvcFdpdGhWYWwudmFsdWVMaXRlcmFsLmNvbXBhcmlzb25PcGVyYXRvci5nZXRDbGFzc05hbWUoKSA9PT0gJ01hdGNoJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgc3RhdGVtZW50IHRvIHZhbHVlIGxpdGVyYWxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gYCR7cHJvcFZhbHVlfSA8JHtHcmF2c2VhcmNoR2VuZXJhdGlvblNlcnZpY2UuY29tcGxleFR5cGVUb1Byb3BbcHJvcFdpdGhWYWwucHJvcGVydHkub2JqZWN0VHlwZV19PiAke3Byb3BWYWx1ZUxpdGVyYWx9YCArICdcXG4nO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlIGNvbnRhaW5zIGZ1bmN0aW9uIGZvciBNQVRDSFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3Rpb24gKz0gYEZJTFRFUiA8JHtLbm9yYUNvbnN0YW50cy5NYXRjaEZ1bmN0aW9ufT4oJHtwcm9wVmFsdWVMaXRlcmFsfSwgJHtwcm9wV2l0aFZhbC52YWx1ZUxpdGVyYWwudmFsdWUudG9TcGFycWwoS25vcmFTY2hlbWEuY29tcGxleCl9KWA7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvcFdpdGhWYWwucHJvcGVydHkub2JqZWN0VHlwZSA9PT0gQ29uc3RhbnRzLkRhdGVWYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxlIGRhdGUgcHJvcGVydHlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gYEZJTFRFUihrbm9yYS1hcGk6dG9TaW1wbGVEYXRlKCR7cHJvcFZhbHVlfSkgJHtwcm9wV2l0aFZhbC52YWx1ZUxpdGVyYWwuY29tcGFyaXNvbk9wZXJhdG9yLnR5cGV9ICR7cHJvcFdpdGhWYWwudmFsdWVMaXRlcmFsLnZhbHVlLnRvU3BhcnFsKEtub3JhU2NoZW1hLmNvbXBsZXgpfSlgO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHByb3BXaXRoVmFsLnByb3BlcnR5Lm9iamVjdFR5cGUgPT09IENvbnN0YW50cy5MaXN0VmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBsaXN0IG5vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gYCR7cHJvcFZhbHVlfSA8JHtHcmF2c2VhcmNoR2VuZXJhdGlvblNlcnZpY2UuY29tcGxleFR5cGVUb1Byb3BbcHJvcFdpdGhWYWwucHJvcGVydHkub2JqZWN0VHlwZV19PiAke3Byb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC52YWx1ZS50b1NwYXJxbChLbm9yYVNjaGVtYS5jb21wbGV4KX1gICsgJ1xcbic7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgY29tcGFyaXNvbiBvcGVyYXRvciBcIm5vdCBlcXVhbHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC5jb21wYXJpc29uT3BlcmF0b3IuZ2V0Q2xhc3NOYW1lKCkgPT09ICdOb3RFcXVhbHMnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3Rpb24gPSBgRklMVEVSIE5PVCBFWElTVFMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3Jlc3RyaWN0aW9ufVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1gO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgc3RhdGVtZW50IHRvIHZhbHVlIGxpdGVyYWxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gYCR7cHJvcFZhbHVlfSA8JHtHcmF2c2VhcmNoR2VuZXJhdGlvblNlcnZpY2UuY29tcGxleFR5cGVUb1Byb3BbcHJvcFdpdGhWYWwucHJvcGVydHkub2JqZWN0VHlwZV19PiAke3Byb3BWYWx1ZUxpdGVyYWx9YCArICdcXG4nO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGUgZmlsdGVyIGV4cHJlc3Npb25cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uICs9IGBGSUxURVIoJHtwcm9wVmFsdWVMaXRlcmFsfSAke3Byb3BXaXRoVmFsLnZhbHVlTGl0ZXJhbC5jb21wYXJpc29uT3BlcmF0b3IudHlwZX0gJHtwcm9wV2l0aFZhbC52YWx1ZUxpdGVyYWwudmFsdWUudG9TcGFycWwoS25vcmFTY2hlbWEuY29tcGxleCl9KWA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBjdXJyZW50IHZhbHVlIGlzIGEgc29ydCBjcml0ZXJpb25cbiAgICAgICAgICAgICAgICBpZiAocHJvcFdpdGhWYWwuaXNTb3J0Q3JpdGVyaW9uKSBvcmRlckJ5Q3JpdGVyaWEucHVzaChwcm9wVmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke3N0YXRlbWVudH1cbiR7cmVzdHJpY3Rpb259XG5gO1xuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBsZXQgb3JkZXJCeVN0YXRlbWVudCA9ICcnO1xuXG4gICAgICAgIGlmIChvcmRlckJ5Q3JpdGVyaWEubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgb3JkZXJCeVN0YXRlbWVudCA9IGBcbk9SREVSIEJZICR7b3JkZXJCeUNyaXRlcmlhLmpvaW4oJyAnKX1cbmA7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0ZW1wbGF0ZSBvZiB0aGUgR3JhdnNlYXJjaCBxdWVyeSB3aXRoIGR5bmFtaWMgY29tcG9uZW50c1xuICAgICAgICBjb25zdCBncmF2c2VhcmNoVGVtcGxhdGUgPSBgXG5QUkVGSVgga25vcmEtYXBpOiA8aHR0cDovL2FwaS5rbm9yYS5vcmcvb250b2xvZ3kva25vcmEtYXBpL3YyIz5cbkNPTlNUUlVDVCB7XG5cbj9tYWluUmVzIGtub3JhLWFwaTppc01haW5SZXNvdXJjZSB0cnVlIC5cblxuJHtyZXR1cm5TdGF0ZW1lbnRzLmpvaW4oJ1xcbicpfVxuXG59IFdIRVJFIHtcblxuP21haW5SZXMgYSBrbm9yYS1hcGk6UmVzb3VyY2UgLlxuXG4ke21haW5SZXNvdXJjZUNsYXNzfVxuXG4ke3Byb3BzLmpvaW4oJycpfVxuXG59XG4ke29yZGVyQnlTdGF0ZW1lbnR9YDtcblxuICAgICAgICAvLyBvZmZzZXQgY29tcG9uZW50IG9mIHRoZSBHcmF2c2VhcmNoIHF1ZXJ5XG4gICAgICAgIGNvbnN0IG9mZnNldFRlbXBsYXRlID0gYFxuT0ZGU0VUICR7b2Zmc2V0fVxuYDtcblxuICAgICAgICAvLyBmdW5jdGlvbiB0aGF0IGdlbmVyYXRlcyB0aGUgc2FtZSBLbmFyUUwgcXVlcnkgd2l0aCB0aGUgZ2l2ZW4gb2Zmc2V0XG4gICAgICAgIGNvbnN0IGdlbmVyYXRlR3JhdnNlYXJjaFF1ZXJ5V2l0aEN1c3RvbU9mZnNldCA9IChsb2NhbE9mZnNldDogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldEN1c3RvbVRlbXBsYXRlID0gYFxuT0ZGU0VUICR7bG9jYWxPZmZzZXR9XG5gO1xuXG4gICAgICAgICAgICByZXR1cm4gZ3JhdnNlYXJjaFRlbXBsYXRlICsgb2Zmc2V0Q3VzdG9tVGVtcGxhdGU7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG9mZnNldCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gc3RvcmUgdGhlIGZ1bmN0aW9uIHNvIGFub3RoZXIgS25hclFMIHF1ZXJ5IGNhbiBiZSBjcmVhdGVkIHdpdGggYW4gaW5jcmVhc2VkIG9mZnNldFxuICAgICAgICAgICAgdGhpcy5fc2VhcmNoUGFyYW1zU2VydmljZS5jaGFuZ2VTZWFyY2hQYXJhbXNNc2cobmV3IEV4dGVuZGVkU2VhcmNoUGFyYW1zKGdlbmVyYXRlR3JhdnNlYXJjaFF1ZXJ5V2l0aEN1c3RvbU9mZnNldCkpO1xuICAgICAgICB9XG5cblxuICAgICAgICByZXR1cm4gZ3JhdnNlYXJjaFRlbXBsYXRlICsgb2Zmc2V0VGVtcGxhdGU7XG5cbiAgICB9XG5cbn1cbiJdfQ==