angular-odata
Version:
Client side OData typescript library for Angular
316 lines • 50.8 kB
JavaScript
import { DEFAULT_VERSION, PARAM_SEPARATOR, QUERY_SEPARATOR, VALUE_SEPARATOR, } from '../constants';
import { ODataHelper } from '../helper';
import { ODataStructuredType } from '../schema';
import { PathSegment, } from '../types';
import { Objects, Strings, Types } from '../utils';
import { ODataPathSegments, ODataPathSegmentsHandler } from './path';
import { isQueryCustomType, ODataQueryOptions, ODataQueryOptionsHandler, } from './query';
export class ODataResource {
// VARIABLES
api;
pathSegments;
queryOptions;
constructor(api, { segments, query, } = {}) {
this.api = api;
this.pathSegments = segments ?? new ODataPathSegments();
this.queryOptions = query ?? new ODataQueryOptions();
}
/**
* @returns string The outgoing type of the resource
*/
outgoingType() {
return this.pathSegments.last()?.outgoingType();
}
/**
* @returns string The incoming type of the resource
*/
incomingType() {
return this.pathSegments.last()?.incomingType();
}
/**
* @returns string The binding type of the resource
*/
bindingType() {
return this.pathSegments.last()?.bindingType();
}
/**
* @returns string All covered types of the resource
*/
types() {
return this.pathSegments.types();
}
callable() {
const type = this.outgoingType() ?? this.incomingType();
return type !== undefined ? this.api.callable(type) : undefined;
}
enumType() {
const type = this.outgoingType() ?? this.incomingType();
return type !== undefined ? this.api.enumType(type) : undefined;
}
structuredType() {
const type = this.outgoingType() ?? this.incomingType();
return type !== undefined ? this.api.structuredType(type) : undefined;
}
/**
* @returns boolean The resource has key ?
*/
hasKey() {
return Boolean(this.pathSegments.last({ key: true })?.hasKey());
}
hasEntityKey() {
return Boolean(this.pathSegments.get(PathSegment.entitySet)?.hasKey());
}
clearKey() {
return this.pathSegments.last({ key: true })?.clearKey();
}
asModel(entity, { reset, annots, ModelType, } = {}) {
reset ??= annots !== undefined;
let resource = this;
const type = annots?.type ?? this.incomingType();
if (type === undefined)
throw Error(`No type for model`);
if (ModelType === undefined)
ModelType = this.api.modelForType(type);
let entitySet = annots?.entitySet;
if (entitySet !== undefined) {
resource = this.api.entitySet(entitySet).entity(entity);
resource.query((q) => q.restore(this.queryOptions.toQueryArguments()));
}
return new ModelType(entity, { resource, annots, reset });
}
asCollection(entities, { reset, annots, CollectionType, } = {}) {
reset ??= annots !== undefined;
let resource = this;
const type = annots?.type ?? this.incomingType();
if (type === undefined)
throw Error(`No type for collection`);
if (CollectionType === undefined)
CollectionType = this.api.collectionForType(type);
let entitySet = annots?.entitySet;
if (entitySet !== undefined) {
resource = this.api.entitySet(entitySet);
resource.query((q) => q.restore(this.queryOptions.toQueryArguments()));
}
return new CollectionType(entities, { resource, annots, reset });
}
//#endregion
isTypeOf(other) {
const thisStructured = this.structuredType();
const otherStructured = other.structuredType();
return (thisStructured !== undefined &&
otherStructured !== undefined &&
thisStructured.isTypeOf(otherStructured));
}
isSubtypeOf(other) {
const thisStructured = this.structuredType();
const otherStructured = other.structuredType();
return (thisStructured !== undefined &&
otherStructured !== undefined &&
thisStructured.isSubtypeOf(otherStructured));
}
isSupertypeOf(other) {
const thisStructured = this.structuredType();
const otherStructured = other.structuredType();
return (thisStructured !== undefined &&
otherStructured !== undefined &&
thisStructured.isSupertypeOf(otherStructured));
}
isEqualTo(other, test) {
const [selfPath, selfParams] = this.pathAndParams();
const [otherPath, otherParams] = other.pathAndParams();
return test === 'path'
? otherPath === selfPath
: test === 'params'
? Types.isEqual(selfParams, otherParams)
: otherPath === selfPath && Types.isEqual(selfParams, otherParams);
}
pathAndParams({ escape, ...options } = {
escape: false,
}) {
const type = this.outgoingType();
const parser = type !== undefined ? this.api.parserForType(type) : undefined;
const [spath, sparams] = this.pathSegments.pathAndParams({
escape,
parser,
options,
});
const [, qparams] = this.queryOptions.pathAndParams({
escape,
parser,
options,
});
return [spath, { ...sparams, ...qparams }];
}
endpointUrl({ escape = false, params = true, ...options } = {}) {
let [path, qparams] = this.pathAndParams({ escape, ...options });
if (params && !Types.isEmpty(qparams)) {
path = `${path}${QUERY_SEPARATOR}${Object.entries(qparams)
.map((e) => `${e[0]}${VALUE_SEPARATOR}${e[1]}`)
.join(PARAM_SEPARATOR)}`;
}
return `${this.api.serviceRootUrl}${path}`;
}
toString({ escape, ...options } = {
escape: false,
}) {
let [path, params] = this.pathAndParams({ escape, ...options });
let queryString = Object.entries(params)
.map((e) => `${e[0]}${VALUE_SEPARATOR}${e[1]}`)
.join(PARAM_SEPARATOR);
return queryString ? `${path}${QUERY_SEPARATOR}${queryString}` : path;
}
clone() {
const Ctor = this.constructor;
return new Ctor(this.api, {
segments: this.cloneSegments(),
query: this.cloneQuery(),
});
}
__parser(value, options, resourceType, bindingType) {
const dataType = options !== undefined && Types.isPlainObject(value)
? ODataHelper[options.version ?? DEFAULT_VERSION].type(value)
: undefined;
if (dataType !== undefined) {
// Parser from data type
return this.api.parserForType(dataType);
}
else if (resourceType !== undefined) {
// Parser from resource type
return this.api.parserForType(resourceType, bindingType);
}
return undefined;
}
deserialize(value, options) {
const resourceType = this.incomingType();
const bindingType = this.bindingType();
const _d = (value, options) => {
const parser = this.__parser(value, options, resourceType, bindingType);
return parser !== undefined ? parser.deserialize(value, options) : value;
};
return Array.isArray(value)
? value.map((v) => _d(v, options))
: _d(value, options);
}
serialize(value, options) {
const resourceType = this.outgoingType();
const bindingType = this.bindingType();
const _s = (value, options) => {
const parser = this.__parser(value, options, resourceType, bindingType);
return parser !== undefined ? parser.serialize(value, options) : value;
};
return Array.isArray(value)
? value.map((v) => _s(v, options))
: _s(value, options);
}
encode(value, options) {
const resourceType = this.outgoingType();
const bindingType = this.bindingType();
const _e = (value, options) => {
const parser = this.__parser(value, options, resourceType, bindingType);
return parser !== undefined ? parser.encode(value, options) : value;
};
return Array.isArray(value)
? value.map((v) => _e(v, options))
: _e(value, options);
}
toJson() {
return {
segments: this.pathSegments.toJson(),
options: this.queryOptions.toJson(),
};
}
cloneSegments() {
return this.pathSegments.clone();
}
//#region Query Options
clearQuery() {
this.queryOptions.clear();
return this;
}
cloneQuery() {
return this.queryOptions.clone();
}
/**
* Handle the path segments of the resource
* Create an object handler for mutate the path segments of the resource
* @param f Function context for handle the segments
* @returns ODataActionResource
*/
segment(f) {
const type = this.outgoingType();
f(new ODataPathSegmentsHandler(this.pathSegments), type !== undefined ? this.api.structuredType(type) : undefined);
return this;
}
/**
* Handle the query options of the resource
* Create an object handler for mutate the query options of the resource
* @param f Function context for handle the query options
*/
query(f) {
const type = this.outgoingType();
f(new ODataQueryOptionsHandler(this.queryOptions), type !== undefined ? this.api.structuredType(type) : undefined);
return this;
}
transform(opts, { type, fields, } = {}) {
if (type === undefined) {
type = Strings.uniqueId({ prefix: 'Transformation', suffix: 'Type' });
}
// Resolve Structured Type
let structuredType = this.api.findStructuredType(type);
if (structuredType === undefined) {
// Resolve Schema
let schema = this.api.findSchema(type);
if (schema === undefined) {
const namespace = type.substring(0, type.lastIndexOf('.')) ?? this.api.name;
schema = this.api.createSchema({ namespace });
}
const name = type.substring(type.lastIndexOf('.'));
structuredType = schema.createStructuredType({ name, fields });
}
// Segments
const segments = this.cloneSegments();
segments.last()?.incomingType(structuredType.type());
// Query
const query = this.cloneQuery();
const handler = new ODataQueryOptionsHandler(query);
handler.apply(opts);
const Ctor = this.constructor;
return new Ctor(this.api, {
segments,
query,
});
}
static resolveKey(value, schema) {
if (isQueryCustomType(value)) {
return value;
}
else if (Types.isPlainObject(value)) {
return schema instanceof ODataStructuredType
? schema.resolveKey(value)
: Objects.resolveKey(value);
}
return value;
}
resolveKey(value) {
const type = this.outgoingType();
const structured = type !== undefined ? this.api.structuredType(type) : undefined;
return ODataResource.resolveKey(value, structured);
}
//#endregion
get(options = {}) {
return this.api.request('GET', this, options);
}
post(body, options = {}) {
return this.api.request('POST', this, { body, ...options });
}
put(body, options = {}) {
return this.api.request('PUT', this, { body, ...options });
}
patch(body, options = {}) {
return this.api.request('PATCH', this, { body, ...options });
}
delete(options = {}) {
return this.api.request('DELETE', this, options);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLW9kYXRhL3NyYy9saWIvcmVzb3VyY2VzL3Jlc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFDTCxlQUFlLEVBQ2YsZUFBZSxFQUNmLGVBQWUsRUFDZixlQUFlLEdBQ2hCLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFeEMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2hELE9BQU8sRUFJTCxXQUFXLEdBRVosTUFBTSxVQUFVLENBQUM7QUFDbEIsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNyRSxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLGlCQUFpQixFQUNqQix3QkFBd0IsR0FDekIsTUFBTSxTQUFTLENBQUM7QUFvQmpCLE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQVk7SUFDTCxHQUFHLENBQVc7SUFDWCxZQUFZLENBQW9CO0lBQ2hDLFlBQVksQ0FBdUI7SUFDN0MsWUFDRSxHQUFhLEVBQ2IsRUFDRSxRQUFRLEVBQ1IsS0FBSyxNQUlILEVBQUU7UUFFTixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNmLElBQUksQ0FBQyxZQUFZLEdBQUcsUUFBUSxJQUFJLElBQUksaUJBQWlCLEVBQUUsQ0FBQztRQUN4RCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssSUFBSSxJQUFJLGlCQUFpQixFQUFFLENBQUM7SUFDdkQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsWUFBWTtRQUNWLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsRUFBRSxZQUFZLEVBQUUsQ0FBQztJQUNsRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxZQUFZO1FBQ1YsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxFQUFFLFlBQVksRUFBRSxDQUFDO0lBQ2xELENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFDakQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSztRQUNILE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lBRUQsUUFBUTtRQUNOLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDeEQsT0FBTyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ3JFLENBQUM7SUFFRCxRQUFRO1FBQ04sTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN4RCxPQUFPLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDckUsQ0FBQztJQUVELGNBQWM7UUFDWixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3hELE9BQU8sSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUMzRSxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNO1FBQ0osT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFFRCxZQUFZO1FBQ1YsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDekUsQ0FBQztJQUVELFFBQVE7UUFDTixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUM7SUFDM0QsQ0FBQztJQWlDRCxPQUFPLENBQ0wsTUFBNkMsRUFDN0MsRUFDRSxLQUFLLEVBQ0wsTUFBTSxFQUNOLFNBQVMsTUFLUCxFQUFFO1FBRU4sS0FBSyxLQUFLLE1BQU0sS0FBSyxTQUFTLENBQUM7UUFDL0IsSUFBSSxRQUFRLEdBQXFCLElBQXdCLENBQUM7UUFDMUQsTUFBTSxJQUFJLEdBQUcsTUFBTSxFQUFFLElBQUksSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDakQsSUFBSSxJQUFJLEtBQUssU0FBUztZQUFFLE1BQU0sS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDekQsSUFBSSxTQUFTLEtBQUssU0FBUztZQUFFLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyRSxJQUFJLFNBQVMsR0FBRyxNQUFNLEVBQUUsU0FBUyxDQUFDO1FBQ2xDLElBQUksU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVCLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBSSxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBb0IsQ0FBQyxDQUFDO1lBQ3pFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN6RSxDQUFDO1FBQ0QsT0FBTyxJQUFJLFNBQVMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQWdDRCxZQUFZLENBQ1YsUUFBbUQsRUFDbkQsRUFDRSxLQUFLLEVBQ0wsTUFBTSxFQUNOLGNBQWMsTUFLWixFQUFFO1FBRU4sS0FBSyxLQUFLLE1BQU0sS0FBSyxTQUFTLENBQUM7UUFDL0IsSUFBSSxRQUFRLEdBQXFCLElBQXdCLENBQUM7UUFDMUQsTUFBTSxJQUFJLEdBQUcsTUFBTSxFQUFFLElBQUksSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDakQsSUFBSSxJQUFJLEtBQUssU0FBUztZQUFFLE1BQU0sS0FBSyxDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFDOUQsSUFBSSxjQUFjLEtBQUssU0FBUztZQUM5QixjQUFjLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRCxJQUFJLFNBQVMsR0FBRyxNQUFNLEVBQUUsU0FBUyxDQUFDO1FBQ2xDLElBQUksU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVCLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBSSxTQUFTLENBQUMsQ0FBQztZQUM1QyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekUsQ0FBQztRQUNELE9BQU8sSUFBSSxjQUFjLENBQUMsUUFBUSxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFDRCxZQUFZO0lBRVosUUFBUSxDQUFDLEtBQXlCO1FBQ2hDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUM3QyxNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDL0MsT0FBTyxDQUNMLGNBQWMsS0FBSyxTQUFTO1lBQzVCLGVBQWUsS0FBSyxTQUFTO1lBQzdCLGNBQWMsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQ3pDLENBQUM7SUFDSixDQUFDO0lBRUQsV0FBVyxDQUFDLEtBQXlCO1FBQ25DLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUM3QyxNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDL0MsT0FBTyxDQUNMLGNBQWMsS0FBSyxTQUFTO1lBQzVCLGVBQWUsS0FBSyxTQUFTO1lBQzdCLGNBQWMsQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQzVDLENBQUM7SUFDSixDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQXlCO1FBQ3JDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUM3QyxNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDL0MsT0FBTyxDQUNMLGNBQWMsS0FBSyxTQUFTO1lBQzVCLGVBQWUsS0FBSyxTQUFTO1lBQzdCLGNBQWMsQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQzlDLENBQUM7SUFDSixDQUFDO0lBRUQsU0FBUyxDQUFDLEtBQXlCLEVBQUUsSUFBd0I7UUFDM0QsTUFBTSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDcEQsTUFBTSxDQUFDLFNBQVMsRUFBRSxXQUFXLENBQUMsR0FBRyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDdkQsT0FBTyxJQUFJLEtBQUssTUFBTTtZQUNwQixDQUFDLENBQUMsU0FBUyxLQUFLLFFBQVE7WUFDeEIsQ0FBQyxDQUFDLElBQUksS0FBSyxRQUFRO2dCQUNqQixDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDO2dCQUN4QyxDQUFDLENBQUMsU0FBUyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRUQsYUFBYSxDQUNYLEVBQUUsTUFBTSxFQUFFLEdBQUcsT0FBTyxLQUEyQztRQUM3RCxNQUFNLEVBQUUsS0FBSztLQUNkO1FBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2pDLE1BQU0sTUFBTSxHQUNWLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDbkUsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQztZQUN2RCxNQUFNO1lBQ04sTUFBTTtZQUNOLE9BQU87U0FDUixDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsRUFBRSxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQztZQUNsRCxNQUFNO1lBQ04sTUFBTTtZQUNOLE9BQU87U0FDUixDQUFDLENBQUM7UUFFSCxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsR0FBRyxPQUFPLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxXQUFXLENBQUMsRUFDVixNQUFNLEdBQUcsS0FBSyxFQUNkLE1BQU0sR0FBRyxJQUFJLEVBQ2IsR0FBRyxPQUFPLEtBQ2dELEVBQUU7UUFDNUQsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNqRSxJQUFJLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUN0QyxJQUFJLEdBQUcsR0FBRyxJQUFJLEdBQUcsZUFBZSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO2lCQUN2RCxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLGVBQWUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztpQkFDOUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7UUFDN0IsQ0FBQztRQUNELE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsR0FBRyxJQUFJLEVBQUUsQ0FBQztJQUM3QyxDQUFDO0lBRUQsUUFBUSxDQUNOLEVBQUUsTUFBTSxFQUFFLEdBQUcsT0FBTyxLQUEyQztRQUM3RCxNQUFNLEVBQUUsS0FBSztLQUNkO1FBRUQsSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNoRSxJQUFJLFdBQVcsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQzthQUNyQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLGVBQWUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUM5QyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDekIsT0FBTyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLGVBQWUsR0FBRyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3hFLENBQUM7SUFFRCxLQUFLO1FBQ0gsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQW1DLENBQUM7UUFDdEQsT0FBTyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQ3hCLFFBQVEsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQzlCLEtBQUssRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFLO1NBQzVCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxRQUFRLENBQ2QsS0FBVSxFQUNWLE9BQXVCLEVBQ3ZCLFlBQXFCLEVBQ3JCLFdBQW9CO1FBRXBCLE1BQU0sUUFBUSxHQUNaLE9BQU8sS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7WUFDakQsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLGVBQWUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDN0QsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNoQixJQUFJLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMzQix3QkFBd0I7WUFDeEIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBSSxRQUFRLENBQUMsQ0FBQztRQUM3QyxDQUFDO2FBQU0sSUFBSSxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdEMsNEJBQTRCO1lBQzVCLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUksWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQzlELENBQUM7UUFDRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsV0FBVyxDQUFDLEtBQVUsRUFBRSxPQUF1QjtRQUM3QyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDekMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sRUFBRSxHQUFHLENBQUMsS0FBVSxFQUFFLE9BQXVCLEVBQUUsRUFBRTtZQUNqRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQ3hFLE9BQU8sTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUMzRSxDQUFDLENBQUM7UUFDRixPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ2xDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxTQUFTLENBQUMsS0FBVSxFQUFFLE9BQXVCO1FBQzNDLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN6QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDdkMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxLQUFVLEVBQUUsT0FBdUIsRUFBRSxFQUFFO1lBQ2pELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDeEUsT0FBTyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ3pFLENBQUMsQ0FBQztRQUNGLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7WUFDekIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDbEMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFVLEVBQUUsT0FBdUI7UUFDeEMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3pDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN2QyxNQUFNLEVBQUUsR0FBRyxDQUFDLEtBQVUsRUFBRSxPQUF1QixFQUFFLEVBQUU7WUFDakQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLENBQUMsQ0FBQztZQUN4RSxPQUFPLE1BQU0sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDdEUsQ0FBQyxDQUFDO1FBQ0YsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztZQUN6QixDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRUQsTUFBTTtRQUNKLE9BQU87WUFDTCxRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUU7WUFDcEMsT0FBTyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFO1NBQ3BDLENBQUM7SUFDSixDQUFDO0lBRUQsYUFBYTtRQUNYLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lBRUQsdUJBQXVCO0lBQ3ZCLFVBQVU7UUFDUixJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzFCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELFVBQVU7UUFDUixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFLLENBQUM7SUFDdEMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsT0FBTyxDQUNMLENBQXVFO1FBRXZFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNqQyxDQUFDLENBQ0MsSUFBSSx3QkFBd0IsQ0FBSSxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQ2xELElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQ2xFLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUNILENBQXVFO1FBRXZFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNqQyxDQUFDLENBQ0MsSUFBSSx3QkFBd0IsQ0FBSSxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQ2xELElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQ2xFLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxTQUFTLENBQ1AsSUFHdUIsRUFDdkIsRUFDRSxJQUFJLEVBQ0osTUFBTSxNQUlKLEVBQUU7UUFFTixJQUFJLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN2QixJQUFJLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBRUQsMEJBQTBCO1FBQzFCLElBQUksY0FBYyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUksSUFBSSxDQUFDLENBQUM7UUFDMUQsSUFBSSxjQUFjLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDakMsaUJBQWlCO1lBQ2pCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3ZDLElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUN6QixNQUFNLFNBQVMsR0FDYixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFLLENBQUM7Z0JBQzdELE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7WUFDaEQsQ0FBQztZQUNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ25ELGNBQWMsR0FBRyxNQUFNLENBQUMsb0JBQW9CLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBRUQsV0FBVztRQUNYLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN0QyxRQUFRLENBQUMsSUFBSSxFQUFFLEVBQUUsWUFBWSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXJELFFBQVE7UUFDUixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFPLENBQUM7UUFDckMsTUFBTSxPQUFPLEdBQUcsSUFBSSx3QkFBd0IsQ0FBSSxLQUFLLENBQUMsQ0FBQztRQUN2RCxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXBCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFtQyxDQUFDO1FBQ3RELE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUN4QixRQUFRO1lBQ1IsS0FBSztTQUNOLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxNQUFNLENBQUMsVUFBVSxDQUNmLEtBQVUsRUFDVixNQUErQjtRQUUvQixJQUFJLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDN0IsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO2FBQU0sSUFBSSxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEMsT0FBTyxNQUFNLFlBQVksbUJBQW1CO2dCQUMxQyxDQUFDLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7Z0JBQzFCLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLENBQUM7UUFDRCxPQUFPLEtBQWlDLENBQUM7SUFDM0MsQ0FBQztJQUVTLFVBQVUsQ0FBQyxLQUFVO1FBQzdCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNqQyxNQUFNLFVBQVUsR0FDZCxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ3BFLE9BQU8sYUFBYSxDQUFDLFVBQVUsQ0FBSSxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUNELFlBQVk7SUFFRixHQUFHLENBQ1gsVUFhSSxFQUFFO1FBRU4sT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBSSxLQUFLLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFUyxJQUFJLENBQ1osSUFBUyxFQUNULFVBV0ksRUFBRTtRQUVOLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUksTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVTLEdBQUcsQ0FDWCxJQUFTLEVBQ1QsVUFZSSxFQUFFO1FBRU4sT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBSSxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRVMsS0FBSyxDQUNiLElBQVMsRUFDVCxVQVlJLEVBQUU7UUFFTixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFJLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFFUyxNQUFNLENBQ2QsVUFZSSxFQUFFO1FBRU4sT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBSSxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3RELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IE9EYXRhQXBpIH0gZnJvbSAnLi4vYXBpJztcbmltcG9ydCB7XG4gIERFRkFVTFRfVkVSU0lPTixcbiAgUEFSQU1fU0VQQVJBVE9SLFxuICBRVUVSWV9TRVBBUkFUT1IsXG4gIFZBTFVFX1NFUEFSQVRPUixcbn0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IE9EYXRhSGVscGVyIH0gZnJvbSAnLi4vaGVscGVyJztcbmltcG9ydCB7IE1vZGVsSW50ZXJmYWNlLCBPRGF0YUNvbGxlY3Rpb24sIE9EYXRhTW9kZWwgfSBmcm9tICcuLi9tb2RlbHMnO1xuaW1wb3J0IHsgT0RhdGFTdHJ1Y3R1cmVkVHlwZSB9IGZyb20gJy4uL3NjaGVtYSc7XG5pbXBvcnQge1xuICBQYXJzZXJPcHRpb25zLFxuICBQYXJzZXIsXG4gIFF1ZXJ5T3B0aW9uLFxuICBQYXRoU2VnbWVudCxcbiAgU3RydWN0dXJlZFR5cGVGaWVsZENvbmZpZyxcbn0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgT2JqZWN0cywgU3RyaW5ncywgVHlwZXMgfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQgeyBPRGF0YVBhdGhTZWdtZW50cywgT0RhdGFQYXRoU2VnbWVudHNIYW5kbGVyIH0gZnJvbSAnLi9wYXRoJztcbmltcG9ydCB7XG4gIGlzUXVlcnlDdXN0b21UeXBlLFxuICBPRGF0YVF1ZXJ5T3B0aW9ucyxcbiAgT0RhdGFRdWVyeU9wdGlvbnNIYW5kbGVyLFxufSBmcm9tICcuL3F1ZXJ5JztcbmltcG9ydCB7XG4gIEFwcGx5RXhwcmVzc2lvbixcbiAgQXBwbHlFeHByZXNzaW9uQnVpbGRlcixcbiAgUXVlcnlDdXN0b21UeXBlLFxufSBmcm9tICcuL3F1ZXJ5JztcbmltcG9ydCB7IE9EYXRhT3B0aW9ucyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtcbiAgT0RhdGFFbnRpdGllc0Fubm90YXRpb25zLFxuICBPRGF0YUVudGl0eUFubm90YXRpb25zLFxufSBmcm9tICcuLi9hbm5vdGF0aW9ucyc7XG5cbmV4cG9ydCB0eXBlIEVudGl0eUtleTxUPiA9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgW1AgaW4ga2V5b2YgVF0/OiBUW1BdO1xuICAgIH1cbiAgfCBRdWVyeUN1c3RvbVR5cGVcbiAgfCBzdHJpbmdcbiAgfCBudW1iZXI7XG5cbmV4cG9ydCBjbGFzcyBPRGF0YVJlc291cmNlPFQ+IHtcbiAgLy8gVkFSSUFCTEVTXG4gIHB1YmxpYyBhcGk6IE9EYXRhQXBpO1xuICBwcm90ZWN0ZWQgcGF0aFNlZ21lbnRzOiBPRGF0YVBhdGhTZWdtZW50cztcbiAgcHJvdGVjdGVkIHF1ZXJ5T3B0aW9uczogT0RhdGFRdWVyeU9wdGlvbnM8VD47XG4gIGNvbnN0cnVjdG9yKFxuICAgIGFwaTogT0RhdGFBcGksXG4gICAge1xuICAgICAgc2VnbWVudHMsXG4gICAgICBxdWVyeSxcbiAgICB9OiB7XG4gICAgICBzZWdtZW50cz86IE9EYXRhUGF0aFNlZ21lbnRzO1xuICAgICAgcXVlcnk/OiBPRGF0YVF1ZXJ5T3B0aW9uczxUPjtcbiAgICB9ID0ge30sXG4gICkge1xuICAgIHRoaXMuYXBpID0gYXBpO1xuICAgIHRoaXMucGF0aFNlZ21lbnRzID0gc2VnbWVudHMgPz8gbmV3IE9EYXRhUGF0aFNlZ21lbnRzKCk7XG4gICAgdGhpcy5xdWVyeU9wdGlvbnMgPSBxdWVyeSA/PyBuZXcgT0RhdGFRdWVyeU9wdGlvbnMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyBzdHJpbmcgVGhlIG91dGdvaW5nIHR5cGUgb2YgdGhlIHJlc291cmNlXG4gICAqL1xuICBvdXRnb2luZ1R5cGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucGF0aFNlZ21lbnRzLmxhc3QoKT8ub3V0Z29pbmdUeXBlKCk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMgc3RyaW5nIFRoZSBpbmNvbWluZyB0eXBlIG9mIHRoZSByZXNvdXJjZVxuICAgKi9cbiAgaW5jb21pbmdUeXBlKCkge1xuICAgIHJldHVybiB0aGlzLnBhdGhTZWdtZW50cy5sYXN0KCk/LmluY29taW5nVHlwZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHN0cmluZyBUaGUgYmluZGluZyB0eXBlIG9mIHRoZSByZXNvdXJjZVxuICAgKi9cbiAgYmluZGluZ1R5cGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucGF0aFNlZ21lbnRzLmxhc3QoKT8uYmluZGluZ1R5cGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyBzdHJpbmcgQWxsIGNvdmVyZWQgdHlwZXMgb2YgdGhlIHJlc291cmNlXG4gICAqL1xuICB0eXBlcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMucGF0aFNlZ21lbnRzLnR5cGVzKCk7XG4gIH1cblxuICBjYWxsYWJsZSgpIHtcbiAgICBjb25zdCB0eXBlID0gdGhpcy5vdXRnb2luZ1R5cGUoKSA/PyB0aGlzLmluY29taW5nVHlwZSgpO1xuICAgIHJldHVybiB0eXBlICE9PSB1bmRlZmluZWQgPyB0aGlzLmFwaS5jYWxsYWJsZTxUPih0eXBlKSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGVudW1UeXBlKCkge1xuICAgIGNvbnN0IHR5cGUgPSB0aGlzLm91dGdvaW5nVHlwZSgpID8/IHRoaXMuaW5jb21pbmdUeXBlKCk7XG4gICAgcmV0dXJuIHR5cGUgIT09IHVuZGVmaW5lZCA/IHRoaXMuYXBpLmVudW1UeXBlPFQ+KHR5cGUpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgc3RydWN0dXJlZFR5cGUoKSB7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMub3V0Z29pbmdUeXBlKCkgPz8gdGhpcy5pbmNvbWluZ1R5cGUoKTtcbiAgICByZXR1cm4gdHlwZSAhPT0gdW5kZWZpbmVkID8gdGhpcy5hcGkuc3RydWN0dXJlZFR5cGU8VD4odHlwZSkgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMgYm9vbGVhbiBUaGUgcmVzb3VyY2UgaGFzIGtleSA/XG4gICAqL1xuICBoYXNLZXkoKSB7XG4gICAgcmV0dXJuIEJvb2xlYW4odGhpcy5wYXRoU2VnbWVudHMubGFzdCh7IGtleTogdHJ1ZSB9KT8uaGFzS2V5KCkpO1xuICB9XG5cbiAgaGFzRW50aXR5S2V5KCkge1xuICAgIHJldHVybiBCb29sZWFuKHRoaXMucGF0aFNlZ21lbnRzLmdldChQYXRoU2VnbWVudC5lbnRpdHlTZXQpPy5oYXNLZXkoKSk7XG4gIH1cblxuICBjbGVhcktleSgpIHtcbiAgICByZXR1cm4gdGhpcy5wYXRoU2VnbWVudHMubGFzdCh7IGtleTogdHJ1ZSB9KT8uY2xlYXJLZXkoKTtcbiAgfVxuXG4gIC8vI3JlZ2lvbiBNb2RlbHNcbiAgYXNNb2RlbChcbiAgICBlbnRpdHk/OiBQYXJ0aWFsPFQ+IHwgeyBbbmFtZTogc3RyaW5nXTogYW55IH0sXG4gICk6IE9EYXRhTW9kZWw8VD4gJiBNb2RlbEludGVyZmFjZTxUPjtcbiAgYXNNb2RlbChcbiAgICBlbnRpdHk6IFBhcnRpYWw8VD4gfCB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfSxcbiAgICB7XG4gICAgICByZXNldCxcbiAgICAgIGFubm90cyxcbiAgICAgIE1vZGVsVHlwZSxcbiAgICB9OiB7XG4gICAgICByZXNldD86IGJvb2xlYW47XG4gICAgICBhbm5vdHM/OiBPRGF0YUVudGl0eUFubm90YXRpb25zPFQ+O1xuICAgICAgTW9kZWxUeXBlPzogdHlwZW9mIE9EYXRhTW9kZWw7XG4gICAgfSxcbiAgKTogT0RhdGFNb2RlbDxUPiAmIE1vZGVsSW50ZXJmYWNlPFQ+O1xuICBhc01vZGVsPE0gZXh0ZW5kcyBPRGF0YU1vZGVsPFQ+PihcbiAgICBlbnRpdHk/OiBQYXJ0aWFsPFQ+IHwgeyBbbmFtZTogc3RyaW5nXTogYW55IH0sXG4gICk6IE07XG4gIGFzTW9kZWw8TSBleHRlbmRzIE9EYXRhTW9kZWw8VD4+KFxuICAgIGVudGl0eTogUGFydGlhbDxUPiB8IHsgW25hbWU6IHN0cmluZ106IGFueSB9LFxuICAgIHtcbiAgICAgIHJlc2V0LFxuICAgICAgYW5ub3RzLFxuICAgICAgTW9kZWxUeXBlLFxuICAgIH06IHtcbiAgICAgIHJlc2V0PzogYm9vbGVhbjtcbiAgICAgIGFubm90cz86IE9EYXRhRW50aXR5QW5ub3RhdGlvbnM8VD47XG4gICAgICBNb2RlbFR5cGU/OiB0eXBlb2YgT0RhdGFNb2RlbDtcbiAgICB9LFxuICApOiBNO1xuICBhc01vZGVsKFxuICAgIGVudGl0eT86IFBhcnRpYWw8VD4gfCB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfSxcbiAgICB7XG4gICAgICByZXNldCxcbiAgICAgIGFubm90cyxcbiAgICAgIE1vZGVsVHlwZSxcbiAgICB9OiB7XG4gICAgICByZXNldD86IGJvb2xlYW47XG4gICAgICBhbm5vdHM/OiBPRGF0YUVudGl0eUFubm90YXRpb25zPFQ+O1xuICAgICAgTW9kZWxUeXBlPzogdHlwZW9mIE9EYXRhTW9kZWw7XG4gICAgfSA9IHt9LFxuICApIHtcbiAgICByZXNldCA/Pz0gYW5ub3RzICE9PSB1bmRlZmluZWQ7XG4gICAgbGV0IHJlc291cmNlOiBPRGF0YVJlc291cmNlPFQ+ID0gdGhpcyBhcyBPRGF0YVJlc291cmNlPFQ+O1xuICAgIGNvbnN0IHR5cGUgPSBhbm5vdHM/LnR5cGUgPz8gdGhpcy5pbmNvbWluZ1R5cGUoKTtcbiAgICBpZiAodHlwZSA9PT0gdW5kZWZpbmVkKSB0aHJvdyBFcnJvcihgTm8gdHlwZSBmb3IgbW9kZWxgKTtcbiAgICBpZiAoTW9kZWxUeXBlID09PSB1bmRlZmluZWQpIE1vZGVsVHlwZSA9IHRoaXMuYXBpLm1vZGVsRm9yVHlwZSh0eXBlKTtcbiAgICBsZXQgZW50aXR5U2V0ID0gYW5ub3RzPy5lbnRpdHlTZXQ7XG4gICAgaWYgKGVudGl0eVNldCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXNvdXJjZSA9IHRoaXMuYXBpLmVudGl0eVNldDxUPihlbnRpdHlTZXQpLmVudGl0eShlbnRpdHkgYXMgUGFydGlhbDxUPik7XG4gICAgICByZXNvdXJjZS5xdWVyeSgocSkgPT4gcS5yZXN0b3JlKHRoaXMucXVlcnlPcHRpb25zLnRvUXVlcnlBcmd1bWVudHMoKSkpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IE1vZGVsVHlwZShlbnRpdHksIHsgcmVzb3VyY2UsIGFubm90cywgcmVzZXQgfSk7XG4gIH1cblxuICBhc0NvbGxlY3Rpb24oXG4gICAgZW50aXRpZXM/OiBQYXJ0aWFsPFQ+W10gfCB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfVtdLFxuICApOiBPRGF0YUNvbGxlY3Rpb248VCwgT0RhdGFNb2RlbDxUPiAmIE1vZGVsSW50ZXJmYWNlPFQ+PjtcbiAgYXNDb2xsZWN0aW9uKFxuICAgIGVudGl0aWVzOiBQYXJ0aWFsPFQ+W10gfCB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfVtdLFxuICAgIHtcbiAgICAgIHJlc2V0LFxuICAgICAgYW5ub3RzLFxuICAgICAgQ29sbGVjdGlvblR5cGUsXG4gICAgfToge1xuICAgICAgcmVzZXQ/OiBib29sZWFuO1xuICAgICAgYW5ub3RzPzogT0RhdGFFbnRpdGllc0Fubm90YXRpb25zPFQ+O1xuICAgICAgQ29sbGVjdGlvblR5cGU/OiB0eXBlb2YgT0RhdGFDb2xsZWN0aW9uO1xuICAgIH0sXG4gICk6IE9EYXRhQ29sbGVjdGlvbjxULCBPRGF0YU1vZGVsPFQ+ICYgTW9kZWxJbnRlcmZhY2U8VD4+O1xuICBhc0NvbGxlY3Rpb248TSBleHRlbmRzIE9EYXRhTW9kZWw8VD4sIEMgZXh0ZW5kcyBPRGF0YUNvbGxlY3Rpb248VCwgTT4+KFxuICAgIGVudGl0aWVzPzogUGFydGlhbDxUPltdIHwgeyBbbmFtZTogc3RyaW5nXTogYW55IH1bXSxcbiAgKTogQztcbiAgYXNDb2xsZWN0aW9uPE0gZXh0ZW5kcyBPRGF0YU1vZGVsPFQ+LCBDIGV4dGVuZHMgT0RhdGFDb2xsZWN0aW9uPFQsIE0+PihcbiAgICBlbnRpdGllczogUGFydGlhbDxUPltdIHwgeyBbbmFtZTogc3RyaW5nXTogYW55IH1bXSxcbiAgICB7XG4gICAgICByZXNldCxcbiAgICAgIGFubm90cyxcbiAgICAgIENvbGxlY3Rpb25UeXBlLFxuICAgIH06IHtcbiAgICAgIHJlc2V0PzogYm9vbGVhbjtcbiAgICAgIGFubm90cz86IE9EYXRhRW50aXRpZXNBbm5vdGF0aW9uczxUPjtcbiAgICAgIENvbGxlY3Rpb25UeXBlPzogdHlwZW9mIE9EYXRhQ29sbGVjdGlvbjtcbiAgICB9LFxuICApOiBDO1xuICBhc0NvbGxlY3Rpb24oXG4gICAgZW50aXRpZXM/OiBQYXJ0aWFsPFQ+W10gfCB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfVtdLFxuICAgIHtcbiAgICAgIHJlc2V0LFxuICAgICAgYW5ub3RzLFxuICAgICAgQ29sbGVjdGlvblR5cGUsXG4gICAgfToge1xuICAgICAgcmVzZXQ/OiBib29sZWFuO1xuICAgICAgYW5ub3RzPzogT0RhdGFFbnRpdGllc0Fubm90YXRpb25zPFQ+O1xuICAgICAgQ29sbGVjdGlvblR5cGU/OiB0eXBlb2YgT0RhdGFDb2xsZWN0aW9uO1xuICAgIH0gPSB7fSxcbiAgKSB7XG4gICAgcmVzZXQgPz89IGFubm90cyAhPT0gdW5kZWZpbmVkO1xuICAgIGxldCByZXNvdXJjZTogT0RhdGFSZXNvdXJjZTxUPiA9IHRoaXMgYXMgT0RhdGFSZXNvdXJjZTxUPjtcbiAgICBjb25zdCB0eXBlID0gYW5ub3RzPy50eXBlID8/IHRoaXMuaW5jb21pbmdUeXBlKCk7XG4gICAgaWYgKHR5cGUgPT09IHVuZGVmaW5lZCkgdGhyb3cgRXJyb3IoYE5vIHR5cGUgZm9yIGNvbGxlY3Rpb25gKTtcbiAgICBpZiAoQ29sbGVjdGlvblR5cGUgPT09IHVuZGVmaW5lZClcbiAgICAgIENvbGxlY3Rpb25UeXBlID0gdGhpcy5hcGkuY29sbGVjdGlvbkZvclR5cGUodHlwZSk7XG4gICAgbGV0IGVudGl0eVNldCA9IGFubm90cz8uZW50aXR5U2V0O1xuICAgIGlmIChlbnRpdHlTZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVzb3VyY2UgPSB0aGlzLmFwaS5lbnRpdHlTZXQ8VD4oZW50aXR5U2V0KTtcbiAgICAgIHJlc291cmNlLnF1ZXJ5KChxKSA9PiBxLnJlc3RvcmUodGhpcy5xdWVyeU9wdGlvbnMudG9RdWVyeUFyZ3VtZW50cygpKSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQ29sbGVjdGlvblR5cGUoZW50aXRpZXMsIHsgcmVzb3VyY2UsIGFubm90cywgcmVzZXQgfSk7XG4gIH1cbiAgLy8jZW5kcmVnaW9uXG5cbiAgaXNUeXBlT2Yob3RoZXI6IE9EYXRhUmVzb3VyY2U8YW55Pikge1xuICAgIGNvbnN0IHRoaXNTdHJ1Y3R1cmVkID0gdGhpcy5zdHJ1Y3R1cmVkVHlwZSgpO1xuICAgIGNvbnN0IG90aGVyU3RydWN0dXJlZCA9IG90aGVyLnN0cnVjdHVyZWRUeXBlKCk7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXNTdHJ1Y3R1cmVkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIG90aGVyU3RydWN0dXJlZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICB0aGlzU3RydWN0dXJlZC5pc1R5cGVPZihvdGhlclN0cnVjdHVyZWQpXG4gICAgKTtcbiAgfVxuXG4gIGlzU3VidHlwZU9mKG90aGVyOiBPRGF0YVJlc291cmNlPGFueT4pIHtcbiAgICBjb25zdCB0aGlzU3RydWN0dXJlZCA9IHRoaXMuc3RydWN0dXJlZFR5cGUoKTtcbiAgICBjb25zdCBvdGhlclN0cnVjdHVyZWQgPSBvdGhlci5zdHJ1Y3R1cmVkVHlwZSgpO1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzU3RydWN0dXJlZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICBvdGhlclN0cnVjdHVyZWQgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgdGhpc1N0cnVjdHVyZWQuaXNTdWJ0eXBlT2Yob3RoZXJTdHJ1Y3R1cmVkKVxuICAgICk7XG4gIH1cblxuICBpc1N1cGVydHlwZU9mKG90aGVyOiBPRGF0YVJlc291cmNlPGFueT4pIHtcbiAgICBjb25zdCB0aGlzU3RydWN0dXJlZCA9IHRoaXMuc3RydWN0dXJlZFR5cGUoKTtcbiAgICBjb25zdCBvdGhlclN0cnVjdHVyZWQgPSBvdGhlci5zdHJ1Y3R1cmVkVHlwZSgpO1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzU3RydWN0dXJlZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICBvdGhlclN0cnVjdHVyZWQgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgdGhpc1N0cnVjdHVyZWQuaXNTdXBlcnR5cGVPZihvdGhlclN0cnVjdHVyZWQpXG4gICAgKTtcbiAgfVxuXG4gIGlzRXF1YWxUbyhvdGhlcjogT0RhdGFSZXNvdXJjZTxhbnk+LCB0ZXN0PzogJ3BhdGgnIHwgJ3BhcmFtcycpIHtcbiAgICBjb25zdCBbc2VsZlBhdGgsIHNlbGZQYXJhbXNdID0gdGhpcy5wYXRoQW5kUGFyYW1zKCk7XG4gICAgY29uc3QgW290aGVyUGF0aCwgb3RoZXJQYXJhbXNdID0gb3RoZXIucGF0aEFuZFBhcmFtcygpO1xuICAgIHJldHVybiB0ZXN0ID09PSAncGF0aCdcbiAgICAgID8gb3RoZXJQYXRoID09PSBzZWxmUGF0aFxuICAgICAgOiB0ZXN0ID09PSAncGFyYW1zJ1xuICAgICAgICA/IFR5cGVzLmlzRXF1YWwoc2VsZlBhcmFtcywgb3RoZXJQYXJhbXMpXG4gICAgICAgIDogb3RoZXJQYXRoID09PSBzZWxmUGF0aCAmJiBUeXBlcy5pc0VxdWFsKHNlbGZQYXJhbXMsIG90aGVyUGFyYW1zKTtcbiAgfVxuXG4gIHBhdGhBbmRQYXJhbXMoXG4gICAgeyBlc2NhcGUsIC4uLm9wdGlvbnMgfTogUGFyc2VyT3B0aW9ucyAmIHsgZXNjYXBlPzogYm9vbGVhbiB9ID0ge1xuICAgICAgZXNjYXBlOiBmYWxzZSxcbiAgICB9LFxuICApOiBbc3RyaW5nLCB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfV0ge1xuICAgIGNvbnN0IHR5cGUgPSB0aGlzLm91dGdvaW5nVHlwZSgpO1xuICAgIGNvbnN0IHBhcnNlciA9XG4gICAgICB0eXBlICE9PSB1bmRlZmluZWQgPyB0aGlzLmFwaS5wYXJzZXJGb3JUeXBlPFQ+KHR5cGUpIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IFtzcGF0aCwgc3BhcmFtc10gPSB0aGlzLnBhdGhTZWdtZW50cy5wYXRoQW5kUGFyYW1zKHtcbiAgICAgIGVzY2FwZSxcbiAgICAgIHBhcnNlcixcbiAgICAgIG9wdGlvbnMsXG4gICAgfSk7XG4gICAgY29uc3QgWywgcXBhcmFtc10gPSB0aGlzLnF1ZXJ5T3B0aW9ucy5wYXRoQW5kUGFyYW1zKHtcbiAgICAgIGVzY2FwZSxcbiAgICAgIHBhcnNlcixcbiAgICAgIG9wdGlvbnMsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gW3NwYXRoLCB7IC4uLnNwYXJhbXMsIC4uLnFwYXJhbXMgfV07XG4gIH1cblxuICBlbmRwb2ludFVybCh7XG4gICAgZXNjYXBlID0gZmFsc2UsXG4gICAgcGFyYW1zID0gdHJ1ZSxcbiAgICAuLi5vcHRpb25zXG4gIH06IFBhcnNlck9wdGlvbnMgJiB7IGVzY2FwZT86IGJvb2xlYW47IHBhcmFtcz86IGJvb2xlYW4gfSA9IHt9KTogc3RyaW5nIHtcbiAgICBsZXQgW3BhdGgsIHFwYXJhbXNdID0gdGhpcy5wYXRoQW5kUGFyYW1zKHsgZXNjYXBlLCAuLi5vcHRpb25zIH0pO1xuICAgIGlmIChwYXJhbXMgJiYgIVR5cGVzLmlzRW1wdHkocXBhcmFtcykpIHtcbiAgICAgIHBhdGggPSBgJHtwYXRofSR7UVVFUllfU0VQQVJBVE9SfSR7T2JqZWN0LmVudHJpZXMocXBhcmFtcylcbiAgICAgICAgLm1hcCgoZSkgPT4gYCR7ZVswXX0ke1ZBTFVFX1NFUEFSQVRPUn0ke2VbMV19YClcbiAgICAgICAgLmpvaW4oUEFSQU1fU0VQQVJBVE9SKX1gO1xuICAgIH1cbiAgICByZXR1cm4gYCR7dGhpcy5hcGkuc2VydmljZVJvb3RVcmx9JHtwYXRofWA7XG4gIH1cblxuICB0b1N0cmluZyhcbiAgICB7IGVzY2FwZSwgLi4ub3B0aW9ucyB9OiBQYXJzZXJPcHRpb25zICYgeyBlc2NhcGU/OiBib29sZWFuIH0gPSB7XG4gICAgICBlc2NhcGU6IGZhbHNlLFxuICAgIH0sXG4gICk6IHN0cmluZyB7XG4gICAgbGV0IFtwYXRoLCBwYXJhbXNdID0gdGhpcy5wYXRoQW5kUGFyYW1zKHsgZXNjYXBlLCAuLi5vcHRpb25zIH0pO1xuICAgIGxldCBxdWVyeVN0cmluZyA9IE9iamVjdC5lbnRyaWVzKHBhcmFtcylcbiAgICAgIC5tYXAoKGUpID0+IGAke2VbMF19JHtWQUxVRV9TRVBBUkFUT1J9JHtlWzFdfWApXG4gICAgICAuam9pbihQQVJBTV9TRVBBUkFUT1IpO1xuICAgIHJldHVybiBxdWVyeVN0cmluZyA/IGAke3BhdGh9JHtRVUVSWV9TRVBBUkFUT1J9JHtxdWVyeVN0cmluZ31gIDogcGF0aDtcbiAgfVxuXG4gIGNsb25lKCk6IE9EYXRhUmVzb3VyY2U8VD4ge1xuICAgIGNvbnN0IEN0b3IgPSB0aGlzLmNvbnN0cnVjdG9yIGFzIHR5cGVvZiBPRGF0YVJlc291cmNlO1xuICAgIHJldHVybiBuZXcgQ3Rvcih0aGlzLmFwaSwge1xuICAgICAgc2VnbWVudHM6IHRoaXMuY2xvbmVTZWdtZW50cygpLFxuICAgICAgcXVlcnk6IHRoaXMuY2xvbmVRdWVyeTxUPigpLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfX3BhcnNlcihcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wdGlvbnM/OiBQYXJzZXJPcHRpb25zLFxuICAgIHJlc291cmNlVHlwZT86IHN0cmluZyxcbiAgICBiaW5kaW5nVHlwZT86IHN0cmluZyxcbiAgKTogUGFyc2VyPFQ+IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBkYXRhVHlwZSA9XG4gICAgICBvcHRpb25zICE9PSB1bmRlZmluZWQgJiYgVHlwZXMuaXNQbGFpbk9iamVjdCh2YWx1ZSlcbiAgICAgICAgPyBPRGF0YUhlbHBlcltvcHRpb25zLnZlcnNpb24gPz8gREVGQVVMVF9WRVJTSU9OXS50eXBlKHZhbHVlKVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICBpZiAoZGF0YVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gUGFyc2VyIGZyb20gZGF0YSB0eXBlXG4gICAgICByZXR1cm4gdGhpcy5hcGkucGFyc2VyRm9yVHlwZTxUPihkYXRhVHlwZSk7XG4gICAgfSBlbHNlIGlmIChyZXNvdXJjZVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gUGFyc2VyIGZyb20gcmVzb3VyY2UgdHlwZVxuICAgICAgcmV0dXJuIHRoaXMuYXBpLnBhcnNlckZvclR5cGU8VD4ocmVzb3VyY2VUeXBlLCBiaW5kaW5nVHlwZSk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBkZXNlcmlhbGl6ZSh2YWx1ZTogYW55LCBvcHRpb25zPzogUGFyc2VyT3B0aW9ucyk6IGFueSB7XG4gICAgY29uc3QgcmVzb3VyY2VUeXBlID0gdGhpcy5pbmNvbWluZ1R5cGUoKTtcbiAgICBjb25zdCBiaW5kaW5nVHlwZSA9IHRoaXMuYmluZGluZ1R5cGUoKTtcbiAgICBjb25zdCBfZCA9ICh2YWx1ZTogYW55LCBvcHRpb25zPzogUGFyc2VyT3B0aW9ucykgPT4ge1xuICAgICAgY29uc3QgcGFyc2VyID0gdGhpcy5fX3BhcnNlcih2YWx1ZSwgb3B0aW9ucywgcmVzb3VyY2VUeXBlLCBiaW5kaW5nVHlwZSk7XG4gICAgICByZXR1cm4gcGFyc2VyICE9PSB1bmRlZmluZWQgPyBwYXJzZXIuZGVzZXJpYWxpemUodmFsdWUsIG9wdGlvbnMpIDogdmFsdWU7XG4gICAgfTtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSlcbiAgICAgID8gdmFsdWUubWFwKCh2KSA9PiBfZCh2LCBvcHRpb25zKSlcbiAgICAgIDogX2QodmFsdWUsIG9wdGlvbnMpO1xuICB9XG5cbiAgc2VyaWFsaXplKHZhbHVlOiBhbnksIG9wdGlvbnM/OiBQYXJzZXJPcHRpb25zKTogYW55IHtcbiAgICBjb25zdCByZXNvdXJjZVR5cGUgPSB0aGlzLm91dGdvaW5nVHlwZSgpO1xuICAgIGNvbnN0IGJpbmRpbmdUeXBlID0gdGhpcy5iaW5kaW5nVHlwZSgpO1xuICAgIGNvbnN0IF9zID0gKHZhbHVlOiBhbnksIG9wdGlvbnM/OiBQYXJzZXJPcHRpb25zKSA9PiB7XG4gICAgICBjb25zdCBwYXJzZXIgPSB0aGlzLl9fcGFyc2VyKHZhbHVlLCBvcHRpb25zLCByZXNvdXJjZVR5cGUsIGJpbmRpbmdUeXBlKTtcbiAgICAgIHJldHVybiBwYXJzZXIgIT09IHVuZGVmaW5lZCA/IHBhcnNlci5zZXJpYWxpemUodmFsdWUsIG9wdGlvbnMpIDogdmFsdWU7XG4gICAgfTtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSlcbiAgICAgID8gdmFsdWUubWFwKCh2KSA9PiBfcyh2LCBvcHRpb25zKSlcbiAgICAgIDogX3ModmFsdWUsIG9wdGlvbnMpO1xuICB9XG5cbiAgZW5jb2RlKHZhbHVlOiBhbnksIG9wdGlvbnM/OiBQYXJzZXJPcHRpb25zKTogYW55IHtcbiAgICBjb25zdCByZXNvdXJjZVR5cGUgPSB0aGlzLm91dGdvaW5nVHlwZSgpO1xuICAgIGNvbnN0IGJpbmRpbmdUeXBlID0gdGhpcy5iaW5kaW5nVHlwZSgpO1xuICAgIGNvbnN0IF9lID0gKHZhbHVlOiBhbnksIG9wdGlvbnM/OiBQYXJzZXJPcHRpb25zKSA9PiB7XG4gICAgICBjb25zdCBwYXJzZXIgPSB0aGlzLl9fcGFyc2VyKHZhbHVlLCBvcHRpb25zLCByZXNvdXJjZVR5cGUsIGJpbmRpbmdUeXBlKTtcbiAgICAgIHJldHVybiBwYXJzZXIgIT09IHVuZGVmaW5lZCA/IHBhcnNlci5lbmNvZGUodmFsdWUsIG9wdGlvbnMpIDogdmFsdWU7XG4gICAgfTtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSlcbiAgICAgID8gdmFsdWUubWFwKCh2KSA9PiBfZSh2LCBvcHRpb25zKSlcbiAgICAgIDogX2UodmFsdWUsIG9wdGlvbnMpO1xuICB9XG5cbiAgdG9Kc29uKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzZWdtZW50czogdGhpcy5wYXRoU2VnbWVudHMudG9Kc29uKCksXG4gICAgICBvcHRpb25zOiB0aGlzLnF1ZXJ5T3B0aW9ucy50b0pzb24oKSxcbiAgICB9O1xuICB9XG5cbiAgY2xvbmVTZWdtZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy5wYXRoU2VnbWVudHMuY2xvbmUoKTtcbiAgfVxuXG4gIC8vI3JlZ2lvbiBRdWVyeSBPcHRpb25zXG4gIGNsZWFyUXVlcnkoKSB7XG4gICAgdGhpcy5xdWVyeU9wdGlvbnMuY2xlYXIoKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGNsb25lUXVlcnk8UD4oKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlPcHRpb25zLmNsb25lPFA+KCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHRoZSBwYXRoIHNlZ21lbnRzIG9mIHRoZSByZXNvdXJjZVxuICAgKiBDcmVhdGUgYW4gb2JqZWN0IGhhbmRsZXIgZm9yIG11dGF0ZSB0aGUgcGF0aCBzZWdtZW50cyBvZiB0aGUgcmVzb3VyY2VcbiAgICogQHBhcmFtIGYgRnVuY3Rpb24gY29udGV4dCBmb3IgaGFuZGxlIHRoZSBzZWdtZW50c1xuICAgKiBAcmV0dXJucyBPRGF0YUFjdGlvblJlc291cmNlXG4gICAqL1xuICBzZWdtZW50KFxuICAgIGY6IChxOiBPRGF0YVBhdGhTZWdtZW50c0hhbmRsZXI8VD4sIHM/OiBPRGF0YVN0cnVjdHVyZWRUeXBlPFQ+KSA9PiB2b2lkLFxuICApIHtcbiAgICBjb25zdCB0eXBlID0gdGhpcy5vdXRnb2luZ1R5cGUoKTtcbiAgICBmKFxuICAgICAgbmV3IE9EYXRhUGF0aFNlZ21lbnRzSGFuZGxlcjxUPih0aGlzLnBhdGhTZWdtZW50cyksXG4gICAgICB0eXBlICE9PSB1bmRlZmluZWQgPyB0aGlzLmFwaS5zdHJ1Y3R1cmVkVHlwZTxUPih0eXBlKSA6IHVuZGVmaW5lZCxcbiAgICApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSB0aGUgcXVlcnkgb3B0aW9ucyBvZiB0aGUgcmVzb3VyY2VcbiAgICogQ3JlYXRlIGFuIG9iamVjdCBoYW5kbGVyIGZvciBtdXRhdGUgdGhlIHF1ZXJ5IG9wdGlvbnMgb2YgdGhlIHJlc291cmNlXG4gICAqIEBwYXJhbSBmIEZ1bmN0aW9uIGNvbnRleHQgZm9yIGhhbmRsZSB0aGUgcXVlcnkgb3B0aW9uc1xuICAgKi9cbiAgcXVlcnkoXG4gICAgZjogKHE6IE9EYXRhUXVlcnlPcHRpb25zSGFuZGxlcjxUPiwgcz86IE9EYXRhU3RydWN0dXJlZFR5cGU8VD4pID0+IHZvaWQsXG4gICkge1xuICAgIGNvbnN0IHR5cGUgPSB0aGlzLm91dGdvaW5nVHlwZSgpO1xuICAgIGYoXG4gICAgICBuZXcgT0RhdGFRdWVyeU9wdGlvbnNIYW5kbGVyPFQ+KHRoaXMucXVlcnlPcHRpb25zKSxcbiAgICAgIHR5cGUgIT09IHVuZGVmaW5lZCA/IHRoaXMuYXBpLnN0cnVjdHVyZWRUeXBlPFQ+KHR5cGUpIDogdW5kZWZpbmVkLFxuICAgICk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB0cmFuc2Zvcm08Uj4oXG4gICAgb3B0czogKFxuICAgICAgYnVpbGRlcjogQXBwbHlFeHByZXNzaW9uQnVpbGRlcjxUPixcbiAgICAgIGN1cnJlbnQ/OiBBcHBseUV4cHJlc3Npb248VD4sXG4gICAgKSA9PiBBcHBseUV4cHJlc3Npb248VD4sXG4gICAge1xuICAgICAgdHlwZSxcbiAgICAgIGZpZWxkcyxcbiAgICB9OiB7XG4gICAgICB0eXBlPzogc3RyaW5nO1xuICAgICAgZmllbGRzPzogeyBbbmFtZTogc3RyaW5nXTogU3RydWN0dXJlZFR5cGVGaWVsZENvbmZpZyB9O1xuICAgIH0gPSB7fSxcbiAgKTogT0RhdGFSZXNvdXJjZTxSPiB7XG4gICAgaWYgKHR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdHlwZSA9IFN0cmluZ3MudW5pcXVlSWQoeyBwcmVmaXg6ICdUcmFuc2Zvcm1hdGlvbicsIHN1ZmZpeDogJ1R5cGUnIH0pO1xuICAgIH1cblxuICAgIC8vIFJlc29sdmUgU3RydWN0dXJlZCBUeXBlXG4gICAgbGV0IHN0cnVjdHVyZWRUeXBlID0gdGhpcy5hcGkuZmluZFN0cnVjdHVyZWRUeXBlPFI+KHR5cGUpO1xuICAgIGlmIChzdHJ1Y3R1cmVkVHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBSZXNvbHZlIFNjaGVtYVxuICAgICAgbGV0IHNjaGVtYSA9IHRoaXMuYXBpLmZpbmRTY2hlbWEodHlwZSk7XG4gICAgICBpZiAoc2NoZW1hID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgbmFtZXNwYWNlID1cbiAgICAgICAgICB0eXBlLnN1YnN0cmluZygwLCB0eXBlLmxhc3RJbmRleE9mKCcuJykpID8/IHRoaXMuYXBpLm5hbWUhO1xuICAgICAgICBzY2hlbWEgPSB0aGlzLmFwaS5jcmVhdGVTY2hlbWEoeyBuYW1lc3BhY2UgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lID0gdHlwZS5zdWJzdHJpbmcodHlwZS5sYXN0SW5kZXhPZignLicpKTtcbiAgICAgIHN0cnVjdHVyZWRUeXBlID0gc2NoZW1hLmNyZWF0ZVN0cnVjdHVyZWRUeXBlKHsgbmFtZSwgZmllbGRzIH0pO1xuICAgIH1cblxuICAgIC8vIFNlZ21lbnRzXG4gICAgY29uc3Qgc2VnbWVudHMgPSB0aGlzLmNsb25lU2VnbWVudHMoKTtcbiAgICBzZWdtZW50cy5sYXN0KCk/LmluY29taW5nVHlwZShzdHJ1Y3R1cmVkVHlwZS50eXBlKCkpO1xuXG4gICAgLy8gUXVlcnlcbiAgICBjb25zdCBxdWVyeSA9IHRoaXMuY2xvbmVRdWVyeTxhbnk+KCk7XG4gICAgY29uc3QgaGFuZGxlciA9IG5ldyBPRGF0YVF1ZXJ5T3B0aW9uc0hhbmRsZXI8VD4ocXVlcnkpO1xuICAgIGhhbmRsZXIuYXBwbHkob3B0cyk7XG5cbiAgICBjb25zdCBDdG9yID0gdGhpcy5jb25zdHJ1Y3RvciBhcyB0eXBlb2YgT0RhdGFSZXNvdXJjZTtcbiAgICByZXR1cm4gbmV3IEN0b3IodGhpcy5hcGksIHtcbiAgICAgIHNlZ21lbnRzLFxuICAgICAgcXVlcnksXG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgcmVzb2x2ZUtleTxUPihcbiAgICB2YWx1ZTogYW55LFxuICAgIHNjaGVtYT86IE9EYXRhU3RydWN0dXJlZFR5cGU8VD4sXG4gICk6IEVudGl0eUtleTxUPiB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGlzUXVlcnlDdXN0b21UeXBlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0gZWxzZSBpZiAoVHlwZXMuaXNQbGFpbk9iamVjdCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBzY2hlbWEgaW5zdGFuY2VvZiBPRGF0YVN0cnVjdHVyZWRUeXBlXG4gICAgICAgID8gc2NoZW1hLnJlc29sdmVLZXkodmFsdWUpXG4gICAgICAgIDogT2JqZWN0cy5yZXNvbHZlS2V5KHZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlIGFzIEVudGl0eUtleTxUPiB8IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByb3RlY3RlZCByZXNvbHZlS2V5KHZhbHVlOiBhbnkpOiBFbnRpdHlLZXk8VD4gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHR5cGUgPSB0aGlzLm91dGdvaW5nVHlwZSgpO1xuICAgIGNvbnN0IHN0cnVjdHVyZWQgPVxuICAgICAgdHlwZSAhPT0gdW5kZWZpbmVkID8gdGhpcy5hcGkuc3RydWN0dXJlZFR5cGU8VD4odHlwZSkgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIE9EYXRhUmVzb3VyY2UucmVzb2x2ZUtleTxUPih2YWx1ZSwgc3RydWN0dXJlZCk7XG4gIH1cbiAgLy8jZW5kcmVnaW9uXG5cbiAgcHJvdGVjdGVkIGdldChcbiAgICBvcHRpb25zOiBPRGF0YU9wdGlvbnMgJiB7XG4gICAgICBldGFnPzogc3RyaW5nO1xuICAgICAgcmVzcG9uc2VUeXBlPzpcbiAgICAgICAgfCAnYXJyYXlidWZmZXInXG4gICAgICAgIHwgJ2Jsb2InXG4gICAgICAgIHwgJ2pzb24nXG4gICAgICAgIHwgJ3RleHQnXG4gICAgICAgIHwgJ3ZhbHVlJ1xuICAgICAgICB8ICdwcm9wZXJ0eSdcbiAgICAgICAgfCAnZW50aXR5J1xuICAgICAgICB8ICdlbnRpdGllcyc7XG4gICAgICB3aXRoQ291bnQ/OiBib29sZWFuO1xuICAgICAgYm9keVF1ZXJ5T3B0aW9ucz86IFF1ZXJ5T3B0aW9uW107XG4gICAgfSA9IHt9LFxuICApOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLmFwaS5yZXF1ZXN0PFQ+KCdHRVQnLCB0aGlzLCBvcHRpb25zKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwb3N0KFxuICAgIGJvZHk6IGFueSxcbiAgICBvcHRpb25zOiBPRGF0YU9wdGlvbnMgJiB7XG4gICAgICByZXNwb25zZVR5cGU/OlxuICAgICAgICB8ICdhcnJheWJ1ZmZlcidcbiAgICAgICAgfCAnYmxvYidcbiAgICAgICAgfCAnanNvbidcbiAgICAgICAgfCAndGV4dCdcbiAgICAgICAgfCAndmFsdWUnXG4gICAgICAgIHwgJ3Byb3BlcnR5J1xuICAgICAgICB8ICdlbnRpdHknXG4gICAgICAgIHwgJ2VudGl0aWVzJztcbiAgICAgIHdpdGhDb3VudD86IGJvb2xlYW47XG4gICAgfSA9IHt9LFxuICApOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLmFwaS5yZXF1ZXN0PFQ+KCdQT1NUJywgdGhpcywgeyBib2R5LCAuLi5vcHRpb25zIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHB1dChcbiAgICBib2R5OiBhbnksXG4gICAgb3B0aW9uczogT0RhdGFPcHRpb25zICYge1xuICAgICAgZXRhZz86IHN0cmluZztcbiAgICAgIHJlc3BvbnNlVHlwZT86XG4gICAgICAgIHwgJ2FycmF5YnVmZmVyJ1xuICAgICAgICB8ICdibG9iJ1xuICAgICAgICB8ICdqc29uJ1xuICAgICAgICB8ICd0ZXh0J1xuICAgICAgICB8ICd2YWx1ZSdcbiAgICAgICAgfCAncHJvcGVydHknXG4gICAgICAgIHwgJ2VudGl0eSdcbiAgICAgICAgfCAnZW50aXRpZXMnO1xuICAgICAgd2l0aENvdW50PzogYm9vbGVhbjtcbiAgICB9ID0ge30sXG4gICk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuYXBpLnJlcXVlc3Q8VD4oJ1BVVCcsIHRoaXMsIHsgYm9keSwgLi4ub3B0aW9ucyB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXRjaChcbiAgICBib2R5OiBhbnksXG4gICAgb3B0aW9uczogT0RhdGFPcHRpb25zICYge1xuICAgICAgZXRhZz86IHN0cmluZztcbiAgICAgIHJlc3BvbnNlVHlwZT86XG4gICAgICAgIHwgJ2FycmF5YnVmZmVyJ1xuICAgICAgICB8ICdibG9iJ1xuICAgICAgICB8ICdqc29uJ1xuICAgICAgICB8ICd0ZXh0J1xuICAgICAgICB8ICd2YWx1ZSdcbiAgICAg