UNPKG

matrix-react-sdk

Version:
168 lines (135 loc) 18.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _lodash = require("lodash"); var _utils = require("matrix-js-sdk/src/utils"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * Simple search matcher that matches any results with the query string anywhere * in the search string. Returns matches in the order the query string appears * in the search key, earliest first, then in the order the search key appears * in the provided array of keys, then in the order the items appeared in the * source array. * * @param {Object[]} objects Initial list of objects. Equivalent to calling * setObjects() after construction * @param {Object} options Options object * @param {string[]} options.keys List of keys to use as indexes on the objects * @param {function[]} options.funcs List of functions that when called with the * object as an arg will return a string to use as an index */ class QueryMatcher /*:: <T extends Object>*/ { constructor(objects /*: T[]*/ , options /*: IOptions<T>*/ = { keys: [] }) { (0, _defineProperty2.default)(this, "_options", void 0); (0, _defineProperty2.default)(this, "_items", void 0); this._options = options; this.setObjects(objects); // By default, we remove any non-alphanumeric characters ([^A-Za-z0-9_]) from the // query and the value being queried before matching if (this._options.shouldMatchWordsOnly === undefined) { this._options.shouldMatchWordsOnly = true; } } setObjects(objects /*: T[]*/ ) { this._items = new Map(); for (const object of objects) { // Need to use unsafe coerce here because the objects can have any // type for their values. We assume that those values who's keys have // been specified will be string. Also, we cannot infer all the // types of the keys of the objects at compile. const keyValues = (0, _lodash.at)(object, this._options.keys); if (this._options.funcs) { for (const f of this._options.funcs) { const v = f(object); if (Array.isArray(v)) { keyValues.push(...v); } else { keyValues.push(v); } } } for (const [index, keyValue] of Object.entries(keyValues)) { if (!keyValue) continue; // skip falsy keyValues const key = this.processQuery(keyValue); if (!this._items.has(key)) { this._items.set(key, []); } this._items.get(key).push({ keyWeight: Number(index), object }); } } } match(query /*: string*/ , limit = -1) /*: T[]*/ { query = this.processQuery(query); if (this._options.shouldMatchWordsOnly) { query = query.replace(/[^\w]/g, ''); } if (query.length === 0) { return []; } const matches = []; // Iterate through the map & check each key. // ES6 Map iteration order is defined to be insertion order, so results // here will come out in the order they were put in. for (const [key, candidates] of this._items.entries()) { let resultKey = key; if (this._options.shouldMatchWordsOnly) { resultKey = resultKey.replace(/[^\w]/g, ''); } const index = resultKey.indexOf(query); if (index !== -1) { matches.push(...candidates.map(candidate => _objectSpread({ index }, candidate))); } } // Sort matches by where the query appeared in the search key, then by // where the matched key appeared in the provided array of keys. matches.sort((a, b) => { if (a.index < b.index) { return -1; } else if (a.index === b.index) { if (a.keyWeight < b.keyWeight) { return -1; } else if (a.keyWeight === b.keyWeight) { return 0; } } return 1; }); // Now map the keys to the result objects. Also remove any duplicates. const dedupped = (0, _lodash.uniq)(matches.map(match => match.object)); const maxLength = limit === -1 ? dedupped.length : limit; return dedupped.slice(0, maxLength); } processQuery(query /*: string*/ ) /*: string*/ { if (this._options.fuzzy !== false) { // lower case both the input and the output for consistency return (0, _utils.removeHiddenChars)(query.toLowerCase()).toLowerCase(); } return query.toLowerCase(); } } exports.default = QueryMatcher; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hdXRvY29tcGxldGUvUXVlcnlNYXRjaGVyLnRzIl0sIm5hbWVzIjpbIlF1ZXJ5TWF0Y2hlciIsImNvbnN0cnVjdG9yIiwib2JqZWN0cyIsIm9wdGlvbnMiLCJrZXlzIiwiX29wdGlvbnMiLCJzZXRPYmplY3RzIiwic2hvdWxkTWF0Y2hXb3Jkc09ubHkiLCJ1bmRlZmluZWQiLCJfaXRlbXMiLCJNYXAiLCJvYmplY3QiLCJrZXlWYWx1ZXMiLCJmdW5jcyIsImYiLCJ2IiwiQXJyYXkiLCJpc0FycmF5IiwicHVzaCIsImluZGV4Iiwia2V5VmFsdWUiLCJPYmplY3QiLCJlbnRyaWVzIiwia2V5IiwicHJvY2Vzc1F1ZXJ5IiwiaGFzIiwic2V0IiwiZ2V0Iiwia2V5V2VpZ2h0IiwiTnVtYmVyIiwibWF0Y2giLCJxdWVyeSIsImxpbWl0IiwicmVwbGFjZSIsImxlbmd0aCIsIm1hdGNoZXMiLCJjYW5kaWRhdGVzIiwicmVzdWx0S2V5IiwiaW5kZXhPZiIsIm1hcCIsImNhbmRpZGF0ZSIsInNvcnQiLCJhIiwiYiIsImRlZHVwcGVkIiwibWF4TGVuZ3RoIiwic2xpY2UiLCJmdXp6eSIsInRvTG93ZXJDYXNlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQWtCQTs7QUFDQTs7Ozs7O0FBVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLE1BQU1BO0FBQU47QUFBcUM7QUFJaERDLEVBQUFBLFdBQVcsQ0FBQ0M7QUFBRDtBQUFBLElBQWVDO0FBQW9CO0FBQUEsSUFBRztBQUFFQyxJQUFBQSxJQUFJLEVBQUU7QUFBUixHQUF0QyxFQUFvRDtBQUFBO0FBQUE7QUFDM0QsU0FBS0MsUUFBTCxHQUFnQkYsT0FBaEI7QUFFQSxTQUFLRyxVQUFMLENBQWdCSixPQUFoQixFQUgyRCxDQUszRDtBQUNBOztBQUNBLFFBQUksS0FBS0csUUFBTCxDQUFjRSxvQkFBZCxLQUF1Q0MsU0FBM0Ms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aUIsV0FBTixFQUFQO0FBQ0g7O0FBekcrQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAxNyBBdmlyYWwgRGFzZ3VwdGFcbkNvcHlyaWdodCAyMDE4IE1pY2hhZWwgVGVsYXR5bnNraSA8N3QzY2hndXlAZ21haWwuY29tPlxuQ29weXJpZ2h0IDIwMTggTmV3IFZlY3RvciBMdGRcblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4qL1xuXG5pbXBvcnQge2F0LCB1bmlxfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHtyZW1vdmVIaWRkZW5DaGFyc30gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL3V0aWxzXCI7XG5cbmludGVyZmFjZSBJT3B0aW9uczxUIGV4dGVuZHMge30+IHtcbiAgICBrZXlzOiBBcnJheTxzdHJpbmcgfCBrZXlvZiBUPjtcbiAgICBmdW5jcz86IEFycmF5PChUKSA9PiBzdHJpbmcgfCBzdHJpbmdbXT47XG4gICAgc2hvdWxkTWF0Y2hXb3Jkc09ubHk/OiBib29sZWFuO1xuICAgIC8vIHdoZXRoZXIgdG8gYXBwbHkgdW5ob21vZ2x5cGggYW5kIHN0cmlwIGRpYWNyaXRpY3MgdG8gZnV6eiB1cCB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byB0cnVlXG4gICAgZnV6enk/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFNpbXBsZSBzZWFyY2ggbWF0Y2hlciB0aGF0IG1hdGNoZXMgYW55IHJlc3VsdHMgd2l0aCB0aGUgcXVlcnkgc3RyaW5nIGFueXdoZXJlXG4gKiBpbiB0aGUgc2VhcmNoIHN0cmluZy4gUmV0dXJucyBtYXRjaGVzIGluIHRoZSBvcmRlciB0aGUgcXVlcnkgc3RyaW5nIGFwcGVhcnNcbiAqIGluIHRoZSBzZWFyY2gga2V5LCBlYXJsaWVzdCBmaXJzdCwgdGhlbiBpbiB0aGUgb3JkZXIgdGhlIHNlYXJjaCBrZXkgYXBwZWFyc1xuICogaW4gdGhlIHByb3ZpZGVkIGFycmF5IG9mIGtleXMsIHRoZW4gaW4gdGhlIG9yZGVyIHRoZSBpdGVtcyBhcHBlYXJlZCBpbiB0aGVcbiAqIHNvdXJjZSBhcnJheS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdFtdfSBvYmplY3RzIEluaXRpYWwgbGlzdCBvZiBvYmplY3RzLiBFcXVpdmFsZW50IHRvIGNhbGxpbmdcbiAqICAgICBzZXRPYmplY3RzKCkgYWZ0ZXIgY29uc3RydWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBPcHRpb25zIG9iamVjdFxuICogQHBhcmFtIHtzdHJpbmdbXX0gb3B0aW9ucy5rZXlzIExpc3Qgb2Yga2V5cyB0byB1c2UgYXMgaW5kZXhlcyBvbiB0aGUgb2JqZWN0c1xuICogQHBhcmFtIHtmdW5jdGlvbltdfSBvcHRpb25zLmZ1bmNzIExpc3Qgb2YgZnVuY3Rpb25zIHRoYXQgd2hlbiBjYWxsZWQgd2l0aCB0aGVcbiAqICAgICBvYmplY3QgYXMgYW4gYXJnIHdpbGwgcmV0dXJuIGEgc3RyaW5nIHRvIHVzZSBhcyBhbiBpbmRleFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBRdWVyeU1hdGNoZXI8VCBleHRlbmRzIE9iamVjdD4ge1xuICAgIHByaXZhdGUgX29wdGlvbnM6IElPcHRpb25zPFQ+O1xuICAgIHByaXZhdGUgX2l0ZW1zOiBNYXA8c3RyaW5nLCB7b2JqZWN0OiBULCBrZXlXZWlnaHQ6IG51bWJlcn1bXT47XG5cbiAgICBjb25zdHJ1Y3RvcihvYmplY3RzOiBUW10sIG9wdGlvbnM6IElPcHRpb25zPFQ+ID0geyBrZXlzOiBbXSB9KSB7XG4gICAgICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgICAgIHRoaXMuc2V0T2JqZWN0cyhvYmplY3RzKTtcblxuICAgICAgICAvLyBCeSBkZWZhdWx0LCB3ZSByZW1vdmUgYW55IG5vbi1hbHBoYW51bWVyaWMgY2hhcmFjdGVycyAoW15BLVphLXowLTlfXSkgZnJvbSB0aGVcbiAgICAgICAgLy8gcXVlcnkgYW5kIHRoZSB2YWx1ZSBiZWluZyBxdWVyaWVkIGJlZm9yZSBtYXRjaGluZ1xuICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5zaG91bGRNYXRjaFdvcmRzT25seSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zLnNob3VsZE1hdGNoV29yZHNPbmx5ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldE9iamVjdHMob2JqZWN0czogVFtdKSB7XG4gICAgICAgIHRoaXMuX2l0ZW1zID0gbmV3IE1hcCgpO1xuXG4gICAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIG9iamVjdHMpIHtcbiAgICAgICAgICAgIC8vIE5lZWQgdG8gdXNlIHVuc2FmZSBjb2VyY2UgaGVyZSBiZWNhdXNlIHRoZSBvYmplY3RzIGNhbiBoYXZlIGFueVxuICAgICAgICAgICAgLy8gdHlwZSBmb3IgdGhlaXIgdmFsdWVzLiBXZSBhc3N1bWUgdGhhdCB0aG9zZSB2YWx1ZXMgd2hvJ3Mga2V5cyBoYXZlXG4gICAgICAgICAgICAvLyBiZWVuIHNwZWNpZmllZCB3aWxsIGJlIHN0cmluZy4gQWxzbywgd2UgY2Fubm90IGluZmVyIGFsbCB0aGVcbiAgICAgICAgICAgIC8vIHR5cGVzIG9mIHRoZSBrZXlzIG9mIHRoZSBvYmplY3RzIGF0IGNvbXBpbGUuXG4gICAgICAgICAgICBjb25zdCBrZXlWYWx1ZXMgPSBhdDxzdHJpbmc+KDxhbnk+b2JqZWN0LCB0aGlzLl9vcHRpb25zLmtleXMpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5mdW5jcykge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZiBvZiB0aGlzLl9vcHRpb25zLmZ1bmNzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHYgPSBmKG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHYpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXlWYWx1ZXMucHVzaCguLi52KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleVZhbHVlcy5wdXNoKHYpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IFtpbmRleCwga2V5VmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGtleVZhbHVlcykpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWtleVZhbHVlKSBjb250aW51ZTsgLy8gc2tpcCBmYWxzeSBrZXlWYWx1ZXNcbiAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSB0aGlzLnByb2Nlc3NRdWVyeShrZXlWYWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9pdGVtcy5oYXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pdGVtcy5zZXQoa2V5LCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2l0ZW1zLmdldChrZXkpLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBrZXlXZWlnaHQ6IE51bWJlcihpbmRleCksXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG1hdGNoKHF1ZXJ5OiBzdHJpbmcsIGxpbWl0ID0gLTEpOiBUW10ge1xuICAgICAgICBxdWVyeSA9IHRoaXMucHJvY2Vzc1F1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMuc2hvdWxkTWF0Y2hXb3Jkc09ubHkpIHtcbiAgICAgICAgICAgIHF1ZXJ5ID0gcXVlcnkucmVwbGFjZSgvW15cXHddL2csICcnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocXVlcnkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWF0Y2hlcyA9IFtdO1xuICAgICAgICAvLyBJdGVyYXRlIHRocm91Z2ggdGhlIG1hcCAmIGNoZWNrIGVhY2gga2V5LlxuICAgICAgICAvLyBFUzYgTWFwIGl0ZXJhdGlvbiBvcmRlciBpcyBkZWZpbmVkIHRvIGJlIGluc2VydGlvbiBvcmRlciwgc28gcmVzdWx0c1xuICAgICAgICAvLyBoZXJlIHdpbGwgY29tZSBvdXQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBwdXQgaW4uXG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgY2FuZGlkYXRlc10gb2YgdGhpcy5faXRlbXMuZW50cmllcygpKSB7XG4gICAgICAgICAgICBsZXQgcmVzdWx0S2V5ID0ga2V5O1xuICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMuc2hvdWxkTWF0Y2hXb3Jkc09ubHkpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRLZXkgPSByZXN1bHRLZXkucmVwbGFjZSgvW15cXHddL2csICcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gcmVzdWx0S2V5LmluZGV4T2YocXVlcnkpO1xuICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIG1hdGNoZXMucHVzaChcbiAgICAgICAgICAgICAgICAgICAgLi4uY2FuZGlkYXRlcy5tYXAoKGNhbmRpZGF0ZSkgPT4gKHtpbmRleCwgLi4uY2FuZGlkYXRlfSkpLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb3J0IG1hdGNoZXMgYnkgd2hlcmUgdGhlIHF1ZXJ5IGFwcGVhcmVkIGluIHRoZSBzZWFyY2gga2V5LCB0aGVuIGJ5XG4gICAgICAgIC8vIHdoZXJlIHRoZSBtYXRjaGVkIGtleSBhcHBlYXJlZCBpbiB0aGUgcHJvdmlkZWQgYXJyYXkgb2Yga2V5cy5cbiAgICAgICAgbWF0Y2hlcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgICBpZiAoYS5pbmRleCA8IGIuaW5kZXgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGEuaW5kZXggPT09IGIuaW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoYS5rZXlXZWlnaHQgPCBiLmtleVdlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhLmtleVdlaWdodCA9PT0gYi5rZXlXZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTm93IG1hcCB0aGUga2V5cyB0byB0aGUgcmVzdWx0IG9iamVjdHMuIEFsc28gcmVtb3ZlIGFueSBkdXBsaWNhdGVzLlxuICAgICAgICBjb25zdCBkZWR1cHBlZCA9IHVuaXEobWF0Y2hlcy5tYXAoKG1hdGNoKSA9PiBtYXRjaC5vYmplY3QpKTtcbiAgICAgICAgY29uc3QgbWF4TGVuZ3RoID0gbGltaXQgPT09IC0xID8gZGVkdXBwZWQubGVuZ3RoIDogbGltaXQ7XG5cbiAgICAgICAgcmV0dXJuIGRlZHVwcGVkLnNsaWNlKDAsIG1heExlbmd0aCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwcm9jZXNzUXVlcnkocXVlcnk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGlmICh0aGlzLl9vcHRpb25zLmZ1enp5ICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgLy8gbG93ZXIgY2FzZSBib3RoIHRoZSBpbnB1dCBhbmQgdGhlIG91dHB1dCBmb3IgY29uc2lzdGVuY3lcbiAgICAgICAgICAgIHJldHVybiByZW1vdmVIaWRkZW5DaGFycyhxdWVyeS50b0xvd2VyQ2FzZSgpKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBxdWVyeS50b0xvd2VyQ2FzZSgpO1xuICAgIH1cbn1cbiJdfQ==