angular-odata
Version:
Client side OData typescript library for Angular
246 lines • 39 kB
JavaScript
import { EMPTY, throwError } from 'rxjs';
import { expand, map, reduce } from 'rxjs/operators';
import { PathSegment, } from '../../types';
import { ODataResource } from '../resource';
import { ODataCountResource } from './count';
import { ODataMediaResource } from './media';
import { ODataPropertyResource } from './property';
import { ODataReferenceResource } from './reference';
/**
* OData Navigation Property Resource
* https://www.odata.org/getting-started/advanced-tutorial/#containment
* https://www.odata.org/getting-started/advanced-tutorial/#derived
*/
export class ODataNavigationPropertyResource extends ODataResource {
//#region Factory
static factory(api, { path, type, segments, }) {
const segment = segments.add(PathSegment.navigationProperty, path);
if (type !== undefined) {
segment.outgoingType(type);
segment.incomingType(type);
}
return new ODataNavigationPropertyResource(api, {
segments,
});
}
static fromResource(resource, path) {
const baseType = resource.outgoingType();
let baseSchema = baseType !== undefined
? resource.api.structuredType(baseType)
: undefined;
let fieldType;
if (baseSchema !== undefined) {
const field = baseSchema.field(path);
fieldType = field?.type;
baseSchema =
field !== undefined
? baseSchema.findParentSchemaForField(field)
: undefined;
}
const navigation = ODataNavigationPropertyResource.factory(resource.api, {
path,
type: fieldType,
segments: resource.cloneSegments(),
});
// Switch entitySet to binding type if available
if (baseSchema !== undefined && baseSchema.type() !== baseType) {
let entitySet = resource.api.findEntitySet(baseSchema.type());
if (entitySet !== undefined) {
navigation.segment((s) => s.entitySet().path(entitySet.name));
}
}
return navigation;
}
clone() {
return super.clone();
}
transform(opts, { type, fields, } = {}) {
return super.transform(opts, {
type,
fields,
});
}
//#endregion
key(value) {
const navigation = this.clone();
var key = this.resolveKey(value);
if (key !== undefined)
navigation.segment((s) => s.navigationProperty().key(key));
return navigation;
}
keys(values) {
const navigation = this.clone();
const types = this.pathSegments.types({ key: true });
const keys = values.map((value, index) => ODataResource.resolveKey(value, this.api.findStructuredType(types[index])));
navigation.segment((s) => s.keys(keys));
return navigation;
}
media() {
return ODataMediaResource.factory(this.api, {
segments: this.cloneSegments(),
query: this.cloneQuery(),
});
}
reference() {
return ODataReferenceResource.factory(this.api, {
segments: this.cloneSegments(),
});
}
navigationProperty(path) {
return ODataNavigationPropertyResource.fromResource(this, path);
}
property(path) {
return ODataPropertyResource.fromResource(this, path);
}
count() {
return ODataCountResource.factory(this.api, {
segments: this.cloneSegments(),
query: this.cloneQuery(),
});
}
cast(type) {
const thisType = this.incomingType();
const baseSchema = thisType !== undefined ? this.api.structuredType(thisType) : undefined;
const castSchema = this.api.findStructuredType(type);
if (castSchema !== undefined &&
baseSchema !== undefined &&
!castSchema.isSubtypeOf(baseSchema))
throw new Error(`Cannot cast to ${type}`);
const segments = this.cloneSegments();
segments.add(PathSegment.type, type).incomingType(type);
return new ODataNavigationPropertyResource(this.api, {
segments,
query: this.cloneQuery(),
});
}
//#region Requests
post(attrs, options = {}) {
return super.post(attrs, { responseType: 'entity', ...options });
}
put(attrs, options = {}) {
return super.put(attrs, { responseType: 'entity', ...options });
}
patch(attrs, options = {}) {
return super.patch(attrs, { responseType: 'entity', ...options });
}
delete(options = {}) {
return super.delete({ responseType: 'entity', ...options });
}
get(options = {}) {
return super.get(options);
}
//#endregion
//#region Shortcuts
/**
* Create a new entity
* @param attrs The entity attributes
* @param options Options for the request
* @returns The created entity with the annotations
*/
create(attrs, options) {
return this.post(attrs, options);
}
/**
* Update an existing entity
* @param attrs The entity attributes
* @param options Options for the request
* @returns The updated entity with the annotations
*/
update(attrs, options) {
return this.put(attrs, options);
}
/**
* Modify an existing entity
* @param attrs The entity attributes
* @param options Options for the request
* @returns The modified entity with the annotations
*/
modify(attrs, options) {
return this.patch(attrs, options);
}
/**
* Delete an existing entity
* @param options Options for the request
* @returns An observable of the destroy
*/
destroy(options) {
return this.delete(options);
}
fetch(options = {}) {
if (!this.hasEntityKey())
return throwError(() => new Error('fetch: Navigation resource without entity key'));
return this.get(options);
}
/**
* Fetch the entity
* @param options Options for the request
* @returns The entity
*/
fetchEntity(options = {}) {
return this.fetch({ responseType: 'entity', ...options }).pipe(map(({ entity }) => entity));
}
fetchModel(options = {}) {
return this.fetch({ responseType: 'entity', ...options }).pipe(map(({ entity, annots }) => entity
? this.asModel(entity, { annots, ModelType: options?.ModelType })
: null));
}
/**
* Fetch entities
* @param options Options for the request
* @returns The entities
*/
fetchEntities(options = {}) {
return this.fetch({ responseType: 'entities', ...options }).pipe(map(({ entities }) => entities));
}
fetchCollection(options = {}) {
return this.fetch({ responseType: 'entities', ...options }).pipe(map(({ entities, annots }) => entities
? this.asCollection(entities, {
annots,
CollectionType: options?.CollectionType,
})
: null));
}
/**
* Fetch all entities
* @param options Options for the request
* @returns All entities
*/
fetchAll(options = {}) {
let res = this.clone();
// Clean Paging
res.query((q) => q.removePaging());
let fetch = (opts) => {
if (opts) {
res.query((q) => q.paging(opts));
}
return res.fetch({ responseType: 'entities', ...options });
};
return fetch().pipe(expand(({ annots }) => annots.skip || annots.skiptoken ? fetch(annots) : EMPTY), map(({ entities, annots }) => ({ entities: entities || [], annots })), reduce((acc, { entities, annots }) => ({
entities: [...(acc.entities || []), ...(entities || [])],
annots: acc.annots.union(annots),
})));
}
//#endregion
fetchMany(top, options) {
let res = this.clone();
let fetch = (opts) => {
if (opts) {
res.query((q) => q.paging(opts));
}
return res.fetch({ responseType: 'entities', ...options });
};
return fetch({ top }).pipe(expand(({ annots }) => annots.skip || annots.skiptoken ? fetch(annots) : EMPTY), map(({ entities, annots }) => ({ entities: entities || [], annots })), reduce((acc, { entities, annots }) => ({
entities: [...(acc.entities || []), ...(entities || [])],
annots: acc.annots.union(annots),
})));
}
fetchOne(options) {
const res = this.clone();
res.query((q) => q.top(1));
return res.fetch({ responseType: 'entities', ...options }).pipe(map(({ entities, annots }) => ({
entity: entities !== null && entities.length === 1 ? entities[0] : null,
annots,
})));
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF2aWdhdGlvbi1wcm9wZXJ0eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItb2RhdGEvc3JjL2xpYi9yZXNvdXJjZXMvdHlwZXMvbmF2aWdhdGlvbi1wcm9wZXJ0eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFjLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyRCxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUdyRCxPQUFPLEVBQ0wsV0FBVyxHQUdaLE1BQU0sYUFBYSxDQUFDO0FBR3JCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFNUMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQU03QyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDbkQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBR3JEOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sK0JBQW1DLFNBQVEsYUFBZ0I7SUFDdEUsaUJBQWlCO0lBQ2pCLE1BQU0sQ0FBQyxPQUFPLENBQ1osR0FBYSxFQUNiLEVBQ0UsSUFBSSxFQUNKLElBQUksRUFDSixRQUFRLEdBS1Q7UUFFRCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNuRSxJQUFJLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN2QixPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzNCLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUNELE9BQU8s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JztcbmltcG9ydCB7IGV4cGFuZCwgbWFwLCByZWR1Y2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBPRGF0YUFwaSB9IGZyb20gJy4uLy4uL2FwaSc7XG5pbXBvcnQgdHlwZSB7IE1vZGVsSW50ZXJmYWNlLCBPRGF0YUNvbGxlY3Rpb24sIE9EYXRhTW9kZWwgfSBmcm9tICcuLi8uLi9tb2RlbHMnO1xuaW1wb3J0IHtcbiAgUGF0aFNlZ21lbnQsXG4gIFF1ZXJ5T3B0aW9uLFxuICBTdHJ1Y3R1cmVkVHlwZUZpZWxkQ29uZmlnLFxufSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBPRGF0YVBhdGhTZWdtZW50cyB9IGZyb20gJy4uL3BhdGgnO1xuaW1wb3J0IHsgQXBwbHlFeHByZXNzaW9uLCBBcHBseUV4cHJlc3Npb25CdWlsZGVyIH0gZnJvbSAnLi4vcXVlcnknO1xuaW1wb3J0IHsgT0RhdGFSZXNvdXJjZSB9IGZyb20gJy4uL3Jlc291cmNlJztcbmltcG9ydCB7IE9EYXRhRW50aXRpZXMsIE9EYXRhRW50aXR5IH0gZnJvbSAnLi4vcmVzcG9uc2UnO1xuaW1wb3J0IHsgT0RhdGFDb3VudFJlc291cmNlIH0gZnJvbSAnLi9jb3VudCc7XG5pbXBvcnQgeyBPRGF0YU1lZGlhUmVzb3VyY2UgfSBmcm9tICcuL21lZGlhJztcbmltcG9ydCB7XG4gIE9EYXRhRW50aXRpZXNPcHRpb25zLFxuICBPRGF0YUVudGl0eU9wdGlvbnMsXG4gIE9EYXRhT3B0aW9ucyxcbn0gZnJvbSAnLi9vcHRpb25zJztcbmltcG9ydCB7IE9EYXRhUHJvcGVydHlSZXNvdXJjZSB9IGZyb20gJy4vcHJvcGVydHknO1xuaW1wb3J0IHsgT0RhdGFSZWZlcmVuY2VSZXNvdXJjZSB9IGZyb20gJy4vcmVmZXJlbmNlJztcbmltcG9ydCB7IE9EYXRhRW50aXRpZXNBbm5vdGF0aW9ucyB9IGZyb20gJy4uLy4uL2Fubm90YXRpb25zJztcblxuLyoqXG4gKiBPRGF0YSBOYXZpZ2F0aW9uIFByb3BlcnR5IFJlc291cmNlXG4gKiBodHRwczovL3d3dy5vZGF0YS5vcmcvZ2V0dGluZy1zdGFydGVkL2FkdmFuY2VkLXR1dG9yaWFsLyNjb250YWlubWVudFxuICogaHR0cHM6Ly93d3cub2RhdGEub3JnL2dldHRpbmctc3RhcnRlZC9hZHZhbmNlZC10dXRvcmlhbC8jZGVyaXZlZFxuICovXG5leHBvcnQgY2xhc3MgT0RhdGFOYXZpZ2F0aW9uUHJvcGVydHlSZXNvdXJjZTxUPiBleHRlbmRzIE9EYXRhUmVzb3VyY2U8VD4ge1xuICAvLyNyZWdpb24gRmFjdG9yeVxuICBzdGF0aWMgZmFjdG9yeTxOPihcbiAgICBhcGk6IE9EYXRhQXBpLFxuICAgIHtcbiAgICAgIHBhdGgsXG4gICAgICB0eXBlLFxuICAgICAgc2VnbWVudHMsXG4gICAgfToge1xuICAgICAgcGF0aDogc3RyaW5nO1xuICAgICAgdHlwZT86IHN0cmluZztcbiAgICAgIHNlZ21lbnRzOiBPRGF0YVBhdGhTZWdtZW50cztcbiAgICB9LFxuICApIHtcbiAgICBjb25zdCBzZWdtZW50ID0gc2VnbWVudHMuYWRkKFBhdGhTZWdtZW50Lm5hdmlnYXRpb25Qcm9wZXJ0eSwgcGF0aCk7XG4gICAgaWYgKHR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgc2VnbWVudC5vdXRnb2luZ1R5cGUodHlwZSk7XG4gICAgICBzZWdtZW50LmluY29taW5nVHlwZSh0eXBlKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBPRGF0YU5hdmlnYXRpb25Qcm9wZXJ0eVJlc291cmNlPE4+KGFwaSwge1xuICAgICAgc2VnbWVudHMsXG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZnJvbVJlc291cmNlPE4+KHJlc291cmNlOiBPRGF0YVJlc291cmNlPGFueT4sIHBhdGg6IHN0cmluZykge1xuICAgIGNvbnN0IGJhc2VUeXBlID0gcmVzb3VyY2Uub3V0Z29pbmdUeXBlKCk7XG4gICAgbGV0IGJhc2VTY2hlbWEgPVxuICAgICAgYmFzZVR5cGUgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IHJlc291cmNlLmFwaS5zdHJ1Y3R1cmVkVHlwZTxhbnk+KGJhc2VUeXBlKVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICBsZXQgZmllbGRUeXBlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgaWYgKGJhc2VTY2hlbWEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZmllbGQgPSBiYXNlU2NoZW1hLmZpZWxkPE4+KHBhdGgpO1xuICAgICAgZmllbGRUeXBlID0gZmllbGQ/LnR5cGU7XG4gICAgICBiYXNlU2NoZW1hID1cbiAgICAgICAgZmllbGQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gYmFzZVNjaGVtYS5maW5kUGFyZW50U2NoZW1hRm9yRmllbGQ8Tj4oZmllbGQpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgbmF2aWdhdGlvbiA9IE9EYXRhTmF2aWdhdGlvblByb3BlcnR5UmVzb3VyY2UuZmFjdG9yeTxOPihcbiAgICAgIHJlc291cmNlLmFwaSxcbiAgICAgIHtcbiAgICAgICAgcGF0aCxcbiAgICAgICAgdHlwZTogZmllbGRUeXBlLFxuICAgICAgICBzZWdtZW50czogcmVzb3VyY2UuY2xvbmVTZWdtZW50cygpLFxuICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gU3dpdGNoIGVudGl0eVNldCB0byBiaW5kaW5nIHR5cGUgaWYgYXZhaWxhYmxlXG4gICAgaWYgKGJhc2VTY2hlbWEgIT09IHVuZGVmaW5lZCAmJiBiYXNlU2NoZW1hLnR5cGUoKSAhPT0gYmFzZVR5cGUpIHtcbiAgICAgIGxldCBlbnRpdHlTZXQgPSByZXNvdXJjZS5hcGkuZmluZEVudGl0eVNldChiYXNlU2NoZW1hLnR5cGUoKSk7XG4gICAgICBpZiAoZW50aXR5U2V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbmF2aWdhdGlvbi5zZWdtZW50KChzKSA9PiBzLmVudGl0eVNldCgpLnBhdGgoZW50aXR5U2V0IS5uYW1lKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5hdmlnYXRpb247XG4gIH1cblxuICBvdmVycmlkZSBjbG9uZSgpOiBPRGF0YU5hdmlnYXRpb25Qcm9wZXJ0eVJlc291cmNlPFQ+IHtcbiAgICByZXR1cm4gc3VwZXIuY2xvbmUoKSBhcyBPRGF0YU5hdmlnYXRpb25Qcm9wZXJ0eVJlc291cmNlPFQ+O1xuICB9XG5cbiAgb3ZlcnJpZGUgdHJhbnNmb3JtPFI+KFxuICAgIG9wdHM6IChcbiAgICAgIGJ1aWxkZXI6IEFwcGx5RXhwcmVzc2lvbkJ1aWxkZXI8VD4sXG4gICAgICBjdXJyZW50PzogQXBwbHlFeHByZXNzaW9uPFQ+LFxuICAgICkgPT4gQXBwbHlFeHByZXNzaW9uPFQ+LFxuICAgIHtcbiAgICAgIHR5cGUsXG4gICAgICBmaWVsZHMsXG4gICAgfToge1xuICAgICAgdHlwZT86IHN0cmluZztcbiAgICAgIGZpZWxkcz86IHsgW25hbWU6IHN0cmluZ106IFN0cnVjdHVyZWRUeXBlRmllbGRDb25maWcgfTtcbiAgICB9ID0ge30sXG4gICk6IE9EYXRhTmF2aWdhdGlvblByb3BlcnR5UmVzb3VyY2U8Uj4ge1xuICAgIHJldHVybiBzdXBlci50cmFuc2Zvcm08Uj4ob3B0cywge1xuICAgICAgdHlwZSxcbiAgICAgIGZpZWxkcyxcbiAgICB9KSBhcyBPRGF0YU5hdmlnYXRpb25Qcm9wZXJ0eVJlc291cmNlPFI+O1xuICB9XG4gIC8vI2VuZHJlZ2lvblxuXG4gIGtleSh2YWx1ZTogYW55KSB7XG4gICAgY29uc3QgbmF2aWdhdGlvbiA9IHRoaXMuY2xvbmUoKTtcbiAgICB2YXIga2V5ID0gdGhpcy5yZXNvbHZlS2V5KHZhbHVlKTtcbiAgICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpXG4gICAgICBuYXZpZ2F0aW9uLnNlZ21lbnQoKHMpID0+IHMubmF2aWdhdGlvblByb3BlcnR5KCkua2V5KGtleSkpO1xuICAgIHJldHVybiBuYXZpZ2F0aW9uO1xuICB9XG5cbiAga2V5cyh2YWx1ZXM6IGFueVtdKSB7XG4gICAgY29uc3QgbmF2aWdhdGlvbiA9IHRoaXMuY2xvbmUoKTtcbiAgICBjb25zdCB0eXBlcyA9IHRoaXMucGF0aFNlZ21lbnRzLnR5cGVzKHsga2V5OiB0cnVlIH0pO1xuICAgIGNvbnN0IGtleXMgPSB2YWx1ZXMubWFwKCh2YWx1ZSwgaW5kZXgpID0+XG4gICAgICBPRGF0YVJlc291cmNlLnJlc29sdmVLZXkoXG4gICAgICAgIHZhbHVlLFxuICAgICAgICB0aGlzLmFwaS5maW5kU3RydWN0dXJlZFR5cGU8VD4odHlwZXNbaW5kZXhdKSxcbiAgICAgICksXG4gICAgKTtcbiAgICBuYXZpZ2F0aW9uLnNlZ21lbnQoKHMpID0+IHMua2V5cyhrZXlzKSk7XG4gICAgcmV0dXJuIG5hdmlnYXRpb247XG4gIH1cblxuICBtZWRpYSgpIHtcbiAgICByZXR1cm4gT0RhdGFNZWRpYVJlc291cmNlLmZhY3Rvcnk8VD4odGhpcy5hcGksIHtcbiAgICAgIHNlZ21lbnRzOiB0aGlzLmNsb25lU2VnbWVudHMoKSxcbiAgICAgIHF1ZXJ5OiB0aGlzLmNsb25lUXVlcnk8VD4oKSxcbiAgICB9KTtcbiAgfVxuXG4gIHJlZmVyZW5jZSgpIHtcbiAgICByZXR1cm4gT0RhdGFSZWZlcmVuY2VSZXNvdXJjZS5mYWN0b3J5PFQ+KHRoaXMuYXBpLCB7XG4gICAgICBzZWdtZW50czogdGhpcy5jbG9uZVNlZ21lbnRzKCksXG4gICAgfSk7XG4gIH1cblxuICBuYXZpZ2F0aW9uUHJvcGVydHk8Tj4ocGF0aDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIE9EYXRhTmF2aWdhdGlvblByb3BlcnR5UmVzb3VyY2UuZnJvbVJlc291cmNlPE4+KHRoaXMsIHBhdGgpO1xuICB9XG5cbiAgcHJvcGVydHk8UD4ocGF0aDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIE9EYXRhUHJvcGVydHlSZXNvdXJjZS5mcm9tUmVzb3VyY2U8UD4odGhpcywgcGF0aCk7XG4gIH1cblxuICBjb3VudCgpIHtcbiAgICByZXR1cm4gT0RhdGFDb3VudFJlc291cmNlLmZhY3Rvcnk8VD4odGhpcy5hcGksIHtcbiAgICAgIHNlZ21lbnRzOiB0aGlzLmNsb25lU2VnbWVudHMoKSxcbiAgICAgIHF1ZXJ5OiB0aGlzLmNsb25lUXVlcnk8VD4oKSxcbiAgICB9KTtcbiAgfVxuXG4gIGNhc3Q8Qz4odHlwZTogc3RyaW5nKSB7XG4gICAgY29uc3QgdGhpc1R5cGUgPSB0aGlzLmluY29taW5nVHlwZSgpO1xuICAgIGNvbnN0IGJhc2VTY2hlbWEgPVxuICAgICAgdGhpc1R5cGUgIT09IHVuZGVmaW5lZCA/IHRoaXMuYXBpLnN0cnVjdHVyZWRUeXBlKHRoaXNUeXBlKSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBjYXN0U2NoZW1hID0gdGhpcy5hcGkuZmluZFN0cnVjdHVyZWRUeXBlPEM+KHR5cGUpO1xuICAgIGlmIChcbiAgICAgIGNhc3RTY2hlbWEgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgYmFzZVNjaGVtYSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAhY2FzdFNjaGVtYS5pc1N1YnR5cGVPZihiYXNlU2NoZW1hKVxuICAgIClcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGNhc3QgdG8gJHt0eXBlfWApO1xuICAgIGNvbnN0IHNlZ21lbnRzID0gdGhpcy5jbG9uZVNlZ21lbnRzKCk7XG4gICAgc2VnbWVudHMuYWRkKFBhdGhTZWdtZW50LnR5cGUsIHR5cGUpLmluY29taW5nVHlwZSh0eXBlKTtcbiAgICByZXR1cm4gbmV3IE9EYXRhTmF2aWdhdGlvblByb3BlcnR5UmVzb3VyY2U8Qz4odGhpcy5hcGksIHtcbiAgICAgIHNlZ21lbnRzLFxuICAgICAgcXVlcnk6IHRoaXMuY2xvbmVRdWVyeTxDPigpLFxuICAgIH0pO1xuICB9XG5cbiAgLy8jcmVnaW9uIFJlcXVlc3RzXG4gIHByb3RlY3RlZCBvdmVycmlkZSBwb3N0KFxuICAgIGF0dHJzOiBQYXJ0aWFsPFQ+LFxuICAgIG9wdGlvbnM6IE9EYXRhT3B0aW9ucyA9IHt9LFxuICApOiBPYnNlcnZhYmxlPE9EYXRhRW50aXR5PFQ+PiB7XG4gICAgcmV0dXJuIHN1cGVyLnBvc3QoYXR0cnMsIHsgcmVzcG9uc2VUeXBlOiAnZW50aXR5JywgLi4ub3B0aW9ucyB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBwdXQoXG4gICAgYXR0cnM6IFBhcnRpYWw8VD4sXG4gICAgb3B0aW9uczogT0RhdGFPcHRpb25zID0ge30sXG4gICk6IE9ic2VydmFibGU8T0RhdGFFbnRpdHk8VD4+IHtcbiAgICByZXR1cm4gc3VwZXIucHV0KGF0dHJzLCB7IHJlc3BvbnNlVHlwZTogJ2VudGl0eScsIC4uLm9wdGlvbnMgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgcGF0Y2goXG4gICAgYXR0cnM6IFBhcnRpYWw8VD4sXG4gICAgb3B0aW9uczogT0RhdGFPcHRpb25zID0ge30sXG4gICk6IE9ic2VydmFibGU8T0RhdGFFbnRpdHk8VD4+IHtcbiAgICByZXR1cm4gc3VwZXIucGF0Y2goYXR0cnMsIHsgcmVzcG9uc2VUeXBlOiAnZW50aXR5JywgLi4ub3B0aW9ucyB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBkZWxldGUob3B0aW9uczogT0RhdGFPcHRpb25zID0ge30pOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiBzdXBlci5kZWxldGUoeyByZXNwb25zZVR5cGU6ICdlbnRpdHknLCAuLi5vcHRpb25zIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGdldChcbiAgICBvcHRpb25zOiBPRGF0YUVudGl0eU9wdGlvbnMgJlxuICAgICAgT0RhdGFFbnRpdGllc09wdGlvbnMgJiB7XG4gICAgICAgIGJvZHlRdWVyeU9wdGlvbnM/OiBRdWVyeU9wdGlvbltdO1xuICAgICAgfSA9IHt9LFxuICApOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiBzdXBlci5nZXQob3B0aW9ucyk7XG4gIH1cblxuICAvLyNlbmRyZWdpb25cblxuICAvLyNyZWdpb24gU2hvcnRjdXRzXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgZW50aXR5XG4gICAqIEBwYXJhbSBhdHRycyBUaGUgZW50aXR5IGF0dHJpYnV0ZXNcbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgdGhlIHJlcXVlc3RcbiAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgZW50aXR5IHdpdGggdGhlIGFubm90YXRpb25zXG4gICAqL1xuICBjcmVhdGUoXG4gICAgYXR0cnM6IFBhcnRpYWw8VD4sXG4gICAgb3B0aW9ucz86IE9EYXRhT3B0aW9ucyxcbiAgKTogT2JzZXJ2YWJsZTxPRGF0YUVudGl0eTxUPj4ge1xuICAgIHJldHVybiB0aGlzLnBvc3QoYXR0cnMsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBhbiBleGlzdGluZyBlbnRpdHlcbiAgICogQHBhcmFtIGF0dHJzIFRoZSBlbnRpdHkgYXR0cmlidXRlc1xuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgcmVxdWVzdFxuICAgKiBAcmV0dXJucyBUaGUgdXBkYXRlZCBlbnRpdHkgd2l0aCB0aGUgYW5ub3RhdGlvbnNcbiAgICovXG4gIHVwZGF0ZShcbiAgICBhdHRyczogUGFydGlhbDxUPixcbiAgICBvcHRpb25zPzogT0RhdGFPcHRpb25zLFxuICApOiBPYnNlcnZhYmxlPE9EYXRhRW50aXR5PFQ+PiB7XG4gICAgcmV0dXJuIHRoaXMucHV0KGF0dHJzLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb2RpZnkgYW4gZXhpc3RpbmcgZW50aXR5XG4gICAqIEBwYXJhbSBhdHRycyBUaGUgZW50aXR5IGF0dHJpYnV0ZXNcbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgdGhlIHJlcXVlc3RcbiAgICogQHJldHVybnMgVGhlIG1vZGlmaWVkIGVudGl0eSB3aXRoIHRoZSBhbm5vdGF0aW9uc1xuICAgKi9cbiAgbW9kaWZ5KFxuICAgIGF0dHJzOiBQYXJ0aWFsPFQ+LFxuICAgIG9wdGlvbnM/OiBPRGF0YU9wdGlvbnMsXG4gICk6IE9ic2VydmFibGU8T0RhdGFFbnRpdHk8VD4+IHtcbiAgICByZXR1cm4gdGhpcy5wYXRjaChhdHRycywgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGFuIGV4aXN0aW5nIGVudGl0eVxuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgcmVxdWVzdFxuICAgKiBAcmV0dXJucyBBbiBvYnNlcnZhYmxlIG9mIHRoZSBkZXN0cm95XG4gICAqL1xuICBkZXN0cm95KG9wdGlvbnM/OiBPRGF0YU9wdGlvbnMpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLmRlbGV0ZShvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaCBlbnRpdHkgLyBlbnRpdGllc1xuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgcmVxdWVzdFxuICAgKiBAcmV0dXJuIEFuIG9ic2VydmFibGUgb2YgdGhlIGVudGl0eSBvciBlbnRpdGllcyB3aXRoIGFubm90YXRpb25zXG4gICAqL1xuICBmZXRjaChcbiAgICBvcHRpb25zPzogT0RhdGFFbnRpdHlPcHRpb25zICYge1xuICAgICAgYm9keVF1ZXJ5T3B0aW9ucz86IFF1ZXJ5T3B0aW9uW107XG4gICAgfSxcbiAgKTogT2JzZXJ2YWJsZTxPRGF0YUVudGl0eTxUPj47XG4gIGZldGNoKFxuICAgIG9wdGlvbnM/OiBPRGF0YUVudGl0aWVzT3B0aW9ucyAmIHtcbiAgICAgIGJvZHlRdWVyeU9wdGlvbnM/OiBRdWVyeU9wdGlvbltdO1xuICAgIH0sXG4gICk6IE9ic2VydmFibGU8T0RhdGFFbnRpdGllczxUPj47XG4gIGZldGNoKFxuICAgIG9wdGlvbnM6IE9EYXRhRW50aXR5T3B0aW9ucyAmXG4gICAgICBPRGF0YUVudGl0aWVzT3B0aW9ucyAmIHtcbiAgICAgICAgYm9keVF1ZXJ5T3B0aW9ucz86IFF1ZXJ5T3B0aW9uW107XG4gICAgICB9ID0ge30sXG4gICk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgaWYgKCF0aGlzLmhhc0VudGl0eUtleSgpKVxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoXG4gICAgICAgICgpID0+IG5ldyBFcnJvcignZmV0Y2g6IE5hdmlnYXRpb24gcmVzb3VyY2Ugd2l0aG91dCBlbnRpdHkga2V5JyksXG4gICAgICApO1xuICAgIHJldHVybiB0aGlzLmdldChvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaCB0aGUgZW50aXR5XG4gICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIHRoZSByZXF1ZXN0XG4gICAqIEByZXR1cm5zIFRoZSBlbnRpdHlcbiAgICovXG4gIGZldGNoRW50aXR5KFxuICAgIG9wdGlvbnM6IE9EYXRhT3B0aW9ucyAmIHtcbiAgICAgIGJvZHlRdWVyeU9wdGlvbnM/OiBRdWVyeU9wdGlvbltdO1xuICAgIH0gPSB7fSxcbiAgKTogT2JzZXJ2YWJsZTxUIHwgbnVsbD4ge1xuICAgIHJldHVybiB0aGlzLmZldGNoKHsgcmVzcG9uc2VUeXBlOiAnZW50aXR5JywgLi4ub3B0aW9ucyB9KS5waXBlKFxuICAgICAgbWFwKCh7IGVudGl0eSB9KSA9PiBlbnRpdHkpLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2ggdGhlIGVudGl0eSBhbmQgcmV0dXJuIGFzIG1vZGVsXG4gICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIHRoZSByZXF1ZXN0XG4gICAqIEByZXR1cm5zIFRoZSBtb2RlbFxuICAgKi9cbiAgZmV0Y2hNb2RlbChcbiAgICBvcHRpb25zPzogT0RhdGFPcHRpb25zICYge1xuICAgICAgYm9keVF1ZXJ5T3B0aW9ucz86IFF1ZXJ5T3B0aW9uW107XG4gICAgICBNb2RlbFR5cGU/OiB0eXBlb2YgT0RhdGFNb2RlbDtcbiAgICB9LFxuICApOiBPYnNlcnZhYmxlPChPRGF0YU1vZGVsPFQ+ICYgTW9kZWxJbnRlcmZhY2U8VD4pIHwgbnVsbD47XG4gIGZldGNoTW9kZWw8TSBleHRlbmRzIE9EYXRhTW9kZWw8VD4+KFxuICAgIG9wdGlvbnM/OiBPRGF0YU9wdGlvbnMgJiB7XG4gICAgICBib2R5UXVlcnlPcHRpb25zPzogUXVlcnlPcHRpb25bXTtcbiAgICAgIE1vZGVsVHlwZT86IHR5cGVvZiBPRGF0YU1vZGVsO1xuICAgIH0sXG4gICk6IE9ic2VydmFibGU8TSB8IG51bGw+O1xuICBmZXRjaE1vZGVsKFxuICAgIG9wdGlvbnM6IE9EYXRhT3B0aW9ucyAmIHtcbiAgICAgIGJvZHlRdWVyeU9wdGlvbnM/OiBRdWVyeU9wdGlvbltdO1xuICAgICAgTW9kZWxUeXBlPzogdHlwZW9mIE9EYXRhTW9kZWw7XG4gICAgfSA9IHt9LFxuICApIHtcbiAgICByZXR1cm4gdGhpcy5mZXRjaCh7IHJlc3BvbnNlVHlwZTogJ2VudGl0eScsIC4uLm9wdGlvbnMgfSkucGlwZShcbiAgICAgIG1hcCgoeyBlbnRpdHksIGFubm90cyB9KSA9PlxuICAgICAgICBlbnRpdHlcbiAgICAgICAgICA/IHRoaXMuYXNNb2RlbChlbnRpdHksIHsgYW5ub3RzLCBNb2RlbFR5cGU6IG9wdGlvbnM/Lk1vZGVsVHlwZSB9KVxuICAgICAgICAgIDogbnVsbCxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaCBlbnRpdGllc1xuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgcmVxdWVzdFxuICAgKiBAcmV0dXJucyBUaGUgZW50aXRpZXNcbiAgICovXG4gIGZldGNoRW50aXRpZXMoXG4gICAgb3B0aW9uczogT0RhdGFPcHRpb25zICYge1xuICAgICAgYm9keVF1ZXJ5T3B0aW9ucz86IFF1ZXJ5T3B0aW9uW107XG4gICAgfSA9IHt9LFxuICApOiBPYnNlcnZhYmxlPFRbXSB8IG51bGw+IHtcbiAgICByZXR1cm4gdGhpcy5mZXRjaCh7IHJlc3BvbnNlVHlwZTogJ2VudGl0aWVzJywgLi4ub3B0aW9ucyB9KS5waXBlKFxuICAgICAgbWFwKCh7IGVudGl0aWVzIH0pID0+IGVudGl0aWVzKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIGVudGl0aWVzIGFuZCByZXR1cm4gYXMgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgcmVxdWVzdFxuICAgKiBAcmV0dXJucyBUaGUgY29sbGVjdGlvblxuICAgKi9cbiAgZmV0Y2hDb2xsZWN0aW9uKFxuICAgIG9wdGlvbnM/OiBPRGF0YU9wdGlvbnMgJiB7XG4gICAgICB3aXRoQ291bnQ/OiBib29sZWFuO1xuICAgICAgYm9keVF1ZXJ5T3B0aW9ucz86IFF1ZXJ5T3B0aW9uW107XG4gICAgICBDb2xsZWN0aW9uVHlwZT86IHR5cGVvZiBPRGF0YUNvbGxlY3Rpb247XG4gICAgfSxcbiAgKTogT2JzZXJ2YWJsZTxPRGF0YUNvbGxlY3Rpb248VCwgT0RhdGFNb2RlbDxUPiAmIE1vZGVsSW50ZXJmYWNlPFQ+PiB8IG51bGw+O1xuICBmZXRjaENvbGxlY3Rpb248TSBleHRlbmRzIE9EYXRhTW9kZWw8VD4sIEMgZXh0ZW5kcyBPRGF0YUNvbGxlY3Rpb248VCwgTT4+KFxuICAgIG9wdGlvbnM/OiBPRGF0YU9wdGlvbnMgJiB7XG4gICAgICB3aXRoQ291bnQ/OiBib29sZWFuO1xuICAgICAgYm9keVF1ZXJ5T3B0aW9ucz86IFF1ZXJ5T3B0aW9uW107XG4gICAgICBDb2xsZWN0aW9uVHlwZT86IHR5cGVvZiBPRGF0YUNvbGxlY3Rpb247XG4gICAgfSxcbiAgKTogT2JzZXJ2YWJsZTxDIHwgbnVsbD47XG4gIGZldGNoQ29sbGVjdGlvbihcbiAgICBvcHRpb25zOiBPRGF0YU9wdGlvbnMgJiB7XG4gICAgICB3aXRoQ291bnQ/OiBib29sZWFuO1xuICAgICAgYm9keVF1ZXJ5T3B0aW9ucz86IFF1ZXJ5T3B0aW9uW107XG4gICAgICBDb2xsZWN0aW9uVHlwZT86IHR5cGVvZiBPRGF0YUNvbGxlY3Rpb247XG4gICAgfSA9IHt9LFxuICApIHtcbiAgICByZXR1cm4gdGhpcy5mZXRjaCh7IHJlc3BvbnNlVHlwZTogJ2VudGl0aWVzJywgLi4ub3B0aW9ucyB9KS5waXBlKFxuICAgICAgbWFwKCh7IGVudGl0aWVzLCBhbm5vdHMgfSkgPT5cbiAgICAgICAgZW50aXRpZXNcbiAgICAgICAgICA/IHRoaXMuYXNDb2xsZWN0aW9uKGVudGl0aWVzLCB7XG4gICAgICAgICAgICAgIGFubm90cyxcbiAgICAgICAgICAgICAgQ29sbGVjdGlvblR5cGU6IG9wdGlvbnM/LkNvbGxlY3Rpb25UeXBlLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICA6IG51bGwsXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2ggYWxsIGVudGl0aWVzXG4gICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIHRoZSByZXF1ZXN0XG4gICAqIEByZXR1cm5zIEFsbCBlbnRpdGllc1xuICAgKi9cbiAgZmV0Y2hBbGwoXG4gICAgb3B0aW9uczogT0RhdGFPcHRpb25zICYge1xuICAgICAgd2l0aENvdW50PzogYm9vbGVhbjtcbiAgICAgIGJvZHlRdWVyeU9wdGlvbnM/OiBRdWVyeU9wdGlvbltdO1xuICAgIH0gPSB7fSxcbiAgKTogT2JzZXJ2YWJsZTx7IGVudGl0aWVzOiBUW107IGFubm90czogT0RhdGFFbnRpdGllc0Fubm90YXRpb25zPFQ+IH0+IHtcbiAgICBsZXQgcmVzID0gdGhpcy5jbG9uZSgpO1xuICAgIC8vIENsZWFuIFBhZ2luZ1xuICAgIHJlcy5xdWVyeSgocSkgPT4gcS5yZW1vdmVQYWdpbmcoKSk7XG4gICAgbGV0IGZldGNoID0gKG9wdHM/OiB7XG4gICAgICBza2lwPzogbnVtYmVyO1xuICAgICAgc2tpcHRva2VuPzogc3RyaW5nO1xuICAgICAgdG9wPzogbnVtYmVyO1xuICAgIH0pOiBPYnNlcnZhYmxlPE9EYXRhRW50aXRpZXM8VD4+ID0+IHtcbiAgICAgIGlmIChvcHRzKSB7XG4gICAgICAgIHJlcy5xdWVyeSgocSkgPT4gcS5wYWdpbmcob3B0cykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcy5mZXRjaCh7IHJlc3BvbnNlVHlwZTogJ2VudGl0aWVzJywgLi4ub3B0aW9ucyB9KTtcbiAgICB9O1xuICAgIHJldHVybiBmZXRjaCgpLnBpcGUoXG4gICAgICBleHBhbmQoKHsgYW5ub3RzIH0pID0+XG4gICAgICAgIGFubm90cy5za2lwIHx8IGFubm90cy5za2lwdG9rZW4gPyBmZXRjaChhbm5vdHMpIDogRU1QVFksXG4gICAgICApLFxuICAgICAgbWFwKCh7IGVudGl0aWVzLCBhbm5vdHMgfSkgPT4gKHsgZW50aXRpZXM6IGVudGl0aWVzIHx8IFtdLCBhbm5vdHMgfSkpLFxuICAgICAgcmVkdWNlKChhY2MsIHsgZW50aXRpZXMsIGFubm90cyB9KSA9PiAoe1xuICAgICAgICBlbnRpdGllczogWy4uLihhY2MuZW50aXRpZXMgfHwgW10pLCAuLi4oZW50aXRpZXMgfHwgW10pXSxcbiAgICAgICAgYW5ub3RzOiBhY2MuYW5ub3RzLnVuaW9uKGFubm90cyksXG4gICAgICB9KSksXG4gICAgKTtcbiAgfVxuICAvLyNlbmRyZWdpb25cblxuICBmZXRjaE1hbnkoXG4gICAgdG9wOiBudW1iZXIsXG4gICAgb3B0aW9ucz86IE9EYXRhT3B0aW9ucyAmIHtcbiAgICAgIHdpdGhDb3VudD86IGJvb2xlYW47XG4gICAgICBib2R5UXVlcnlPcHRpb25zPzogUXVlcnlPcHRpb25bXTtcbiAgICB9LFxuICApOiBPYnNlcnZhYmxlPHsgZW50aXRpZXM6IFRbXTsgYW5ub3RzOiBPRGF0YUVudGl0aWVzQW5ub3RhdGlvbnM8VD4gfT4ge1xuICAgIGxldCByZXMgPSB0aGlzLmNsb25lKCk7XG4gICAgbGV0IGZldGNoID0gKG9wdHM/OiB7XG4gICAgICBza2lwPzogbnVtYmVyO1xuICAgICAgc2tpcHRva2VuPzogc3RyaW5nO1xuICAgICAgdG9wPzogbnVtYmVyO1xuICAgIH0pOiBPYnNlcnZhYmxlPE9EYXRhRW50aXRpZXM8VD4+ID0+IHtcbiAgICAgIGlmIChvcHRzKSB7XG4gICAgICAgIHJlcy5xdWVyeSgocSkgPT4gcS5wYWdpbmcob3B0cykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcy5mZXRjaCh7IHJlc3BvbnNlVHlwZTogJ2VudGl0aWVzJywgLi4ub3B0aW9ucyB9KTtcbiAgICB9O1xuICAgIHJldHVybiBmZXRjaCh7IHRvcCB9KS5waXBlKFxuICAgICAgZXhwYW5kKCh7IGFubm90cyB9KSA9PlxuICAgICAgICBhbm5vdHMuc2tpcCB8fCBhbm5vdHMuc2tpcHRva2VuID8gZmV0Y2goYW5ub3RzKSA6IEVNUFRZLFxuICAgICAgKSxcbiAgICAgIG1hcCgoeyBlbnRpdGllcywgYW5ub3RzIH0pID0+ICh7IGVudGl0aWVzOiBlbnRpdGllcyB8fCBbXSwgYW5ub3RzIH0pKSxcbiAgICAgIHJlZHVjZSgoYWNjLCB7IGVudGl0aWVzLCBhbm5vdHMgfSkgPT4gKHtcbiAgICAgICAgZW50aXRpZXM6IFsuLi4oYWNjLmVudGl0aWVzIHx8IFtdKSwgLi4uKGVudGl0aWVzIHx8IFtdKV0sXG4gICAgICAgIGFubm90czogYWNjLmFubm90cy51bmlvbihhbm5vdHMpLFxuICAgICAgfSkpLFxuICAgICk7XG4gIH1cblxuICBmZXRjaE9uZShcbiAgICBvcHRpb25zPzogT0RhdGFPcHRpb25zICYge1xuICAgICAgd2l0aENvdW50PzogYm9vbGVhbjtcbiAgICAgIGJvZHlRdWVyeU9wdGlvbnM/OiBRdWVyeU9wdGlvbltdO1xuICAgIH0sXG4gICk6IE9ic2VydmFibGU8eyBlbnRpdHk6IFQgfCBudWxsOyBhbm5vdHM6IE9EYXRhRW50aXRpZXNBbm5vdGF0aW9uczxUPiB9PiB7XG4gICAgY29uc3QgcmVzID0gdGhpcy5jbG9uZSgpO1xuICAgIHJlcy5xdWVyeSgocSkgPT4gcS50b3AoMSkpO1xuICAgIHJldHVybiByZXMuZmV0Y2goeyByZXNwb25zZVR5cGU6ICdlbnRpdGllcycsIC4uLm9wdGlvbnMgfSkucGlwZShcbiAgICAgIG1hcCgoeyBlbnRpdGllcywgYW5ub3RzIH0pID0+ICh7XG4gICAgICAgIGVudGl0eTogZW50aXRpZXMgIT09IG51bGwgJiYgZW50aXRpZXMubGVuZ3RoID09PSAxID8gZW50aXRpZXNbMF0gOiBudWxsLFxuICAgICAgICBhbm5vdHMsXG4gICAgICB9KSksXG4gICAgKTtcbiAgfVxufVxuIl19