'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // Thanks to https://github.com/mattyork/fuzzy var TributeSearch = function () { function TributeSearch(tribute) { _classCallCheck(this, TributeSearch); this.tribute = tribute; this.tribute.search = this; } _createClass(TributeSearch, [{ key: 'simpleFilter', value: function simpleFilter(pattern, array) { var _this = this; return array.filter(function (string) { return _this.test(pattern, string); }); } }, { key: 'test', value: function test(pattern, string) { return this.match(pattern, string) !== null; } }, { key: 'match', value: function match(pattern, string, opts) { opts = opts || {}; var patternIdx = 0, result = [], len = string.length, totalScore = 0, currScore = 0, pre = opts.pre || '', post = opts.post || '', compareString = opts.caseSensitive && string || string.toLowerCase(), ch = void 0, compareChar = void 0; pattern = opts.caseSensitive && pattern || pattern.toLowerCase(); var patternCache = this.traverse(compareString, pattern, 0, 0, []); if (!patternCache) { return null; } return { rendered: this.render(string, patternCache.cache, pre, post), score: patternCache.score }; } }, { key: 'traverse', value: function traverse(string, pattern, stringIndex, patternIndex, patternCache) { // if the pattern search at end if (pattern.length === patternIndex) { // calculate score and copy the cache containing the indices where it's found return { score: this.calculateScore(patternCache), cache: patternCache.slice() }; } // if string at end or remaining pattern > remaining string if (string.length === stringIndex || pattern.length - patternIndex > string.length - stringIndex) { return undefined; } var c = pattern[patternIndex]; var index = string.indexOf(c, stringIndex); var best = void 0, temp = void 0; while (index > -1) { patternCache.push(index); temp = this.traverse(string, pattern, index + 1, patternIndex + 1, patternCache); patternCache.pop(); // if downstream traversal failed, return best answer so far if (!temp) { return best; } if (!best || best.score < temp.score) { best = temp; } index = string.indexOf(c, index + 1); } return best; } }, { key: 'calculateScore', value: function calculateScore(patternCache) { var score = 0; var temp = 1; patternCache.forEach(function (index, i) { if (i > 0) { if (patternCache[i - 1] + 1 === index) { temp += temp + 1; } else { temp = 1; } } score += temp; }); return score; } }, { key: 'render', value: function render(string, indices, pre, post) { var rendered = string.substring(0, indices[0]); indices.forEach(function (index, i) { rendered += pre + string[index] + post + string.substring(index + 1, indices[i + 1] ? indices[i + 1] : string.length); }); return rendered; } }, { key: 'filter', value: function filter(pattern, arr, opts) { var _this2 = this; opts = opts || {}; return arr.reduce(function (prev, element, idx, arr) { var str = element; if (opts.extract) { str = opts.extract(element); if (!str) { // take care of undefineds / nulls / etc. str = ''; } } var rendered = _this2.match(pattern, str, opts); if (rendered != null) { prev[prev.length] = { string: rendered.rendered, score: rendered.score, index: idx, original: element }; } return prev; }, []).sort(function (a, b) { var compare = b.score - a.score; if (compare) return compare; return a.index - b.index; }); } }]); return TributeSearch; }(); exports.default = TributeSearch; module.exports = exports['default'];