UNPKG

@orbit/core

Version:

Core library for Orbit - a flexible data access and synchronization layer.

156 lines 16.4 kB
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