UNPKG

@ngqp/core

Version:

Synchronizing form controls with the URL for Angular

157 lines 20.6 kB
import { Subject } from 'rxjs'; import { isMissing, undefinedToNull } from '../util'; /** * Groups multiple {@link QueryParam} instances to a single unit. * * This "bundles" multiple parameters together such that changes can be emitted as a * complete unit. Collecting parameters into a group is required for the synchronization * to and from the URL. */ export class QueryParamGroup { constructor(queryParams, extras = {}) { /** @internal */ this._valueChanges = new Subject(); /** * Emits the values of all parameters in this group whenever at least one changes. * * This observable emits an object keyed by the {@QueryParam} names where each key * carries the current value of the represented parameter. It emits whenever at least * one parameter's value is changed. * * NOTE: This observable does not complete on its own, so ensure to unsubscribe from it. */ this.valueChanges = this._valueChanges.asObservable(); /** @internal */ this._queryParamAdded$ = new Subject(); /** @internal */ this.queryParamAdded$ = this._queryParamAdded$.asObservable(); this.changeFunctions = []; this.queryParams = queryParams; this.routerOptions = extras; this.options = extras; Object.values(this.queryParams).forEach(queryParam => queryParam._setParent(this)); } /** @internal */ _registerOnChange(fn) { this.changeFunctions.push(fn); } /** @internal */ _clearChangeFunctions() { this.changeFunctions = []; } /** * Retrieves a specific parameter from this group by name. * * This returns an instance of either {@link QueryParam}, {@link MultiQueryParam} * or {@link PartitionedQueryParam} depending on the configuration, or `null` * if no parameter with that name is found in this group. * * @param queryParamName The name of the parameter instance to retrieve. */ get(queryParamName) { const param = this.queryParams[queryParamName]; if (!param) { return null; } return param; } /** * Adds a new {@link QueryParam} to this group. * * This adds the parameter under the given name to this group. The current * URL will be evaluated to synchronize its value initially. Afterwards * it is treated just like any other parameter in this group. * * @param queryParamName Name of the parameter to reference it with. * @param queryParam The new parameter to add. */ add(queryParamName, queryParam) { if (this.get(queryParamName)) { throw new Error(`A parameter with name ${queryParamName} already exists.`); } this.queryParams[queryParamName] = queryParam; queryParam._setParent(this); this._queryParamAdded$.next(queryParamName); } /** * Removes a {@link QueryParam} from this group. * * This removes the parameter defined by the provided name from this group. * No further synchronization with this parameter will occur and it will not * be reported in the value of this group anymore. * * @param queryParamName The name of the parameter to remove. */ remove(queryParamName) { const queryParam = this.get(queryParamName); if (!queryParam) { throw new Error(`No parameter with name ${queryParamName} found.`); } delete this.queryParams[queryParamName]; queryParam._setParent(null); queryParam._clearChangeFunctions(); } /** * The current value of this group. * * See {@link QueryParamGroup#valueChanges} for a description of the format of * the value. */ get value() { const value = {}; Object.keys(this.queryParams).forEach(queryParamName => value[queryParamName] = this.queryParams[queryParamName].value); return value; } /** * Updates the value of this group by merging it in. * * This sets the value of each provided parameter to the respective provided * value. If a parameter is not listed, its value remains unchanged. * * @param value See {@link QueryParamGroup#valueChanges} for a description of the format. * @param opts Additional options */ patchValue(value, opts = {}) { Object.keys(value).forEach(queryParamName => { const queryParam = this.queryParams[queryParamName]; if (isMissing(queryParam)) { return; } queryParam.setValue(value[queryParamName], { emitEvent: opts.emitEvent, onlySelf: true, emitModelToViewChange: false, }); }); this._updateValue(opts); } /** * Updates the value of this group by overwriting it. * * This sets the value of each provided parameter to the respective provided * value. If a parameter is not listed, its value is set to `undefined`. * * @param value See {@link QueryParamGroup#valueChanges} for a description of the format. * @param opts Additional options */ setValue(value, opts = {}) { Object.keys(this.queryParams).forEach(queryParamName => { this.queryParams[queryParamName].setValue(undefinedToNull(value === null || value === void 0 ? void 0 : value[queryParamName]), { emitEvent: opts.emitEvent, onlySelf: true, emitModelToViewChange: false, }); }); this._updateValue(opts); } /** @internal */ _updateValue(opts = {}) { 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktcGFyYW0tZ3JvdXAuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmdxcC9jb3JlL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9tb2RlbC9xdWVyeS1wYXJhbS1ncm91cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBTXJEOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBaUN4QixZQUNJLFdBQTRILEVBQzVILFNBQThDLEVBQUU7UUFqQ3BELGdCQUFnQjtRQUNDLGtCQUFhLEdBQUcsSUFBSSxPQUFPLEVBQXVCLENBQUM7UUFFcEU7Ozs7Ozs7O1dBUUc7UUFDYSxpQkFBWSxHQUFvQyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRWxHLGdCQUFnQjtRQUNDLHNCQUFpQixHQUFHLElBQUksT0FBTyxFQUFVLENBQUM7UUFFM0QsZ0JBQWdCO1FBQ0EscUJBQWdCLEdBQXVCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQVdyRixvQkFBZSxHQUE0QyxFQUFFLENBQUM7UUFNbEUsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDL0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUM7UUFDNUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFFdEIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFFRCxnQkFBZ0I7SUFDVCxpQkFBaUIsQ0FBQyxFQUF5QztRQUM5RCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FB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LENBQUksY0FBYyxFQUFHLEVBQUU7Z0JBQ3BGLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztnQkFDekIsUUFBUSxFQUFFLElBQUk7Z0JBQ2QscUJBQXFCLEVBQUUsS0FBSzthQUMvQixDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVELGdCQUFnQjtJQUNULFlBQVksQ0FBQyxPQUdoQixFQUFFO1FBQ0YsSUFBSSxJQUFJLENBQUMscUJBQXFCLEtBQUssS0FBSyxFQUFFO1lBQ3RDLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1NBQ2xFO1FBRUQsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLEtBQUssRUFBRTtZQUMxQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDdkM7SUFDTCxDQUFDO0NBRUoiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBpc01pc3NpbmcsIHVuZGVmaW5lZFRvTnVsbCB9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHsgT25DaGFuZ2VGdW5jdGlvbiB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IE11bHRpUXVlcnlQYXJhbSwgUXVlcnlQYXJhbSwgUGFydGl0aW9uZWRRdWVyeVBhcmFtIH0gZnJvbSAnLi9xdWVyeS1wYXJhbSc7XG5pbXBvcnQgeyBSb3V0ZXJPcHRpb25zIH0gZnJvbSAnLi4vcm91dGVyLWFkYXB0ZXIvcm91dGVyLWFkYXB0ZXIuaW50ZXJmYWNlJztcbmltcG9ydCB7UXVlcnlQYXJhbUdyb3VwT3B0c30gZnJvbSAnLi9xdWVyeS1wYXJhbS1vcHRzJztcblxuLyoqXG4gKiBHcm91cHMgbXVsdGlwbGUge0BsaW5rIFF1ZXJ5UGFyYW19IGluc3RhbmNlcyB0byBhIHNpbmdsZSB1bml0LlxuICpcbiAqIFRoaXMgXCJidW5kbGVzXCIgbXVsdGlwbGUgcGFyYW1ldGVycyB0b2dldGhlciBzdWNoIHRoYXQgY2hhbmdlcyBjYW4gYmUgZW1pdHRlZCBhcyBhXG4gKiBjb21wbGV0ZSB1bml0LiBDb2xsZWN0aW5nIHBhcmFtZXRlcnMgaW50byBhIGdyb3VwIGlzIHJlcXVpcmVkIGZvciB0aGUgc3luY2hyb25pemF0aW9uXG4gKiB0byBhbmQgZnJvbSB0aGUgVVJMLlxuICovXG5leHBvcnQgY2xhc3MgUXVlcnlQYXJhbUdyb3VwIHtcblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF92YWx1ZUNoYW5nZXMgPSBuZXcgU3ViamVjdDxSZWNvcmQ8c3RyaW5nLCBhbnk+PigpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgdGhlIHZhbHVlcyBvZiBhbGwgcGFyYW1ldGVycyBpbiB0aGlzIGdyb3VwIHdoZW5ldmVyIGF0IGxlYXN0IG9uZSBjaGFuZ2VzLlxuICAgICAqXG4gICAgICogVGhpcyBvYnNlcnZhYmxlIGVtaXRzIGFuIG9iamVjdCBrZXllZCBieSB0aGUge0BRdWVyeVBhcmFtfSBuYW1lcyB3aGVyZSBlYWNoIGtleVxuICAgICAqIGNhcnJpZXMgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHJlcHJlc2VudGVkIHBhcmFtZXRlci4gSXQgZW1pdHMgd2hlbmV2ZXIgYXQgbGVhc3RcbiAgICAgKiBvbmUgcGFyYW1ldGVyJ3MgdmFsdWUgaXMgY2hhbmdlZC5cbiAgICAgKlxuICAgICAqIE5PVEU6IFRoaXMgb2JzZXJ2YWJsZSBkb2VzIG5vdCBjb21wbGV0ZSBvbiBpdHMgb3duLCBzbyBlbnN1cmUgdG8gdW5zdWJzY3JpYmUgZnJvbSBpdC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdmFsdWVDaGFuZ2VzOiBPYnNlcnZhYmxlPFJlY29yZDxzdHJpbmcsIGFueT4+ID0gdGhpcy5fdmFsdWVDaGFuZ2VzLmFzT2JzZXJ2YWJsZSgpO1xuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3F1ZXJ5UGFyYW1BZGRlZCQgPSBuZXcgU3ViamVjdDxzdHJpbmc+KCk7XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgcHVibGljIHJlYWRvbmx5IHF1ZXJ5UGFyYW1BZGRlZCQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuX3F1ZXJ5UGFyYW1BZGRlZCQuYXNPYnNlcnZhYmxlKCk7XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgcHVibGljIHJlYWRvbmx5IHF1ZXJ5UGFyYW1zOiB7IFsgcXVlcnlQYXJhbU5hbWU6IHN0cmluZyBdOiBRdWVyeVBhcmFtPHVua25vd24+IHwgTXVsdGlRdWVyeVBhcmFtPHVua25vd24+IHwgUGFydGl0aW9uZWRRdWVyeVBhcmFtPHVua25vd24+IH07XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgcHVibGljIHJlYWRvbmx5IHJvdXRlck9wdGlvbnM6IFJvdXRlck9wdGlvbnM7XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgcHVibGljIHJlYWRvbmx5IG9wdGlvbnM6IFF1ZXJ5UGFyYW1Hcm91cE9wdHM7XG5cbiAgICBwcml2YXRlIGNoYW5nZUZ1bmN0aW9uczogT25DaGFuZ2VGdW5jdGlvbjxSZWNvcmQ8c3RyaW5nLCBhbnk+PltdID0gW107XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcXVlcnlQYXJhbXM6IHsgWyBxdWVyeVBhcmFtTmFtZTogc3RyaW5nIF06IFF1ZXJ5UGFyYW08dW5rbm93bj4gfCBNdWx0aVF1ZXJ5UGFyYW08dW5rbm93bj4gfCBQYXJ0aXRpb25lZFF1ZXJ5UGFyYW08dW5rbm93bj4gfSxcbiAgICAgICAgZXh0cmFzOiBSb3V0ZXJPcHRpb25zICYgUXVlcnlQYXJhbUdyb3VwT3B0cyA9IHt9XG4gICAgKSB7XG4gICAgICAgIHRoaXMucXVlcnlQYXJhbXMgPSBxdWVyeVBhcmFtcztcbiAgICAgICAgdGhpcy5yb3V0ZXJPcHRpb25zID0gZXh0cmFzO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBleHRyYXM7XG5cbiAgICAgICAgT2JqZWN0LnZhbHVlcyh0aGlzLnF1ZXJ5UGFyYW1zKS5mb3JFYWNoKHF1ZXJ5UGFyYW0gPT4gcXVlcnlQYXJhbS5fc2V0UGFyZW50KHRoaXMpKTtcbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgcHVibGljIF9yZWdpc3Rlck9uQ2hhbmdlKGZuOiBPbkNoYW5nZUZ1bmN0aW9uPFJlY29yZDxzdHJpbmcsIGFueT4+KTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2hhbmdlRnVuY3Rpb25zLnB1c2goZm4pO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgX2NsZWFyQ2hhbmdlRnVuY3Rpb25zKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNoYW5nZUZ1bmN0aW9ucyA9IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhIHNwZWNpZmljIHBhcmFtZXRlciBmcm9tIHRoaXMgZ3JvdXAgYnkgbmFtZS5cbiAgICAgKlxuICAgICAqIFRoaXMgcmV0dXJucyBhbiBpbnN0YW5jZSBvZiBlaXRoZXIge0BsaW5rIFF1ZXJ5UGFyYW19LCB7QGxpbmsgTXVsdGlRdWVyeVBhcmFtfVxuICAgICAqIG9yIHtAbGluayBQYXJ0aXRpb25lZFF1ZXJ5UGFyYW19IGRlcGVuZGluZyBvbiB0aGUgY29uZmlndXJhdGlvbiwgb3IgYG51bGxgXG4gICAgICogaWYgbm8gcGFyYW1ldGVyIHdpdGggdGhhdCBuYW1lIGlzIGZvdW5kIGluIHRoaXMgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcXVlcnlQYXJhbU5hbWUgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciBpbnN0YW5jZSB0byByZXRyaWV2ZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0KHF1ZXJ5UGFyYW1OYW1lOiBzdHJpbmcpOiBRdWVyeVBhcmFtPHVua25vd24+IHwgTXVsdGlRdWVyeVBhcmFtPHVua25vd24+IHwgUGFydGl0aW9uZWRRdWVyeVBhcmFtPHVua25vd24+IHwgbnVsbCB7XG4gICAgICAgIGNvbnN0IHBhcmFtID0gdGhpcy5xdWVyeVBhcmFtc1sgcXVlcnlQYXJhbU5hbWUgXTtcbiAgICAgICAgaWYgKCFwYXJhbSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGFyYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIG5ldyB7QGxpbmsgUXVlcnlQYXJhbX0gdG8gdGhpcyBncm91cC5cbiAgICAgKlxuICAgICAqIFRoaXMgYWRkcyB0aGUgcGFyYW1ldGVyIHVuZGVyIHRoZSBnaXZlbiBuYW1lIHRvIHRoaXMgZ3JvdXAuIFRoZSBjdXJyZW50XG4gICAgICogVVJMIHdpbGwgYmUgZXZhbHVhdGVkIHRvIHN5bmNocm9uaXplIGl0cyB2YWx1ZSBpbml0aWFsbHkuIEFmdGVyd2FyZHNcbiAgICAgKiBpdCBpcyB0cmVhdGVkIGp1c3QgbGlrZSBhbnkgb3RoZXIgcGFyYW1ldGVyIGluIHRoaXMgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcXVlcnlQYXJhbU5hbWUgTmFtZSBvZiB0aGUgcGFyYW1ldGVyIHRvIHJlZmVyZW5jZSBpdCB3aXRoLlxuICAgICAqIEBwYXJhbSBxdWVyeVBhcmFtIFRoZSBuZXcgcGFyYW1ldGVyIHRvIGFkZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgYWRkKHF1ZXJ5UGFyYW1OYW1lOiBzdHJpbmcsIHF1ZXJ5UGFyYW06IFF1ZXJ5UGFyYW08dW5rbm93bj4gfCBNdWx0aVF1ZXJ5UGFyYW08dW5rbm93bj4gfCBQYXJ0aXRpb25lZFF1ZXJ5UGFyYW08dW5rbm93bj4pOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0KHF1ZXJ5UGFyYW1OYW1lKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBIHBhcmFtZXRlciB3aXRoIG5hbWUgJHtxdWVyeVBhcmFtTmFtZX0gYWxyZWFkeSBleGlzdHMuYCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnF1ZXJ5UGFyYW1zWyBxdWVyeVBhcmFtTmFtZSBdID0gcXVlcnlQYXJhbTtcbiAgICAgICAgcXVlcnlQYXJhbS5fc2V0UGFyZW50KHRoaXMpO1xuICAgICAgICB0aGlzLl9xdWVyeVBhcmFtQWRkZWQkLm5leHQocXVlcnlQYXJhbU5hbWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSB7QGxpbmsgUXVlcnlQYXJhbX0gZnJvbSB0aGlzIGdyb3VwLlxuICAgICAqXG4gICAgICogVGhpcyByZW1vdmVzIHRoZSBwYXJhbWV0ZXIgZGVmaW5lZCBieSB0aGUgcHJvdmlkZWQgbmFtZSBmcm9tIHRoaXMgZ3JvdXAuXG4gICAgICogTm8gZnVydGhlciBzeW5jaHJvbml6YXRpb24gd2l0aCB0aGlzIHBhcmFtZXRlciB3aWxsIG9jY3VyIGFuZCBpdCB3aWxsIG5vdFxuICAgICAqIGJlIHJlcG9ydGVkIGluIHRoZSB2YWx1ZSBvZiB0aGlzIGdyb3VwIGFueW1vcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcXVlcnlQYXJhbU5hbWUgVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciB0byByZW1vdmUuXG4gICAgICovXG4gICAgcHVibGljIHJlbW92ZShxdWVyeVBhcmFtTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW0gPSB0aGlzLmdldChxdWVyeVBhcmFtTmFtZSk7XG4gICAgICAgIGlmICghcXVlcnlQYXJhbSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBwYXJhbWV0ZXIgd2l0aCBuYW1lICR7cXVlcnlQYXJhbU5hbWV9IGZvdW5kLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVsZXRlIHRoaXMucXVlcnlQYXJhbXNbIHF1ZXJ5UGFyYW1OYW1lIF07XG4gICAgICAgIHF1ZXJ5UGFyYW0uX3NldFBhcmVudChudWxsKTtcbiAgICAgICAgcXVlcnlQYXJhbS5fY2xlYXJDaGFuZ2VGdW5jdGlvbnMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGlzIGdyb3VwLlxuICAgICAqXG4gICAgICogU2VlIHtAbGluayBRdWVyeVBhcmFtR3JvdXAjdmFsdWVDaGFuZ2VzfSBmb3IgYSBkZXNjcmlwdGlvbiBvZiB0aGUgZm9ybWF0IG9mXG4gICAgICogdGhlIHZhbHVlLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgdmFsdWUoKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMucXVlcnlQYXJhbXMpLmZvckVhY2gocXVlcnlQYXJhbU5hbWUgPT4gdmFsdWVbIHF1ZXJ5UGFyYW1OYW1lIF0gPSB0aGlzLnF1ZXJ5UGFyYW1zWyBxdWVyeVBhcmFtTmFtZSBdLnZhbHVlKTtcblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyB0aGUgdmFsdWUgb2YgdGhpcyBncm91cCBieSBtZXJnaW5nIGl0IGluLlxuICAgICAqXG4gICAgICogVGhpcyBzZXRzIHRoZSB2YWx1ZSBvZiBlYWNoIHByb3ZpZGVkIHBhcmFtZXRlciB0byB0aGUgcmVzcGVjdGl2ZSBwcm92aWRlZFxuICAgICAqIHZhbHVlLiBJZiBhIHBhcmFtZXRlciBpcyBub3QgbGlzdGVkLCBpdHMgdmFsdWUgcmVtYWlucyB1bmNoYW5nZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUgU2VlIHtAbGluayBRdWVyeVBhcmFtR3JvdXAjdmFsdWVDaGFuZ2VzfSBmb3IgYSBkZXNjcmlwdGlvbiBvZiB0aGUgZm9ybWF0LlxuICAgICAqIEBwYXJhbSBvcHRzIEFkZGl0aW9uYWwgb3B0aW9uc1xuICAgICAqL1xuICAgIHB1YmxpYyBwYXRjaFZhbHVlKHZhbHVlOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBvcHRzOiB7XG4gICAgICAgIGVtaXRFdmVudD86IGJvb2xlYW4sXG4gICAgICAgIGVtaXRNb2RlbFRvVmlld0NoYW5nZT86IGJvb2xlYW4sXG4gICAgfSA9IHt9KTogdm9pZCB7XG4gICAgICAgIE9iamVjdC5rZXlzKHZhbHVlKS5mb3JFYWNoKHF1ZXJ5UGFyYW1OYW1lID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW0gPSB0aGlzLnF1ZXJ5UGFyYW1zWyBxdWVyeVBhcmFtTmFtZSBdO1xuICAgICAgICAgICAgaWYgKGlzTWlzc2luZyhxdWVyeVBhcmFtKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcXVlcnlQYXJhbS5zZXRWYWx1ZSh2YWx1ZVsgcXVlcnlQYXJhbU5hbWUgXSwge1xuICAgICAgICAgICAgICAgIGVtaXRFdmVudDogb3B0cy5lbWl0RXZlbnQsXG4gICAgICAgICAgICAgICAgb25seVNlbGY6IHRydWUsXG4gICAgICAgICAgICAgICAgZW1pdE1vZGVsVG9WaWV3Q2hhbmdlOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLl91cGRhdGVWYWx1ZShvcHRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIHRoZSB2YWx1ZSBvZiB0aGlzIGdyb3VwIGJ5IG92ZXJ3cml0aW5nIGl0LlxuICAgICAqXG4gICAgICogVGhpcyBzZXRzIHRoZSB2YWx1ZSBvZiBlYWNoIHByb3ZpZGVkIHBhcmFtZXRlciB0byB0aGUgcmVzcGVjdGl2ZSBwcm92aWRlZFxuICAgICAqIHZhbHVlLiBJZiBhIHBhcmFtZXRlciBpcyBub3QgbGlzdGVkLCBpdHMgdmFsdWUgaXMgc2V0IHRvIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIFNlZSB7QGxpbmsgUXVlcnlQYXJhbUdyb3VwI3ZhbHVlQ2hhbmdlc30gZm9yIGEgZGVzY3JpcHRpb24gb2YgdGhlIGZvcm1hdC5cbiAgICAgKiBAcGFyYW0gb3B0cyBBZGRpdGlvbmFsIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0VmFsdWUodmFsdWU6IFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsLCBvcHRzOiB7XG4gICAgICAgIGVtaXRFdmVudD86IGJvb2xlYW4sXG4gICAgICAgIGVtaXRNb2RlbFRvVmlld0NoYW5nZT86IGJvb2xlYW4sXG4gICAgfSA9IHt9KTogdm9pZCB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMucXVlcnlQYXJhbXMpLmZvckVhY2gocXVlcnlQYXJhbU5hbWUgPT4ge1xuICAgICAgICAgICAgdGhpcy5xdWVyeVBhcmFtc1sgcXVlcnlQYXJhbU5hbWUgXS5zZXRWYWx1ZSh1bmRlZmluZWRUb051bGwodmFsdWU/LlsgcXVlcnlQYXJhbU5hbWUgXSksIHtcbiAgICAgICAgICAgICAgICBlbWl0RXZlbnQ6IG9wdHMuZW1pdEV2ZW50LFxuICAgICAgICAgICAgICAgIG9ubHlTZWxmOiB0cnVlLFxuICAgICAgICAgICAgICAgIGVtaXRNb2RlbFRvVmlld0NoYW5nZTogZmFsc2UsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fdXBkYXRlVmFsdWUob3B0cyk7XG4gICAgfVxuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIHB1YmxpYyBfdXBkYXRlVmFsdWUob3B0czoge1xuICAgICAgICBlbWl0RXZlbnQ/OiBib29sZWFuLFxuICAgICAgICBlbWl0TW9kZWxUb1ZpZXdDaGFuZ2U/OiBib29sZWFuLFxuICAgIH0gPSB7fSk6IHZvaWQge1xuICAgICAgICBpZiAob3B0cy5lbWl0TW9kZWxUb1ZpZXdDaGFuZ2UgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZUZ1bmN0aW9ucy5mb3JFYWNoKGNoYW5nZUZuID0+IGNoYW5nZUZuKHRoaXMudmFsdWUpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlQ2hhbmdlcy5uZXh0KHRoaXMudmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuXG59Il19