@fingerprintsoft/angular-spring-hal
Version:
This Angular module offers a HAL/JSON http-client to easily interact with a Spring Data Rest API or any API that implements the Spring Data Rest resource model
216 lines • 41.9 kB
JavaScript
import { of as observableOf, throwError as observableThrowError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { HttpParams } from '@angular/common/http';
import { ResourceHelper } from './resource-helper';
import { Injectable } from '@angular/core';
import { CustomEncoder } from '../services/CustomEncoder';
import { Utils } from '../Utils';
import { CacheHelper } from '../cache/cache.helper';
import * as i0 from "@angular/core";
export class Resource {
constructor() {
}
get subtypes() {
return this._subtypes;
}
set subtypes(_subtypes) {
this._subtypes = _subtypes;
}
// Get self
uri() {
if (!Utils.isNullOrUndefined(this._links) && !Utils.isNullOrUndefined(this._links['self'])) {
return ResourceHelper.getProxy(this._links['self'].href);
}
else {
return null;
}
}
// Get rel uri
relURI(rel) {
if (!Utils.isNullOrUndefined(this._links) && !Utils.isNullOrUndefined(this._links[rel])) {
return ResourceHelper.getProxy(this._links[rel].href);
}
else {
return null;
}
}
// Get related resource
getRelation(type, relation, builder, expireMs = CacheHelper.defaultExpire, isCacheActive = true) {
let result = new type();
if (this.existRelationLink(relation)) {
if (CacheHelper.ifPresent(this.getRelationLinkHref(relation), null, null, isCacheActive)) {
const cached = CacheHelper.get(this.getRelationLinkHref(relation));
return observableOf(cached);
}
let observable = ResourceHelper.getHttp().get(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), { headers: ResourceHelper.headers });
return observable.pipe(map((data) => {
if (builder) {
for (const embeddedClassName of Object.keys(data['_links'])) {
if (embeddedClassName == 'self') {
let href = data._links[embeddedClassName].href;
let idx = href.lastIndexOf('/');
let realClassName = href.replace(ResourceHelper.getRootUri(), '').substring(0, idx);
result = ResourceHelper.searchSubtypes(builder, realClassName, result);
break;
}
}
}
let resource = ResourceHelper.instantiateResource(result, data);
CacheHelper.put(this.getRelationLinkHref(relation), resource, expireMs);
return resource;
}));
}
else {
return observableOf(null);
}
}
addRelations(relation, resources) {
if (!Utils.isNullOrUndefined(this._links) && !Utils.isNullOrUndefined(this._links[relation])) {
let header = ResourceHelper.headers.append('Content-Type', 'text/uri-list');
let uris = resources.map(r => r._links.self.href).join('\n');
return ResourceHelper.getHttp().post(ResourceHelper.getProxy(this._links[relation].href), uris, { headers: header });
}
else {
return observableThrowError('no relation found');
}
}
replaceRelations(relation, resources) {
if (!Utils.isNullOrUndefined(this._links) && !Utils.isNullOrUndefined(this._links[relation])) {
let header = ResourceHelper.headers.append('Content-Type', 'text/uri-list');
let uris = resources.map(r => r._links.self.href).join('\n');
return ResourceHelper.getHttp().put(ResourceHelper.getProxy(this._links[relation].href), uris, { headers: header });
}
else {
return observableThrowError('no relation found');
}
}
// Get collection of related resources
getRelationArray(type, relation, _embedded, options, builder, expireMs = CacheHelper.defaultExpire, isCacheActive = true) {
const params = ResourceHelper.optionParams(new HttpParams({ encoder: new CustomEncoder() }), options);
const result = ResourceHelper.createEmptyResult(Utils.isNullOrUndefined(_embedded) ? '_embedded' : _embedded);
if (this.existRelationLink(relation)) {
if (CacheHelper.ifPresent(this.getRelationLinkHref(relation), null, options, isCacheActive))
return observableOf(CacheHelper.getArray(this.getRelationLinkHref(relation)));
let observable = ResourceHelper.getHttp().get(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), {
headers: ResourceHelper.headers, observe: 'response', params: params,
});
return observable
.pipe(map(response => ResourceHelper.instantiateResourceCollection(type, response, result, builder)), catchError(error => observableThrowError(error))).pipe(map((array) => {
CacheHelper.putArray(this.getRelationLinkHref(relation), array.result, expireMs);
return array.result;
}));
}
else {
return observableOf([]);
}
}
getProjection(type, resource, id, projectionName, expireMs = CacheHelper.defaultExpire, isCacheActive = true) {
const uri = this.getResourceUrl(resource).concat('/', id).concat('?projection=' + projectionName);
const result = new type();
if (CacheHelper.ifPresent(uri, null, null, isCacheActive)) {
const cached = CacheHelper.get(uri);
return observableOf(cached);
}
let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers });
return observable.pipe(map(data => {
let resource = ResourceHelper.instantiateResource(result, data);
CacheHelper.put(uri, resource, expireMs);
return resource;
}), catchError(error => observableThrowError(error)));
}
getProjectionArray(type, resource, projectionName, expireMs = CacheHelper.defaultExpire, isCacheActive = true) {
const uri = this.getResourceUrl(resource).concat('?projection=' + projectionName);
const result = ResourceHelper.createEmptyResult('_embedded');
if (CacheHelper.ifPresent(uri, null, null, isCacheActive))
return observableOf(CacheHelper.getArray(uri));
let observable = ResourceHelper.getHttp().get(uri, { headers: ResourceHelper.headers, observe: 'response' });
return observable.pipe(map(response => ResourceHelper.instantiateResourceCollection(type, response, result)), map((array) => {
CacheHelper.putArray(uri, array.result, expireMs);
return array.result;
}));
}
getResourceUrl(resource) {
let url = ResourceHelper.getURL();
if (!url.endsWith('/')) {
url = url.concat('/');
}
if (resource) {
return url.concat(resource);
}
url = url.replace('{?projection}', '');
return url;
}
getRelationLinkHref(relation) {
if (this._links[relation].templated)
return this._links[relation].href.replace('{?projection}', '');
return this._links[relation].href;
}
existRelationLink(relation) {
return !Utils.isNullOrUndefined(this._links) && !Utils.isNullOrUndefined(this._links[relation]);
}
// Adds the given resource to the bound collection by the relation
addRelation(relation, resource) {
if (this.existRelationLink(relation)) {
let header = ResourceHelper.headers.append('Content-Type', 'text/uri-list');
return ResourceHelper.getHttp().post(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), resource._links.self.href, { headers: header });
}
else {
return observableThrowError('no relation found');
}
}
// Allow for resources that are verbs instead of nouns e.g. payment/changeofaddress etc.
postRelation(relation, type, resource = null) {
if (this.existRelationLink(relation)) {
let observable = ResourceHelper.getHttp().post(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), resource, {
headers: ResourceHelper.headers,
observe: 'response'
});
const result = new type();
return observable.pipe(map((response) => {
return ResourceHelper.instantiateResourceFromResponse(result, response);
}), catchError(error => observableThrowError(error)));
}
else {
return observableThrowError('no payment relation found');
}
}
updateRelation(relation, resource) {
if (this.existRelationLink(relation)) {
let header = ResourceHelper.headers.append('Content-Type', 'text/uri-list');
return ResourceHelper.getHttp().patch(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), resource._links.self.href, { headers: header });
}
else {
return observableThrowError('no relation found');
}
}
// Bind the given resource to this resource by the given relation
substituteRelation(relation, resource) {
if (this.existRelationLink(relation)) {
let header = ResourceHelper.headers.append('Content-Type', 'text/uri-list');
return ResourceHelper.getHttp().put(ResourceHelper.getProxy(this.getRelationLinkHref(relation)), resource._links.self.href, { headers: header });
}
else {
return observableThrowError('no relation found');
}
}
// Unbind the resource with the given relation from this resource
deleteRelation(relation, resource) {
if (this.existRelationLink(relation)) {
let link = resource._links['self'].href;
let idx = link.lastIndexOf('/') + 1;
if (idx == -1)
return observableThrowError('no relation found');
let relationId = link.substring(idx);
return ResourceHelper.getHttp().delete(ResourceHelper.getProxy(this.getRelationLinkHref(relation) + '/' + relationId), { headers: ResourceHelper.headers });
}
else {
return observableThrowError('no relation found');
}
}
}
Resource.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: Resource, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
Resource.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: Resource });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: Resource, decorators: [{
type: Injectable
}], ctorParameters: function () { return []; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9maW5nZXJwcmludHNvZnQvYW5ndWxhci1zcHJpbmctaGFsL3NyYy9saWIvbW9kZWxzL3Jlc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBYyxFQUFFLElBQUksWUFBWSxFQUFFLFVBQVUsSUFBSSxvQkFBb0IsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUxRixPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxVQUFVLEVBQWdCLE1BQU0sc0JBQXNCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBS25ELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzFELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDakMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHVCQUF1QixDQUFDOztBQU1wRCxNQUFNLE9BQWdCLFFBQVE7SUFnQjFCO0lBQ0EsQ0FBQztJQVRELElBQVcsUUFBUTtRQUNmLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUMxQixDQUFDO0lBRUQsSUFBVyxRQUFRLENBQUMsU0FBMkI7UUFDM0MsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7SUFDL0IsQ0FBQztJQUtELFdBQVc7SUFDSixHQUFHO1FBQ04sSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFO1lBQ3hGLE9BQU8sY0FBYyxDQUFDLFFBQVEs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QUFjLENBQUMsT0FBTyxFQUFDLENBQUMsQ0FBQztTQUM3SjthQUFNO1lBQ0gsT0FBTyxvQkFBb0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1NBQ3BEO0lBQ0wsQ0FBQzs7cUdBcFFpQixRQUFRO3lHQUFSLFFBQVE7MkZBQVIsUUFBUTtrQkFEN0IsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9ic2VydmFibGUsIG9mIGFzIG9ic2VydmFibGVPZiwgdGhyb3dFcnJvciBhcyBvYnNlcnZhYmxlVGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBIdHRwUGFyYW1zLCBIdHRwUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBSZXNvdXJjZUhlbHBlciB9IGZyb20gJy4vcmVzb3VyY2UtaGVscGVyJztcbmltcG9ydCB7IFJlc291cmNlQXJyYXkgfSBmcm9tICcuL3Jlc291cmNlLWFycmF5JztcblxuaW1wb3J0IHsgSGFsT3B0aW9ucyB9IGZyb20gJy4uL3NlcnZpY2VzL3Jlc3Quc2VydmljZSc7XG5pbXBvcnQgeyBTdWJUeXBlQnVpbGRlciB9IGZyb20gJy4vc3VidHlwZS1idWlsZGVyJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEN1c3RvbUVuY29kZXIgfSBmcm9tICcuLi9zZXJ2aWNlcy9DdXN0b21FbmNvZGVyJztcbmltcG9ydCB7IFV0aWxzIH0gZnJvbSAnLi4vVXRpbHMnO1xuaW1wb3J0IHsgQ2FjaGVIZWxwZXIgfSBmcm9tICcuLi9jYWNoZS9jYWNoZS5oZWxwZXInO1xuXG5leHBvcnQgdHlwZSBMaW5rID0geyBocmVmOiBzdHJpbmcsIHRlbXBsYXRlZD86IGJvb2xlYW4gfTtcbmV4cG9ydCB0eXBlIExpbmtzID0geyBba2V5OiBzdHJpbmddOiBMaW5rIH07XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBSZXNvdXJjZSB7XG5cbiAgICBwdWJsaWMgcHJveHlVcmw6IHN0cmluZztcbiAgICBwdWJsaWMgcm9vdFVybDogc3RyaW5nO1xuXG4gICAgcHVibGljIF9saW5rczogYW55O1xuICAgIHB1YmxpYyBfc3VidHlwZXM6IE1hcDxzdHJpbmcsIGFueT47XG5cbiAgICBwdWJsaWMgZ2V0IHN1YnR5cGVzKCk6IE1hcDxzdHJpbmcsIGFueT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3VidHlwZXM7XG4gICAgfVxuXG4gICAgcHVibGljIHNldCBzdWJ0eXBlcyhfc3VidHlwZXM6IE1hcDxzdHJpbmcsIGFueT4pIHtcbiAgICAgICAgdGhpcy5fc3VidHlwZXMgPSBfc3VidHlwZXM7XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgfVxuXG4gICAgLy8gR2V0IHNlbGZcbiAgICBwdWJsaWMgdXJpKCk6IHN0cmluZyB7XG4gICAgICAgIGlmICghVXRpbHMuaXNOdWxsT3JVbmRlZmluZWQodGhpcy5fbGlua3MpICYmICFVdGlscy5pc051bGxPclVuZGVmaW5lZCh0aGlzLl9saW5rc1snc2VsZiddKSkge1xuICAgICAgICAgICAgcmV0dXJuIFJlc291cmNlSGVscGVyLmdldFByb3h5KHRoaXMuX2xpbmtzWydzZWxmJ10uaHJlZik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEdldCByZWwgdXJpXG4gICAgcHVibGljIHJlbFVSSShyZWw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGlmICghVXRpbHMuaXNOdWxsT3JVbmRlZmluZWQodGhpcy5fbGlua3MpICYmICFVdGlscy5pc051bGxPclVuZGVmaW5lZCh0aGlzLl9saW5rc1tyZWxdKSkge1xuICAgICAgICAgICAgcmV0dXJuIFJlc291cmNlSGVscGVyLmdldFByb3h5KHRoaXMuX2xpbmtzW3JlbF0uaHJlZik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEdldCByZWxhdGVkIHJlc291cmNlXG4gICAgcHVibGljIGdldFJlbGF0aW9uPFQgZXh0ZW5kcyBSZXNvdXJjZT4odHlwZTogeyBuZXcoKTogVCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0aW9uOiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRlcj86IFN1YlR5cGVCdWlsZGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGlyZU1zOiBudW1iZXIgPSBDYWNoZUhlbHBlci5kZWZhdWx0RXhwaXJlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2FjaGVBY3RpdmU6IGJvb2xlYW4gPSB0cnVlKTogT2JzZXJ2YWJsZTxUPiB7XG4gICAgICAgIGxldCByZXN1bHQ6IFQgPSBuZXcgdHlwZSgpO1xuICAgICAgICBpZiAodGhpcy5leGlzdFJlbGF0aW9uTGluayhyZWxhdGlvbikpIHtcbiAgICAgICAgICAgIGlmIChDYWNoZUhlbHBlci5pZlByZXNlbnQodGhpcy5nZXRSZWxhdGlvbkxpbmtIcmVmKHJlbGF0aW9uKSwgbnVsbCwgbnVsbCwgaXNDYWNoZUFjdGl2ZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjYWNoZWQ6IFQgPSBDYWNoZUhlbHBlci5nZXQodGhpcy5nZXRSZWxhdGlvbkxpbmtIcmVmKHJlbGF0aW9uKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVPZihjYWNoZWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgb2JzZXJ2YWJsZSA9IFJlc291cmNlSGVscGVyLmdldEh0dHAoKS5nZXQoUmVzb3VyY2VIZWxwZXIuZ2V0UHJveHkodGhpcy5nZXRSZWxhdGlvbkxpbmtIcmVmKHJlbGF0aW9uKSksIHtoZWFkZXJzOiBSZXNvdXJjZUhlbHBlci5oZWFkZXJzfSk7XG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZS5waXBlKG1hcCgoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGJ1aWxkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBlbWJlZGRlZENsYXNzTmFtZSBvZiBPYmplY3Qua2V5cyhkYXRhWydfbGlua3MnXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbWJlZGRlZENsYXNzTmFtZSA9PSAnc2VsZicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaHJlZjogc3RyaW5nID0gZGF0YS5fbGlua3NbZW1iZWRkZWRDbGFzc05hbWVdLmhyZWY7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGlkeDogbnVtYmVyID0gaHJlZi5sYXN0SW5kZXhPZignLycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZWFsQ2xhc3NOYW1lID0gaHJlZi5yZXBsYWNlKFJlc291cmNlSGVscGVyLmdldFJvb3RVcmkoKSwgJycpLnN1YnN0cmluZygwLCBpZHgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFJlc291cmNlSGVscGVyLnNlYXJjaFN1YnR5cGVzKGJ1aWxkZXIsIHJlYWxDbGFzc05hbWUsIHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IHJlc291cmNlOiBUID0gUmVzb3VyY2VIZWxwZXIuaW5zdGFudGlhdGVSZXNvdXJjZShyZXN1bHQsIGRhdGEpO1xuICAgICAgICAgICAgICAgIENhY2hlSGVscGVyLnB1dCh0aGlzLmdldFJlbGF0aW9uTGlua0hyZWYocmVsYXRpb24pLCByZXNvdXJjZSwgZXhwaXJlTXMpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNvdXJjZTtcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBvYnNlcnZhYmxlT2YobnVsbCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkUmVsYXRpb25zPFQgZXh0ZW5kcyBSZXNvdXJjZT4ocmVsYXRpb246IHN0cmluZywgcmVzb3VyY2VzOiBUW10pOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgICAgICBpZiAoIVV0aWxzLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMuX2xpbmtzKSAmJiAhVXRpbHMuaXNOdWxsT3JVbmRlZmluZWQodGhpcy5fbGlua3NbcmVsYXRpb25dKSkge1xuICAgICAgICAgICAgbGV0IGhlYWRlciA9IFJlc291cmNlSGVscGVyLmhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCAndGV4dC91cmktbGlzdCcpO1xuICAgICAgICAgICAgbGV0IHVyaXMgPSByZXNvdXJjZXMubWFwKHIgPT4gci5fbGlua3Muc2VsZi5ocmVmKS5qb2luKCdcXG4nKTtcbiAgICAgICAgICAgIHJldHVybiBSZXNvdXJjZUhlbHBlci5nZXRIdHRwKCkucG9zdChSZXNvdXJjZUhlbHBlci5nZXRQcm94eSh0aGlzLl9saW5rc1tyZWxhdGlvbl0uaHJlZiksIHVyaXMsIHtoZWFkZXJzOiBoZWFkZXJ9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBvYnNlcnZhYmxlVGhyb3dFcnJvcignbm8gcmVsYXRpb24gZm91bmQnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyByZXBsYWNlUmVsYXRpb25zPFQgZXh0ZW5kcyBSZXNvdXJjZT4ocmVsYXRpb246IHN0cmluZywgcmVzb3VyY2VzOiBUW10pOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgICAgICBpZiAoIVV0aWxzLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMuX2xpbmtzKSAmJiAhVXRpbHMuaXNOdWxsT3JVbmRlZmluZWQodGhpcy5fbGlua3NbcmVsYXRpb25dKSkge1xuICAgICAgICAgICAgbGV0IGhlYWRlciA9IFJlc291cmNlSGVscGVyLmhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCAndGV4dC91cmktbGlzdCcpO1xuICAgICAgICAgICAgbGV0IHVyaXMgPSByZXNvdXJjZXMubWFwKHIgPT4gci5fbGlua3Muc2VsZi5ocmVmKS5qb2luKCdcXG4nKTtcbiAgICAgICAgICAgIHJldHVybiBSZXNvdXJjZUhlbHBlci5nZXRIdHRwKCkucHV0KFJlc291cmNlSGVscGVyLmdldFByb3h5KHRoaXMuX2xpbmtzW3JlbGF0aW9uXS5ocmVmKSwgdXJpcywge2hlYWRlcnM6IGhlYWRlcn0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVUaHJvd0Vycm9yKCdubyByZWxhdGlvbiBmb3VuZCcpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICAvLyBHZXQgY29sbGVjdGlvbiBvZiByZWxhdGVkIHJlc291cmNlc1xuICAgIHB1YmxpYyBnZXRSZWxhdGlvbkFycmF5PFQgZXh0ZW5kcyBSZXNvdXJjZT4odHlwZTogeyBuZXcoKTogVCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpb246IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9lbWJlZGRlZD86IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnM/OiBIYWxPcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRlcj86IFN1YlR5cGVCdWlsZGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJlTXM6IG51bWJlciA9IENhY2hlSGVscGVyLmRlZmF1bHRFeHBpcmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0NhY2hlQWN0aXZlOiBib29sZWFuID0gdHJ1ZSk6IE9ic2VydmFibGU8VFtdPiB7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0gUmVzb3VyY2VIZWxwZXIub3B0aW9uUGFyYW1zKG5ldyBIdHRwUGFyYW1zKHtlbmNvZGVyOiBuZXcgQ3VzdG9tRW5jb2RlcigpfSksIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCByZXN1bHQ6IFJlc291cmNlQXJyYXk8VD4gPSBSZXNvdXJjZUhlbHBlci5jcmVhdGVFbXB0eVJlc3VsdDxUPihVdGlscy5pc051bGxPclVuZGVmaW5lZChfZW1iZWRkZWQpID8gJ19lbWJlZGRlZCcgOiBfZW1iZWRkZWQpO1xuICAgICAgICBpZiAodGhpcy5leGlzdFJlbGF0aW9uTGluayhyZWxhdGlvbikpIHtcbiAgICAgICAgICAgIGlmIChDYWNoZUhlbHBlci5pZlByZXNlbnQodGhpcy5nZXRSZWxhdGlvbkxpbmtIcmVmKHJlbGF0aW9uKSwgbnVsbCwgb3B0aW9ucywgaXNDYWNoZUFjdGl2ZSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVPZihDYWNoZUhlbHBlci5nZXRBcnJheSh0aGlzLmdldFJlbGF0aW9uTGlua0hyZWYocmVsYXRpb24pKSk7XG5cbiAgICAgICAgICAgIGxldCBvYnNlcnZhYmxlID0gUmVzb3VyY2VIZWxwZXIuZ2V0SHR0cCgpLmdldChSZXNvdXJjZUhlbHBlci5nZXRQcm94eSh0aGlzLmdldFJlbGF0aW9uTGlua0hyZWYocmVsYXRpb24pKSwge1xuICAgICAgICAgICAgICAgIGhlYWRlcnM6IFJlc291cmNlSGVscGVyLmhlYWRlcnMsIG9ic2VydmU6ICdyZXNwb25zZScsIHBhcmFtczogcGFyYW1zLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZVxuICAgICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgICAgICBtYXAocmVzcG9uc2UgPT4gUmVzb3VyY2VIZWxwZXIuaW5zdGFudGlhdGVSZXNvdXJjZUNvbGxlY3Rpb248VD4odHlwZSwgcmVzcG9uc2UsIHJlc3VsdCwgYnVpbGRlcikpLFxuICAgICAgICAgICAgICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IG9ic2VydmFibGVUaHJvd0Vycm9yKGVycm9yKSksXG4gICAgICAgICAgICAgICAgKS5waXBlKG1hcCgoYXJyYXk6IFJlc291cmNlQXJyYXk8VD4pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgQ2FjaGVIZWxwZXIucHV0QXJyYXkodGhpcy5nZXRSZWxhdGlvbkxpbmtIcmVmKHJlbGF0aW9uKSwgYXJyYXkucmVzdWx0LCBleHBpcmVNcyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheS5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVPZihbXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0UHJvamVjdGlvbjxUIGV4dGVuZHMgUmVzb3VyY2U+KHR5cGU6IHsgbmV3KCk6IFQgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc291cmNlOiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvamVjdGlvbk5hbWU6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGlyZU1zOiBudW1iZXIgPSBDYWNoZUhlbHBlci5kZWZhdWx0RXhwaXJlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDYWNoZUFjdGl2ZTogYm9vbGVhbiA9IHRydWUpOiBPYnNlcnZhYmxlPFQ+IHtcbiAgICAgICAgY29uc3QgdXJpID0gdGhpcy5nZXRSZXNvdXJjZVVybChyZXNvdXJjZSkuY29uY2F0KCcvJywgaWQpLmNvbmNhdCgnP3Byb2plY3Rpb249JyArIHByb2plY3Rpb25OYW1lKTtcbiAgICAgICAgY29uc3QgcmVzdWx0OiBUID0gbmV3IHR5cGUoKTtcblxuICAgICAgICBpZiAoQ2FjaGVIZWxwZXIuaWZQcmVzZW50KHVyaSwgbnVsbCwgbnVsbCwgaXNDYWNoZUFjdGl2ZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlZDogVCA9IENhY2hlSGVscGVyLmdldCh1cmkpO1xuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVPZihjYWNoZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG9ic2VydmFibGUgPSBSZXNvdXJjZUhlbHBlci5nZXRIdHRwKCkuZ2V0KHVyaSwge2hlYWRlcnM6IFJlc291cmNlSGVscGVyLmhlYWRlcnN9KTtcbiAgICAgICAgcmV0dXJuIG9ic2VydmFibGUucGlwZShcbiAgICAgICAgICAgIG1hcChkYXRhID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgcmVzb3VyY2U6IFQgPSBSZXNvdXJjZUhlbHBlci5pbnN0YW50aWF0ZVJlc291cmNlKHJlc3VsdCwgZGF0YSk7XG4gICAgICAgICAgICAgICAgQ2FjaGVIZWxwZXIucHV0KHVyaSwgcmVzb3VyY2UsIGV4cGlyZU1zKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb3VyY2U7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGNhdGNoRXJyb3IoZXJyb3IgPT4gb2JzZXJ2YWJsZVRocm93RXJyb3IoZXJyb3IpKSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0UHJvamVjdGlvbkFycmF5PFQgZXh0ZW5kcyBSZXNvdXJjZT4odHlwZTogeyBuZXcoKTogVCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvdXJjZTogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9qZWN0aW9uTmFtZTogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBpcmVNczogbnVtYmVyID0gQ2FjaGVIZWxwZXIuZGVmYXVsdEV4cGlyZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDYWNoZUFjdGl2ZTogYm9vbGVhbiA9IHRydWUpOiBPYnNlcnZhYmxlPFRbXT4ge1xuICAgICAgICBjb25zdCB1cmkgPSB0aGlzLmdldFJlc291cmNlVXJsKHJlc291cmNlKS5jb25jYXQoJz9wcm9qZWN0aW9uPScgKyBwcm9qZWN0aW9uTmFtZSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdDogUmVzb3VyY2VBcnJheTxUPiA9IFJlc291cmNlSGVscGVyLmNyZWF0ZUVtcHR5UmVzdWx0PFQ+KCdfZW1iZWRkZWQnKTtcblxuICAgICAgICBpZiAoQ2FjaGVIZWxwZXIuaWZQcmVzZW50KHVyaSwgbnVsbCwgbnVsbCwgaXNDYWNoZUFjdGl2ZSkpXG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZU9mKENhY2hlSGVscGVyLmdldEFycmF5KHVyaSkpO1xuXG4gICAgICAgIGxldCBvYnNlcnZhYmxlID0gUmVzb3VyY2VIZWxwZXIuZ2V0SHR0cCgpLmdldCh1cmksIHtoZWFkZXJzOiBSZXNvdXJjZUhlbHBlci5oZWFkZXJzLCBvYnNlcnZlOiAncmVzcG9uc2UnfSk7XG4gICAgICAgIHJldHVybiBvYnNlcnZhYmxlLnBpcGUoXG4gICAgICAgICAgICBtYXAocmVzcG9uc2UgPT4gUmVzb3VyY2VIZWxwZXIuaW5zdGFudGlhdGVSZXNvdXJjZUNvbGxlY3Rpb248VD4odHlwZSwgcmVzcG9uc2UsIHJlc3VsdCkpLFxuICAgICAgICAgICAgbWFwKChhcnJheTogUmVzb3VyY2VBcnJheTxUPikgPT4ge1xuICAgICAgICAgICAgICAgIENhY2hlSGVscGVyLnB1dEFycmF5KHVyaSwgYXJyYXkucmVzdWx0LCBleHBpcmVNcyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5LnJlc3VsdDtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UmVzb3VyY2VVcmwocmVzb3VyY2U/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBsZXQgdXJsID0gUmVzb3VyY2VIZWxwZXIuZ2V0VVJMKCk7XG4gICAgICAgIGlmICghdXJsLmVuZHNXaXRoKCcvJykpIHtcbiAgICAgICAgICAgIHVybCA9IHVybC5jb25jYXQoJy8nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb3VyY2UpIHtcbiAgICAgICAgICAgIHJldHVybiB1cmwuY29uY2F0KHJlc291cmNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHVybCA9IHVybC5yZXBsYWNlKCd7P3Byb2plY3Rpb259JywgJycpO1xuICAgICAgICByZXR1cm4gdXJsO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UmVsYXRpb25MaW5rSHJlZihyZWxhdGlvbjogc3RyaW5nKSB7XG4gICAgICAgIGlmICh0aGlzLl9saW5rc1tyZWxhdGlvbl0udGVtcGxhdGVkKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xpbmtzW3JlbGF0aW9uXS5ocmVmLnJlcGxhY2UoJ3s/cHJvamVjdGlvbn0nLCAnJyk7XG4gICAgICAgIHJldHVybiB0aGlzLl9saW5rc1tyZWxhdGlvbl0uaHJlZjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGV4aXN0UmVsYXRpb25MaW5rKHJlbGF0aW9uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICFVdGlscy5pc051bGxPclVuZGVmaW5lZCh0aGlzLl9saW5rcykgJiYgIVV0aWxzLmlzTnVsbE9yVW5kZWZpbmVkKHRoaXMuX2xpbmtzW3JlbGF0aW9uXSk7XG4gICAgfVxuXG4gICAgLy8gQWRkcyB0aGUgZ2l2ZW4gcmVzb3VyY2UgdG8gdGhlIGJvdW5kIGNvbGxlY3Rpb24gYnkgdGhlIHJlbGF0aW9uXG4gICAgcHVibGljIGFkZFJlbGF0aW9uPFQgZXh0ZW5kcyBSZXNvdXJjZT4ocmVsYXRpb246IHN0cmluZywgcmVzb3VyY2U6IFQpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgICAgICBpZiAodGhpcy5leGlzdFJlbGF0aW9uTGluayhyZWxhdGlvbikpIHtcbiAgICAgICAgICAgIGxldCBoZWFkZXIgPSBSZXNvdXJjZUhlbHBlci5oZWFkZXJzLmFwcGVuZCgnQ29udGVudC1UeXBlJywgJ3RleHQvdXJpLWxpc3QnKTtcbiAgICAgICAgICAgIHJldHVybiBSZXNvdXJjZUhlbHBlci5nZXRIdHRwKCkucG9zdChSZXNvdXJjZUhlbHBlci5nZXRQcm94eSh0aGlzLmdldFJlbGF0aW9uTGlua0hyZWYocmVsYXRpb24pKSwgcmVzb3VyY2UuX2xpbmtzLnNlbGYuaHJlZiwge2hlYWRlcnM6IGhlYWRlcn0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVUaHJvd0Vycm9yKCdubyByZWxhdGlvbiBmb3VuZCcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWxsb3cgZm9yIHJlc291cmNlcyB0aGF0IGFyZSB2ZXJicyBpbnN0ZWFkIG9mIG5vdW5zIGUuZy4gcGF5bWVudC9jaGFuZ2VvZmFkZHJlc3MgZXRjLlxuICAgIHB1YmxpYyBwb3N0UmVsYXRpb248VCBleHRlbmRzIFJlc291cmNlPihyZWxhdGlvbjogc3RyaW5nLCB0eXBlOiB7IG5ldygpOiBUIH0sIHJlc291cmNlOiBUID0gbnVsbCk6IE9ic2VydmFibGU8VD4ge1xuICAgICAgICBpZiAodGhpcy5leGlzdFJlbGF0aW9uTGluayhyZWxhdGlvbikpIHtcbiAgICAgICAgICBsZXQgb2JzZXJ2YWJsZSA9IFJlc291cmNlSGVscGVyLmdldEh0dHAoKS5wb3N0KFxuICAgICAgICAgICAgUmVzb3VyY2VIZWxwZXIuZ2V0UHJveHkodGhpcy5nZXRSZWxhdGlvbkxpbmtIcmVmKHJlbGF0aW9uKSksXG4gICAgICAgICAgICByZXNvdXJjZSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaGVhZGVyczogUmVzb3VyY2VIZWxwZXIuaGVhZGVycyxcbiAgICAgICAgICAgICAgb2JzZXJ2ZTogJ3Jlc3BvbnNlJ1xuICAgICAgICAgICAgfVxuICAgICAgICAgIClcbiAgICAgICAgICBjb25zdCByZXN1bHQ6IFQgPSBuZXcgdHlwZSgpO1xuICAgICAgICAgIHJldHVybiBvYnNlcnZhYmxlLnBpcGUoXG4gICAgICAgICAgICBtYXAoKHJlc3BvbnNlOiBIdHRwUmVzcG9uc2U8YW55PikgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gUmVzb3VyY2VIZWxwZXIuaW5zdGFudGlhdGVSZXNvdXJjZUZyb21SZXNwb25zZShyZXN1bHQsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PiBvYnNlcnZhYmxlVGhyb3dFcnJvcihlcnJvcikpLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZVRocm93RXJyb3IoJ25vIHBheW1lbnQgcmVsYXRpb24gZm91bmQnKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgcHVibGljIHVwZGF0ZVJlbGF0aW9uPFQgZXh0ZW5kcyBSZXNvdXJjZT4ocmVsYXRpb246IHN0cmluZywgcmVzb3VyY2U6IFQpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgICAgICBpZiAodGhpcy5leGlzdFJlbGF0aW9uTGluayhyZWxhdGlvbikpIHtcbiAgICAgICAgICAgIGxldCBoZWFkZXIgPSBSZXNvdXJjZUhlbHBlci5oZWFkZXJzLmFwcGVuZCgnQ29udGVudC1UeXBlJywgJ3RleHQvdXJpLWxpc3QnKTtcbiAgICAgICAgICAgIHJldHVybiBSZXNvdXJjZUhlbHBlci5nZXRIdHRwKCkucGF0Y2goUmVzb3VyY2VIZWxwZXIuZ2V0UHJveHkodGhpcy5nZXRSZWxhdGlvbkxpbmtIcmVmKHJlbGF0aW9uKSksIHJlc291cmNlLl9saW5rcy5zZWxmLmhyZWYsIHtoZWFkZXJzOiBoZWFkZXJ9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBvYnNlcnZhYmxlVGhyb3dFcnJvcignbm8gcmVsYXRpb24gZm91bmQnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEJpbmQgdGhlIGdpdmVuIHJlc291cmNlIHRvIHRoaXMgcmVzb3VyY2UgYnkgdGhlIGdpdmVuIHJlbGF0aW9uXG4gICAgcHVibGljIHN1YnN0aXR1dGVSZWxhdGlvbjxUIGV4dGVuZHMgUmVzb3VyY2U+KHJlbGF0aW9uOiBzdHJpbmcsIHJlc291cmNlOiBUKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICAgICAgaWYgKHRoaXMuZXhpc3RSZWxhdGlvbkxpbmsocmVsYXRpb24pKSB7XG4gICAgICAgICAgICBsZXQgaGVhZGVyID0gUmVzb3VyY2VIZWxwZXIuaGVhZGVycy5hcHBlbmQoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L3VyaS1saXN0Jyk7XG4gICAgICAgICAgICByZXR1cm4gUmVzb3VyY2VIZWxwZXIuZ2V0SHR0cCgpLnB1dChSZXNvdXJjZUhlbHBlci5nZXRQcm94eSh0aGlzLmdldFJlbGF0aW9uTGlua0hyZWYocmVsYXRpb24pKSwgcmVzb3VyY2UuX2xpbmtzLnNlbGYuaHJlZiwge2hlYWRlcnM6IGhlYWRlcn0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVUaHJvd0Vycm9yKCdubyByZWxhdGlvbiBmb3VuZCcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVW5iaW5kIHRoZSByZXNvdXJjZSB3aXRoIHRoZSBnaXZlbiByZWxhdGlvbiBmcm9tIHRoaXMgcmVzb3VyY2VcbiAgICBwdWJsaWMgZGVsZXRlUmVsYXRpb248VCBleHRlbmRzIFJlc291cmNlPihyZWxhdGlvbjogc3RyaW5nLCByZXNvdXJjZTogVCk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICAgIGlmICh0aGlzLmV4aXN0UmVsYXRpb25MaW5rKHJlbGF0aW9uKSkge1xuICAgICAgICAgICAgbGV0IGxpbms6IHN0cmluZyA9IHJlc291cmNlLl9saW5rc1snc2VsZiddLmhyZWY7XG4gICAgICAgICAgICBsZXQgaWR4OiBudW1iZXIgPSBsaW5rLmxhc3RJbmRleE9mKCcvJykgKyAxO1xuXG4gICAgICAgICAgICBpZiAoaWR4ID09IC0xKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYnNlcnZhYmxlVGhyb3dFcnJvcignbm8gcmVsYXRpb24gZm91bmQnKTtcblxuICAgICAgICAgICAgbGV0IHJlbGF0aW9uSWQ6IHN0cmluZyA9IGxpbmsuc3Vic3RyaW5nKGlkeCk7XG4gICAgICAgICAgICByZXR1cm4gUmVzb3VyY2VIZWxwZXIuZ2V0SHR0cCgpLmRlbGV0ZShSZXNvdXJjZUhlbHBlci5nZXRQcm94eSh0aGlzLmdldFJlbGF0aW9uTGlua0hyZWYocmVsYXRpb24pICsgJy8nICsgcmVsYXRpb25JZCksIHtoZWFkZXJzOiBSZXNvdXJjZUhlbHBlci5oZWFkZXJzfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZVRocm93RXJyb3IoJ25vIHJlbGF0aW9uIGZvdW5kJyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=