saij
Version:
A learning engine.
245 lines (205 loc) • 19.2 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.getChangeEventType = exports.ObjectEvent = void 0;
var _ObjectEventType = _interopRequireDefault(require("./ObjectEventType.js"));
var _Observable = _interopRequireDefault(require("./Observable.js"));
var _Event = _interopRequireDefault(require("./Event.js"));
var _object = require("./utils/object.js");
var _uid = require("./utils/uid.js");
/**
* @module saij/core/Object
*/
/**
* @classdesc
* Events emitted by {@link module:saij/core/Object~BaseObject} instances are
* instances of this type.
*/
class ObjectEvent extends _Event.default {
/**
* @param {string} type The event type.
* @param {string} key The property name.
* @param {*} oldValue The old value for `key`.
*/
constructor(type, key, oldValue) {
super(type);
/**
* The name of the property whose value is changing.
* @type {string}
* @api
*/
this.key = key;
/**
* The old value. To get the new value use `e.target.get(e.key)` where
* `e` is the event object.
* @type {*}
* @api
*/
this.oldValue = oldValue;
}
}
/**
* @type {Object<string, string>}
*/
exports.ObjectEvent = ObjectEvent;
const changeEventTypeCache = {};
/**
* @param {string} key Key name.
* @return {string} Change name.
*/
// eslint-disable-next-line no-return-assign
const getChangeEventType = key => changeEventTypeCache.hasOwnProperty(key) ? changeEventTypeCache[key] : changeEventTypeCache[key] = `change:${key}`;
/**
* @classdesc
* Abstract base class; normally only used for creating subclasses and not
* instantiated in apps.
* Most non-trivial classes inherit from this.
*
* This extends {@link module:saij/core/Observable} with observable
* properties, where each property is observable as well as the object as a
* whole.
*
* Classes that inherit from this have pre-defined properties, to which you can
* add your owns. The pre-defined properties are listed in this documentation as
* 'Observable Properties', and have their own accessors; for example,
* {@link module:saij/Engine~Engine} has a `target` property, accessed with
* `getTarget()` and changed with `setTarget()`. Not all properties are however
* settable. There are also general-purpose accessors `get()` and `set()`. For
* example, `get('target')` is equivalent to `getTarget()`.
*
* The `set` accessors trigger a change event, and you can monitor this by
* registering a listener. For example, {@link module:saij/Reactor~Reactor} has
* an `input` property, so `reactor.on('change:input', function(evt) {...});`
* would call the function whenever the value of the input property changes.
* Within the function, `evt.target` would be the Reactor, so
* `evt.target.getInput()` would return the new input.
*
* You can add your own observable properties with
* `object.set('prop', 'value')`, and retrieve that with `object.get('prop')`.
* You can listen for changes on that property value with
* `object.on('change:prop', listener)`. You can get a list of all
* properties with {@link module:saij/Object~BaseObject#getProperties}.
*
* Note that the observable properties are separate from standard JS properties.
* You can, for example, give your map object a title with
* `Engine.name='New name'` and with `Engine.set('title', 'Another title')`. The
* first will be a `hasOwnProperty`; the second will appear in
* `getProperties()`. Only the second is observable.
*
* Properties can be deleted by using the unset method. E.g.
* object.unset('foo').
*
* @fires module:saij/core/Object~ObjectEvent
* @api
*/
exports.getChangeEventType = getChangeEventType;
class BaseObject extends _Observable.default {
/**
* @param {Object<string, *>=} opt_values An object with key-value pairs.
*/
constructor(opt_values) {
super(); // Call {@link module:ol/util~getUid} to ensure that the order of objects'
// ids is the same as the order in which they were created. This also helps
// to ensure that object properties are always added in the same order,
// which helps many JavaScript engines generate faster code.
(0, _uid.getUid)(this);
/**
* @private
* @type {!Object<string, *>}
*/
this.values_ = {};
if (opt_values !== undefined) {
this.setProperties(opt_values);
}
}
/**
* Gets a value.
* @param {string} key Key name.
* @return {*} Value.
* @api
*/
get(key) {
if (this.values_.hasOwnProperty(key)) {
return this.values_[key];
}
return;
}
/**
* Get a list of object property names.
* @return {Array<string>} List of property names.
* @api
*/
getKeys() {
return Object.keys(this.values_);
}
/**
* Get an object of all property names and values.
* @return {Object<string, *>} Object.
* @api
*/
getProperties() {
return (0, _object.assign)({}, this.values_);
}
/**
* @param {string} key Key name.
* @param {*} oldValue Old value.
*/
notify(key, oldValue) {
let eventType = null;
eventType = getChangeEventType(key);
this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
eventType = _ObjectEventType.default.PROPERTYCHANGE;
this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
}
/**
* Sets a value.
* @param {string} key Key name.
* @param {*} value Value.
* @param {boolean=} opt_silent Update without triggering an event.
* @api
*/
set(key, value, opt_silent) {
if (opt_silent) {
this.values_[key] = value;
} else {
const oldValue = this.values_[key];
this.values_[key] = value;
if (oldValue !== value) {
this.notify(key, oldValue);
}
}
}
/**
* Sets a collection of key-value pairs. Note that this changes any existing
* properties and adds new ones (it does not remove any existing properties).
* @param {Object<string, *>} values Values.
* @param {boolean=} opt_silent Update without triggering an event.
* @api
*/
setProperties(values, opt_silent) {
// eslint-disable-next-line guard-for-in
for (const key in values) {
this.set(key, values[key], opt_silent);
}
}
/**
* Unsets a property.
* @param {string} key Key name.
* @param {boolean=} opt_silent Unset without triggering an event.
* @api
*/
unset(key, opt_silent) {
if (key in this.values_) {
const oldValue = this.values_[key];
Reflect.deleteProperty(this.values_, key);
if (!opt_silent) {
this.notify(key, oldValue);
}
}
}
}
var _default = BaseObject;
exports.default = _default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zYWlqL2NvcmUvT2JqZWN0LmpzIl0sIm5hbWVzIjpbIk9iamVjdEV2ZW50IiwiRXZlbnQiLCJjb25zdHJ1Y3RvciIsInR5cGUiLCJrZXkiLCJvbGRWYWx1ZSIsImNoYW5nZUV2ZW50VHlwZUNhY2hlIiwiZ2V0Q2hhbmdlRXZlbnRUeXBlIiwiaGFzT3duUHJvcGVydHkiLCJCYXNlT2JqZWN0IiwiT2JzZXJ2YWJsZSIsIm9wdF92YWx1ZXMiLCJ2YWx1ZXNfIiwidW5kZWZpbmVkIiwic2V0UHJvcGVydGllcyIsImdldCIsImdldEtleXMiLCJPYmplY3QiLCJrZXlzIiwiZ2V0UHJvcGVydGllcyIsIm5vdGlmeSIsImV2ZW50VHlwZSIsImRpc3BhdGNoRXZlbnQiLCJPYmplY3RFdmVudFR5cGUiLCJQUk9QRVJUWUNIQU5HRSIsInNldCIsInZhbHVlIiwib3B0X3NpbGVudCIsInZhbHVlcyIsInVuc2V0IiwiUmVmbGVjdCIsImRlbGV0ZVByb3BlcnR5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFHQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFQQTs7OztBQVVBOzs7OztBQUtPLE1BQU1BLFdBQU4sU0FBMEJDLGNBQTFCLENBQWdDO0FBRXJDOzs7OztBQUtBQyxFQUFBQSxXQUFXLENBQUNDLElBQUQsRUFBT0MsR0FBUCxFQUFZQyxRQUFaLEVBQXNCO0FBQy9CLFVBQU1GLElBQU47QUFFQTs7Ozs7O0FBS0EsU0FBS0MsR0FBTCxHQUFXQSxHQUFYO0FBRUE7Ozs7Ozs7QUFNQSxTQUFLQyxRQUFMLEdBQWdCQSxRQUFoQjtBQUNEOztBQXhCb0M7QUE0QnZDOzs7Ozs7QUFHQSxNQUFNQyxvQkFBb0IsR0FBRyxFQUE3QjtBQUdBOzs7O0FBSUE7O0FBQ08sTUFBTUMsa0JBQWtCLEdBQUlILEdBQUQsSUFDaENFLG9CQUFvQixDQUFDRSxjQUFyQixDQUFvQ0osR0FBcEMsSUFDRUUsb0JBQW9CLENBQUNGLEdBQUQsQ0FEdEIsR0FFR0Usb0JBQW9C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RDtBQUNGO0FBQ0Y7O0FBbkhpQzs7ZUF1SHJCSSxVIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIHNhaWovY29yZS9PYmplY3RcbiAqL1xuaW1wb3J0IE9iamVjdEV2ZW50VHlwZSBmcm9tICcuL09iamVjdEV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgT2JzZXJ2YWJsZSBmcm9tICcuL09ic2VydmFibGUuanMnO1xuaW1wb3J0IEV2ZW50IGZyb20gJy4vRXZlbnQuanMnO1xuaW1wb3J0IHthc3NpZ259IGZyb20gJy4vdXRpbHMvb2JqZWN0LmpzJztcbmltcG9ydCB7Z2V0VWlkfSBmcm9tICcuL3V0aWxzL3VpZC5qcyc7XG5cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBFdmVudHMgZW1pdHRlZCBieSB7QGxpbmsgbW9kdWxlOnNhaWovY29yZS9PYmplY3R+QmFzZU9iamVjdH0gaW5zdGFuY2VzIGFyZVxuICogaW5zdGFuY2VzIG9mIHRoaXMgdHlwZS5cbiAgKi9cbmV4cG9ydCBjbGFzcyBPYmplY3RFdmVudCBleHRlbmRzIEV2ZW50IHtcblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVGhlIGV2ZW50IHR5cGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHByb3BlcnR5IG5hbWUuXG4gICAqIEBwYXJhbSB7Kn0gb2xkVmFsdWUgVGhlIG9sZCB2YWx1ZSBmb3IgYGtleWAuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih0eXBlLCBrZXksIG9sZFZhbHVlKSB7XG4gICAgc3VwZXIodHlwZSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgd2hvc2UgdmFsdWUgaXMgY2hhbmdpbmcuXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAYXBpXG4gICAgICovXG4gICAgdGhpcy5rZXkgPSBrZXk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb2xkIHZhbHVlLiBUbyBnZXQgdGhlIG5ldyB2YWx1ZSB1c2UgYGUudGFyZ2V0LmdldChlLmtleSlgIHdoZXJlXG4gICAgICogYGVgIGlzIHRoZSBldmVudCBvYmplY3QuXG4gICAgICogQHR5cGUgeyp9XG4gICAgICogQGFwaVxuICAgICAqL1xuICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgfVxufVxuXG5cbi8qKlxuICogQHR5cGUge09iamVjdDxzdHJpbmcsIHN0cmluZz59XG4gKi9cbmNvbnN0IGNoYW5nZUV2ZW50VHlwZUNhY2hlID0ge307XG5cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IEtleSBuYW1lLlxuICogQHJldHVybiB7c3RyaW5nfSBDaGFuZ2UgbmFtZS5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJldHVybi1hc3NpZ25cbmV4cG9ydCBjb25zdCBnZXRDaGFuZ2VFdmVudFR5cGUgPSAoa2V5KT0+IChcbiAgY2hhbmdlRXZlbnRUeXBlQ2FjaGUuaGFzT3duUHJvcGVydHkoa2V5KSA/XG4gICAgY2hhbmdlRXZlbnRUeXBlQ2FjaGVba2V5XSA6XG4gICAgKGNoYW5nZUV2ZW50VHlwZUNhY2hlW2tleV0gPSBgY2hhbmdlOiR7a2V5fWApXG4pO1xuXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWJzdHJhY3QgYmFzZSBjbGFzczsgbm9ybWFsbHkgb25seSB1c2VkIGZvciBjcmVhdGluZyBzdWJjbGFzc2VzIGFuZCBub3RcbiAqIGluc3RhbnRpYXRlZCBpbiBhcHBzLlxuICogTW9zdCBub24tdHJpdmlhbCBjbGFzc2VzIGluaGVyaXQgZnJvbSB0aGlzLlxuICpcbiAqIFRoaXMgZXh0ZW5kcyB7QGxpbmsgbW9kdWxlOnNhaWovY29yZS9PYnNlcnZhYmxlfSB3aXRoIG9ic2VydmFibGVcbiAqIHByb3BlcnRpZXMsIHdoZXJlIGVhY2ggcHJvcGVydHkgaXMgb2JzZXJ2YWJsZSBhcyB3ZWxsIGFzIHRoZSBvYmplY3QgYXMgYVxuICogd2hvbGUuXG4gKlxuICogQ2xhc3NlcyB0aGF0IGluaGVyaXQgZnJvbSB0aGlzIGhhdmUgcHJlLWRlZmluZWQgcHJvcGVydGllcywgdG8gd2hpY2ggeW91IGNhblxuICogYWRkIHlvdXIgb3ducy4gVGhlIHByZS1kZWZpbmVkIHByb3BlcnRpZXMgYXJlIGxpc3RlZCBpbiB0aGlzIGRvY3VtZW50YXRpb24gYXNcbiAqICdPYnNlcnZhYmxlIFByb3BlcnRpZXMnLCBhbmQgaGF2ZSB0aGVpciBvd24gYWNjZXNzb3JzOyBmb3IgZXhhbXBsZSxcbiAqIHtAbGluayBtb2R1bGU6c2Fpai9FbmdpbmV+RW5naW5lfSBoYXMgYSBgdGFyZ2V0YCBwcm9wZXJ0eSwgYWNjZXNzZWQgd2l0aFxuICogYGdldFRhcmdldCgpYCBhbmQgY2hhbmdlZCB3aXRoIGBzZXRUYXJnZXQoKWAuIE5vdCBhbGwgcHJvcGVydGllcyBhcmUgaG93ZXZlclxuICogc2V0dGFibGUuIFRoZXJlIGFyZSBhbHNvIGdlbmVyYWwtcHVycG9zZSBhY2Nlc3NvcnMgYGdldCgpYCBhbmQgYHNldCgpYC4gRm9yXG4gKiBleGFtcGxlLCBgZ2V0KCd0YXJnZXQnKWAgaXMgZXF1aXZhbGVudCB0byBgZ2V0VGFyZ2V0KClgLlxuICpcbiAqIFRoZSBgc2V0YCBhY2Nlc3NvcnMgdHJpZ2dlciBhIGNoYW5nZSBldmVudCwgYW5kIHlvdSBjYW4gbW9uaXRvciB0aGlzIGJ5XG4gKiByZWdpc3RlcmluZyBhIGxpc3RlbmVyLiBGb3IgZXhhbXBsZSwge0BsaW5rIG1vZHVsZTpzYWlqL1JlYWN0b3J+UmVhY3Rvcn0gaGFzXG4gKiBhbiBgaW5wdXRgIHByb3BlcnR5LCBzbyBgcmVhY3Rvci5vbignY2hhbmdlOmlucHV0JywgZnVuY3Rpb24oZXZ0KSB7Li4ufSk7YFxuICogd291bGQgY2FsbCB0aGUgZnVuY3Rpb24gd2hlbmV2ZXIgdGhlIHZhbHVlIG9mIHRoZSBpbnB1dCBwcm9wZXJ0eSBjaGFuZ2VzLlxuICogV2l0aGluIHRoZSBmdW5jdGlvbiwgYGV2dC50YXJnZXRgIHdvdWxkIGJlIHRoZSBSZWFjdG9yLCBzb1xuICogYGV2dC50YXJnZXQuZ2V0SW5wdXQoKWAgd291bGQgcmV0dXJuIHRoZSBuZXcgaW5wdXQuXG4gKlxuICogWW91IGNhbiBhZGQgeW91ciBvd24gb2JzZXJ2YWJsZSBwcm9wZXJ0aWVzIHdpdGhcbiAqIGBvYmplY3Quc2V0KCdwcm9wJywgJ3ZhbHVlJylgLCBhbmQgcmV0cmlldmUgdGhhdCB3aXRoIGBvYmplY3QuZ2V0KCdwcm9wJylgLlxuICogWW91IGNhbiBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhhdCBwcm9wZXJ0eSB2YWx1ZSB3aXRoXG4gKiBgb2JqZWN0Lm9uKCdjaGFuZ2U6cHJvcCcsIGxpc3RlbmVyKWAuIFlvdSBjYW4gZ2V0IGEgbGlzdCBvZiBhbGxcbiAqIHByb3BlcnRpZXMgd2l0aCB7QGxpbmsgbW9kdWxlOnNhaWovT2JqZWN0fkJhc2VPYmplY3QjZ2V0UHJvcGVydGllc30uXG4gKlxuICogTm90ZSB0aGF0IHRoZSBvYnNlcnZhYmxlIHByb3BlcnRpZXMgYXJlIHNlcGFyYXRlIGZyb20gc3RhbmRhcmQgSlMgcHJvcGVydGllcy5cbiAqIFlvdSBjYW4sIGZvciBleGFtcGxlLCBnaXZlIHlvdXIgbWFwIG9iamVjdCBhIHRpdGxlIHdpdGhcbiAqIGBFbmdpbmUubmFtZT0nTmV3IG5hbWUnYCBhbmQgd2l0aCBgRW5naW5lLnNldCgndGl0bGUnLCAnQW5vdGhlciB0aXRsZScpYC4gVGhlXG4gKiBmaXJzdCB3aWxsIGJlIGEgYGhhc093blByb3BlcnR5YDsgdGhlIHNlY29uZCB3aWxsIGFwcGVhciBpblxuICogYGdldFByb3BlcnRpZXMoKWAuIE9ubHkgdGhlIHNlY29uZCBpcyBvYnNlcnZhYmxlLlxuICpcbiAqIFByb3BlcnRpZXMgY2FuIGJlIGRlbGV0ZWQgYnkgdXNpbmcgdGhlIHVuc2V0IG1ldGhvZC4gRS5nLlxuICogb2JqZWN0LnVuc2V0KCdmb28nKS5cbiAqXG4gKiBAZmlyZXMgbW9kdWxlOnNhaWovY29yZS9PYmplY3R+T2JqZWN0RXZlbnRcbiAqIEBhcGlcbiAqL1xuY2xhc3MgQmFzZU9iamVjdCBleHRlbmRzIE9ic2VydmFibGUge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdDxzdHJpbmcsICo+PX0gb3B0X3ZhbHVlcyBBbiBvYmplY3Qgd2l0aCBrZXktdmFsdWUgcGFpcnMuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRfdmFsdWVzKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIC8vIENhbGwge0BsaW5rIG1vZHVsZTpvbC91dGlsfmdldFVpZH0gdG8gZW5zdXJlIHRoYXQgdGhlIG9yZGVyIG9mIG9iamVjdHMnXG4gICAgLy8gaWRzIGlzIHRoZSBzYW1lIGFzIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IHdlcmUgY3JlYXRlZC4gIFRoaXMgYWxzbyBoZWxwc1xuICAgIC8vIHRvIGVuc3VyZSB0aGF0IG9iamVjdCBwcm9wZXJ0aWVzIGFyZSBhbHdheXMgYWRkZWQgaW4gdGhlIHNhbWUgb3JkZXIsXG4gICAgLy8gd2hpY2ggaGVscHMgbWFueSBKYXZhU2NyaXB0IGVuZ2luZXMgZ2VuZXJhdGUgZmFzdGVyIGNvZGUuXG4gICAgZ2V0VWlkKHRoaXMpO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsICo+fVxuICAgICAqL1xuICAgIHRoaXMudmFsdWVzXyA9IHt9O1xuXG4gICAgaWYgKG9wdF92YWx1ZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zZXRQcm9wZXJ0aWVzKG9wdF92YWx1ZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGEgdmFsdWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5IG5hbWUuXG4gICAqIEByZXR1cm4geyp9IFZhbHVlLlxuICAgKiBAYXBpXG4gICAqL1xuICBnZXQoa2V5KSB7XG4gICAgaWYgKHRoaXMudmFsdWVzXy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICByZXR1cm4gdGhpcy52YWx1ZXNfW2tleV07XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBsaXN0IG9mIG9iamVjdCBwcm9wZXJ0eSBuYW1lcy5cbiAgICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn0gTGlzdCBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICogQGFwaVxuICAgKi9cbiAgZ2V0S2V5cygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy52YWx1ZXNfKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYW4gb2JqZWN0IG9mIGFsbCBwcm9wZXJ0eSBuYW1lcyBhbmQgdmFsdWVzLlxuICAgKiBAcmV0dXJuIHtPYmplY3Q8c3RyaW5nLCAqPn0gT2JqZWN0LlxuICAgKiBAYXBpXG4gICAqL1xuICBnZXRQcm9wZXJ0aWVzKCkge1xuICAgIHJldHVybiBhc3NpZ24oe30sIHRoaXMudmFsdWVzXyk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkgbmFtZS5cbiAgICogQHBhcmFtIHsqfSBvbGRWYWx1ZSBPbGQgdmFsdWUuXG4gICAqL1xuICBub3RpZnkoa2V5LCBvbGRWYWx1ZSkge1xuICAgIGxldCBldmVudFR5cGUgPSBudWxsO1xuICAgIGV2ZW50VHlwZSA9IGdldENoYW5nZUV2ZW50VHlwZShrZXkpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgT2JqZWN0RXZlbnQoZXZlbnRUeXBlLCBrZXksIG9sZFZhbHVlKSk7XG4gICAgZXZlbnRUeXBlID0gT2JqZWN0RXZlbnRUeXBlLlBST1BFUlRZQ0hBTkdFO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgT2JqZWN0RXZlbnQoZXZlbnRUeXBlLCBrZXksIG9sZFZhbHVlKSk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIHZhbHVlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IEtleSBuYW1lLlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc2lsZW50IFVwZGF0ZSB3aXRob3V0IHRyaWdnZXJpbmcgYW4gZXZlbnQuXG4gICAqIEBhcGlcbiAgICovXG4gIHNldChrZXksIHZhbHVlLCBvcHRfc2lsZW50KSB7XG4gICAgaWYgKG9wdF9zaWxlbnQpIHtcbiAgICAgIHRoaXMudmFsdWVzX1trZXldID0gdmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy52YWx1ZXNfW2tleV07XG4gICAgICB0aGlzLnZhbHVlc19ba2V5XSA9IHZhbHVlO1xuICAgICAgaWYgKG9sZFZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgICB0aGlzLm5vdGlmeShrZXksIG9sZFZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIGNvbGxlY3Rpb24gb2Yga2V5LXZhbHVlIHBhaXJzLiAgTm90ZSB0aGF0IHRoaXMgY2hhbmdlcyBhbnkgZXhpc3RpbmdcbiAgICogcHJvcGVydGllcyBhbmQgYWRkcyBuZXcgb25lcyAoaXQgZG9lcyBub3QgcmVtb3ZlIGFueSBleGlzdGluZyBwcm9wZXJ0aWVzKS5cbiAgICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCAqPn0gdmFsdWVzIFZhbHVlcy5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3NpbGVudCBVcGRhdGUgd2l0aG91dCB0cmlnZ2VyaW5nIGFuIGV2ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuICBzZXRQcm9wZXJ0aWVzKHZhbHVlcywgb3B0X3NpbGVudCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBndWFyZC1mb3ItaW5cbiAgICBmb3IgKGNvbnN0IGtleSBpbiB2YWx1ZXMpIHtcbiAgICAgIHRoaXMuc2V0KGtleSwgdmFsdWVzW2tleV0sIG9wdF9zaWxlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVbnNldHMgYSBwcm9wZXJ0eS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkgbmFtZS5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3NpbGVudCBVbnNldCB3aXRob3V0IHRyaWdnZXJpbmcgYW4gZXZlbnQuXG4gICAqIEBhcGlcbiAgICovXG4gIHVuc2V0KGtleSwgb3B0X3NpbGVudCkge1xuICAgIGlmIChrZXkgaW4gdGhpcy52YWx1ZXNfKSB7XG4gICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMudmFsdWVzX1trZXldO1xuICAgICAgUmVmbGVjdC5kZWxldGVQcm9wZXJ0eSh0aGlzLnZhbHVlc18sIGtleSk7XG4gICAgICBpZiAoIW9wdF9zaWxlbnQpIHtcbiAgICAgICAgdGhpcy5ub3RpZnkoa2V5LCBvbGRWYWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cblxuZXhwb3J0IGRlZmF1bHQgQmFzZU9iamVjdDtcbiJdfQ==