@activejs/core
Version:
Pragmatic, Reactive State Management for JavaScript Apps
205 lines • 26 kB
JavaScript
import '../../../../LICENSE';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { EventReplay } from '../models';
import { getLocationId, isFunction, isValidId } from '../utils/funcs';
import { Configuration, UniqueIdsAndLocationIdMap } from './configuration';
/**
* This is the most basic building block of ActiveJS.
*
* Base serves as the base for all fundamental ActiveJS constructs: Units, Systems, Actions and Clusters.
*
* This is an internal construct, normally you'd never have to use this class directly.
* However, if you're just reading the documentation, or want to learn more about how ActiveJS works,
* or want to extend this class to build something on your own, please continue.
*
* It extends RxJS `Observable`.
* Source of this Observable is either a BehaviorSubject or Subject depending on the {@link BaseConfig.replay} flag.
* By default, it's a BehaviourSubject for the Units, Systems and Clusters; and a Subject for Actions.
*
* There's another non-replaying Observable named `future$` to observe the value, whose source is always a simple Subject,
* This Subject also serves as the source for default extended Observable when {@link BaseConfig.replay} is `false`.
*
* In simple terms Base is an elaborate RxJS Subject like construct, with custom features like replay on demand.
* Although that's just one aspect of Base.
*
* It also implements `Object.prototype` methods
* to make working with the stored value a bit easier and efficient.
*
* Other than that, It also provides functionalities like: On-demand Observable custom-event, to listen to events like manual replay.
*
* @category 2. Abstract
*/
export class Base extends Observable {
// tslint:enable:variable-name
constructor(config) {
super();
/**
* @internal please do not use.
*/
this.futureSubject = new Subject();
/**
* An Observable to observe future values,
* unlike the default Observable it doesn't replay when subscribed to,
* rather it waits for the next value.
*/
this.future$ = this.futureSubject.asObservable();
/**
* @internal please do not use.
*/
this._emitCount = 0;
this.config = Object.assign({}, config);
if (this.config.id !== undefined) {
if (!isValidId(this.config.id)) {
throw new TypeError(`Invalid id provided, expected a non-empty string, got ${String(this.config.id)}`);
}
if (Configuration.ENVIRONMENT.checkUniqueId === true) {
const locationId = getLocationId(this);
if (UniqueIdsAndLocationIdMap[this.config.id] != null &&
UniqueIdsAndLocationIdMap[this.config.id] !== locationId) {
throw new TypeError(`Duplicate id "${this.config.id}" detected by "checkUniqueId" check, consider assigning a unique id.`);
}
UniqueIdsAndLocationIdMap[this.config.id] = locationId;
}
}
else if (this.config.persistent === true) {
throw new TypeError(`An id is required for persistence to work.`);
}
if (this.config.replay === false) {
this.sourceSubject = this.futureSubject;
this.source = this.future$;
}
else {
this.sourceSubject = new BehaviorSubject(undefined);
this.source = this.sourceSubject.asObservable();
}
this.setupEvents();
Object.freeze(this.config);
}
/**
* A counter to keep track of how many times has a Unit, System, Action or Cluster emitted.
* @returns Number of times a Unit, System, Action or Cluster has emitted.
*/
get emitCount() {
return this._emitCount;
}
/**
* Current value.
* Used internally, for operations that don't mutate the value.
*
* @internal please do not use.
*
* @category Access Value
*/
rawValue() {
return this.value();
}
/**
* Creates a new Observable using the default Observable as source.
* Use this to conceal other aspects of a Unit, System, Action or Cluster except the Observable part.
*
* @returns An Observable with the value of a Unit, System, Action or Cluster.
*
* @category Common
*/
asObservable() {
const observable = new Observable();
observable.source = this.source;
return observable;
}
/**
* To manually re-emit the last emitted value again.
*
* @triggers {@link EventReplay}
* @category Common
*/
replay() {
var _a;
this.emit(this.emittedValue);
if ((_a = this.eventsSubject) === null || _a === void 0 ? void 0 : _a.observers.length) {
this.eventsSubject.next(new EventReplay(this.emittedValue));
}
}
/**
* Converts the value to JSON string, using `JSON.stringify`.
*
* @category Common
*/
toJsonString() {
return JSON.stringify(this.rawValue());
}
/**
* Returns the {@link rawValue},
* JavaScript automatically invokes it when encountering an object where a primitive value is expected.
*
* @alias {@link rawValue}
* This method is not intended to be used by developers, use {@link rawValue} instead.
* It only exists to be used by JavaScript implicitly.
*
* @hidden
* @category Customised Object.prototype
*/
valueOf() {
return this.rawValue();
}
/**
* Returns the {@link rawValue}.
* JavaScript automatically invokes it when `JSON.stringify` is invoked on an object.
*
* @alias {@link rawValue}
* This method is not intended to be used by developers, use {@link rawValue} instead.
* It only exists to be used by `JSON.stringify` implicitly.
*
* @hidden
* @category Common
*/
toJSON() {
return this.rawValue();
}
/**
* @internal please do not use.
*/
emit(value = this.value()) {
++this._emitCount;
this.emittedValue = value;
if (this.sourceSubject !== this.futureSubject) {
this.sourceSubject.next(value);
}
this.futureSubject.next(value);
}
/**
* @internal please do not use.
*/
setupEvents() {
Object.defineProperty(this, 'events$', {
get() {
if (this._events) {
return this._events;
}
this.eventsSubject = new Subject();
this._events = this.eventsSubject.asObservable();
Object.defineProperty(this, 'eventsSubject', { enumerable: false });
Object.defineProperty(this, '_events', { enumerable: false });
return this._events;
},
enumerable: false,
});
}
}
/**
* @internal please do not use.
*/
const MethodsNotToImplement = [
...Object.getOwnPropertyNames(Observable.prototype),
...Object.getOwnPropertyNames(Base.prototype),
];
Object.getOwnPropertyNames(Object.prototype).forEach(method => {
if (!isFunction(Object.prototype[method]) || MethodsNotToImplement.includes(method)) {
return;
}
Object.defineProperty(Base.prototype, method, {
value(...args) {
return this.rawValue()[method](...args);
},
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3QtYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIvaG9tZS9ydW5uZXIvd29yay9hY3RpdmVqcy9hY3RpdmVqcy9wYWNrYWdlcy9jb3JlL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9hYnN0cmFjdC1iYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFDLGVBQWUsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzFELE9BQU8sRUFBeUIsV0FBVyxFQUFhLE1BQU0sV0FBVyxDQUFDO0FBQzFFLE9BQU8sRUFBQyxhQUFhLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3BFLE9BQU8sRUFBQyxhQUFhLEVBQUUseUJBQXlCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUV6RTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUNILE1BQU0sT0FBZ0IsSUFBUSxTQUFRLFVBQWE7SUFrRmpELDhCQUE4QjtJQUU5QixZQUFzQixNQUFtQjtRQUN2QyxLQUFLLEVBQUUsQ0FBQztRQW5EVjs7V0FFRztRQUNjLGtCQUFhLEdBQUcsSUFBSSxPQUFPLEVBQUssQ0FBQztRQUNsRDs7OztXQUlHO1FBQ00sWUFBTyxHQUFrQixJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBT3BFOztXQUVHO1FBQ0ssZUFBVSxHQUFHLENBQUMsQ0FBQztRQWtDckIsSUFBSSxDQUFDLE1BQU0scUJBQU8sTUFBTSxDQUFDLENBQUM7UUFFMUIsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxTQUFTLEVBQUU7WUFDaEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUM5QixNQUFNLElBQUksU0FBUyxDQUNqQix5REFBeUQsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FDbEYsQ0FBQzthQUNIO1lBQ0QsSUFBSSxhQUFhLENBQUMsV0FBVyxDQUFDLGFBQWEsS0FBSyxJQUFJLEVBQUU7Z0JBQ3BELE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDdkMsSUFDRSx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUk7b0JBQ2pELHlCQUF5QixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssVUFBVSxFQUN4RDtvQkFDQSxNQUFNLElBQUksU0FBUyxDQUNqQixpQkFBaUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLHNFQUFzRSxDQUN0RyxDQUFDO2lCQUNIO2dCQUNELHlCQUF5QixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDO2FBQ3hEO1NBQ0Y7YUFBTSxJQUFLLElBQUksQ0FBQyxNQUEwQixDQUFDLFVBQVUsS0FBSyxJQUFJLEVBQUU7WUFDL0QsTUFBTSxJQUFJLFNBQVMsQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1NBQ25FO1FBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxLQUFLLEVBQUU7WUFDaEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1lBQ3ZDLElBQVksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztTQUNyQzthQUFNO1lBQ0wsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNuRCxJQUFZLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUM7U0FDMUQ7UUFFRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQWxFRDs7O09BR0c7SUFDSCxJQUFJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDekIsQ0FBQztJQVNEOzs7Ozs7O09BT0c7SUFDTyxRQUFRO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUEyQ0Q7Ozs7Ozs7T0FPRztJQUNILFlBQVk7UUFDVixNQUFNLFVBQVUsR0FBRyxJQUFJLFVBQVUsRUFBSyxDQUFDO1FBQ3RDLFVBQWtCLENBQUMsTUFBTSxHQUFJLElBQVksQ0FBQyxNQUFNLENBQUM7UUFDbEQsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTTs7UUFDSixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUU3QixVQUFJLElBQUksQ0FBQyxhQUFhLDBDQUFFLFNBQVMsQ0FBQyxNQUFNLEVBQUU7WUFDeEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7U0FDN0Q7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFlBQVk7UUFDVixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxPQUFPO1FBQ0wsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDekIsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxNQUFNO1FBQ0osT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDekIsQ0FBQztJQUVEOztPQUVHO0lBQ08sSUFBSSxDQUFDLFFBQVcsSUFBSSxDQUFDLEtBQUssRUFBRTtRQUNwQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDbEIsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7UUFFMUIsSUFBSSxJQUFJLENBQUMsYUFBYSxLQUFLLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDN0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDaEM7UUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQ7O09BRUc7SUFDSyxXQUFXO1FBQ2pCLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRTtZQUNyQyxHQUFHO2dCQUNELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtvQkFDaEIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO2lCQUNyQjtnQkFFRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksT0FBTyxFQUFpQixDQUFDO2dCQUNsRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBRWpELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRSxFQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDO2dCQUNsRSxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBQyxVQUFVLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQztnQkFFNUQsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO1lBQ3RCLENBQUM7WUFDRCxVQUFVLEVBQUUsS0FBSztTQUNsQixDQUFDLENBQUM7SUFDTCxDQUFDO0NBcUVGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLHFCQUFxQixHQUFHO0lBQzVCLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUM7SUFDbkQsR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztDQUM5QyxDQUFDO0FBRUYsTUFBTSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7SUFDNUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUkscUJBQXFCLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQ25GLE9BQU87S0FDUjtJQUVELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUU7UUFDNUMsS0FBSyxDQUFDLEdBQUcsSUFBSTtZQUNYLE9BQU8sSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDMUMsQ0FBQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICcuLi8uLi8uLi8uLi9MSUNFTlNFJztcbmltcG9ydCB7QmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlLCBTdWJqZWN0fSBmcm9tICdyeGpzJztcbmltcG9ydCB7QmFzZUNvbmZpZywgQmFzZUV2ZW50cywgRXZlbnRSZXBsYXksIFVuaXRDb25maWd9IGZyb20gJy4uL21vZGVscyc7XG5pbXBvcnQge2dldExvY2F0aW9uSWQsIGlzRnVuY3Rpb24sIGlzVmFsaWRJZH0gZnJvbSAnLi4vdXRpbHMvZnVuY3MnO1xuaW1wb3J0IHtDb25maWd1cmF0aW9uLCBVbmlxdWVJZHNBbmRMb2NhdGlvbklkTWFwfSBmcm9tICcuL2NvbmZpZ3VyYXRpb24nO1xuXG4vKipcbiAqIFRoaXMgaXMgdGhlIG1vc3QgYmFzaWMgYnVpbGRpbmcgYmxvY2sgb2YgQWN0aXZlSlMuXG4gKlxuICogQmFzZSBzZXJ2ZXMgYXMgdGhlIGJhc2UgZm9yIGFsbCBmdW5kYW1lbnRhbCBBY3RpdmVKUyBjb25zdHJ1Y3RzOiBVbml0cywgU3lzdGVtcywgQWN0aW9ucyBhbmQgQ2x1c3RlcnMuXG4gKlxuICogVGhpcyBpcyBhbiBpbnRlcm5hbCBjb25zdHJ1Y3QsIG5vcm1hbGx5IHlvdSdkIG5ldmVyIGhhdmUgdG8gdXNlIHRoaXMgY2xhc3MgZGlyZWN0bHkuXG4gKiBIb3dldmVyLCBpZiB5b3UncmUganVzdCByZWFkaW5nIHRoZSBkb2N1bWVudGF0aW9uLCBvciB3YW50IHRvIGxlYXJuIG1vcmUgYWJvdXQgaG93IEFjdGl2ZUpTIHdvcmtzLFxuICogb3Igd2FudCB0byBleHRlbmQgdGhpcyBjbGFzcyB0byBidWlsZCBzb21ldGhpbmcgb24geW91ciBvd24sIHBsZWFzZSBjb250aW51ZS5cbiAqXG4gKiBJdCBleHRlbmRzIFJ4SlMgYE9ic2VydmFibGVgLlxuICogU291cmNlIG9mIHRoaXMgT2JzZXJ2YWJsZSBpcyBlaXRoZXIgYSBCZWhhdmlvclN1YmplY3Qgb3IgU3ViamVjdCBkZXBlbmRpbmcgb24gdGhlIHtAbGluayBCYXNlQ29uZmlnLnJlcGxheX0gZmxhZy5cbiAqIEJ5IGRlZmF1bHQsIGl0J3MgYSBCZWhhdmlvdXJTdWJqZWN0IGZvciB0aGUgVW5pdHMsIFN5c3RlbXMgYW5kIENsdXN0ZXJzOyBhbmQgYSBTdWJqZWN0IGZvciBBY3Rpb25zLlxuICpcbiAqIFRoZXJlJ3MgYW5vdGhlciBub24tcmVwbGF5aW5nIE9ic2VydmFibGUgbmFtZWQgYGZ1dHVyZSRgIHRvIG9ic2VydmUgdGhlIHZhbHVlLCB3aG9zZSBzb3VyY2UgaXMgYWx3YXlzIGEgc2ltcGxlIFN1YmplY3QsXG4gKiBUaGlzIFN1YmplY3QgYWxzbyBzZXJ2ZXMgYXMgdGhlIHNvdXJjZSBmb3IgZGVmYXVsdCBleHRlbmRlZCBPYnNlcnZhYmxlIHdoZW4ge0BsaW5rIEJhc2VDb25maWcucmVwbGF5fSBpcyBgZmFsc2VgLlxuICpcbiAqIEluIHNpbXBsZSB0ZXJtcyBCYXNlIGlzIGFuIGVsYWJvcmF0ZSBSeEpTIFN1YmplY3QgbGlrZSBjb25zdHJ1Y3QsIHdpdGggY3VzdG9tIGZlYXR1cmVzIGxpa2UgcmVwbGF5IG9uIGRlbWFuZC5cbiAqIEFsdGhvdWdoIHRoYXQncyBqdXN0IG9uZSBhc3BlY3Qgb2YgQmFzZS5cbiAqXG4gKiBJdCBhbHNvIGltcGxlbWVudHMgYE9iamVjdC5wcm90b3R5cGVgIG1ldGhvZHNcbiAqIHRvIG1ha2Ugd29ya2luZyB3aXRoIHRoZSBzdG9yZWQgdmFsdWUgYSBiaXQgZWFzaWVyIGFuZCBlZmZpY2llbnQuXG4gKlxuICogT3RoZXIgdGhhbiB0aGF0LCBJdCBhbHNvIHByb3ZpZGVzIGZ1bmN0aW9uYWxpdGllcyBsaWtlOiBPbi1kZW1hbmQgT2JzZXJ2YWJsZSBjdXN0b20tZXZlbnQsIHRvIGxpc3RlbiB0byBldmVudHMgbGlrZSBtYW51YWwgcmVwbGF5LlxuICpcbiAqIEBjYXRlZ29yeSAyLiBBYnN0cmFjdFxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZTxUPiBleHRlbmRzIE9ic2VydmFibGU8VD4ge1xuICAvLyB0c2xpbnQ6ZGlzYWJsZTp2YXJpYWJsZS1uYW1lXG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyZWQgb3B0aW9ucy5cbiAgICogQ29tYmluYXRpb24gb2YgYXBwbGljYWJsZSBnbG9iYWwtb3B0aW9ucyBhbmQgdGhlIG9wdGlvbnMgcGFzc2VkIG9uIGluc3RhbnRpYXRpb24uXG4gICAqL1xuICByZWFkb25seSBjb25maWc6IFJlYWRvbmx5PEJhc2VDb25maWc+O1xuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc291cmNlU3ViamVjdDogU3ViamVjdDxUPiB8IEJlaGF2aW9yU3ViamVjdDxUPjtcbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkXG4gICAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZTogT2JzZXJ2YWJsZTxUPjtcblxuICAvKipcbiAgICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGV2ZW50c1N1YmplY3Q6IFN1YmplY3Q8QmFzZUV2ZW50czxUPiB8IGFueT47XG4gIC8qKlxuICAgKiBPbi1kZW1hbmQgb2JzZXJ2YWJsZSBldmVudHMuXG4gICAqIFNlZSB7QGxpbmsgaHR0cHM6Ly9kb2NzLmFjdGl2ZWpzLmRldi9ndWlkZXMvZXZlbnRzfSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgKi9cbiAgcmVhZG9ubHkgZXZlbnRzJDogT2JzZXJ2YWJsZTxCYXNlRXZlbnRzPFQ+IHwgYW55PjtcblxuICAvKipcbiAgICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICAgKi9cbiAgcHJpdmF0ZSBfZXZlbnRzOiBPYnNlcnZhYmxlPEJhc2VFdmVudHM8VD4+O1xuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGZ1dHVyZVN1YmplY3QgPSBuZXcgU3ViamVjdDxUPigpO1xuICAvKipcbiAgICogQW4gT2JzZXJ2YWJsZSB0byBvYnNlcnZlIGZ1dHVyZSB2YWx1ZXMsXG4gICAqIHVubGlrZSB0aGUgZGVmYXVsdCBPYnNlcnZhYmxlIGl0IGRvZXNuJ3QgcmVwbGF5IHdoZW4gc3Vic2NyaWJlZCB0byxcbiAgICogcmF0aGVyIGl0IHdhaXRzIGZvciB0aGUgbmV4dCB2YWx1ZS5cbiAgICovXG4gIHJlYWRvbmx5IGZ1dHVyZSQ6IE9ic2VydmFibGU8VD4gPSB0aGlzLmZ1dHVyZVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAgICovXG4gIHByb3RlY3RlZCBlbWl0dGVkVmFsdWU6IFQ7XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAgICovXG4gIHByaXZhdGUgX2VtaXRDb3VudCA9IDA7XG5cbiAgLyoqXG4gICAqIEEgY291bnRlciB0byBrZWVwIHRyYWNrIG9mIGhvdyBtYW55IHRpbWVzIGhhcyBhIFVuaXQsIFN5c3RlbSwgQWN0aW9uIG9yIENsdXN0ZXIgZW1pdHRlZC5cbiAgICogQHJldHVybnMgTnVtYmVyIG9mIHRpbWVzIGEgVW5pdCwgU3lzdGVtLCBBY3Rpb24gb3IgQ2x1c3RlciBoYXMgZW1pdHRlZC5cbiAgICovXG4gIGdldCBlbWl0Q291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fZW1pdENvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEN1cnJlbnQgdmFsdWUuXG4gICAqXG4gICAqIEBjYXRlZ29yeSBBY2Nlc3MgVmFsdWVcbiAgICovXG4gIGFic3RyYWN0IHZhbHVlKCk6IFQ7XG5cbiAgLyoqXG4gICAqIEN1cnJlbnQgdmFsdWUuXG4gICAqIFVzZWQgaW50ZXJuYWxseSwgZm9yIG9wZXJhdGlvbnMgdGhhdCBkb24ndCBtdXRhdGUgdGhlIHZhbHVlLlxuICAgKlxuICAgKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gICAqXG4gICAqIEBjYXRlZ29yeSBBY2Nlc3MgVmFsdWVcbiAgICovXG4gIHByb3RlY3RlZCByYXdWYWx1ZSgpOiBUIHtcbiAgICByZXR1cm4gdGhpcy52YWx1ZSgpO1xuICB9XG5cbiAgLy8gdHNsaW50OmVuYWJsZTp2YXJpYWJsZS1uYW1lXG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGNvbmZpZz86IEJhc2VDb25maWcpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5jb25maWcgPSB7Li4uY29uZmlnfTtcblxuICAgIGlmICh0aGlzLmNvbmZpZy5pZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoIWlzVmFsaWRJZCh0aGlzLmNvbmZpZy5pZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICBgSW52YWxpZCBpZCBwcm92aWRlZCwgZXhwZWN0ZWQgYSBub24tZW1wdHkgc3RyaW5nLCBnb3QgJHtTdHJpbmcodGhpcy5jb25maWcuaWQpfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChDb25maWd1cmF0aW9uLkVOVklST05NRU5ULmNoZWNrVW5pcXVlSWQgPT09IHRydWUpIHtcbiAgICAgICAgY29uc3QgbG9jYXRpb25JZCA9IGdldExvY2F0aW9uSWQodGhpcyk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBVbmlxdWVJZHNBbmRMb2NhdGlvbklkTWFwW3RoaXMuY29uZmlnLmlkXSAhPSBudWxsICYmXG4gICAgICAgICAgVW5pcXVlSWRzQW5kTG9jYXRpb25JZE1hcFt0aGlzLmNvbmZpZy5pZF0gIT09IGxvY2F0aW9uSWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgIGBEdXBsaWNhdGUgaWQgXCIke3RoaXMuY29uZmlnLmlkfVwiIGRldGVjdGVkIGJ5IFwiY2hlY2tVbmlxdWVJZFwiIGNoZWNrLCBjb25zaWRlciBhc3NpZ25pbmcgYSB1bmlxdWUgaWQuYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgVW5pcXVlSWRzQW5kTG9jYXRpb25JZE1hcFt0aGlzLmNvbmZpZy5pZF0gPSBsb2NhdGlvbklkO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoKHRoaXMuY29uZmlnIGFzIFVuaXRDb25maWc8YW55PikucGVyc2lzdGVudCA9PT0gdHJ1ZSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgQW4gaWQgaXMgcmVxdWlyZWQgZm9yIHBlcnNpc3RlbmNlIHRvIHdvcmsuYCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLnJlcGxheSA9PT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuc291cmNlU3ViamVjdCA9IHRoaXMuZnV0dXJlU3ViamVjdDtcbiAgICAgICh0aGlzIGFzIGFueSkuc291cmNlID0gdGhpcy5mdXR1cmUkO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNvdXJjZVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KHVuZGVmaW5lZCk7XG4gICAgICAodGhpcyBhcyBhbnkpLnNvdXJjZSA9IHRoaXMuc291cmNlU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgICB9XG5cbiAgICB0aGlzLnNldHVwRXZlbnRzKCk7XG4gICAgT2JqZWN0LmZyZWV6ZSh0aGlzLmNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBPYnNlcnZhYmxlIHVzaW5nIHRoZSBkZWZhdWx0IE9ic2VydmFibGUgYXMgc291cmNlLlxuICAgKiBVc2UgdGhpcyB0byBjb25jZWFsIG90aGVyIGFzcGVjdHMgb2YgYSBVbml0LCBTeXN0ZW0sIEFjdGlvbiBvciBDbHVzdGVyIGV4Y2VwdCB0aGUgT2JzZXJ2YWJsZSBwYXJ0LlxuICAgKlxuICAgKiBAcmV0dXJucyBBbiBPYnNlcnZhYmxlIHdpdGggdGhlIHZhbHVlIG9mIGEgVW5pdCwgU3lzdGVtLCBBY3Rpb24gb3IgQ2x1c3Rlci5cbiAgICpcbiAgICogQGNhdGVnb3J5IENvbW1vblxuICAgKi9cbiAgYXNPYnNlcnZhYmxlKCk6IE9ic2VydmFibGU8VD4ge1xuICAgIGNvbnN0IG9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTxUPigpO1xuICAgIChvYnNlcnZhYmxlIGFzIGFueSkuc291cmNlID0gKHRoaXMgYXMgYW55KS5zb3VyY2U7XG4gICAgcmV0dXJuIG9ic2VydmFibGU7XG4gIH1cblxuICAvKipcbiAgICogVG8gbWFudWFsbHkgcmUtZW1pdCB0aGUgbGFzdCBlbWl0dGVkIHZhbHVlIGFnYWluLlxuICAgKlxuICAgKiBAdHJpZ2dlcnMge0BsaW5rIEV2ZW50UmVwbGF5fVxuICAgKiBAY2F0ZWdvcnkgQ29tbW9uXG4gICAqL1xuICByZXBsYXkoKTogdm9pZCB7XG4gICAgdGhpcy5lbWl0KHRoaXMuZW1pdHRlZFZhbHVlKTtcblxuICAgIGlmICh0aGlzLmV2ZW50c1N1YmplY3Q/Lm9ic2VydmVycy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuZXZlbnRzU3ViamVjdC5uZXh0KG5ldyBFdmVudFJlcGxheSh0aGlzLmVtaXR0ZWRWYWx1ZSkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0aGUgdmFsdWUgdG8gSlNPTiBzdHJpbmcsIHVzaW5nIGBKU09OLnN0cmluZ2lmeWAuXG4gICAqXG4gICAqIEBjYXRlZ29yeSBDb21tb25cbiAgICovXG4gIHRvSnNvblN0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLnJhd1ZhbHVlKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHtAbGluayByYXdWYWx1ZX0sXG4gICAqIEphdmFTY3JpcHQgYXV0b21hdGljYWxseSBpbnZva2VzIGl0IHdoZW4gZW5jb3VudGVyaW5nIGFuIG9iamVjdCB3aGVyZSBhIHByaW1pdGl2ZSB2YWx1ZSBpcyBleHBlY3RlZC5cbiAgICpcbiAgICogQGFsaWFzIHtAbGluayByYXdWYWx1ZX1cbiAgICogVGhpcyBtZXRob2QgaXMgbm90IGludGVuZGVkIHRvIGJlIHVzZWQgYnkgZGV2ZWxvcGVycywgdXNlIHtAbGluayByYXdWYWx1ZX0gaW5zdGVhZC5cbiAgICogSXQgb25seSBleGlzdHMgdG8gYmUgdXNlZCBieSBKYXZhU2NyaXB0IGltcGxpY2l0bHkuXG4gICAqXG4gICAqIEBoaWRkZW5cbiAgICogQGNhdGVnb3J5IEN1c3RvbWlzZWQgT2JqZWN0LnByb3RvdHlwZVxuICAgKi9cbiAgdmFsdWVPZigpOiBUIHtcbiAgICByZXR1cm4gdGhpcy5yYXdWYWx1ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHtAbGluayByYXdWYWx1ZX0uXG4gICAqIEphdmFTY3JpcHQgYXV0b21hdGljYWxseSBpbnZva2VzIGl0IHdoZW4gYEpTT04uc3RyaW5naWZ5YCBpcyBpbnZva2VkIG9uIGFuIG9iamVjdC5cbiAgICpcbiAgICogQGFsaWFzIHtAbGluayByYXdWYWx1ZX1cbiAgICogVGhpcyBtZXRob2QgaXMgbm90IGludGVuZGVkIHRvIGJlIHVzZWQgYnkgZGV2ZWxvcGVycywgdXNlIHtAbGluayByYXdWYWx1ZX0gaW5zdGVhZC5cbiAgICogSXQgb25seSBleGlzdHMgdG8gYmUgdXNlZCBieSBgSlNPTi5zdHJpbmdpZnlgIGltcGxpY2l0bHkuXG4gICAqXG4gICAqIEBoaWRkZW5cbiAgICogQGNhdGVnb3J5IENvbW1vblxuICAgKi9cbiAgdG9KU09OKCk6IFQge1xuICAgIHJldHVybiB0aGlzLnJhd1ZhbHVlKCk7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGVtaXQodmFsdWU6IFQgPSB0aGlzLnZhbHVlKCkpOiB2b2lkIHtcbiAgICArK3RoaXMuX2VtaXRDb3VudDtcbiAgICB0aGlzLmVtaXR0ZWRWYWx1ZSA9IHZhbHVlO1xuXG4gICAgaWYgKHRoaXMuc291cmNlU3ViamVjdCAhPT0gdGhpcy5mdXR1cmVTdWJqZWN0KSB7XG4gICAgICB0aGlzLnNvdXJjZVN1YmplY3QubmV4dCh2YWx1ZSk7XG4gICAgfVxuICAgIHRoaXMuZnV0dXJlU3ViamVjdC5uZXh0KHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gICAqL1xuICBwcml2YXRlIHNldHVwRXZlbnRzKCk6IHZvaWQge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZXZlbnRzJCcsIHtcbiAgICAgIGdldCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50cykge1xuICAgICAgICAgIHJldHVybiB0aGlzLl9ldmVudHM7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmV2ZW50c1N1YmplY3QgPSBuZXcgU3ViamVjdDxCYXNlRXZlbnRzPFQ+PigpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSB0aGlzLmV2ZW50c1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdldmVudHNTdWJqZWN0Jywge2VudW1lcmFibGU6IGZhbHNlfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnX2V2ZW50cycsIHtlbnVtZXJhYmxlOiBmYWxzZX0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHM7XG4gICAgICB9LFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgfSk7XG4gIH1cblxuICAvLyB0c2xpbnQ6ZGlzYWJsZVxuICAvLyBPdmVycmlkaW5nIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGFuZCBtZXRob2RzIGZyb20gUnhKUyBPYnNlcnZhYmxlLlxuICAvLyBUaGlzIGhhY2sgaXMgZXNzZW50aWFsIHRvIHJlZHVjZSBBUEkgc3VyZmFjZSBhcmVhIGFuZCBhdm9pZCBjb25mdXNpb25cbiAgLy8gd2l0aCBvdXIgb3duIGltcGxlbWVudGF0aW9ucyBsaWtlIGBmb3JFdmVyeWAuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZFxuICAgKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gICAqL1xuICBfaXNTY2FsYXI6IGFueTtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWRcbiAgICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICAgKi9cbiAgb3BlcmF0b3I6IGFueTtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWRcbiAgICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICAgKi9cbiAgbGlmdDogYW55O1xuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZFxuICAgKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gICAqL1xuICBfdHJ5U3Vic2NyaWJlOiBhbnk7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkXG4gICAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAgICovXG4gIF9zdWJzY3JpYmU6IGFueTtcblxuICAvKipcbiAgICogQGFsaWFzIGZvckV2ZXJ5XG4gICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgZm9yRXZlcnl9IGluc3RlYWQuXG4gICAqIFRoaXMgYGZvckVhY2hgIGlzIG5vdCB0aGUgdXN1YWwgYEFycmF5LmZvckVhY2hgLlxuICAgKiBUaGlzIGBmb3JFYWNoYCBpcyBhbiBSeEpTIGZlYXR1cmUsIHdoaWNoIGdvdCBpbmhlcml0ZWQgZHVlIHRvIGV4dGVuZGluZyB0aGUgT2JzZXJ2YWJsZSBjbGFzcyxcbiAgICogQnV0IHRoaXMgaXMgbm90IHdoYXQgeW91IHdhbnQsIG1vc3QgcHJvYmFibHkgeW91IGp1c3Qgd2FudCB0byBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zLCBmb3IgdGhhdFxuICAgKiB3ZSd2ZSBpbXBsZW1lbnRlZCB0aGUgbm9ybWFsIGBmb3JFYWNoYCBmdW5jdGlvbmFsaXR5IGludG8gYGZvckV2ZXJ5YCBtZXRob2QuXG4gICAqXG4gICAqIFRoaXMgYGZvckVhY2hgIGlzIG1hcmtlZCBkZXByZWNhdGVkIHRvIHByZXZlbnQgYWNjaWRlbnRhbCB1c2FnZSwgYW5kIGF2b2lkIGNvbmZ1c2lvbi5cbiAgICogWW91IGNhbiBzdGlsbCB1c2UgaXQgdGhvdWdoLCBpZiB5b3Ugd2FudCB0aGUgUnhKUyBmZWF0dXJlLFxuICAgKiBzZWUge0BsaW5rIE9ic2VydmFibGUuZm9yRWFjaH0gZm9yIHVzYWdlLlxuICAgKiBAaGlkZGVuXG4gICAqL1xuICBmb3JFYWNoOiBhbnk7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkXG4gICAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAgICovXG4gIHN0YXRpYyBjcmVhdGU6IGFueTtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWRcbiAgICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICAgKi9cbiAgc3RhdGljIGlmOiBhbnk7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkXG4gICAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAgICovXG4gIHN0YXRpYyB0aHJvdzogYW55O1xuICAvLyB0c2xpbnQ6ZW5hYmxlXG59XG5cbi8qKlxuICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICovXG5jb25zdCBNZXRob2RzTm90VG9JbXBsZW1lbnQgPSBbXG4gIC4uLk9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE9ic2VydmFibGUucHJvdG90eXBlKSxcbiAgLi4uT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoQmFzZS5wcm90b3R5cGUpLFxuXTtcblxuT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoT2JqZWN0LnByb3RvdHlwZSkuZm9yRWFjaChtZXRob2QgPT4ge1xuICBpZiAoIWlzRnVuY3Rpb24oT2JqZWN0LnByb3RvdHlwZVttZXRob2RdKSB8fCBNZXRob2RzTm90VG9JbXBsZW1lbnQuaW5jbHVkZXMobWV0aG9kKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCYXNlLnByb3RvdHlwZSwgbWV0aG9kLCB7XG4gICAgdmFsdWUoLi4uYXJncykge1xuICAgICAgcmV0dXJuIHRoaXMucmF3VmFsdWUoKVttZXRob2RdKC4uLmFyZ3MpO1xuICAgIH0sXG4gIH0pO1xufSk7XG4iXX0=