@ngqp/core
Version:
205 lines • 30.6 kB
JavaScript
import { forkJoin, of, Subject } from 'rxjs';
import { first } from 'rxjs/operators';
import { areEqualUsing, isFunction, isMissing, isPresent, undefinedToNull, wrapIntoObservable, wrapTryCatch } from '../util';
/** @internal */
class AbstractQueryParamBase {
constructor() {
this.parent = null;
this._valueChanges = new Subject();
this.changeFunctions = [];
/**
* Emits the current value of this parameter whenever it changes.
*
* NOTE: This observable does not complete on its own, so ensure to unsubscribe from it.
*/
this.valueChanges = this._valueChanges.asObservable();
}
_registerOnChange(fn) {
this.changeFunctions.push(fn);
}
_clearChangeFunctions() {
this.changeFunctions = [];
}
_setParent(parent) {
if (this.parent && parent) {
throw new Error(`Parameter already belongs to a QueryParamGroup.`);
}
this.parent = parent;
}
}
/**
* Abstract base for {@link QueryParam} and {@link MultiQueryParam}.
*
* This base class holds most of the parameter's options, but is unaware of
* how to actually (de-)serialize any values.
*/
export class AbstractQueryParam extends AbstractQueryParamBase {
constructor(urlParam, opts = {}) {
super();
/**
* The current value of this parameter.
*/
this.value = null;
const { serialize, deserialize, debounceTime, compareWith, emptyOn, combineWith } = opts;
if (isMissing(urlParam)) {
throw new Error(`Please provide a URL parameter name for each query parameter.`);
}
if (!isFunction(serialize)) {
throw new Error(`serialize must be a function, but received ${serialize}`);
}
if (!isFunction(deserialize)) {
throw new Error(`deserialize must be a function, but received ${deserialize}`);
}
if (emptyOn !== undefined && !isFunction(compareWith)) {
throw new Error(`compareWith must be a function, but received ${compareWith}`);
}
if (isPresent(combineWith) && !isFunction(combineWith)) {
throw new Error(`combineWith must be a function, but received ${combineWith}`);
}
this.urlParam = urlParam;
this.serialize = wrapTryCatch(serialize, `Error while serializing value for ${this.urlParam}`);
this.deserialize = wrapTryCatch(deserialize, `Error while deserializing value for ${this.urlParam}`);
this.debounceTime = undefinedToNull(debounceTime);
this.emptyOn = emptyOn;
this.compareWith = compareWith;
this.combineWith = combineWith;
}
/**
* Updates the value of this parameter.
*
* If wired up with a {@link QueryParamGroup}, this will also synchronize
* the value to the URL.
*/
setValue(value, opts = {}) {
this.value = value;
if (opts.emitModelToViewChange !== false) {
this.changeFunctions.forEach(changeFn => changeFn(value));
}
if (opts.emitEvent !== false) {
this._valueChanges.next(this.value);
}
if (isPresent(this.parent) && !opts.onlySelf) {
this.parent._updateValue({
emitEvent: opts.emitEvent,
emitModelToViewChange: false,
});
}
}
}
/**
* Describes a single parameter.
*
* This is the description of a single parameter and essentially serves
* as the glue between its representation in the URL and its connection
* to a form control.
*/
export class QueryParam extends AbstractQueryParam {
constructor(urlParam, opts) {
super(urlParam, opts);
/** See {@link QueryParamOpts}. */
this.multi = false;
}
/** @internal */
serializeValue(value) {
if (this.emptyOn !== undefined && areEqualUsing(value, this.emptyOn, this.compareWith)) {
return null;
}
return this.serialize(value);
}
/** @internal */
deserializeValue(value) {
if (this.emptyOn !== undefined && value === null) {
return of(this.emptyOn);
}
return wrapIntoObservable(this.deserialize(value)).pipe(first());
}
}
/**
* Like {@link QueryParam}, but for array-typed parameters
*/
export class MultiQueryParam extends AbstractQueryParam {
constructor(urlParam, opts) {
super(urlParam, opts);
/** See {@link QueryParamOpts}. */
this.multi = true;
const { serializeAll, deserializeAll } = opts;
if (serializeAll !== undefined) {
if (!isFunction(serializeAll)) {
throw new Error(`serializeAll must be a function, but received ${serializeAll}`);
}
this.serializeAll = wrapTryCatch(serializeAll, `Error while serializing value for ${this.urlParam}`);
}
if (deserializeAll !== undefined) {
if (!isFunction(deserializeAll)) {
throw new Error(`deserializeAll must be a function, but received ${deserializeAll}`);
}
this.deserializeAll = wrapTryCatch(deserializeAll, `Error while deserializing value for ${this.urlParam}`);
}
}
/** @internal */
serializeValue(value) {
if (this.emptyOn !== undefined && areEqualUsing(value, this.emptyOn, this.compareWith)) {
return null;
}
if (this.serializeAll !== undefined) {
return this.serializeAll(value);
}
return (value || []).map(this.serialize.bind(this));
}
/** @internal */
deserializeValue(values) {
if (this.emptyOn !== undefined && (values || []).length === 0) {
return of(this.emptyOn);
}
if (this.deserializeAll !== undefined) {
return wrapIntoObservable(this.deserializeAll(values));
}
if (!values || values.length === 0) {
return of([]);
}
return forkJoin(...values
.map(value => wrapIntoObservable(this.deserialize(value)).pipe(first())));
}
}
/**
* Describes a partitioned query parameter.
*
* This encapsulates a list of query parameters such that a single form control
* can be bound against multiple URL parameters. To achieve this, functions must
* be defined which can convert the models between the parameters.
*/
export class PartitionedQueryParam extends AbstractQueryParamBase {
constructor(queryParams, opts) {
super();
if (queryParams.length === 0) {
throw new Error(`Partitioned parameters must contain at least one parameter.`);
}
if (!isFunction(opts.partition)) {
throw new Error(`partition must be a function, but received ${opts.partition}`);
}
if (!isFunction(opts.reduce)) {
throw new Error(`reduce must be a function, but received ${opts.reduce}`);
}
this.queryParams = queryParams;
this.partition = opts.partition;
this.reduce = opts.reduce;
}
get value() {
return this.reduce(this.queryParams.map(queryParam => queryParam.value));
}
setValue(value, opts = {}) {
const partitioned = this.partition(value);
this.queryParams.forEach((queryParam, index) => queryParam.setValue(partitioned[index], {
emitEvent: opts.emitEvent,
onlySelf: true,
emitModelToViewChange: false,
}));
if (opts.emitModelToViewChange !== false) {
this.changeFunctions.forEach(changeFn => changeFn(this.value));
}
if (opts.emitEvent !== false) {
this._valueChanges.next(this.value);
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktcGFyYW0uanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmdxcC9jb3JlL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9tb2RlbC9xdWVyeS1wYXJhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUE0QixFQUFFLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFjN0gsZ0JBQWdCO0FBQ2hCLE1BQWUsc0JBQXNCO0lBQXJDO1FBSWMsV0FBTSxHQUEyQixJQUFJLENBQUM7UUFDN0Isa0JBQWEsR0FBRyxJQUFJLE9BQU8sRUFBWSxDQUFDO1FBQ2pELG9CQUFlLEdBQTBCLEVBQUUsQ0FBQztRQUV0RDs7OztXQUlHO1FBQ2EsaUJBQVksR0FBeUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQXdCM0YsQ0FBQztJQXRCVSxpQkFBaUIsQ0FBQyxFQUF1QjtRQUM1QyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRU0scUJBQXFCO1FBQ3hCLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFRTSxVQUFVLENBQUMsTUFBOEI7UUFDNUMsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7U0FDdEU7UUFFRCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN6QixDQUFDO0NBRUo7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sT0FBZ0Is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Q0FBQyxVQUFVLENBQUMsS0FBSyxDQUFNLENBQUMsQ0FBQztJQUNsRixDQUFDO0lBRU0sUUFBUSxDQUFDLEtBQVEsRUFBRSxPQUl0QixFQUFFO1FBQ0YsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBUSxFQUFFO1lBQzNGLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixRQUFRLEVBQUUsSUFBSTtZQUNkLHFCQUFxQixFQUFFLEtBQUs7U0FDL0IsQ0FBQyxDQUFDLENBQUM7UUFFSixJQUFJLElBQUksQ0FBQyxxQkFBcUIsS0FBSyxLQUFLLEVBQUU7WUFDdEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7U0FDbEU7UUFFRCxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssS0FBSyxFQUFFO1lBQzFCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN2QztJQUNMLENBQUM7Q0FFSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGZvcmtKb2luLCBpc09ic2VydmFibGUsIE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaXJzdCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IGFyZUVxdWFsVXNpbmcsIGlzRnVuY3Rpb24sIGlzTWlzc2luZywgaXNQcmVzZW50LCB1bmRlZmluZWRUb051bGwsIHdyYXBJbnRvT2JzZXJ2YWJsZSwgd3JhcFRyeUNhdGNoIH0gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQge1xuICAgIENvbXBhcmF0b3IsIE11bHRpUGFyYW1EZXNlcmlhbGl6ZXIsXG4gICAgTXVsdGlQYXJhbVNlcmlhbGl6ZXIsXG4gICAgT25DaGFuZ2VGdW5jdGlvbixcbiAgICBQYXJhbUNvbWJpbmF0b3IsXG4gICAgUGFyYW1EZXNlcmlhbGl6ZXIsXG4gICAgUGFyYW1TZXJpYWxpemVyLFxuICAgIFBhcnRpdGlvbmVyLFxuICAgIFJlZHVjZXJcbn0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgUXVlcnlQYXJhbUdyb3VwIH0gZnJvbSAnLi9xdWVyeS1wYXJhbS1ncm91cCc7XG5pbXBvcnQgeyBNdWx0aVF1ZXJ5UGFyYW1PcHRzLCBQYXJ0aXRpb25lZFF1ZXJ5UGFyYW1PcHRzLCBRdWVyeVBhcmFtT3B0cywgUXVlcnlQYXJhbU9wdHNCYXNlIH0gZnJvbSAnLi9xdWVyeS1wYXJhbS1vcHRzJztcblxuLyoqIEBpbnRlcm5hbCAqL1xuYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RRdWVyeVBhcmFtQmFzZTxUPiB7XG5cbiAgICBwdWJsaWMgYWJzdHJhY3QgdmFsdWU6IFQgfCBudWxsO1xuXG4gICAgcHJvdGVjdGVkIHBhcmVudDogUXVlcnlQYXJhbUdyb3VwIHwgbnVsbCA9IG51bGw7XG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IF92YWx1ZUNoYW5nZXMgPSBuZXcgU3ViamVjdDxUIHwgbnVsbD4oKTtcbiAgICBwcm90ZWN0ZWQgY2hhbmdlRnVuY3Rpb25zOiBPbkNoYW5nZUZ1bmN0aW9uPFQ+W10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoaXMgcGFyYW1ldGVyIHdoZW5ldmVyIGl0IGNoYW5nZXMuXG4gICAgICpcbiAgICAgKiBOT1RFOiBUaGlzIG9ic2VydmFibGUgZG9lcyBub3QgY29tcGxldGUgb24gaXRzIG93biwgc28gZW5zdXJlIHRvIHVuc3Vic2NyaWJlIGZyb20gaXQuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHZhbHVlQ2hhbmdlczogT2JzZXJ2YWJsZTxUIHwgbnVsbD4gPSB0aGlzLl92YWx1ZUNoYW5nZXMuYXNPYnNlcnZhYmxlKCk7XG5cbiAgICBwdWJsaWMgX3JlZ2lzdGVyT25DaGFuZ2UoZm46IE9uQ2hhbmdlRnVuY3Rpb248VD4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jaGFuZ2VGdW5jdGlvbnMucHVzaChmbik7XG4gICAgfVxuXG4gICAgcHVibGljIF9jbGVhckNoYW5nZUZ1bmN0aW9ucygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jaGFuZ2VGdW5jdGlvbnMgPSBbXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYWJzdHJhY3Qgc2V0VmFsdWUodmFsdWU6IFQgfCBudWxsLCBvcHRzOiB7XG4gICAgICAgIGVtaXRFdmVudD86IGJvb2xlYW4sXG4gICAgICAgIG9ubHlTZWxmPzogYm9vbGVhbixcbiAgICAgICAgZW1pdE1vZGVsVG9WaWV3Q2hhbmdlPzogYm9vbGVhbixcbiAgICB9KTogdm9pZDtcblxuICAgIHB1YmxpYyBfc2V0UGFyZW50KHBhcmVudDogUXVlcnlQYXJhbUdyb3VwIHwgbnVsbCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5wYXJlbnQgJiYgcGFyZW50KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFBhcmFtZXRlciBhbHJlYWR5IGJlbG9uZ3MgdG8gYSBRdWVyeVBhcmFtR3JvdXAuYCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgICB9XG5cbn1cblxuLyoqXG4gKiBBYnN0cmFjdCBiYXNlIGZvciB7QGxpbmsgUXVlcnlQYXJhbX0gYW5kIHtAbGluayBNdWx0aVF1ZXJ5UGFyYW19LlxuICpcbiAqIFRoaXMgYmFzZSBjbGFzcyBob2xkcyBtb3N0IG9mIHRoZSBwYXJhbWV0ZXIncyBvcHRpb25zLCBidXQgaXMgdW5hd2FyZSBvZlxuICogaG93IHRvIGFjdHVhbGx5IChkZS0pc2VyaWFsaXplIGFueSB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFF1ZXJ5UGFyYW08VSwgVD4gZXh0ZW5kcyBBYnN0cmFjdFF1ZXJ5UGFyYW1CYXNlPFQ+IHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoaXMgcGFyYW1ldGVyLlxuICAgICAqL1xuICAgIHB1YmxpYyB2YWx1ZTogVCB8IG51bGwgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciB0byBiZSB1c2VkIGluIHRoZSBVUkwuXG4gICAgICpcbiAgICAgKiBUaGlzIHJlcHJlc2VudHMgdGhlIG5hbWUgb2YgdGhlIHF1ZXJ5IHBhcmFtZXRlciB3aGljaCB3aWxsIGJlXG4gICAgICogdXNlZCBpbiB0aGUgVVJMIChlLmcuLCBgP3E9YCksIHdoaWNoIGRpZmZlcnMgZnJvbSB0aGUgbmFtZSBvZlxuICAgICAqIHRoZSB7QGxpbmsgUXVlcnlQYXJhbX0gbW9kZWwgdXNlZCBpbnNpZGUge0BsaW5rIFF1ZXJ5UGFyYW1Hcm91cH0uXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHVybFBhcmFtOiBzdHJpbmc7XG5cbiAgICAvKiogU2VlIHtAbGluayBRdWVyeVBhcmFtT3B0c30uICovXG4gICAgcHVibGljIHJlYWRvbmx5IHNlcmlhbGl6ZTogUGFyYW1TZXJpYWxpemVyPFU+O1xuXG4gICAgLyoqIFNlZSB7QGxpbmsgUXVlcnlQYXJhbU9wdHN9LiAqL1xuICAgIHB1YmxpYyByZWFkb25seSBkZXNlcmlhbGl6ZTogUGFyYW1EZXNlcmlhbGl6ZXI8VT47XG5cbiAgICAvKiogU2VlIHtAbGluayBRdWVyeVBhcmFtT3B0c30uICovXG4gICAgcHVibGljIHJlYWRvbmx5IGRlYm91bmNlVGltZTogbnVtYmVyIHwgbnVsbDtcblxuICAgIC8qKiBTZWUge0BsaW5rIFF1ZXJ5UGFyYW1PcHRzfS4gKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZW1wdHlPbj86IFQgfCBudWxsO1xuXG4gICAgLyoqIFNlZSB7QGxpbmsgUXVlcnlQYXJhbU9wdHN9LiAqL1xuICAgIHB1YmxpYyByZWFkb25seSBjb21wYXJlV2l0aD86IENvbXBhcmF0b3I8VCB8IG51bGw+O1xuXG4gICAgLyoqIFNlZSB7QGxpbmsgUXVlcnlQYXJhbU9wdHN9LiAqL1xuICAgIHB1YmxpYyByZWFkb25seSBjb21iaW5lV2l0aD86IFBhcmFtQ29tYmluYXRvcjxUPjtcblxuICAgIHByb3RlY3RlZCBjb25zdHJ1Y3Rvcih1cmxQYXJhbTogc3RyaW5nLCBvcHRzOiBRdWVyeVBhcmFtT3B0c0Jhc2U8VSwgVD4gPSB7fSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBjb25zdCB7IHNlcmlhbGl6ZSwgZGVzZXJpYWxpemUsIGRlYm91bmNlVGltZSwgY29tcGFyZVdpdGgsIGVtcHR5T24sIGNvbWJpbmVXaXRoIH0gPSBvcHRzO1xuXG4gICAgICAgIGlmIChpc01pc3NpbmcodXJsUGFyYW0pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFBsZWFzZSBwcm92aWRlIGEgVVJMIHBhcmFtZXRlciBuYW1lIGZvciBlYWNoIHF1ZXJ5IHBhcmFtZXRlci5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihzZXJpYWxpemUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHNlcmlhbGl6ZSBtdXN0IGJlIGEgZnVuY3Rpb24sIGJ1dCByZWNlaXZlZCAke3NlcmlhbGl6ZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihkZXNlcmlhbGl6ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZGVzZXJpYWxpemUgbXVzdCBiZSBhIGZ1bmN0aW9uLCBidXQgcmVjZWl2ZWQgJHtkZXNlcmlhbGl6ZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbXB0eU9uICE9PSB1bmRlZmluZWQgJiYgIWlzRnVuY3Rpb24oY29tcGFyZVdpdGgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGNvbXBhcmVXaXRoIG11c3QgYmUgYSBmdW5jdGlvbiwgYnV0IHJlY2VpdmVkICR7Y29tcGFyZVdpdGh9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNQcmVzZW50KGNvbWJpbmVXaXRoKSAmJiAhaXNGdW5jdGlvbihjb21iaW5lV2l0aCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgY29tYmluZVdpdGggbXVzdCBiZSBhIGZ1bmN0aW9uLCBidXQgcmVjZWl2ZWQgJHtjb21iaW5lV2l0aH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudXJsUGFyYW0gPSB1cmxQYXJhbTtcbiAgICAgICAgdGhpcy5zZXJpYWxpemUgPSB3cmFwVHJ5Q2F0Y2goc2VyaWFsaXplLCBgRXJyb3Igd2hpbGUgc2VyaWFsaXppbmcgdmFsdWUgZm9yICR7dGhpcy51cmxQYXJhbX1gKTtcbiAgICAgICAgdGhpcy5kZXNlcmlhbGl6ZSA9IHdyYXBUcnlDYXRjaChkZXNlcmlhbGl6ZSwgYEVycm9yIHdoaWxlIGRlc2VyaWFsaXppbmcgdmFsdWUgZm9yICR7dGhpcy51cmxQYXJhbX1gKTtcbiAgICAgICAgdGhpcy5kZWJvdW5jZVRpbWUgPSB1bmRlZmluZWRUb051bGwoZGVib3VuY2VUaW1lKTtcbiAgICAgICAgdGhpcy5lbXB0eU9uID0gZW1wdHlPbjtcbiAgICAgICAgdGhpcy5jb21wYXJlV2l0aCA9IGNvbXBhcmVXaXRoO1xuICAgICAgICB0aGlzLmNvbWJpbmVXaXRoID0gY29tYmluZVdpdGg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyB0aGUgdmFsdWUgb2YgdGhpcyBwYXJhbWV0ZXIuXG4gICAgICpcbiAgICAgKiBJZiB3aXJlZCB1cCB3aXRoIGEge0BsaW5rIFF1ZXJ5UGFyYW1Hcm91cH0sIHRoaXMgd2lsbCBhbHNvIHN5bmNocm9uaXplXG4gICAgICogdGhlIHZhbHVlIHRvIHRoZSBVUkwuXG4gICAgICovXG4gICAgcHVibGljIHNldFZhbHVlKHZhbHVlOiBUIHwgbnVsbCwgb3B0czoge1xuICAgICAgICBlbWl0RXZlbnQ/OiBib29sZWFuLFxuICAgICAgICBvbmx5U2VsZj86IGJvb2xlYW4sXG4gICAgICAgIGVtaXRNb2RlbFRvVmlld0NoYW5nZT86IGJvb2xlYW4sXG4gICAgfSA9IHt9KTogdm9pZCB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICBpZiAob3B0cy5lbWl0TW9kZWxUb1ZpZXdDaGFuZ2UgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZUZ1bmN0aW9ucy5mb3JFYWNoKGNoYW5nZUZuID0+IGNoYW5nZUZuKHZhbHVlKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLl92YWx1ZUNoYW5nZXMubmV4dCh0aGlzLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc1ByZXNlbnQodGhpcy5wYXJlbnQpICYmICFvcHRzLm9ubHlTZWxmKSB7XG4gICAgICAgICAgICB0aGlzLnBhcmVudC5fdXBkYXRlVmFsdWUoe1xuICAgICAgICAgICAgICAgIGVtaXRFdmVudDogb3B0cy5lbWl0RXZlbnQsXG4gICAgICAgICAgICAgICAgZW1pdE1vZGVsVG9WaWV3Q2hhbmdlOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG59XG5cbi8qKlxuICogRGVzY3JpYmVzIGEgc2luZ2xlIHBhcmFtZXRlci5cbiAqXG4gKiBUaGlzIGlzIHRoZSBkZXNjcmlwdGlvbiBvZiBhIHNpbmdsZSBwYXJhbWV0ZXIgYW5kIGVzc2VudGlhbGx5IHNlcnZlc1xuICogYXMgdGhlIGdsdWUgYmV0d2VlbiBpdHMgcmVwcmVzZW50YXRpb24gaW4gdGhlIFVSTCBhbmQgaXRzIGNvbm5lY3Rpb25cbiAqIHRvIGEgZm9ybSBjb250cm9sLlxuICovXG5leHBvcnQgY2xhc3MgUXVlcnlQYXJhbTxUPiBleHRlbmRzIEFic3RyYWN0UXVlcnlQYXJhbTxUIHwgbnVsbCwgVCB8IG51bGw+IGltcGxlbWVudHMgUmVhZG9ubHk8UXVlcnlQYXJhbU9wdHM8VD4+IHtcblxuICAgIC8qKiBTZWUge0BsaW5rIFF1ZXJ5UGFyYW1PcHRzfS4gKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgbXVsdGkgPSBmYWxzZTtcblxuICAgIGNvbnN0cnVjdG9yKHVybFBhcmFtOiBzdHJpbmcsIG9wdHM6IFF1ZXJ5UGFyYW1PcHRzPFQ+KSB7XG4gICAgICAgIHN1cGVyKHVybFBhcmFtLCBvcHRzKTtcbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgcHVibGljIHNlcmlhbGl6ZVZhbHVlKHZhbHVlOiBUIHwgbnVsbCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgICBpZiAodGhpcy5lbXB0eU9uICE9PSB1bmRlZmluZWQgJiYgYXJlRXF1YWxVc2luZyh2YWx1ZSwgdGhpcy5lbXB0eU9uLCB0aGlzLmNvbXBhcmVXaXRoISkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc2VyaWFsaXplKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgcHVibGljIGRlc2VyaWFsaXplVmFsdWUodmFsdWU6IHN0cmluZyB8IG51bGwpOiBPYnNlcnZhYmxlPFQgfCBudWxsPiB7XG4gICAgICAgIGlmICh0aGlzLmVtcHR5T24gIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIG9mKHRoaXMuZW1wdHlPbik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gd3JhcEludG9PYnNlcnZhYmxlKHRoaXMuZGVzZXJpYWxpemUodmFsdWUpKS5waXBlKGZpcnN0KCkpO1xuICAgIH1cblxufVxuXG4vKipcbiAqIExpa2Uge0BsaW5rIFF1ZXJ5UGFyYW19LCBidXQgZm9yIGFycmF5LXR5cGVkIHBhcmFtZXRlcnNcbiAqL1xuZXhwb3J0IGNsYXNzIE11bHRpUXVlcnlQYXJhbTxUPiBleHRlbmRzIEFic3RyYWN0UXVlcnlQYXJhbTxUIHwgbnVsbCwgKFQgfCBudWxsKVtdPiBpbXBsZW1lbnRzIFJlYWRvbmx5PE11bHRpUXVlcnlQYXJhbU9wdHM8VD4+IHtcblxuICAgIC8qKiBTZWUge0BsaW5rIFF1ZXJ5UGFyYW1PcHRzfS4gKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgbXVsdGkgPSB0cnVlO1xuXG4gICAgLyoqIFNlZSB7QGxpbmsgTXVsdGlRdWVyeVBhcmFtT3B0c30uICovXG4gICAgcHVibGljIHJlYWRvbmx5IHNlcmlhbGl6ZUFsbD86IE11bHRpUGFyYW1TZXJpYWxpemVyPFQ+O1xuXG4gICAgLyoqIFNlZSB7QGxpbmsgTXVsdGlRdWVyeVBhcmFtT3B0c30uICovXG4gICAgcHVibGljIHJlYWRvbmx5IGRlc2VyaWFsaXplQWxsPzogTXVsdGlQYXJhbURlc2VyaWFsaXplcjxUPjtcblxuICAgIGNvbnN0cnVjdG9yKHVybFBhcmFtOiBzdHJpbmcsIG9wdHM6IE11bHRpUXVlcnlQYXJhbU9wdHM8VD4pIHtcbiAgICAgICAgc3VwZXIodXJsUGFyYW0sIG9wdHMpO1xuICAgICAgICBjb25zdCB7IHNlcmlhbGl6ZUFsbCwgZGVzZXJpYWxpemVBbGwgfSA9IG9wdHM7XG5cbiAgICAgICAgaWYgKHNlcmlhbGl6ZUFsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAoIWlzRnVuY3Rpb24oc2VyaWFsaXplQWxsKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgc2VyaWFsaXplQWxsIG11c3QgYmUgYSBmdW5jdGlvbiwgYnV0IHJlY2VpdmVkICR7c2VyaWFsaXplQWxsfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnNlcmlhbGl6ZUFsbCA9IHdyYXBUcnlDYXRjaChzZXJpYWxpemVBbGwsIGBFcnJvciB3aGlsZSBzZXJpYWxpemluZyB2YWx1ZSBmb3IgJHt0aGlzLnVybFBhcmFtfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRlc2VyaWFsaXplQWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmICghaXNGdW5jdGlvbihkZXNlcmlhbGl6ZUFsbCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGRlc2VyaWFsaXplQWxsIG11c3QgYmUgYSBmdW5jdGlvbiwgYnV0IHJlY2VpdmVkICR7ZGVzZXJpYWxpemVBbGx9YCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuZGVzZXJpYWxpemVBbGwgPSB3cmFwVHJ5Q2F0Y2goZGVzZXJpYWxpemVBbGwsIGBFcnJvciB3aGlsZSBkZXNlcmlhbGl6aW5nIHZhbHVlIGZvciAke3RoaXMudXJsUGFyYW19YCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgcHVibGljIHNlcmlhbGl6ZVZhbHVlKHZhbHVlOiAoVCB8IG51bGwpW10gfCBudWxsKTogKHN0cmluZyB8IG51bGwpW10gfCBudWxsIHtcbiAgICAgICAgaWYgKHRoaXMuZW1wdHlPbiAhPT0gdW5kZWZpbmVkICYmIGFyZUVxdWFsVXNpbmcodmFsdWUsIHRoaXMuZW1wdHlPbiwgdGhpcy5jb21wYXJlV2l0aCEpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnNlcmlhbGl6ZUFsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZXJpYWxpemVBbGwodmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICh2YWx1ZSB8fCBbXSkubWFwKHRoaXMuc2VyaWFsaXplLmJpbmQodGhpcykpO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgZGVzZXJpYWxpemVWYWx1ZSh2YWx1ZXM6IChzdHJpbmcgfCBudWxsKVtdIHwgbnVsbCk6IE9ic2VydmFibGU8KFQgfCBudWxsKVtdIHwgbnVsbD4ge1xuICAgICAgICBpZiAodGhpcy5lbXB0eU9uICE9PSB1bmRlZmluZWQgJiYgKHZhbHVlcyB8fCBbXSkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gb2YodGhpcy5lbXB0eU9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmRlc2VyaWFsaXplQWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB3cmFwSW50b09ic2VydmFibGUodGhpcy5kZXNlcmlhbGl6ZUFsbCh2YWx1ZXMpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdmFsdWVzIHx8IHZhbHVlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBvZihbXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZm9ya0pvaW48VCB8IG51bGw+KC4uLnZhbHVlc1xuICAgICAgICAgICAgLm1hcCh2YWx1ZSA9PiB3cmFwSW50b09ic2VydmFibGUodGhpcy5kZXNlcmlhbGl6ZSh2YWx1ZSkpLnBpcGUoZmlyc3QoKSkpXG4gICAgICAgICk7XG4gICAgfVxuXG59XG5cbi8qKlxuICogRGVzY3JpYmVzIGEgcGFydGl0aW9uZWQgcXVlcnkgcGFyYW1ldGVyLlxuICpcbiAqIFRoaXMgZW5jYXBzdWxhdGVzIGEgbGlzdCBvZiBxdWVyeSBwYXJhbWV0ZXJzIHN1Y2ggdGhhdCBhIHNpbmdsZSBmb3JtIGNvbnRyb2xcbiAqIGNhbiBiZSBib3VuZCBhZ2FpbnN0IG11bHRpcGxlIFVSTCBwYXJhbWV0ZXJzLiBUbyBhY2hpZXZlIHRoaXMsIGZ1bmN0aW9ucyBtdXN0XG4gKiBiZSBkZWZpbmVkIHdoaWNoIGNhbiBjb252ZXJ0IHRoZSBtb2RlbHMgYmV0d2VlbiB0aGUgcGFyYW1ldGVycy5cbiAqL1xuZXhwb3J0IGNsYXNzIFBhcnRpdGlvbmVkUXVlcnlQYXJhbTxULCBHIGV4dGVuZHMgdW5rbm93bltdID0gdW5rbm93bltdPiBleHRlbmRzIEFic3RyYWN0UXVlcnlQYXJhbUJhc2U8VD4ge1xuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIHB1YmxpYyByZWFkb25seSBxdWVyeVBhcmFtczogKFF1ZXJ5UGFyYW08R1tudW1iZXJdPiB8IE11bHRpUXVlcnlQYXJhbTxHW251bWJlcl0+KVtdO1xuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIHB1YmxpYyByZWFkb25seSBwYXJ0aXRpb246IFBhcnRpdGlvbmVyPFQsIEc+O1xuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIHB1YmxpYyByZWFkb25seSByZWR1Y2U6IFJlZHVjZXI8RywgVD47XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcXVlcnlQYXJhbXM6IChRdWVyeVBhcmFtPEdbbnVtYmVyXT4gfCBNdWx0aVF1ZXJ5UGFyYW08R1tudW1iZXJdPilbXSxcbiAgICAgICAgb3B0czogUGFydGl0aW9uZWRRdWVyeVBhcmFtT3B0czxULCBHPixcbiAgICApIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICBpZiAocXVlcnlQYXJhbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFBhcnRpdGlvbmVkIHBhcmFtZXRlcnMgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBwYXJhbWV0ZXIuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzRnVuY3Rpb24ob3B0cy5wYXJ0aXRpb24pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHBhcnRpdGlvbiBtdXN0IGJlIGEgZnVuY3Rpb24sIGJ1dCByZWNlaXZlZCAke29wdHMucGFydGl0aW9ufWApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKG9wdHMucmVkdWNlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGByZWR1Y2UgbXVzdCBiZSBhIGZ1bmN0aW9uLCBidXQgcmVjZWl2ZWQgJHtvcHRzLnJlZHVjZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucXVlcnlQYXJhbXMgPSBxdWVyeVBhcmFtcztcbiAgICAgICAgdGhpcy5wYXJ0aXRpb24gPSBvcHRzLnBhcnRpdGlvbjtcbiAgICAgICAgdGhpcy5yZWR1Y2UgPSBvcHRzLnJlZHVjZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHZhbHVlKCk6IFQge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWR1Y2UodGhpcy5xdWVyeVBhcmFtcy5tYXAocXVlcnlQYXJhbSA9PiBxdWVyeVBhcmFtLnZhbHVlKSBhcyBHKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0VmFsdWUodmFsdWU6IFQsIG9wdHM6IHtcbiAgICAgICAgZW1pdEV2ZW50PzogYm9vbGVhbixcbiAgICAgICAgb25seVNlbGY/OiBib29sZWFuLFxuICAgICAgICBlbWl0TW9kZWxUb1ZpZXdDaGFuZ2U/OiBib29sZWFuLFxuICAgIH0gPSB7fSk6IHZvaWQge1xuICAgICAgICBjb25zdCBwYXJ0aXRpb25lZCA9IHRoaXMucGFydGl0aW9uKHZhbHVlKTtcbiAgICAgICAgdGhpcy5xdWVyeVBhcmFtcy5mb3JFYWNoKChxdWVyeVBhcmFtLCBpbmRleCkgPT4gcXVlcnlQYXJhbS5zZXRWYWx1ZShwYXJ0aXRpb25lZFtpbmRleF0gYXMgYW55LCB7XG4gICAgICAgICAgICBlbWl0RXZlbnQ6IG9wdHMuZW1pdEV2ZW50LFxuICAgICAgICAgICAgb25seVNlbGY6IHRydWUsXG4gICAgICAgICAgICBlbWl0TW9kZWxUb1ZpZXdDaGFuZ2U6IGZhbHNlLFxuICAgICAgICB9KSk7XG5cbiAgICAgICAgaWYgKG9wdHMuZW1pdE1vZGVsVG9WaWV3Q2hhbmdlICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VGdW5jdGlvbnMuZm9yRWFjaChjaGFuZ2VGbiA9PiBjaGFuZ2VGbih0aGlzLnZhbHVlKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0cy5lbWl0RXZlbnQgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLl92YWx1ZUNoYW5nZXMubmV4dCh0aGlzLnZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxufSJdfQ==