@orbit/core
Version:
Core library for Orbit - a flexible data access and synchronization layer.
156 lines • 16.4 kB
JavaScript
import { Notifier } from './notifier';
const EVENTED = '__evented__';
/**
* Has a class been decorated as `@evented`?
*/
export function isEvented(obj) {
return !!obj[EVENTED];
}
/**
* Marks a class as evented.
*
* An evented class should also implement the `Evented` interface.
*
* ```ts
* import { evented, Evented } from '@orbit/core';
*
* @evented
* class Source implements Evented {
* ...
* }
* ```
*
* Listeners can then register themselves for particular events with `on`:
*
* ```ts
* let source = new Source();
*
* function listener1(message: string) {
* console.log('listener1 heard ' + message);
* };
* function listener2(message: string) {
* console.log('listener2 heard ' + message);
* };
*
* source.on('greeting', listener1);
* source.on('greeting', listener2);
*
* evented.emit('greeting', 'hello'); // logs "listener1 heard hello" and
* // "listener2 heard hello"
* ```
*
* Listeners can be unregistered from events at any time with `off`:
*
* ```ts
* source.off('greeting', listener2);
* ```
*/
export function evented(Klass) {
let proto = Klass.prototype;
if (isEvented(proto)) {
return;
}
proto[EVENTED] = true;
proto.on = function (eventName, listener) {
return notifierForEvent(this, eventName, true).addListener(listener);
};
proto.off = function (eventName, listener) {
const notifier = notifierForEvent(this, eventName);
if (notifier) {
if (listener) {
notifier.removeListener(listener);
}
else {
removeNotifierForEvent(this, eventName);
}
}
};
proto.one = function (eventName, listener) {
const notifier = notifierForEvent(this, eventName, true);
const callOnce = function () {
listener(...arguments);
notifier.removeListener(callOnce);
};
return notifier.addListener(callOnce);
};
proto.emit = function (eventName, ...args) {
let notifier = notifierForEvent(this, eventName);
if (notifier) {
notifier.emit.apply(notifier, args);
}
};
proto.listeners = function (eventName) {
let notifier = notifierForEvent(this, eventName);
return notifier ? notifier.listeners : [];
};
}
/**
* Settle any promises returned by event listeners in series.
*
* Returns an array of results (or `undefined`) returned by listeners.
*
* If any errors are encountered during processing, they will be caught and
* returned with other results. Errors will not interrupt further processing.
*/
export async function settleInSeries(obj, eventName, ...args) {
const listeners = obj.listeners(eventName);
const results = [];
for (let listener of listeners) {
try {
results.push(await listener(...args));
}
catch (e) {
results.push(e);
}
}
return results;
}
/**
* Fulfills any promises returned by event listeners in series.
*
* Returns an array of results (or `undefined`) returned by listeners.
*
* On error, processing will stop and the returned promise will be rejected with
* the error that was encountered.
*/
export async function fulfillInSeries(obj, eventName, ...args) {
const listeners = obj.listeners(eventName);
const results = [];
for (let listener of listeners) {
results.push(await listener(...args));
}
return results;
}
/**
* Fulfills any promises returned by event listeners in parallel, using
* `Promise.all`.
*
* Returns an array of results (or `undefined`) returned by listeners.
*
* On error, processing will stop and the returned promise will be rejected with
* the error that was encountered.
*/
export async function fulfillAll(obj, eventName, ...args) {
const listeners = obj.listeners(eventName);
const promises = [];
for (let listener of listeners) {
promises.push(listener(...args));
}
return Promise.all(promises);
}
function notifierForEvent(object, eventName, createIfUndefined = false) {
if (object._eventedNotifiers === undefined) {
object._eventedNotifiers = {};
}
let notifier = object._eventedNotifiers[eventName];
if (!notifier && createIfUndefined) {
notifier = object._eventedNotifiers[eventName] = new Notifier();
}
return notifier;
}
function removeNotifierForEvent(object, eventName) {
if (object._eventedNotifiers && object._eventedNotifiers[eventName]) {
delete object._eventedNotifiers[eventName];
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ldmVudGVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQVksTUFBTSxZQUFZLENBQUM7QUFFaEQsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDO0FBRTlCOztHQUVHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FBQyxHQUFZO0lBQ3BDLE9BQU8sQ0FBQyxDQUFFLEdBQStCLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDckQsQ0FBQztBQXVCRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQ0c7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFDLEtBQXlCO0lBQy9DLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7SUFFNUIsSUFBSSxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDcEIsT0FBTztLQUNSO0lBRUQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQztJQUV0QixLQUFLLENBQUMsRUFBRSxHQUFHLFVBQVUsU0FBaUIsRUFBRSxRQUFrQjtRQUN4RCxPQUFPLGdCQUFnQixDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3ZFLENBQUMsQ0FBQztJQUVGLEtBQUssQ0FBQyxHQUFHLEdBQUcsVUFBVSxTQUFpQixFQUFFLFFBQWtCO1FBQ3pELE1BQU0sUUFBUSxHQUFHLGdCQUFnQixDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUVuRCxJQUFJLFFBQVEsRUFBRTtZQUNaLElBQUksUUFBUSxFQUFFO2dCQUNaLFFBQVEsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDbkM7aUJBQU07Z0JBQ0wsc0JBQXNCLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQ3pDO1NBQ0Y7SUFDSCxDQUFD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QUksTUFBTSxDQUFDLGlCQUFpQixLQUFLLFNBQVMsRUFBRTtRQUMxQyxNQUFNLENBQUMsaUJBQWlCLEdBQUcsRUFBRSxDQUFDO0tBQy9CO0lBQ0QsSUFBSSxRQUFRLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ25ELElBQUksQ0FBQyxRQUFRLElBQUksaUJBQWlCLEVBQUU7UUFDbEMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO0tBQ2pFO0lBQ0QsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQztBQUVELFNBQVMsc0JBQXNCLENBQUMsTUFBVyxFQUFFLFNBQWlCO0lBQzVELElBQUksTUFBTSxDQUFDLGlCQUFpQixJQUFJLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsRUFBRTtRQUNuRSxPQUFPLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUM1QztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOb3RpZmllciwgTGlzdGVuZXIgfSBmcm9tICcuL25vdGlmaWVyJztcblxuY29uc3QgRVZFTlRFRCA9ICdfX2V2ZW50ZWRfXyc7XG5cbi8qKlxuICogSGFzIGEgY2xhc3MgYmVlbiBkZWNvcmF0ZWQgYXMgYEBldmVudGVkYD9cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRXZlbnRlZChvYmo6IHVua25vd24pOiBib29sZWFuIHtcbiAgcmV0dXJuICEhKG9iaiBhcyB7IFtFVkVOVEVEXT86IGJvb2xlYW4gfSlbRVZFTlRFRF07XG59XG5cbi8qKlxuICogQSBjbGFzcyBkZWNvcmF0ZWQgYXMgYEBldmVudGVkYCBzaG91bGQgYWxzbyBpbXBsZW1lbnQgdGhlIGBFdmVudGVkYFxuICogaW50ZXJmYWNlLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBldmVudGVkLCBFdmVudGVkIH0gZnJvbSAnQG9yYml0L2NvcmUnO1xuICpcbiAqIEBldmVudGVkXG4gKiBjbGFzcyBTb3VyY2UgaW1wbGVtZW50cyBFdmVudGVkIHtcbiAqICAgLy8gLi4uIEV2ZW50ZWQgaW1wbGVtZW50YXRpb25cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV2ZW50ZWQ8RXZlbnQgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+IHtcbiAgb246IChldmVudDogRXZlbnQsIGxpc3RlbmVyOiBMaXN0ZW5lcikgPT4gKCkgPT4gdm9pZDtcbiAgb2ZmOiAoZXZlbnQ6IEV2ZW50LCBsaXN0ZW5lcj86IExpc3RlbmVyKSA9PiB2b2lkO1xuICBvbmU6IChldmVudDogRXZlbnQsIGxpc3RlbmVyOiBMaXN0ZW5lcikgPT4gKCkgPT4gdm9pZDtcbiAgZW1pdDogKGV2ZW50OiBFdmVudCwgLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkO1xuICBsaXN0ZW5lcnM6IChldmVudDogRXZlbnQpID0+IExpc3RlbmVyW107XG59XG5cbi8qKlxuICogTWFya3MgYSBjbGFzcyBhcyBldmVudGVkLlxuICpcbiAqIEFuIGV2ZW50ZWQgY2xhc3Mgc2hvdWxkIGFsc28gaW1wbGVtZW50IHRoZSBgRXZlbnRlZGAgaW50ZXJmYWNlLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBldmVudGVkLCBFdmVudGVkIH0gZnJvbSAnQG9yYml0L2NvcmUnO1xuICpcbiAqIEBldmVudGVkXG4gKiBjbGFzcyBTb3VyY2UgaW1wbGVtZW50cyBFdmVudGVkIHtcbiAqICAgLi4uXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBMaXN0ZW5lcnMgY2FuIHRoZW4gcmVnaXN0ZXIgdGhlbXNlbHZlcyBmb3IgcGFydGljdWxhciBldmVudHMgd2l0aCBgb25gOlxuICpcbiAqIGBgYHRzXG4gKiBsZXQgc291cmNlID0gbmV3IFNvdXJjZSgpO1xuICpcbiAqIGZ1bmN0aW9uIGxpc3RlbmVyMShtZXNzYWdlOiBzdHJpbmcpIHtcbiAqICAgY29uc29sZS5sb2coJ2xpc3RlbmVyMSBoZWFyZCAnICsgbWVzc2FnZSk7XG4gKiB9O1xuICogZnVuY3Rpb24gbGlzdGVuZXIyKG1lc3NhZ2U6IHN0cmluZykge1xuICogICBjb25zb2xlLmxvZygnbGlzdGVuZXIyIGhlYXJkICcgKyBtZXNzYWdlKTtcbiAqIH07XG4gKlxuICogc291cmNlLm9uKCdncmVldGluZycsIGxpc3RlbmVyMSk7XG4gKiBzb3VyY2Uub24oJ2dyZWV0aW5nJywgbGlzdGVuZXIyKTtcbiAqXG4gKiBldmVudGVkLmVtaXQoJ2dyZWV0aW5nJywgJ2hlbGxvJyk7IC8vIGxvZ3MgXCJsaXN0ZW5lcjEgaGVhcmQgaGVsbG9cIiBhbmRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICBcImxpc3RlbmVyMiBoZWFyZCBoZWxsb1wiXG4gKiBgYGBcbiAqXG4gKiBMaXN0ZW5lcnMgY2FuIGJlIHVucmVnaXN0ZXJlZCBmcm9tIGV2ZW50cyBhdCBhbnkgdGltZSB3aXRoIGBvZmZgOlxuICpcbiAqIGBgYHRzXG4gKiBzb3VyY2Uub2ZmKCdncmVldGluZycsIGxpc3RlbmVyMik7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV2ZW50ZWQoS2xhc3M6IHsgcHJvdG90eXBlOiBhbnkgfSk6IHZvaWQge1xuICBsZXQgcHJvdG8gPSBLbGFzcy5wcm90b3R5cGU7XG5cbiAgaWYgKGlzRXZlbnRlZChwcm90bykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBwcm90b1tFVkVOVEVEXSA9IHRydWU7XG5cbiAgcHJvdG8ub24gPSBmdW5jdGlvbiAoZXZlbnROYW1lOiBzdHJpbmcsIGxpc3RlbmVyOiBMaXN0ZW5lcik6ICgpID0+IHZvaWQge1xuICAgIHJldHVybiBub3RpZmllckZvckV2ZW50KHRoaXMsIGV2ZW50TmFtZSwgdHJ1ZSkuYWRkTGlzdGVuZXIobGlzdGVuZXIpO1xuICB9O1xuXG4gIHByb3RvLm9mZiA9IGZ1bmN0aW9uIChldmVudE5hbWU6IHN0cmluZywgbGlzdGVuZXI6IExpc3RlbmVyKSB7XG4gICAgY29uc3Qgbm90aWZpZXIgPSBub3RpZmllckZvckV2ZW50KHRoaXMsIGV2ZW50TmFtZSk7XG5cbiAgICBpZiAobm90aWZpZXIpIHtcbiAgICAgIGlmIChsaXN0ZW5lcikge1xuICAgICAgICBub3RpZmllci5yZW1vdmVMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZW1vdmVOb3RpZmllckZvckV2ZW50KHRoaXMsIGV2ZW50TmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHByb3RvLm9uZSA9IGZ1bmN0aW9uIChldmVudE5hbWU6IHN0cmluZywgbGlzdGVuZXI6IExpc3RlbmVyKTogKCkgPT4gdm9pZCB7XG4gICAgY29uc3Qgbm90aWZpZXIgPSBub3RpZmllckZvckV2ZW50KHRoaXMsIGV2ZW50TmFtZSwgdHJ1ZSk7XG5cbiAgICBjb25zdCBjYWxsT25jZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGxpc3RlbmVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICBub3RpZmllci5yZW1vdmVMaXN0ZW5lcihjYWxsT25jZSk7XG4gICAgfTtcblxuICAgIHJldHVybiBub3RpZmllci5hZGRMaXN0ZW5lcihjYWxsT25jZSk7XG4gIH07XG5cbiAgcHJvdG8uZW1pdCA9IGZ1bmN0aW9uIChldmVudE5hbWU6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKSB7XG4gICAgbGV0IG5vdGlmaWVyID0gbm90aWZpZXJGb3JFdmVudCh0aGlzLCBldmVudE5hbWUpO1xuXG4gICAgaWYgKG5vdGlmaWVyKSB7XG4gICAgICBub3RpZmllci5lbWl0LmFwcGx5KG5vdGlmaWVyLCBhcmdzKTtcbiAgICB9XG4gIH07XG5cbiAgcHJvdG8ubGlzdGVuZXJzID0gZnVuY3Rpb24gKGV2ZW50TmFtZTogc3RyaW5nKSB7XG4gICAgbGV0IG5vdGlmaWVyID0gbm90aWZpZXJGb3JFdmVudCh0aGlzLCBldmVudE5hbWUpO1xuICAgIHJldHVybiBub3RpZmllciA/IG5vdGlmaWVyLmxpc3RlbmVycyA6IFtdO1xuICB9O1xufVxuXG4vKipcbiAqIFNldHRsZSBhbnkgcHJvbWlzZXMgcmV0dXJuZWQgYnkgZXZlbnQgbGlzdGVuZXJzIGluIHNlcmllcy5cbiAqXG4gKiBSZXR1cm5zIGFuIGFycmF5IG9mIHJlc3VsdHMgKG9yIGB1bmRlZmluZWRgKSByZXR1cm5lZCBieSBsaXN0ZW5lcnMuXG4gKlxuICogSWYgYW55IGVycm9ycyBhcmUgZW5jb3VudGVyZWQgZHVyaW5nIHByb2Nlc3NpbmcsIHRoZXkgd2lsbCBiZSBjYXVnaHQgYW5kXG4gKiByZXR1cm5lZCB3aXRoIG90aGVyIHJlc3VsdHMuIEVycm9ycyB3aWxsIG5vdCBpbnRlcnJ1cHQgZnVydGhlciBwcm9jZXNzaW5nLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0dGxlSW5TZXJpZXMoXG4gIG9iajogRXZlbnRlZCxcbiAgZXZlbnROYW1lOiBzdHJpbmcsXG4gIC4uLmFyZ3M6IHVua25vd25bXVxuKTogUHJvbWlzZTx1bmtub3duW10+IHtcbiAgY29uc3QgbGlzdGVuZXJzID0gb2JqLmxpc3RlbmVycyhldmVudE5hbWUpO1xuICBjb25zdCByZXN1bHRzOiB1bmtub3duW10gPSBbXTtcblxuICBmb3IgKGxldCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0cy5wdXNoKGF3YWl0IGxpc3RlbmVyKC4uLmFyZ3MpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXN1bHRzLnB1c2goZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuXG4vKipcbiAqIEZ1bGZpbGxzIGFueSBwcm9taXNlcyByZXR1cm5lZCBieSBldmVudCBsaXN0ZW5lcnMgaW4gc2VyaWVzLlxuICpcbiAqIFJldHVybnMgYW4gYXJyYXkgb2YgcmVzdWx0cyAob3IgYHVuZGVmaW5lZGApIHJldHVybmVkIGJ5IGxpc3RlbmVycy5cbiAqXG4gKiBPbiBlcnJvciwgcHJvY2Vzc2luZyB3aWxsIHN0b3AgYW5kIHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aFxuICogdGhlIGVycm9yIHRoYXQgd2FzIGVuY291bnRlcmVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZnVsZmlsbEluU2VyaWVzKFxuICBvYmo6IEV2ZW50ZWQsXG4gIGV2ZW50TmFtZTogc3RyaW5nLFxuICAuLi5hcmdzOiB1bmtub3duW11cbik6IFByb21pc2U8dW5rbm93bltdPiB7XG4gIGNvbnN0IGxpc3RlbmVycyA9IG9iai5saXN0ZW5lcnMoZXZlbnROYW1lKTtcbiAgY29uc3QgcmVzdWx0czogdW5rbm93bltdID0gW107XG5cbiAgZm9yIChsZXQgbGlzdGVuZXIgb2YgbGlzdGVuZXJzKSB7XG4gICAgcmVzdWx0cy5wdXNoKGF3YWl0IGxpc3RlbmVyKC4uLmFyZ3MpKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHRzO1xufVxuXG4vKipcbiAqIEZ1bGZpbGxzIGFueSBwcm9taXNlcyByZXR1cm5lZCBieSBldmVudCBsaXN0ZW5lcnMgaW4gcGFyYWxsZWwsIHVzaW5nXG4gKiBgUHJvbWlzZS5hbGxgLlxuICpcbiAqIFJldHVybnMgYW4gYXJyYXkgb2YgcmVzdWx0cyAob3IgYHVuZGVmaW5lZGApIHJldHVybmVkIGJ5IGxpc3RlbmVycy5cbiAqXG4gKiBPbiBlcnJvciwgcHJvY2Vzc2luZyB3aWxsIHN0b3AgYW5kIHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aFxuICogdGhlIGVycm9yIHRoYXQgd2FzIGVuY291bnRlcmVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZnVsZmlsbEFsbChcbiAgb2JqOiBFdmVudGVkLFxuICBldmVudE5hbWU6IHN0cmluZyxcbiAgLi4uYXJnczogdW5rbm93bltdXG4pOiBQcm9taXNlPHVua25vd25bXT4ge1xuICBjb25zdCBsaXN0ZW5lcnMgPSBvYmoubGlzdGVuZXJzKGV2ZW50TmFtZSk7XG4gIGNvbnN0IHByb21pc2VzOiBQcm9taXNlPHVua25vd24+W10gPSBbXTtcblxuICBmb3IgKGxldCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICBwcm9taXNlcy5wdXNoKGxpc3RlbmVyKC4uLmFyZ3MpKTtcbiAgfVxuXG4gIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG59XG5cbmZ1bmN0aW9uIG5vdGlmaWVyRm9yRXZlbnQoXG4gIG9iamVjdDogYW55LFxuICBldmVudE5hbWU6IHN0cmluZyxcbiAgY3JlYXRlSWZVbmRlZmluZWQgPSBmYWxzZVxuKSB7XG4gIGlmIChvYmplY3QuX2V2ZW50ZWROb3RpZmllcnMgPT09IHVuZGVmaW5lZCkge1xuICAgIG9iamVjdC5fZXZlbnRlZE5vdGlmaWVycyA9IHt9O1xuICB9XG4gIGxldCBub3RpZmllciA9IG9iamVjdC5fZXZlbnRlZE5vdGlmaWVyc1tldmVudE5hbWVdO1xuICBpZiAoIW5vdGlmaWVyICYmIGNyZWF0ZUlmVW5kZWZpbmVkKSB7XG4gICAgbm90aWZpZXIgPSBvYmplY3QuX2V2ZW50ZWROb3RpZmllcnNbZXZlbnROYW1lXSA9IG5ldyBOb3RpZmllcigpO1xuICB9XG4gIHJldHVybiBub3RpZmllcjtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlTm90aWZpZXJGb3JFdmVudChvYmplY3Q6IGFueSwgZXZlbnROYW1lOiBzdHJpbmcpIHtcbiAgaWYgKG9iamVjdC5fZXZlbnRlZE5vdGlmaWVycyAmJiBvYmplY3QuX2V2ZW50ZWROb3RpZmllcnNbZXZlbnROYW1lXSkge1xuICAgIGRlbGV0ZSBvYmplY3QuX2V2ZW50ZWROb3RpZmllcnNbZXZlbnROYW1lXTtcbiAgfVxufVxuIl19