1
0
mirror of https://github.com/nextapps-de/flexsearch.git synced 2025-09-01 01:51:57 +02:00
This commit is contained in:
Thomas Wilkerling
2019-01-24 18:18:20 +01:00
parent 779905f262
commit 8ccc4f01d9
14 changed files with 2737 additions and 2354 deletions

9
.gitignore vendored
View File

@@ -1,3 +1,10 @@
node_modules
.idea
.nyc_output
.db
coverage
perf
node_modules
!*.keep
src
tmp
log

438
README.md
View File

@@ -15,53 +15,343 @@
<h1></h1>
<h3>World's fastest and most memory efficient full text search library with zero dependencies.</h3>
When it comes to raw search speed <a href="https://jsperf.com/compare-search-libraries" target="_blank">FlexSearch outperforms every single searching library out there</a> and also provides flexible search capabilities like multi-word matching, phonetic transformations or partial matching.
When it comes to raw search speed <a href="https://rawgit.com/nextapps-de/flexsearch/master/test/benchmark.html" target="_blank">FlexSearch outperforms every single searching library out there</a> and also provides flexible search capabilities like multi-word matching, phonetic transformations or partial matching.
It also has the <a href="#memory">most memory-efficient index</a>. Keep in mind that updating and/or removing existing items from the index has a significant cost. When your index needs to be updated continuously then <a href="bulksearch/" target="_blank">BulkSearch</a> may be a better choice.
FlexSearch also provides you a non-blocking asynchronous processing model as well as web workers to perform any updates or queries on the index in parallel through dedicated balanced threads.
<a href="#installation">Installation Guide</a> &ensp;&bull;&ensp; <a href="#api">API Reference</a> &ensp;&bull;&ensp; <a href="#profiles">Example Options</a> &ensp;&bull;&ensp; <a href="#builds">Custom Builds</a>
Comparison:
- <a href="https://jsperf.com/compare-search-libraries" target="_blank">Library Query Benchmarks</a>
- <a href="https://rawgit.com/nextapps-de/flexsearch/master/test/matching.html" target="_blank">Library Relevance Scoring</a>
- <a href="#consumption">Library Memory Consumption</a>
Supported Platforms:
- Browser
- Node.js
Get Latest (Stable Release):
<table>
<tr></tr>
<tr>
<td>Build</td>
<td>File</td>
<td>CDN</td>
</tr>
<tr>
<td>flexsearch.min.js</td>
<td><a href="https://github.com/nextapps-de/flexsearch/raw/master/flexsearch.min.js" target="_blank">Download</a></td>
<td><a href="https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@master/flexsearch.min.js" target="_blank">https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@master/flexsearch.min.js</a></td>
</tr>
<tr></tr>
<tr>
<td>flexsearch.light.js</td>
<td><a href="https://github.com/nextapps-de/flexsearch/raw/master/flexsearch.light.js" target="_blank">Download</a></td>
<td><a href="https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@master/flexsearch.light.js" target="_blank">https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@master/flexsearch.light.js</a></td>
</tr>
<tr></tr>
<tr>
<td>flexsearch.compact.js</td>
<td><a href="https://github.com/nextapps-de/flexsearch/raw/master/flexsearch.compact.js" target="_blank">Download</a></td>
<td><a href="https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@master/flexsearch.compact.js" target="_blank">https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@master/flexsearch.compact.js</a></td>
</tr>
<tr></tr>
<tr>
<td>flexsearch.custom.js</td>
<td><a href="#builds">Custom Build</a></td>
<td></td>
</tr>
</table>
All Features:
<ul>
<li><a href="#webworker">Web-Worker Sharding</a> (not available in Node.js)</li>
<li><a href="#contextual">Contextual Indexes</a></li>
<li>Partial Matching</li>
<li>Multi-Phrase Search</li>
<li><a href="#phonetic">Phonetic Mathching</a></li>
<li>Relevance-based Scoring</li>
<li>Auto-Balanced Cache by Popularity</li>
<li>Suggestions (Results)</li>
<li>Asynchronous Processing & Concurrency Control</li>
<li>Customizable: Matcher, Encoder, Tokenizer, Stemmer, Filter</li>
</ul>
These features are not available in the 50% smaller <a href="flexsearch.light.js">light version</a>:
- WebWorker
- Asynchronous Processing
- Cache
- Built-in encoders except 'balance' and 'icase' (you can still pass in customs) <!--- Built-in stemmer and filter (you can still pass in customs)-->
- Debug logging
- Methods: _index.info()_
The light version is just available as compiled version (<a href="flexsearch.light.js">flexsearch.light.js</a>).
<table>
<tr></tr>
<tr>
<td>Feature</td>
<td>flexsearch.min.js</td>
<td>flexsearch.compact.js</td>
<td>flexsearch.light.js</td>
</tr>
<tr>
<td>
<a href="#webworker">Web-Worker Sharding</a> (not available in Node.js)
</td>
<td>x</td>
<td>x</td>
<td>-</td>
</tr>
<tr></tr>
<tr>
<td>
<a href="#contextual">Contextual Indexes</a>
</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
<tr></tr>
<tr>
<td>
Partial Matching
</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
<tr></tr>
<tr>
<td>
Multi-Phrase Search
</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
<tr></tr>
<tr>
<td>
Relevance-based Scoring
</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
<tr></tr>
<tr>
<td>
Auto-Balanced Cache by Popularity
</td>
<td>x</td>
<td>x</td>
<td>-</td>
</tr>
<tr></tr>
<tr>
<td>
Suggestions (Results)
</td>
<td>x</td>
<td>x</td>
<td>-</td>
</tr>
<tr></tr>
<tr>
<td>
Asynchronous Processing & Concurrency Control
</td>
<td>x</td>
<td>x</td>
<td>-</td>
</tr>
<tr></tr>
<tr>
<td>
<a href="#phonetic">Phonetic Mathching</a>
</td>
<td>x</td>
<td>x</td>
<td>-</td>
</tr>
<tr></tr>
<tr>
<td>
Customizable: Matcher, Encoder, Tokenizer, Stemmer, Filter
</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
<tr>
<td>File Size (gzip)</td>
<td>6.7 kb</td>
<td>4.5 kb</td>
<td>1.9 kb</td>
</tr>
</table>
> It is also pretty simple to make <a href="#builds">Custom Builds</a>
<a name="contextual"></a>
<a name="compare" id="compare"></a>
#### Benchmark Ranking
- Library Comparison: <a href="https://rawgit.com/nextapps-de/flexsearch/master/test/benchmark.html" target="_blank">Benchmark "Gulliver's Travels"</a>
- Library Comparison: <a href="https://rawgit.com/nextapps-de/flexsearch/master/test/matching.html" target="_blank">Relevance Scoring</a>
- Library Comparison: <a href="#consumption">Memory Consumption</a>
__Query Test: "Gulliver's Travels"__
<table>
<tr></tr>
<tr>
<td align="left">Rank</td>
<td align="left">Library Name</td>
<td align="left">Library Version</td>
<td align="left">Library Size</td>
<td align="left">Operations per second</td>
</tr>
<tr>
<td>1</td>
<td>FlexSearch</td>
<td>0.3.0</td>
<td>2.9 kb</td>
<td><b>316336</b></td>
</tr>
<tr></tr>
<tr>
<td>2</td>
<td>Wade</td>
<td>0.3.3</td>
<td>1.6 kb</td>
<td><b>1524</b></td>
</tr>
<tr></tr>
<tr>
<td>3</td>
<td>JS Search</td>
<td>1.4.2</td>
<td>3.8 kb</td>
<td><b>739</b></td>
</tr>
<tr></tr>
<tr>
<td>4</td>
<td>JSii</td>
<td>1.0</td>
<td>3.9 kb</td>
<td><b>544</b></td>
</tr>
<tr></tr>
<tr>
<td>5</td>
<td>Lunr.js</td>
<td>2.3.5</td>
<td>8.8 kb</td>
<td><b>310</b></td>
</tr>
<tr></tr>
<tr>
<td>6</td>
<td>Elasticlunr.js</td>
<td>0.9.6</td>
<td>5.6 kb</td>
<td><b>286</b></td>
</tr>
<tr></tr>
<tr>
<td>7</td>
<td>BulkSearch</td>
<td>0.1.3</td>
<td>3.1 kb</td>
<td><b>265</b></td>
</tr>
<tr></tr>
<tr>
<td>8</td>
<td>bm25</td>
<td>0.2</td>
<td>3.5 kb</td>
<td><b>72</b></td>
</tr>
<tr></tr>
<tr>
<td>9</td>
<td>Fuse</td>
<td>3.3.0</td>
<td>3.7 kb</td>
<td><b>1</b></td>
</tr>
</table>
__Memory Test: "Gulliver's Travels"__
<table>
<tr></tr>
<tr>
<td align="left">Rank</td>
<td align="left">Library Name</td>
<td align="left">Library Version</td>
<td align="left">Index Size <a href="#notes">*</a></td>
<td align="left">Memory Allocation <a href="#notes">**</a></td>
</tr>
<tr>
<td>1</td>
<td>FlexSearch</td>
<td>0.3.0</td>
<td>1.33 Mb</td>
<td>20.31 kb</td>
</tr>
<tr></tr>
<tr>
<td>2</td>
<td>Wade</td>
<td>0.3.3</td>
<td>3.18 Mb</td>
<td>68.53 kb</td>
</tr>
<tr></tr>
<tr>
<td>3</td>
<td>JS Search</td>
<td>1.4.2</td>
<td>36.9 Mb</td>
<td>53.0 kb</td>
</tr>
<tr></tr>
<tr>
<td>4</td>
<td>JSii</td>
<td>1.0</td>
<td>8.9 Mb</td>
<td>81.03 kb</td>
</tr>
<tr></tr>
<tr>
<td>5</td>
<td>Lunr.js</td>
<td>2.3.5</td>
<td>16.24 Mb</td>
<td>84.73 kb</td>
</tr>
<tr></tr>
<tr>
<td>6</td>
<td>Elasticlunr.js</td>
<td>0.9.6</td>
<td>11.83 Mb</td>
<td>68.69 kb</td>
</tr>
<tr></tr>
<tr>
<td>7</td>
<td>BulkSearch</td>
<td>0.1.3</td>
<td>1.53 Mb</td>
<td>984.30 kb</td>
</tr>
<tr></tr>
<tr>
<td>8</td>
<td>bm25</td>
<td>0.2</td>
<td>6.95 Mb</td>
<td>137.88 kb</td>
</tr>
<tr></tr>
<tr>
<td>9</td>
<td>Fuse</td>
<td>3.3.0</td>
<td>0.22 Mb</td>
<td>156.46 kb</td>
</tr>
</table>
<a name="notes" id="notes"></a>
_* Index Size: The size of memory the index requires_<br>
_** Memory Allocation: The amount of memory which was additionally allocated during a row of 10 queries_
Library Comparison: <a href="https://rawgit.com/nextapps-de/flexsearch/master/test/benchmark.html" target="_blank">Benchmark "Gulliver's Travels"</a>
<a name="contextual"></a>
#### Contextual Search
FlexSearch introduce a new scoring mechanism called __Contextual Search__ which was invented by Thomas Wilkerling, the author of this library. A Contextual Search <a href="https://jsperf.com/compare-search-libraries" target="_blank">incredibly boost up queries to a complete new level</a>.
FlexSearch introduce a new scoring mechanism called __Contextual Search__ which was invented by Thomas Wilkerling, the author of this library. A Contextual Search <a href="https://rawgit.com/nextapps-de/flexsearch/master/test/benchmark.html" target="_blank">incredibly boost up queries to a complete new level</a> but also requires a lot of additionally memory.
The basic idea of this concept is to limit relevance by its context instead of calculating relevance through the whole (unlimited) distance.
Imagine you add a text block of some sentences to an index ID. Assuming the query includes a combination of first and last word from this text block, are they really relevant to each other?
In this way contextual search <a href="https://rawgit.com/nextapps-de/flexsearch/master/test/matching.html" target="_blank">also improves the results of relevance-based queries</a> on large amount of text data.
@@ -226,7 +516,7 @@ Index methods:
- <a href="#index.search">Index.__search__(\<options\>)</a>
- <a href="#index.update">Index.__update__(id, string)</a>
- <a href="#index.remove">Index.__remove__(id)</a>
- <a href="#index.reset">Index.__reset__()</a>
- <a href="#index.clear">Index.__clear__()</a>
- <a href="#index.destroy">Index.__destroy__()</a>
- <a href="#index.init">Index.__init__(\<options\>)</a>
- <a href="#index.info">Index.__info__()</a>
@@ -352,6 +642,7 @@ When suggestion is enabled all results will be filled up (until limit, default 1
```js
index.update(10025, "Road Runner");
```
<a name="index.remove"></a>
#### Remove item to the index
@@ -360,18 +651,20 @@ index.update(10025, "Road Runner");
```js
index.remove(10025);
```
<a name="index.reset"></a>
<a name="index.clear"></a>
#### Reset index
```js
index.reset();
index.clear();
```
<a name="index.destroy"></a>
#### Destroy the index
```js
index.destroy();
```
<a name="index.init"></a>
#### Re-Initialize index
@@ -1175,6 +1468,11 @@ Full Build:
npm run build
```
Compact Build:
```bash
npm run build-compact
```
Light Build:
```bash
npm run build-light
@@ -1190,27 +1488,69 @@ Custom Build:
npm run build-custom SUPPORT_WORKER=true SUPPORT_ASYNC=true
```
Supported flags:
- SUPPORT_DEBUG
- SUPPORT_WORKER
- SUPPORT_CACHE
- SUPPORT_ASYNC
- SUPPORT_BUILTINS (built-in encoders)
Supported language flags (includes stemmer and filter):
- SUPPORT_LANG_EN
- SUPPORT_LANG_DE
Alternatively you can also use:
```bash
node compile SUPPORT_WORKER=true
```
The custom build was saved to flexsearch.custom.js
> The custom build will be saved to flexsearch.custom.xxxxx.js (the "xxxxx" is a hash based on the used build flags).
__Supported Build Flags__
<table>
<tr></tr>
<tr>
<td align="left">Flag</td>
<td align="left">Values</td>
</tr>
<tr>
<td>SUPPORT_DEBUG</td>
<td>true, false</td>
</tr>
<tr></tr>
<tr>
<td>SUPPORT_WORKER</td>
<td>true, false</td>
</tr>
<tr></tr>
<tr>
<td>SUPPORT_CACHE</td>
<td>true, false</td>
</tr>
<tr></tr>
<tr>
<td>SUPPORT_ASYNC</td>
<td>true, false</td>
</tr>
<tr></tr>
<tr>
<td>SUPPORT_BUILTINS (built-in encoders)</td>
<td>true, false</td>
</tr>
<tr>
<td><br><b>Language Flags </b>(includes stemmer and filter)</td>
<td></td>
</tr>
<tr>
<td>SUPPORT_LANG_EN</td>
<td>true, false</td>
</tr>
<tr></tr>
<tr>
<td><a>SUPPORT_LANG_DE</td>
<td>true, false</td>
</tr>
<tr>
<td><br><b>Compiler Flags</b></td>
<td></td>
</tr>
<tr>
<td>LANGUAGE_OUT<br><br><br><br><br><br><br><br></td>
<td>ECMASCRIPT3<br>ECMASCRIPT5<br>ECMASCRIPT5_STRICT<br>ECMASCRIPT6<br>ECMASCRIPT6_STRICT<br>ECMASCRIPT_2015<br>ECMASCRIPT_2017<br>STABLE</td>
</tr>
</table>
---
Copyright 2018 Thomas Wilkerling<br>
Copyright 2019 Nextapps GmbH<br>
Released under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">Apache 2.0 License</a><br>

View File

@@ -11,6 +11,9 @@ console.log("Start build .....");
fs.existsSync("log") || fs.mkdirSync("log");
var flag_str = "";
var language_out;
var options = (function(argv){
var arr = {};
@@ -22,9 +25,18 @@ var options = (function(argv){
index = val.split('=');
val = index[1];
index = index[0];
index = index[0].toUpperCase();
arr[index] = val;
if(index === "LANGUAGE_OUT"){
language_out = val;
}
else{
flag_str += " --define='" + index + "=" + val + "'";
arr[index] = val;
}
if(count > 3) console.log(index + ': ' + val);
}
@@ -58,25 +70,39 @@ var parameter = (function(opt){
//jscomp_error: "strictCheckTypes",
generate_exports: true,
export_local_property_definitions: true,
language_in: "ECMASCRIPT5_STRICT",
language_out: "ECMASCRIPT5_STRICT",
language_in: "ECMASCRIPT6_STRICT",
language_out: language_out || "ECMASCRIPT5_STRICT",
process_closure_primitives: true,
summary_detail_level: 3,
warning_level: "VERBOSE",
emit_use_strict: options['RELEASE'] !== 'lang',
emit_use_strict: options["RELEASE"] !== "lang",
output_manifest: "log/manifest.log",
output_module_dependencies: "log/module_dependencies.log",
property_renaming_report: "log/renaming_report.log"
//formatting: "PRETTY_PRINT"
});
if(options['RELEASE'] === 'lang'){
var release = options["RELEASE"];
if(release === "demo"){
options['RELEASE'] = "custom";
}
var custom = (!options["RELEASE"] || (options["RELEASE"] === "custom"));
if(custom){
options["RELEASE"] = "custom." + hashCode(parameter + flag_str);
}
if(release === "lang"){
for(var i = 0; i < supported_lang.length; i++){
(function(i){
exec("java -jar node_modules/google-closure-compiler/compiler.jar" + parameter + " --define='SUPPORT_LANG_" + supported_lang[i].toUpperCase() + "=true' --js='lang/" + supported_lang[i] + ".js' --js_output_file='lang/" + supported_lang[i] + ".min.js' && exit 0", function(){
exec("java -jar node_modules/google-closure-compiler-java/compiler.jar" + parameter + " --js='lang/" + supported_lang[i] + ".js'" + flag_str + " --js_output_file='lang/" + supported_lang[i] + ".min.js' && exit 0", function(){
console.log("Build Complete: " + supported_lang[i] + ".min.js");
});
@@ -86,12 +112,44 @@ if(options['RELEASE'] === 'lang'){
}
else{
exec("java -jar node_modules/google-closure-compiler/compiler.jar" + parameter + " --define='SUPPORT_DEBUG=" + (options['SUPPORT_DEBUG'] || 'false') + "' --define='SUPPORT_WORKER=" + (options['SUPPORT_WORKER'] || 'false') + "' --define='SUPPORT_BUILTINS=" + (options['SUPPORT_BUILTINS'] || 'false') + "' --define='SUPPORT_CACHE=" + (options['SUPPORT_CACHE'] || 'false') + "' --define='SUPPORT_ASYNC=" + (options['SUPPORT_ASYNC'] || 'false') + "' --define='SUPPORT_LANG_EN=" + (options['SUPPORT_LANG_EN'] || 'false') + "' --define='SUPPORT_LANG_DE=" + (options['SUPPORT_LANG_DE'] || 'false') + "' --js='flexsearch.js' --js='lang/**.js' --js='!lang/**.min.js' --js_output_file='flexsearch." + (options['RELEASE'] || 'custom') + ".js' && exit 0", function(){
exec("java -jar node_modules/google-closure-compiler-java/compiler.jar" + parameter + "' --js='flexsearch.js' --js='lang/**.js' --js='!lang/**.min.js'" + flag_str + " --js_output_file='flexsearch." + (options["RELEASE"] || "custom") + ".js' && exit 0", function(){
console.log("Build Complete: flexsearch." + (options['RELEASE'] || 'custom') + ".js");
var filename = "flexsearch." + (options["RELEASE"] || "custom") + ".js";
console.log("Build Complete: " + filename);
if(release === "demo"){
//fs.existsSync("dist/") || fs.mkdirSync("dist/");
//fs.existsSync("dist/latest") || fs.mkdirSync("dist/latest");
fs.copyFileSync(filename, "docs/" + filename);
//fs.copyFileSync(filename, "dist/latest/" + filename);
fs.unlinkSync(filename);
}
});
}
function hashCode(str) {
var hash = 0, i, chr;
if(str.length === 0){
return hash;
}
for(i = 0; i < str.length; i++){
chr = str.charCodeAt(i);
hash = (hash << 5) - hash + chr;
}
hash = Math.abs(hash) >> 0;
return hash.toString(16).substring(0, 5);
}
function exec(prompt, callback){
var child = child_process.exec(prompt, function(err, stdout, stderr){

3
data/gulliver.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,682 +1,24 @@
/*
FlexSearch v0.2.68
Copyright 2018 Thomas Wilkerling
FlexSearch v0.3.0
Copyright 2019 Nextapps GmbH
Author: Thomas Wilkerling
Released under the Apache 2.0 Licence
https://github.com/nextapps-de/flexsearch
*/
'use strict';
(function(){
provide("FlexSearch", function factory(){
var defaults = {
encode: "icase",
mode: "forward",
suggest: false,
cache: false,
async: false,
worker: false,
threshold: 0,
depth: 0
};
var profiles = {
"memory": {encode: "extra", mode: "strict", threshold: 7},
"speed": {encode: "icase", mode: "strict", threshold: 7, depth: 2},
"match": {encode: "extra", mode: "full"},
"score": {encode: "extra", mode: "strict", threshold: 5, depth: 4},
"balance": {encode: "balance", mode: "ngram", threshold: 6, depth: 3},
"fastest": {encode: "icase", mode: "strict", threshold: 9, depth: 1}
};
var globalMatcher = [];
var idCounter = 0;
var regexSplit = regex("[ -/]");
var filter = createObject();
var stemmer = createObject();
var indexBlacklist = function(){
var array = Object.getOwnPropertyNames({}.__proto__);
var map = createObject();
for(var i = 0; i < array.length; i++){
map[array[i]] = 1;
}
return map;
}();
function FlexSearch(options){
if(typeof options === "string" && !indexBlacklist[options]){
options = profiles[options];
}
options || (options = defaults);
this.id = options["id"] || idCounter++;
this.init(options);
registerProperty(this, "index", function(){
return this._ids;
});
registerProperty(this, "length", function(){
return Object.keys(this._ids).length;
});
}
FlexSearch.new = function(options){
return new this(options);
};
FlexSearch.create = function(options){
return FlexSearch.new(options);
};
FlexSearch.registerMatcher = function(matcher){
for(var key in matcher){
if(matcher.hasOwnProperty(key)){
globalMatcher.push(regex(key), matcher[key]);
}
}
return this;
};
FlexSearch.registerEncoder = function(name, encoder){
if(!indexBlacklist[name]){
globalEncoder[name] = encoder;
}
return this;
};
FlexSearch.registerLanguage = function(lang, languagePack){
if(!indexBlacklist[lang]){
filter[lang] = languagePack["filter"];
stemmer[lang] = languagePack["stemmer"];
}
return this;
};
FlexSearch.encode = function(name, value){
if(indexBlacklist[name]){
return value;
}
else{
return globalEncoder[name].call(globalEncoder, value);
}
};
FlexSearch.prototype.init = function(options){
this._matcher = [];
options || (options = defaults);
var custom = options["profile"];
var profile = custom && !indexBlacklist[custom] ? profiles[custom] : createObject();
this.mode = options["mode"] || profile.mode || this.mode || defaults.mode;
this.threshold = options["threshold"] || profile.threshold || this.threshold || defaults.threshold;
this.depth = options["depth"] || profile.depth || this.depth || defaults.depth;
this.suggest = options["suggest"] || this.suggest || defaults.suggest;
custom = options["encode"] || profile.encode;
this.encoder = custom && !indexBlacklist[custom] && globalEncoder[custom] || (typeof custom === "function" ? custom : this.encoder || false);
if(custom = options["matcher"]){
this.addMatcher(custom);
}
if((custom = options["filter"]) && !indexBlacklist[custom]){
this.filter = initFilter(filter[custom] || custom, this.encoder);
}
if((custom = options["stemmer"]) && !indexBlacklist[custom]){
this.stemmer = initStemmer(stemmer[custom] || custom, this.encoder);
}
this._map = createObject(10);
this._ctx = createObject();
this._ids = createObject();
this._stack = createObject();
this._stackKeys = [];
this._timer = null;
return this;
};
FlexSearch.prototype.encode = function(value){
if(value && globalMatcher.length){
value = replace(value, globalMatcher);
}
if(value && this._matcher.length){
value = replace(value, this._matcher);
}
if(value && this.encoder){
value = this.encoder.call(globalEncoder, value);
}
if(value && this.stemmer){
value = replace(value, this.stemmer);
}
return value;
};
FlexSearch.prototype.addMatcher = function(custom){
var matcher = this._matcher;
for(var key in custom){
if(custom.hasOwnProperty(key)){
matcher.push(regex(key), custom[key]);
}
}
return this;
};
FlexSearch.prototype.add = function(id, content, _skipUpdate){
if(typeof content === "string" && content && (id && !indexBlacklist[id] || id === 0)){
if(this._ids[id] && !_skipUpdate){
this.update(id, content);
}
else{
content = this.encode(content);
if(!content.length){
return this;
}
var tokenizer = this.mode;
var words = typeof tokenizer === "function" ? tokenizer(content) : tokenizer === "ngram" ? ngram(content) : content.split(regexSplit);
var dupes = createObject();
dupes["_ctx"] = createObject();
var threshold = this.threshold;
var depth = this.depth;
var map = this._map;
var wordLength = words.length;
for(var i = 0; i < wordLength; i++){
var value = words[i];
if(value){
var length = value.length;
var contextScore = (wordLength - i) / wordLength;
switch(tokenizer){
case "reverse":
case "both":
var tmp = "";
for(var a = length - 1; a >= 1; a--){
tmp = value[a] + tmp;
addIndex(map, dupes, tmp, id, (length - a) / length, contextScore, threshold);
}
case "forward":
var tmp = "";
for(var a = 0; a < length; a++){
tmp += value[a];
addIndex(map, dupes, tmp, id, 1, contextScore, threshold);
}
break;
case "full":
var tmp = "";
for(var x = 0; x < length; x++){
var partialScore = (length - x) / length;
for(var y = length; y > x; y--){
tmp = value.substring(x, y);
addIndex(map, dupes, tmp, id, partialScore, contextScore, threshold);
}
}
break;
case "strict":
case "ngram":
default:
var score = addIndex(map, dupes, value, id, 1, contextScore, threshold);
if(depth && wordLength > 1 && score >= threshold){
var ctxDupes = dupes["_ctx"][value] || (dupes["_ctx"][value] = createObject());
var ctxTmp = this._ctx[value] || (this._ctx[value] = createObject(10));
var x = i - depth;
var y = i + depth + 1;
if(x < 0){
x = 0;
}
if(y > wordLength){
y = wordLength;
}
for(; x < y; x++){
if(x !== i){
addIndex(ctxTmp, ctxDupes, words[x], id, 0, 10 - (x < i ? i - x : x - i), threshold);
}
}
}
break;
}
}
}
this._ids[id] = "1";
}
}
return this;
};
FlexSearch.prototype.update = function(id, content){
if(this._ids[id] && content && typeof content === "string"){
this.remove(id);
this.add(id, content, true);
}
return this;
};
FlexSearch.prototype.remove = function(id){
if(this._ids[id] && !indexBlacklist[id]){
for(var z = 0; z < 10; z++){
removeIndex(this._map[z], id);
}
if(this.depth){
removeIndex(this._ctx, id);
}
delete this._ids[id];
}
return this;
};
FlexSearch.prototype.search = function(query, limit, callback){
var threshold;
var result = [];
if(query && typeof query === "object"){
callback = query["callback"] || limit;
limit = query["limit"];
threshold = query["threshold"];
query = query["query"];
}
threshold = (threshold || this.threshold || 0) | 0;
if(typeof limit === "function"){
callback = limit;
limit = 1000;
}
else{
limit || (limit = 1000);
}
if(callback){
var self = this;
queue(function(){
callback(self.search(query, limit));
self = null;
}, 1, "search-" + this.id);
return null;
}
if(!query || typeof query !== "string"){
return result;
}
var _query = query;
_query = this.encode(_query);
if(!_query.length){
return result;
}
var tokenizer = this.mode;
var words = typeof tokenizer === "function" ? tokenizer(_query) : tokenizer === "ngram" ? ngram(_query) : _query.split(regexSplit);
var length = words.length;
var found = true;
var check = [];
var checkWords = createObject();
if(length > 1){
if(this.depth){
var useContextual = true;
var ctxRoot = words[0];
checkWords[ctxRoot] = "1";
}
else{
words.sort(sortByLengthDown);
}
}
var ctxMap;
if(!useContextual || (ctxMap = this._ctx)[ctxRoot]){
for(var a = useContextual ? 1 : 0; a < length; a++){
var value = words[a];
if(value && !checkWords[value]){
var map;
var mapFound = false;
var mapCheck = [];
var count = 0;
for(var z = 9; z >= threshold; z--){
map = (useContextual ? ctxMap[ctxRoot] : this._map)[z][value];
if(map){
mapCheck[count++] = map;
mapFound = true;
}
}
if(!mapFound){
if(!this.suggest){
found = false;
break;
}
}
else{
check[check.length] = count > 1 ? check.concat.apply([], mapCheck) : mapCheck[0];
}
checkWords[value] = "1";
}
ctxRoot = value;
}
}
else{
found = false;
}
if(found){
result = intersect(check, limit, this.suggest);
}
return result;
};
FlexSearch.prototype.reset = function(){
this.destroy();
return this.init();
};
FlexSearch.prototype.destroy = function(){
this.filter = this.stemmer = this._scores = this._map = this._ctx = this._ids = this._stack = this._stackKeys = null;
return this;
};
var globalEncoderBalance = function(){
var regexWhitespace = regex("\\s\\s+"), regexStrip = regex("[^a-z0-9 ]"), regexSpace = regex("[-/]"),
regexVowel = regex("[aeiouy]");
var regexPairs = [regexSpace, " ", regexStrip, "", regexWhitespace, " "];
return function(value){
return collapseRepeatingChars(replace(value.toLowerCase(), regexPairs));
};
}();
var globalEncoderIcase = function(value){
return value.toLowerCase();
};
var globalEncoder = Object.create({
"icase": globalEncoderIcase, "simple": function(){
var regexWhitespace = regex("\\s\\s+"), regexStrip = regex("[^a-z0-9 ]"), regexSpace = regex("[-/]"),
regexA = regex("[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]"),
regexE = regex("[\u00e8\u00e9\u00ea\u00eb]"), regexI = regex("[\u00ec\u00ed\u00ee\u00ef]"),
regexO = regex("[\u00f2\u00f3\u00f4\u00f5\u00f6\u0151]"),
regexU = regex("[\u00f9\u00fa\u00fb\u00fc\u0171]"), regexY = regex("[\u00fd\u0177\u00ff]"),
regexN = regex("\u00f1"), regexC = regex("\u00e7"), regexS = regex("\u00df"),
regexAnd = regex(" & ");
var regexPairs = [regexA, "a", regexE, "e", regexI, "i", regexO, "o", regexU, "u", regexY, "y", regexN, "n", regexC, "c", regexS, "s", regexAnd, " and ", regexSpace, " ", regexStrip, "", regexWhitespace, " "];
return function(str){
str = replace(str.toLowerCase(), regexPairs);
return str !== " " ? str : "";
};
}(), "advanced": function(){
var regexSpace = regex(" "), regexAe = regex("ae"), regexAi = regex("ai"), regexAy = regex("ay"),
regexEy = regex("ey"), regexOe = regex("oe"), regexUe = regex("ue"), regexIe = regex("ie"),
regexSz = regex("sz"), regexZs = regex("zs"), regexCk = regex("ck"), regexCc = regex("cc"),
regexSh = regex("sh"), regexDt = regex("dt"), regexPh = regex("ph"), regexPf = regex("pf"),
regexOu = regex("ou"), regexUo = regex("uo");
var regexPairs = [regexAe, "a", regexAi, "ei", regexAy, "ei", regexEy, "ei", regexOe, "o", regexUe, "u", regexIe, "i", regexSz, "s", regexZs, "s", regexSh, "s", regexCk, "k", regexCc, "k", regexDt, "t", regexPh, "f", regexPf, "f", regexOu, "o", regexUo, "u"];
return function(string, _skipPostProcessing){
if(!string){
return string;
}
string = this["simple"](string);
if(string.length > 2){
string = replace(string, regexPairs);
}
if(!_skipPostProcessing){
if(string.length > 1){
string = collapseRepeatingChars(string);
}
}
return string;
};
}(), "extra": function(){
var soundexB = regex("p"), soundexS = regex("z"), soundexK = regex("[cgq]"), soundexM = regex("n"),
soundexT = regex("d"), soundexF = regex("[vw]");
var regexVowel = regex("[aeiouy]");
var regexPairs = [soundexB, "b", soundexS, "s", soundexK, "k", soundexM, "m", soundexT, "t", soundexF, "f", regexVowel, ""];
return function(str){
if(!str){
return str;
}
str = this["advanced"](str, true);
if(str.length > 1){
str = str.split(" ");
for(var i = 0; i < str.length; i++){
var current = str[i];
if(current.length > 1){
str[i] = current[0] + replace(current.substring(1), regexPairs);
}
}
str = str.join(" ");
str = collapseRepeatingChars(str);
}
return str;
};
}(), "balance": globalEncoderBalance
});
var queue = null;
return FlexSearch;
function registerProperty(obj, key, fn){
Object.defineProperty(obj, key, {get: fn});
}
function regex(str){
return new RegExp(str, "g");
}
function replace(str, regex, replacement){
if(typeof replacement === "undefined"){
for(var i = 0; i < regex.length; i += 2){
str = str.replace(regex[i], regex[i + 1]);
}
return str;
}
else{
return str.replace(regex, replacement);
}
}
function addIndex(map, dupes, tmp, id, partialScore, contextScore, threshold){
if(typeof dupes[tmp] === "undefined"){
var score = partialScore ? (9 - (threshold || 6)) * contextScore + (threshold || 6) * partialScore : contextScore;
dupes[tmp] = score;
if(score >= threshold){
var arr = map[score + 0.5 | 0];
arr = arr[tmp] || (arr[tmp] = []);
arr[arr.length] = id;
}
}
return score || dupes[tmp];
}
function removeIndex(map, id){
if(map){
var keys = Object.keys(map);
for(var i = 0, lengthKeys = keys.length; i < lengthKeys; i++){
var key = keys[i];
var tmp = map[key];
if(tmp){
for(var a = 0, lengthMap = tmp.length; a < lengthMap; a++){
if(tmp[a] === id){
if(lengthMap === 1){
delete map[key];
}
else{
tmp.splice(a, 1);
}
break;
}
else{
if(typeof tmp[a] === "object"){
removeIndex(tmp[a], id);
}
}
}
}
}
}
}
function ngram(value){
var parts = [];
if(!value){
return parts;
}
var countVowels = 0, countLiteral = 0, countParts = 0;
var tmp = "";
var length = value.length;
for(var i = 0; i < length; i++){
var char = value[i];
var charIsVowel = char === "a" || char === "e" || char === "i" || char === "o" || char === "u" || char === "y";
if(charIsVowel){
countVowels++;
}
else{
countLiteral++;
}
if(char !== " "){
tmp += char;
}
if(char === " " || countVowels >= (length > 8 ? 2 : 1) && countLiteral >= 2 || countVowels >= 2 && countLiteral >= (length > 8 ? 2 : 1) || i === length - 1){
if(tmp){
if(parts[countParts] && tmp.length > 2){
countParts++;
}
if(parts[countParts]){
parts[countParts] += tmp;
}
else{
parts[countParts] = tmp;
}
if(char === " "){
countParts++;
}
tmp = "";
}
countVowels = 0;
countLiteral = 0;
}
}
return parts;
}
function collapseRepeatingChars(string){
var collapsedString = "", charPrev = "", charNext = "";
for(var i = 0; i < string.length; i++){
var char = string[i];
if(char !== charPrev){
if(i && char === "h"){
var charPrevIsVowel = charPrev === "a" || charPrev === "e" || charPrev === "i" || charPrev === "o" || charPrev === "u" || charPrev === "y";
var charNextIsVowel = charNext === "a" || charNext === "e" || charNext === "i" || charNext === "o" || charNext === "u" || charNext === "y";
if(charPrevIsVowel && charNextIsVowel || charPrev === " "){
collapsedString += char;
}
}
else{
collapsedString += char;
}
}
charNext = i === string.length - 1 ? "" : string[i + 1];
charPrev = char;
}
return collapsedString;
}
function initFilter(words, encoder){
var final = createObject();
if(words){
for(var i = 0; i < words.length; i++){
var word = encoder ? encoder.call(globalEncoder, words[i]) : words[i];
final[word] = String.fromCharCode(65000 - words.length + i);
}
}
return final;
}
function initStemmer(stemmer, encoder){
var final = [];
if(stemmer){
for(var key in stemmer){
if(stemmer.hasOwnProperty(key)){
var tmp = encoder ? encoder.call(globalEncoder, key) : key;
final.push(regex("(?=.{" + (tmp.length + 3) + ",})" + tmp + "$"), encoder ? encoder.call(globalEncoder, stemmer[key]) : stemmer[key]);
}
}
}
return final;
}
function sortByLengthDown(a, b){
var diff = a.length - b.length;
return diff < 0 ? 1 : diff > 0 ? -1 : 0;
}
function sortByLengthUp(a, b){
var diff = a.length - b.length;
return diff < 0 ? -1 : diff > 0 ? 1 : 0;
}
function intersect(arrays, limit, suggest){
var result = [];
var suggestions = [];
var lengthZ = arrays.length;
if(lengthZ > 1){
arrays.sort(sortByLengthUp);
var check = createObject();
var arr = arrays[0];
var length = arr.length;
var i = 0;
while(i < length){
check[arr[i++]] = 1;
}
var tmp, count = 0;
var z = 1;
while(z < lengthZ){
var found = false;
var isFinalLoop = z === lengthZ - 1;
suggestions = [];
arr = arrays[z];
length = arr.length;
i = -1;
while(i < length){
var checkVal = check[tmp = arr[++i]];
if(checkVal === z){
if(isFinalLoop){
result[count++] = tmp;
if(limit && count === limit){
return result;
}
}
found = true;
check[tmp] = z + 1;
}
else{
if(suggest){
var currentSuggestion = suggestions[checkVal] || (suggestions[checkVal] = []);
currentSuggestion[currentSuggestion.length] = tmp;
}
}
}
if(!found && !suggest){
break;
}
z++;
}
if(suggest){
limit || (limit = 1000);
count = result.length;
length = suggestions.length;
if(count < limit && length){
for(z = length - 1; z >= 0; z--){
tmp = suggestions[z];
if(tmp){
for(i = 0; i < tmp.length; i++){
result[count++] = tmp[i];
if(limit && count === limit){
return result;
}
}
}
}
}
}
}
else{
if(lengthZ){
result = arrays[0];
if(limit && result.length > limit){
result = result.slice(0, limit);
}
}
}
return result;
}
function createObject(count){
if(count){
var array = new Array(count);
for(var i = 0; i < count; i++){
array[i] = createObject();
}
return array;
}
else{
return Object.create(null);
}
}
}(), this);
function provide(name, factory, root){
var prop;
if((prop = root["define"]) && prop["amd"]){
prop([], function(){
return factory;
});
}
else{
if(prop = root["modules"]){
prop[name.toLowerCase()] = factory;
}
else{
if(typeof module !== "undefined"){
module.exports = factory;
}
else{
root[name] = factory;
}
}
}
}
}).call(this);
'use strict';(function(m,x,c){var r;(r=c.define)&&r.amd?r([],function(){return x}):(r=c.modules)?r[m.toLowerCase()]=x:"object"===typeof exports?module.exports=x:c[m]=x})("FlexSearch",function(){function m(b){"string"===typeof b&&(b=D[b]);b||(b=v);this.id=b.id||J++;this.init(b);x(this,"index",function(){return this.a});x(this,"length",function(){return Object.keys(this.a).length})}function x(b,a,d){Object.defineProperty(b,a,{get:d})}function c(b){return new RegExp(b,"g")}function r(b,a,d){if("undefined"===
typeof d){for(d=0;d<a.length;d+=2)b=b.replace(a[d],a[d+1]);return b}return b.replace(a,d)}function z(b,a,d,n,g,e,c){if(a[d])return a[d];g=g?(9-(c||6))*e+(c||6)*g:e;a[d]=g;g>=c&&(b=b[g+.5>>0],b=b[d]||(b[d]=[]),b[b.length]=n);return g}function A(b,a){if(b)for(var d=Object.keys(b),n=0,g=d.length;n<g;n++){var c=d[n],k=b[c];if(k)for(var f=0,h=k.length;f<h;f++)if(k[f]===a){1===h?delete b[c]:k.splice(f,1);break}else"object"===typeof k[f]&&A(k[f],a)}}function E(b){var a=[];if(!b)return a;for(var d=0,n=0,
c=0,e="",k=b.length,f=0;f<k;f++){var h=b[f];"a"===h||"e"===h||"i"===h||"o"===h||"u"===h||"y"===h?d++:n++;" "!==h&&(e+=h);if(" "===h||d>=(8<k?2:1)&&2<=n||2<=d&&n>=(8<k?2:1)||f===k-1)e&&(a[c]&&2<e.length&&c++,a[c]=a[c]?a[c]+e:e," "===h&&c++,e=""),n=d=0}return a}function B(b){for(var a="",d="",n="",c=0;c<b.length;c++){var e=b[c];if(e!==d)if(c&&"h"===e){if(n="a"===n||"e"===n||"i"===n||"o"===n||"u"===n||"y"===n,("a"===d||"e"===d||"i"===d||"o"===d||"u"===d||"y"===d)&&n||" "===d)a+=e}else a+=e;n=c===b.length-
1?"":b[c+1];d=e}return a}function K(b,a){b=b.length-a.length;return 0>b?1:b?-1:0}function L(b,a){b=b.length-a.length;return 0>b?-1:b?1:0}function F(b){for(var a=Array(b),d=0;d<b;d++)a[d]={};return a}var v={encode:"icase",mode:"forward",g:!1,cache:!1,async:!1,m:!1,threshold:0,depth:0},D={memory:{encode:"extra",mode:"strict",threshold:7},speed:{encode:"icase",mode:"strict",threshold:7,depth:2},match:{encode:"extra",mode:"full"},score:{encode:"extra",mode:"strict",threshold:5,depth:4},balance:{encode:"balance",
mode:"strict",threshold:6,depth:3},fastest:{encode:"icase",mode:"strict",threshold:9,depth:1}},C=[],J=0,G=c("[ -/]"),H={},I={};m.create=function(b){return new this(b)};m.registerMatcher=function(b){for(var a in b)b.hasOwnProperty(a)&&C.push(c(a),b[a]);return this};m.registerEncoder=function(b,a){y[b]=a.bind(y);return this};m.registerLanguage=function(b,a){H[b]=a.filter;I[b]=a.stemmer;return this};m.encode=function(b,a){return y[b](a)};m.prototype.init=function(b){this.j=[];b||(b=v);var a=b.profile;
a=a?D[a]:{};this.mode=b.mode||a.mode||this.mode||v.mode;this.threshold=b.threshold||a.threshold||this.threshold||v.threshold;this.depth=b.depth||a.depth||this.depth||v.depth;this.g=b.suggest||this.g||v.g;this.f=(a=b.encode||a.encode)&&y[a]&&y[a].bind(y)||("function"===typeof a?a:this.f||!1);(a=b.matcher)&&this.addMatcher(a);if(a=b.filter){a=H[a]||a;var d=this.f,n={};if(a)for(var g=0;g<a.length;g++){var e=d?d(a[g]):a[g];n[e]=String.fromCharCode(65E3-a.length+g)}this.filter=n}if(a=b.stemmer){a=I[a]||
a;d=this.f;n=[];if(a)for(var k in a)a.hasOwnProperty(k)&&(g=d?d(k):k,n.push(c("(?=.{"+(g.length+3)+",})"+g+"$"),d?d(a[k]):a[k]));this.stemmer=n}this.i=F(10);this.c={};this.a={};this.h=!0;this.b=(this.cache=a=b.cache||this.cache||v.cache)?new M(a):!1;return this};m.prototype.encode=function(b){b&&C.length&&(b=r(b,C));b&&this.j.length&&(b=r(b,this.j));b&&this.f&&(b=this.f(b));b&&this.stemmer&&(b=r(b,this.stemmer));return b};m.prototype.addMatcher=function(b){var a=this.j,d;for(d in b)b.hasOwnProperty(d)&&
a.push(c(d),b[d]);return this};m.prototype.add=function(b,a,d){if(a&&"string"===typeof a&&(b||0===b))if(this.a[b]&&!d)this.update(b,a);else{a=this.encode(a);if(!a.length)return this;d=this.mode;a="function"===typeof d?d(a):"ngram"===d?E(a):a.split(G);for(var c={_ctx:{}},g=this.threshold,e=this.depth,k=this.i,f=a.length,h=0;h<f;h++){var u=a[h];if(u){var p=u.length,t=(f-h)/f,q="";switch(d){case "reverse":case "both":for(var l=p-1;1<=l;l--)q=u[l]+q,z(k,c,q,b,(p-l)/p,t,g);q="";case "forward":for(l=0;l<
p;l++)q+=u[l],z(k,c,q,b,1,t,g);break;case "full":for(l=0;l<p;l++)for(var m=(p-l)/p,r=p;r>l;r--)q=u.substring(l,r),z(k,c,q,b,m,t,g);break;default:if(p=z(k,c,u,b,1,t,g),e&&1<f&&p>=g)for(p=c._ctx[u]||(c._ctx[u]={}),u=this.c[u]||(this.c[u]=F(10)),t=h-e,q=h+e+1,0>t&&(t=0),q>f&&(q=f);t<q;t++)t!==h&&z(u,p,a[t],b,0,10-(t<h?h-t:t-h),g)}}}this.a[b]="1";this.h=!1}return this};m.prototype.update=function(b,a){this.a[b]&&a&&"string"===typeof a&&(this.remove(b),this.add(b,a,!0));return this};m.prototype.remove=
function(b){if(this.a[b]){for(var a=0;10>a;a++)A(this.i[a],b);this.depth&&A(this.c,b);delete this.a[b];this.h=!1}return this};m.prototype.search=function(b,a,d){var c=[];if("object"===typeof b){d=b.callback||a;a=b.limit;var g=b.threshold;b=b.query}g||(g=this.threshold||0);"function"===typeof a?(d=a,a=1E3):a||0===a||(a=1E3);if(d)d(this.search(b,a));else{if(!b||"string"!==typeof b)return c;d=b;if(this.cache)if(this.h){var e=this.b.get(b);if(e)return e}else this.b.clear(),this.h=!0;d=this.encode(d);
if(!d.length)return c;e=this.mode;e="function"===typeof e?e(d):"ngram"===e?E(d):d.split(G);var k=e.length,f=!0;d=[];var h={};if(1<k)if(this.depth){var u=!0;var p=e[0];h[p]="1"}else e.sort(K);var t;if(!u||(t=this.c)[p])for(var q=u?1:0;q<k;q++){var l=e[q];if(l&&!h[l]){for(var m,r=!1,w=[],x=0,v=9;v>=g;v--)m=(u?t[p]:this.i)[v],m[l]&&(w[x++]=m[l],r=!0);if(r)d[d.length]=1<x?d.concat.apply([],w):w[0];else if(!this.g){f=!1;break}h[l]="1"}p=l}else f=!1;if(f)a:if(g=this.g,c=[],p=[],u=d.length,1<u){d.sort(L);
t={};e=d[0];k=e.length;for(f=0;f<k;)t[e[f++]]=1;q=0;for(l=1;l<u;){m=!1;r=l===u-1;p=[];e=d[l];k=e.length;for(f=-1;f<k;)if(h=e[++f],t[h])if(w=t[h],w===l){if(r){if(c[q++]=h,a&&q===a)break a}else t[h]=l+1;m=!0}else g&&(w=p[w]?p[w]:p[w]=[],w[w.length]=h);if(!m&&!g)break;l++}if(g&&(q=c.length,(k=p.length)&&(!a||q<a)))for(l=k-1;0<=l;l--)if(h=p[l])for(f=0;f<h.length;f++)if(c[q++]=h[f],a&&q===a)break a}else u&&(c=d[0],a&&c.length>a&&(c=c.slice(0,a)));this.cache&&this.b.set(b,c);return c}};m.prototype.clear=
function(){this.destroy();return this.init()};m.prototype.destroy=function(){this.cache&&(this.b.clear(),this.b=null);this.filter=this.stemmer=this.i=this.c=this.a=null;return this};var y={icase:function(b){return b.toLowerCase()},simple:function(){var b=[c("[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]"),"a",c("[\u00e8\u00e9\u00ea\u00eb]"),"e",c("[\u00ec\u00ed\u00ee\u00ef]"),"i",c("[\u00f2\u00f3\u00f4\u00f5\u00f6\u0151]"),"o",c("[\u00f9\u00fa\u00fb\u00fc\u0171]"),"u",c("[\u00fd\u0177\u00ff]"),"y",c("\u00f1"),
"n",c("\u00e7"),"c",c("\u00df"),"s",c(" & ")," and ",c("[-/]")," ",c("[^a-z0-9 ]"),"",c("\\s\\s+")," "];return function(a){a=r(a.toLowerCase(),b);return" "!==a?a:""}}(),advanced:function(){var b=[c("ae"),"a",c("ai"),"ei",c("ay"),"ei",c("ey"),"ei",c("oe"),"o",c("ue"),"u",c("ie"),"i",c("sz"),"s",c("zs"),"s",c("sh"),"s",c("ck"),"k",c("cc"),"k",c("dt"),"t",c("ph"),"f",c("pf"),"f",c("ou"),"o",c("uo"),"u"];return function(a,d){if(!a)return a;a=this.simple(a);2<a.length&&(a=r(a,b));d||1<a.length&&(a=B(a));
return a}}(),extra:function(){var b=[c("p"),"b",c("z"),"s",c("[cgq]"),"k",c("n"),"m",c("d"),"t",c("[vw]"),"f",c("[aeiouy]"),""];return function(a){if(!a)return a;a=this.advanced(a,!0);if(1<a.length){a=a.split(" ");for(var d=0;d<a.length;d++){var c=a[d];1<c.length&&(a[d]=c[0]+r(c.substring(1),b))}a=a.join(" ");a=B(a)}return a}}(),balance:function(){var b=[c("[-/]")," ",c("[^a-z0-9 ]"),"",c("\\s\\s+")," "];return function(a){return B(r(a.toLowerCase(),b))}}()},M=function(){function b(a){this.clear();
this.l=!0!==a&&a}b.prototype.clear=function(){this.cache={};this.count={};this.index={};this.a=[]};b.prototype.set=function(a,b){if(this.l&&"undefined"===typeof this.cache[a]){var c=this.a.length;if(c===this.l){c--;var d=this.a[c];delete this.cache[d];delete this.count[d];delete this.index[d]}this.index[a]=c;this.a[c]=a;this.count[a]=-1;this.cache[a]=b;this.get(a)}else this.cache[a]=b};b.prototype.get=function(a){var b=this.cache[a];if(this.l&&b){var c=++this.count[a],g=this.index,e=g[a];if(0<e){for(var k=
this.a,f=e;this.count[k[--e]]<=c&&-1!==e;);e++;if(e!==f){for(c=f;c>e;c--)f=k[c-1],k[c]=f,g[f]=c;k[e]=a;g[a]=e}}}return b};return b}();return m}(!1),this);

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,17 @@
/*
FlexSearch v0.2.70
Copyright 2018 Thomas Wilkerling
FlexSearch v0.3.0
Copyright 2019 Nextapps GmbH
Author: Thomas Wilkerling
Released under the Apache 2.0 Licence
https://github.com/nextapps-de/flexsearch
*/
'use strict';(function(d,x,p){var t;(t=p.define)&&t.amd?t([],function(){return x}):(t=p.modules)?t[d.toLowerCase()]=x:"undefined"!==typeof module?module.exports=x:p[d]=x})("FlexSearch",function(){function d(a){"string"!==typeof a||v[a]||(a=D[a]);a||(a=y);this.id=a.id||I++;this.init(a);x(this,"index",function(){return this.a});x(this,"length",function(){return Object.keys(this.a).length})}function x(a,b,c){Object.defineProperty(a,b,{get:c})}function p(a){return new RegExp(a,"g")}function t(a,b,c){if("undefined"===
typeof c){for(c=0;c<b.length;c+=2)a=a.replace(b[c],b[c+1]);return a}return a.replace(b,c)}function A(a,b,c,e,f,q,g){if(b[c])return b[c];f=f?(9-(g||6))*q+(g||6)*f:q;b[c]=f;f>=g&&(a=a[f+.5|0],a=a[c]||(a[c]=[]),a[a.length]=e);return f}function B(a,b){if(a)for(var c=Object.keys(a),e=0,f=c.length;e<f;e++){var q=c[e],g=a[q];if(g)for(var l=0,h=g.length;l<h;l++)if(g[l]===b){1===h?delete a[q]:g.splice(l,1);break}else"object"===typeof g[l]&&B(g[l],b)}}function E(a){var b=[];if(!a)return b;for(var c=0,e=0,f=
0,q="",g=a.length,l=0;l<g;l++){var h=a[l];"a"===h||"e"===h||"i"===h||"o"===h||"u"===h||"y"===h?c++:e++;" "!==h&&(q+=h);if(" "===h||c>=(8<g?2:1)&&2<=e||2<=c&&e>=(8<g?2:1)||l===g-1)q&&(b[f]&&2<q.length&&f++,b[f]=b[f]?b[f]+q:q," "===h&&f++,q=""),e=c=0}return b}function J(a,b){a=a.length-b.length;return 0>a?1:0<a?-1:0}function K(a,b){a=a.length-b.length;return 0>a?-1:0<a?1:0}function L(a,b,c){var e=[],f=[],q=a.length;if(1<q){a.sort(K);for(var g=u(),l=a[0],h=l.length,z=0;z<h;)g[l[z++]]=1;for(var m,d=0,
n=1;n<q;){var k=!1,p=n===q-1;f=[];l=a[n];h=l.length;for(z=-1;z<h;)if(m=l[++z],g[m]){var r=g[m];if(r===n){if(p){if(e[d++]=m,b&&d===b)return e}else g[m]=n+1;k=!0}else c&&(r=f[r]?f[r]:f[r]=[],r[r.length]=m)}if(!k&&!c)break;n++}if(c&&(d=e.length,(h=f.length)&&(!b||d<b)))for(n=h-1;0<=n;n--)if(m=f[n])for(z=0;z<m.length;z++)if(e[d++]=m[z],b&&d===b)return e}else q&&(e=a[0],b&&e.length>b&&(e=e.slice(0,b)));return e}function u(a){if(a){for(var b=Array(a),c=0;c<a;c++)b[c]=Object.create(null);return b}return Object.create(null)}
var y={encode:"icase",mode:"forward",f:!1,cache:!1,async:!1,i:!1,threshold:0,depth:0},D={memory:{encode:"extra",mode:"strict",threshold:7},speed:{encode:"icase",mode:"strict",threshold:7,depth:2},match:{encode:"extra",mode:"full"},score:{encode:"extra",mode:"strict",threshold:5,depth:4},balance:{encode:"balance",mode:"ngram",threshold:6,depth:3},fastest:{encode:"icase",mode:"strict",threshold:9,depth:1}},C=[],I=0,F=p("[ -/]"),G=u(),H=u(),v=function(){for(var a=Object.getOwnPropertyNames({}.__proto__),
b=u(),c=0;c<a.length;c++)b[a[c]]=1;return b}();d.new=function(a){return new this(a)};d.create=function(a){return d.new(a)};d.registerMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&C.push(p(b),a[b]);return this};d.registerEncoder=function(a,b){v[a]||(w[a]=b);return this};d.registerLanguage=function(a,b){v[a]||(G[a]=b.filter,H[a]=b.stemmer);return this};d.encode=function(a,b){return v[a]?b:w[a].call(w,b)};d.prototype.init=function(a){this.h=[];a||(a=y);var b=a.profile;b=b&&!v[b]?D[b]:u();this.mode=
a.mode||b.mode||this.mode||y.mode;this.threshold=a.threshold||b.threshold||this.threshold||y.threshold;this.depth=a.depth||b.depth||this.depth||y.depth;this.f=a.suggest||this.f||y.f;this.c=(b=a.encode||b.encode)&&!v[b]&&w[b]||("function"===typeof b?b:this.c||!1);(b=a.matcher)&&this.addMatcher(b);if(b=a.filter){b=G[b]||b;var c=this.c,e=u();if(b)for(var f=0;f<b.length;f++){var q=c?c.call(w,b[f]):b[f];e[q]=String.fromCharCode(65E3-b.length+f)}this.filter=e}if(b=a.stemmer){a=H[b]||b;b=this.c;c=[];if(a)for(var g in a)a.hasOwnProperty(g)&&
(e=b?b.call(w,g):g,c.push(p("(?=.{"+(e.length+3)+",})"+e+"$"),b?b.call(w,a[g]):a[g]));this.stemmer=c}this.g=u(10);this.b=u();this.a=u();u();return this};d.prototype.encode=function(a){a&&C.length&&(a=t(a,C));a&&this.h.length&&(a=t(a,this.h));a&&this.c&&(a=this.c.call(w,a));a&&this.stemmer&&(a=t(a,this.stemmer));return a};d.prototype.addMatcher=function(a){var b=this.h,c;for(c in a)a.hasOwnProperty(c)&&b.push(p(c),a[c]);return this};d.prototype.add=function(a,b,c){if("string"===typeof b&&b&&(a&&!v[a]||
0===a))if(this.a[a]&&!c)this.update(a,b);else{b=this.encode(b);if(!b.length)return this;c=this.mode;b="function"===typeof c?c(b):"ngram"===c?E(b):b.split(F);var e=u();e._ctx=u();for(var f=this.threshold,q=this.depth,g=this.g,l=b.length,h=0;h<l;h++){var d=b[h];if(d){var m=d.length,p=(l-h)/l;switch(c){case "reverse":case "both":for(var n="",k=m-1;1<=k;k--)n=d[k]+n,A(g,e,n,a,(m-k)/m,p,f);case "forward":n="";for(k=0;k<m;k++)n+=d[k],A(g,e,n,a,1,p,f);break;case "full":for(k=0;k<m;k++)for(var t=(m-k)/m,
r=m;r>k;r--)n=d.substring(k,r),A(g,e,n,a,t,p,f);break;default:if(k=A(g,e,d,a,1,p,f),q&&1<l&&k>=f)for(m=e._ctx[d]||(e._ctx[d]=u()),d=this.b[d]||(this.b[d]=u(10)),k=h-q,r=h+q+1,0>k&&(k=0),r>l&&(r=l);k<r;k++)k!==h&&A(d,m,b[k],a,0,10-(k<h?h-k:k-h),f)}}}this.a[a]="1"}return this};d.prototype.update=function(a,b){this.a[a]&&b&&"string"===typeof b&&(this.remove(a),this.add(a,b,!0));return this};d.prototype.remove=function(a){if(this.a[a]&&!v[a]){for(var b=0;10>b;b++)B(this.g[b],a);this.depth&&B(this.b,a);
delete this.a[a]}return this};d.prototype.search=function(a,b,c){var e=[];if("object"===typeof a){c=a.callback||b;b=a.limit;var f=a.threshold;a=a.query}f||(f=this.threshold||0);"function"===typeof b?(c=b,b=1E3):b||0===b||(b=1E3);if(c){var d=this;M(function(){c(d.search(a,b));d=null},1,"search-"+this.id);return null}if(!a||"string"!==typeof a)return e;var g=this.encode(a);if(!g.length)return e;var l=this.mode;g="function"===typeof l?l(g):"ngram"===l?E(g):g.split(F);l=g.length;var h=!0,p=[],m=u();if(1<
l)if(this.depth){var t=!0,n=g[0];m[n]="1"}else g.sort(J);var k;if(!t||(k=this.b)[n])for(var v=t?1:0;v<l;v++){var r=g[v];if(r&&!m[r]){for(var w,x=!1,y=[],A=0,B=9;B>=f;B--)w=(t?k[n]:this.g)[B],w[r]&&(y[A++]=w[r],x=!0);if(x)p[p.length]=1<A?p.concat.apply([],y):y[0];else if(!this.f){h=!1;break}m[r]="1"}n=r}else h=!1;h&&(e=L(p,b,this.f));return e};d.prototype.reset=function(){this.destroy();return this.init()};d.prototype.destroy=function(){this.filter=this.stemmer=this.g=this.b=this.a=null;return this};
var w=Object.create({icase:function(a){return a.toLowerCase()},balance:function(){var a=[p("[-/]")," ",p("[^a-z0-9 ]"),"",p("\\s\\s+")," "];return function(b){b=t(b.toLowerCase(),a);for(var c="",e="",f="",d=0;d<b.length;d++){var g=b[d];if(g!==e)if(d&&"h"===g){if(f="a"===f||"e"===f||"i"===f||"o"===f||"u"===f||"y"===f,("a"===e||"e"===e||"i"===e||"o"===e||"u"===e||"y"===e)&&f||" "===e)c+=g}else c+=g;f=d===b.length-1?"":b[d+1];e=g}return c}}()}),M=null;return d}(!1),this);
'use strict';(function(h,w,u){var r;(r=u.define)&&r.amd?r([],function(){return w}):(r=u.modules)?r[h.toLowerCase()]=w:"object"===typeof exports?module.exports=w:u[h]=w})("FlexSearch",function(){function h(a){a||(a=x);this.id=a.id||F++;this.init(a);w(this,"index",function(){return this.a});w(this,"length",function(){return Object.keys(this.a).length})}function w(a,b,c){Object.defineProperty(a,b,{get:c})}function u(a,b,c){if("undefined"===typeof c){for(c=0;c<b.length;c+=2)a=a.replace(b[c],b[c+1]);return a}return a.replace(b,
c)}function r(a,b,c,e,f,v,d){if(b[c])return b[c];f=f?(9-(d||6))*v+(d||6)*f:v;b[c]=f;f>=d&&(a=a[f+.5>>0],a=a[c]||(a[c]=[]),a[a.length]=e);return f}function z(a,b){if(a)for(var c=Object.keys(a),e=0,f=c.length;e<f;e++){var v=c[e],d=a[v];if(d)for(var k=0,n=d.length;k<n;k++)if(d[k]===b){1===n?delete a[v]:d.splice(k,1);break}else"object"===typeof d[k]&&z(d[k],b)}}function G(a,b){a=a.length-b.length;return 0>a?1:a?-1:0}function H(a,b){a=a.length-b.length;return 0>a?-1:a?1:0}function B(a){for(var b=Array(a),
c=0;c<a;c++)b[c]={};return b}var x={encode:"icase",mode:"forward",f:!1,cache:!1,async:!1,i:!1,threshold:0,depth:0},A=[],F=0,C=/[ -/]/g,D={},E={};h.create=function(a){return new this(a)};h.registerMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&A.push(new RegExp(b,"g"),a[b]);return this};h.registerEncoder=function(a,b){y[a]=b.bind(y);return this};h.registerLanguage=function(a,b){D[a]=b.filter;E[a]=b.stemmer;return this};h.encode=function(a,b){return y[a](b)};h.prototype.init=function(a){this.h=
[];a||(a=x);var b={};this.mode=a.mode||b.mode||this.mode||x.mode;this.threshold=a.threshold||b.threshold||this.threshold||x.threshold;this.depth=a.depth||b.depth||this.depth||x.depth;this.f=a.suggest||this.f||x.f;this.c=(b=a.encode||b.encode)&&y[b]&&y[b].bind(y)||("function"===typeof b?b:this.c||!1);(b=a.matcher)&&this.addMatcher(b);if(b=a.filter){b=D[b]||b;var c=this.c,e={};if(b)for(var f=0;f<b.length;f++){var v=c?c(b[f]):b[f];e[v]=String.fromCharCode(65E3-b.length+f)}this.filter=e}if(b=a.stemmer){a=
E[b]||b;b=this.c;c=[];if(a)for(var d in a)a.hasOwnProperty(d)&&(e=b?b(d):d,c.push(new RegExp("(?=.{"+(e.length+3)+",})"+e+"$","g"),b?b(a[d]):a[d]));this.stemmer=c}this.g=B(10);this.b={};this.a={};return this};h.prototype.encode=function(a){a&&A.length&&(a=u(a,A));a&&this.h.length&&(a=u(a,this.h));a&&this.c&&(a=this.c(a));a&&this.stemmer&&(a=u(a,this.stemmer));return a};h.prototype.addMatcher=function(a){var b=this.h,c;for(c in a)a.hasOwnProperty(c)&&b.push(new RegExp(c,"g"),a[c]);return this};h.prototype.add=
function(a,b,c){if(b&&"string"===typeof b&&(a||0===a))if(this.a[a]&&!c)this.update(a,b);else{b=this.encode(b);if(!b.length)return this;c=this.mode;b="function"===typeof c?c(b):b.split(C);for(var e={_ctx:{}},f=this.threshold,v=this.depth,d=this.g,k=b.length,n=0;n<k;n++){var m=b[n];if(m){var q=m.length,l=(k-n)/k,g="";switch(c){case "reverse":case "both":for(var p=q-1;1<=p;p--)g=m[p]+g,r(d,e,g,a,(q-p)/q,l,f);g="";case "forward":for(p=0;p<q;p++)g+=m[p],r(d,e,g,a,1,l,f);break;case "full":for(p=0;p<q;p++)for(var h=
(q-p)/q,t=q;t>p;t--)g=m.substring(p,t),r(d,e,g,a,h,l,f);break;default:if(q=r(d,e,m,a,1,l,f),v&&1<k&&q>=f)for(q=e._ctx[m]||(e._ctx[m]={}),m=this.b[m]||(this.b[m]=B(10)),l=n-v,g=n+v+1,0>l&&(l=0),g>k&&(g=k);l<g;l++)l!==n&&r(m,q,b[l],a,0,10-(l<n?n-l:l-n),f)}}}this.a[a]="1"}return this};h.prototype.update=function(a,b){this.a[a]&&b&&"string"===typeof b&&(this.remove(a),this.add(a,b,!0));return this};h.prototype.remove=function(a){if(this.a[a]){for(var b=0;10>b;b++)z(this.g[b],a);this.depth&&z(this.b,a);
delete this.a[a]}return this};h.prototype.search=function(a,b,c){var e=[];if("object"===typeof a){c=a.callback||b;b=a.limit;var f=a.threshold;a=a.query}f||(f=this.threshold||0);"function"===typeof b?(c=b,b=1E3):b||0===b||(b=1E3);if(c)c(this.search(a,b));else{if(!a||"string"!==typeof a)return e;a=this.encode(a);if(!a.length)return e;c=this.mode;c="function"===typeof c?c(a):a.split(C);var h=c.length,d=!0;a=[];var k={};if(1<h)if(this.depth){var n=!0;var m=c[0];k[m]="1"}else c.sort(G);var q;if(!n||(q=
this.b)[m])for(var l=n?1:0;l<h;l++){var g=c[l];if(g&&!k[g]){for(var p,r=!1,t=[],w=0,u=9;u>=f;u--)p=(n?q[m]:this.g)[u],p[g]&&(t[w++]=p[g],r=!0);if(r)a[a.length]=1<w?a.concat.apply([],t):t[0];else if(!this.f){d=!1;break}k[g]="1"}m=g}else d=!1;if(d)a:if(f=this.f,e=[],m=[],n=a.length,1<n){a.sort(H);q={};c=a[0];h=c.length;for(d=0;d<h;)q[c[d++]]=1;l=0;for(g=1;g<n;){p=!1;r=g===n-1;m=[];c=a[g];h=c.length;for(d=-1;d<h;)if(k=c[++d],q[k])if(t=q[k],t===g){if(r){if(e[l++]=k,b&&l===b)break a}else q[k]=g+1;p=!0}else f&&
(t=m[t]?m[t]:m[t]=[],t[t.length]=k);if(!p&&!f)break;g++}if(f&&(l=e.length,(h=m.length)&&(!b||l<b)))for(g=h-1;0<=g;g--)if(k=m[g])for(d=0;d<k.length;d++)if(e[l++]=k[d],b&&l===b)break a}else n&&(e=a[0],b&&e.length>b&&(e=e.slice(0,b)));return e}};h.prototype.clear=function(){this.destroy();return this.init()};h.prototype.destroy=function(){this.filter=this.stemmer=this.g=this.b=this.a=null;return this};var y={icase:function(a){return a.toLowerCase()}};return h}(!1),this);

51
flexsearch.min.js vendored
View File

@@ -1,30 +1,29 @@
/*
FlexSearch v0.2.70
Copyright 2018 Thomas Wilkerling
FlexSearch v0.3.0
Copyright 2019 Nextapps GmbH
Author: Thomas Wilkerling
Released under the Apache 2.0 Licence
https://github.com/nextapps-de/flexsearch
*/
'use strict';(function(v,D,f){var w;(w=f.define)&&w.amd?w([],function(){return D}):(w=f.modules)?w[v.toLowerCase()]=D:"undefined"!==typeof module?module.exports=D:f[v]=D})("FlexSearch",function P(v){function f(a){"string"!==typeof a||y[a]||(a=I[a]);a||(a=z);this.id=a.id||Q++;this.init(a);w(this,"index",function(){return this.a});w(this,"length",function(){return Object.keys(this.a).length})}function w(a,b,d){Object.defineProperty(a,b,{get:d})}function e(a){return new RegExp(a,"g")}function x(a,b,
d){if("undefined"===typeof d){for(d=0;d<b.length;d+=2)a=a.replace(b[d],b[d+1]);return a}return a.replace(b,d)}function A(a,b,d,c,g,B,h){if(b[d])return b[d];g=g?(9-(h||6))*B+(h||6)*g:B;b[d]=g;g>=h&&(a=a[g+.5|0],a=a[d]||(a[d]=[]),a[a.length]=c);return g}function r(a,b){if(a)for(var d=Object.keys(a),c=0,g=d.length;c<g;c++){var B=d[c],h=a[B];if(h)for(var l=0,e=h.length;l<e;l++)if(h[l]===b){1===e?delete a[B]:h.splice(l,1);break}else"object"===typeof h[l]&&r(h[l],b)}}function J(a){var b=[];if(!a)return b;
for(var d=0,c=0,g=0,B="",h=a.length,l=0;l<h;l++){var e=a[l];"a"===e||"e"===e||"i"===e||"o"===e||"u"===e||"y"===e?d++:c++;" "!==e&&(B+=e);if(" "===e||d>=(8<h?2:1)&&2<=c||2<=d&&c>=(8<h?2:1)||l===h-1)B&&(b[g]&&2<B.length&&g++,b[g]=b[g]?b[g]+B:B," "===e&&g++,B=""),c=d=0}return b}function G(a){for(var b="",d="",c="",g=0;g<a.length;g++){var e=a[g];if(e!==d)if(g&&"h"===e){if(c="a"===c||"e"===c||"i"===c||"o"===c||"u"===c||"y"===c,("a"===d||"e"===d||"i"===d||"o"===d||"u"===d||"y"===d)&&c||" "===d)b+=e}else b+=
e;c=g===a.length-1?"":a[g+1];d=e}return b}function R(a,b){var d=t();if(a)for(var c=0;c<a.length;c++){var g=b?b.call(C,a[c]):a[c];d[g]=String.fromCharCode(65E3-a.length+c)}return d}function S(a,b){var d=[];if(a)for(var c in a)if(a.hasOwnProperty(c)){var g=b?b.call(C,c):c;d.push(e("(?=.{"+(g.length+3)+",})"+g+"$"),b?b.call(C,a[c]):a[c])}return d}function T(a,b){a=a.length-b.length;return 0>a?1:0<a?-1:0}function U(a,b){a=a.length-b.length;return 0>a?-1:0<a?1:0}function V(a,b,d){var c=[],g=[],e=a.length;
if(1<e){a.sort(U);for(var h=t(),l=a[0],f=l.length,m=0;m<f;)h[l[m++]]=1;for(var n,u=0,p=1;p<e;){var k=!1,r=p===e-1;g=[];l=a[p];f=l.length;for(m=-1;m<f;)if(n=l[++m],h[n]){var q=h[n];if(q===p){if(r){if(c[u++]=n,b&&u===b)return c}else h[n]=p+1;k=!0}else d&&(q=g[q]?g[q]:g[q]=[],q[q.length]=n)}if(!k&&!d)break;p++}if(d&&(u=c.length,(f=g.length)&&(!b||u<b)))for(p=f-1;0<=p;p--)if(n=g[p])for(m=0;m<n.length;m++)if(c[u++]=n[m],b&&u===b)return c}else e&&(c=a[0],b&&c.length>b&&(c=c.slice(0,b)));return c}function H(a){a.C||
(a.C=K(function(){a.C=null;var b=a.async;b&&(a.async=!1);if(a.c.length){for(var d=L(),c;(c=a.c.shift())||0===c;){var g=a.f[c];switch(g[0]){case E.add:a.add(g[1],g[2]);break;case E.remove:a.remove(g[1])}delete a.f[c];if(100<L()-d)break}a.c.length&&H(a)}b&&(a.async=b)},1,"search-async-"+a.id))}function L(){return"undefined"!==typeof performance?performance.now():(new Date).getTime()}function t(a){if(a){for(var b=Array(a),d=0;d<a;d++)b[d]=Object.create(null);return b}return Object.create(null)}function W(a,
b,d,c){a=v("flexsearch","id"+a,function(){var a,b;self.onmessage=function(c){if(c=c.data)if(c.search){var d=b.search(c.content,c.threshold?{limit:c.limit,threshold:c.threshold}:c.limit);self.postMessage({id:a,content:c.content,limit:c.limit,result:d})}else c.add?b.add(c.id,c.content):c.update?b.update(c.id,c.content):c.remove?b.remove(c.id):c.reset?b.reset():c.info?(c=b.info(),c.worker=a,b.debug&&console.log(c)):c.register&&(a=c.id,c.options.cache=!1,c.options.async=!0,c.options.worker=!1,b=(new Function(c.register.substring(c.register.indexOf("{")+
1,c.register.lastIndexOf("}"))))(),b=new b(c.options))}},function(a){(a=a.data)&&a.result?c(a.id,a.content,a.result,a.limit):d.debug&&console.log(a)},b);var g=P.toString();d.id=b;a.postMessage(b,{register:g,options:d,id:b});return a}var z={encode:"icase",mode:"forward",u:!1,cache:!1,async:!1,b:!1,threshold:0,depth:0},I={memory:{encode:"extra",mode:"strict",threshold:7},speed:{encode:"icase",mode:"strict",threshold:7,depth:2},match:{encode:"extra",mode:"full"},score:{encode:"extra",mode:"strict",threshold:5,
depth:4},balance:{encode:"balance",mode:"ngram",threshold:6,depth:3},fastest:{encode:"icase",mode:"strict",threshold:9,depth:1}},F=[],Q=0,E={add:0,update:1,remove:2},M=e("[ -/]"),N=t(),O=t(),y=function(){for(var a=Object.getOwnPropertyNames({}.__proto__),b=t(),d=0;d<a.length;d++)b[a[d]]=1;return b}();f.new=function(a){return new this(a)};f.create=function(a){return f.new(a)};f.registerMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&F.push(e(b),a[b]);return this};f.registerEncoder=function(a,
b){y[a]||(C[a]=b);return this};f.registerLanguage=function(a,b){y[a]||(N[a]=b.filter,O[a]=b.stemmer);return this};f.encode=function(a,b){return y[a]?b:C[a].call(C,b)};f.prototype.init=function(a){this.B=[];a||(a=z);var b=a.profile,d=b&&!y[b]?I[b]:t();if(b=a.worker)if(Worker){var c=this;b=parseInt(b,10)||4;c.m=-1;c.o=0;c.g=[];c.A=null;c.h=Array(b);for(var g=0;g<b;g++)c.h[g]=W(c.id,g,a,function(a,b,d,g){if(c.o!==c.b)return c.g=c.g.concat(d),c.o++,g&&c.g.length>=g&&(c.o=c.b),c.A&&c.o===c.b&&(c.cache&&
c.i.set(b,c.g),c.A(c.g),c.g=[]),c})}else a.worker=!1,this.h=null;this.mode=a.mode||d.mode||this.mode||z.mode;this.async=a.async||this.async||z.async;this.b=a.worker||this.b||z.b;this.threshold=a.threshold||d.threshold||this.threshold||z.threshold;this.depth=a.depth||d.depth||this.depth||z.depth;this.u=a.suggest||this.u||z.u;this.s=(b=a.encode||d.encode)&&!y[b]&&C[b]||("function"===typeof b?b:this.s||!1);this.debug=a.debug||this.debug;(b=a.matcher)&&this.addMatcher(b);if(b=a.filter)this.filter=R(N[b]||
b,this.s);if(b=a.stemmer)this.stemmer=S(O[b]||b,this.s);this.j=t(10);this.l=t();this.a=t();this.f=t();this.c=[];this.C=null;this.v=!0;this.i=(this.cache=b=a.cache||this.cache||z.cache)?new X(b):!1;return this};f.prototype.encode=function(a){a&&F.length&&(a=x(a,F));a&&this.B.length&&(a=x(a,this.B));a&&this.s&&(a=this.s.call(C,a));a&&this.stemmer&&(a=x(a,this.stemmer));return a};f.prototype.addMatcher=function(a){var b=this.B,d;for(d in a)a.hasOwnProperty(d)&&b.push(e(d),a[d]);return this};f.prototype.add=
function(a,b,d){if("string"===typeof b&&b&&(a&&!y[a]||0===a))if(this.a[a]&&!d)this.update(a,b);else{if(this.b)return++this.m>=this.h.length&&(this.m=0),this.h[this.m].postMessage(this.m,{add:!0,id:a,content:b}),this.a[a]=""+this.m,this;if(this.async)return this.f[a]||(this.c[this.c.length]=a),this.f[a]=[E.add,a,b],H(this),this;b=this.encode(b);if(!b.length)return this;d=this.mode;b="function"===typeof d?d(b):"ngram"===d?J(b):b.split(M);var c=t();c._ctx=t();for(var g=this.threshold,e=this.depth,h=
this.j,l=b.length,f=0;f<l;f++){var m=b[f];if(m){var n=m.length,u=(l-f)/l;switch(d){case "reverse":case "both":for(var p="",k=n-1;1<=k;k--)p=m[k]+p,A(h,c,p,a,(n-k)/n,u,g);case "forward":p="";for(k=0;k<n;k++)p+=m[k],A(h,c,p,a,1,u,g);break;case "full":for(k=0;k<n;k++)for(var r=(n-k)/n,q=n;q>k;q--)p=m.substring(k,q),A(h,c,p,a,r,u,g);break;default:if(k=A(h,c,m,a,1,u,g),e&&1<l&&k>=g)for(n=c._ctx[m]||(c._ctx[m]=t()),m=this.l[m]||(this.l[m]=t(10)),k=f-e,q=f+e+1,0>k&&(k=0),q>l&&(q=l);k<q;k++)k!==f&&A(m,n,
b[k],a,0,10-(k<f?f-k:k-f),g)}}}this.a[a]="1";this.v=!1}return this};f.prototype.update=function(a,b){this.a[a]&&b&&"string"===typeof b&&(this.remove(a),this.add(a,b,!0));return this};f.prototype.remove=function(a){if(this.a[a]&&!y[a]){if(this.b){var b=parseInt(this.a[a],10);this.h[b].postMessage(b,{remove:!0,id:a});delete this.a[a];return this}if(this.async)return this.f[a]||(this.c[this.c.length]=a),this.f[a]=[E.remove,a],H(this),this;for(b=0;10>b;b++)r(this.j[b],a);this.depth&&r(this.l,a);delete this.a[a];
this.v=!1}return this};f.prototype.search=function(a,b,d){var c=[];if("object"===typeof a){d=a.callback||b;b=a.limit;var g=a.threshold;a=a.query}g||(g=this.threshold||0);"function"===typeof b?(d=b,b=1E3):b||0===b||(b=1E3);if(this.b){this.A=d;this.o=0;this.g=[];for(c=0;c<this.b;c++)this.h[c].postMessage(c,{search:!0,limit:b,threshold:g,content:a});return null}if(d){var e=this;K(function(){d(e.search(a,b));e=null},1,"search-"+this.id);return null}if(!a||"string"!==typeof a)return c;var h=a;if(this.cache)if(this.v){var f=
this.i.get(a);if(f)return f}else this.i.reset(),this.v=!0;h=this.encode(h);if(!h.length)return c;f=this.mode;h="function"===typeof f?f(h):"ngram"===f?J(h):h.split(M);f=h.length;var r=!0,m=[],n=t();if(1<f)if(this.depth){var u=!0,p=h[0];n[p]="1"}else h.sort(T);var k;if(!u||(k=this.l)[p])for(var v=u?1:0;v<f;v++){var q=h[v];if(q&&!n[q]){for(var w,z=!1,x=[],A=0,y=9;y>=g;y--)w=(u?k[p]:this.j)[y],w[q]&&(x[A++]=w[q],z=!0);if(z)m[m.length]=1<A?m.concat.apply([],x):x[0];else if(!this.u){r=!1;break}n[q]="1"}p=
q}else r=!1;r&&(c=V(m,b,this.u));this.cache&&this.i.set(a,c);return c};f.prototype.info=function(){if(this.b)for(var a=0;a<this.b;a++)this.h[a].postMessage(a,{info:!0,id:this.id});else{for(var b,d,c=0,e=0,f=0,h=0;10>h;h++)for(b=Object.keys(this.j[h]),a=0;a<b.length;a++)d=this.j[h][b[a]].length,c+=1*d+2*b[a].length+4,e+=d,f+=2*b[a].length;b=Object.keys(this.a);d=b.length;for(a=0;a<d;a++)c+=2*b[a].length+2;return{id:this.id,memory:c,items:d,sequences:e,chars:f,cache:this.c.length,matcher:F.length,worker:this.b}}};
f.prototype.reset=function(){this.destroy();return this.init()};f.prototype.destroy=function(){this.cache&&(this.i.reset(),this.i=null);this.filter=this.stemmer=this.j=this.l=this.a=this.f=this.c=null;return this};var C=Object.create({icase:function(a){return a.toLowerCase()},simple:function(){var a=[e("[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]"),"a",e("[\u00e8\u00e9\u00ea\u00eb]"),"e",e("[\u00ec\u00ed\u00ee\u00ef]"),"i",e("[\u00f2\u00f3\u00f4\u00f5\u00f6\u0151]"),"o",e("[\u00f9\u00fa\u00fb\u00fc\u0171]"),
"u",e("[\u00fd\u0177\u00ff]"),"y",e("\u00f1"),"n",e("\u00e7"),"c",e("\u00df"),"s",e(" & ")," and ",e("[-/]")," ",e("[^a-z0-9 ]"),"",e("\\s\\s+")," "];return function(b){b=x(b.toLowerCase(),a);return" "!==b?b:""}}(),advanced:function(){var a=[e("ae"),"a",e("ai"),"ei",e("ay"),"ei",e("ey"),"ei",e("oe"),"o",e("ue"),"u",e("ie"),"i",e("sz"),"s",e("zs"),"s",e("sh"),"s",e("ck"),"k",e("cc"),"k",e("dt"),"t",e("ph"),"f",e("pf"),"f",e("ou"),"o",e("uo"),"u"];return function(b,d){if(!b)return b;b=this.simple(b);
2<b.length&&(b=x(b,a));d||1<b.length&&(b=G(b));return b}}(),extra:function(){var a=[e("p"),"b",e("z"),"s",e("[cgq]"),"k",e("n"),"m",e("d"),"t",e("[vw]"),"f",e("[aeiouy]"),""];return function(b){if(!b)return b;b=this.advanced(b,!0);if(1<b.length){b=b.split(" ");for(var d=0;d<b.length;d++){var c=b[d];1<c.length&&(b[d]=c[0]+x(c.substring(1),a))}b=b.join(" ");b=G(b)}return b}}(),balance:function(){var a=[e("[-/]")," ",e("[^a-z0-9 ]"),"",e("\\s\\s+")," "];return function(b){return G(x(b.toLowerCase(),
a))}}()}),K=function(){var a=t();return function(b,d,c){var e=a[c];e&&clearTimeout(e);return a[c]=setTimeout(b,d)}}(),X=function(){function a(a){this.reset();this.w=!0!==a&&a}a.prototype.reset=function(){this.cache=t();this.count=t();this.index=t();this.a=[]};a.prototype.set=function(a,d){if(this.w&&"undefined"===typeof this.cache[a]){var b=this.a.length;if(b===this.w){b--;var e=this.a[b];delete this.cache[e];delete this.count[e];delete this.index[e]}this.index[a]=b;this.a[b]=a;this.count[a]=-1;this.cache[a]=
d;this.get(a)}else this.cache[a]=d};a.prototype.get=function(a){var b=this.cache[a];if(this.w&&b){var c=++this.count[a],e=this.index,f=e[a];if(0<f){for(var h=this.a,l=f;this.count[h[--f]]<=c&&-1!==f;);f++;if(f!==l){for(c=l;c>f;c--)l=h[c-1],h[c]=l,e[l]=c;h[f]=a;e[a]=f}}}return b};return a}();return f}(function(){var v=Object.create(null),D=!("undefined"===typeof Blob||"undefined"===typeof URL||!URL.createObjectURL);return function(f,w,e,x,A){var r=f;f=D?URL.createObjectURL(new Blob(["var SUPPORT_WORKER = true;var SUPPORT_BUILTINS = true;var SUPPORT_DEBUG = true;var SUPPORT_CACHE = true;var SUPPORT_ASYNC = true;("+
e.toString()+")()"],{type:"text/javascript"})):"../"+r+".js";r+="-"+w;v[r]||(v[r]=[]);v[r][A]=new Worker(f);v[r][A].onmessage=x;console.log("Register Worker: "+r+"@"+A);return{postMessage:function(e,f){v[r][e].postMessage(f)}}}}()),this);
'use strict';(function(v,B,f){var w;(w=f.define)&&w.amd?w([],function(){return B}):(w=f.modules)?w[v.toLowerCase()]=B:"object"===typeof exports?module.exports=B:f[v]=B})("FlexSearch",function O(v){function f(a){"string"===typeof a&&(a=H[a]);a||(a=y);this.id=a.id||P++;this.init(a);w(this,"index",function(){return this.a});w(this,"length",function(){return Object.keys(this.a).length})}function w(a,b,e){Object.defineProperty(a,b,{get:e})}function d(a){return new RegExp(a,"g")}function x(a,b,e){if("undefined"===
typeof e){for(e=0;e<b.length;e+=2)a=a.replace(b[e],b[e+1]);return a}return a.replace(b,e)}function z(a,b,e,c,k,u,g){if(b[e])return b[e];k=k?(9-(g||6))*u+(g||6)*k:u;b[e]=k;k>=g&&(a=a[k+.5>>0],a=a[e]||(a[e]=[]),a[a.length]=c);return k}function q(a,b){if(a)for(var e=Object.keys(a),c=0,k=e.length;c<k;c++){var u=e[c],g=a[u];if(g)for(var h=0,d=g.length;h<d;h++)if(g[h]===b){1===d?delete a[u]:g.splice(h,1);break}else"object"===typeof g[h]&&q(g[h],b)}}function I(a){var b=[];if(!a)return b;for(var e=0,c=0,
k=0,u="",g=a.length,h=0;h<g;h++){var d=a[h];"a"===d||"e"===d||"i"===d||"o"===d||"u"===d||"y"===d?e++:c++;" "!==d&&(u+=d);if(" "===d||e>=(8<g?2:1)&&2<=c||2<=e&&c>=(8<g?2:1)||h===g-1)u&&(b[k]&&2<u.length&&k++,b[k]=b[k]?b[k]+u:u," "===d&&k++,u=""),c=e=0}return b}function E(a){for(var b="",e="",c="",k=0;k<a.length;k++){var d=a[k];if(d!==e)if(k&&"h"===d){if(c="a"===c||"e"===c||"i"===c||"o"===c||"u"===c||"y"===c,("a"===e||"e"===e||"i"===e||"o"===e||"u"===e||"y"===e)&&c||" "===e)b+=d}else b+=d;c=k===a.length-
1?"":a[k+1];e=d}return b}function Q(a,b){var e={};if(a)for(var c=0;c<a.length;c++){var k=b?b(a[c]):a[c];e[k]=String.fromCharCode(65E3-a.length+c)}return e}function R(a,b){var e=[];if(a)for(var c in a)if(a.hasOwnProperty(c)){var k=b?b(c):c;e.push(d("(?=.{"+(k.length+3)+",})"+k+"$"),b?b(a[c]):a[c])}return e}function S(a,b){a=a.length-b.length;return 0>a?1:a?-1:0}function T(a,b){a=a.length-b.length;return 0>a?-1:a?1:0}function U(a,b,e){var c=[],k=[],d=a.length;if(1<d){a.sort(T);for(var g={},h=a[0],C=
h.length,m=0;m<C;)g[h[m++]]=1;for(var n,p=0,l=1;l<d;){var f=!1,q=l===d-1;k=[];h=a[l];C=h.length;for(m=-1;m<C;)if(n=h[++m],g[n]){var r=g[n];if(r===l){if(q){if(c[p++]=n,b&&p===b)return c}else g[n]=l+1;f=!0}else e&&(r=k[r]?k[r]:k[r]=[],r[r.length]=n)}if(!f&&!e)break;l++}if(e&&(p=c.length,(C=k.length)&&(!b||p<b)))for(l=C-1;0<=l;l--)if(n=k[l])for(m=0;m<n.length;m++)if(c[p++]=n[m],b&&p===b)return c}else d&&(c=a[0],b&&c.length>b&&(c=c.slice(0,b)));return c}function F(a){a.C||(a.C=J(function(){a.C=0;var b=
a.async;b&&(a.async=!1);if(a.c.length){for(var e=Date.now(),c;(c=a.c.shift())||0===c;){var d=a.f[c];switch(d[0]){case D.add:a.add(d[1],d[2]);break;case D.remove:a.remove(d[1])}delete a.f[c];if(100<Date.now()-e)break}a.c.length&&F(a)}b&&(a.async=b)},1,"search-async-"+a.id))}function K(a){for(var b=Array(a),e=0;e<a;e++)b[e]={};return b}function V(a,b,e,c){a=v("flexsearch","id"+a,function(){var a,b;self.onmessage=function(c){if(c=c.data)if(c.search){var e=b.search(c.content,c.threshold?{limit:c.limit,
threshold:c.threshold}:c.limit);self.postMessage({id:a,content:c.content,limit:c.limit,result:e})}else c.add?b.add(c.id,c.content):c.update?b.update(c.id,c.content):c.remove?b.remove(c.id):c.clear?b.clear():c.register&&(a=c.id,c.options.cache=!1,c.options.async=!0,c.options.worker=!1,b=(new Function(c.register.substring(c.register.indexOf("{")+1,c.register.lastIndexOf("}"))))(),b=new b(c.options))}},function(a){(a=a.data)&&a.result&&c(a.id,a.content,a.result,a.limit)},b);var d=O.toString();e.id=b;
a.postMessage(b,{register:d,options:e,id:b});return a}var y={encode:"icase",mode:"forward",s:!1,cache:!1,async:!1,b:!1,threshold:0,depth:0},H={memory:{encode:"extra",mode:"strict",threshold:7},speed:{encode:"icase",mode:"strict",threshold:7,depth:2},match:{encode:"extra",mode:"full"},score:{encode:"extra",mode:"strict",threshold:5,depth:4},balance:{encode:"balance",mode:"strict",threshold:6,depth:3},fastest:{encode:"icase",mode:"strict",threshold:9,depth:1}},G=[],P=0,D={add:0,update:1,remove:2},L=
d("[ -/]"),M={},N={};f.create=function(a){return new this(a)};f.registerMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&G.push(d(b),a[b]);return this};f.registerEncoder=function(a,b){A[a]=b.bind(A);return this};f.registerLanguage=function(a,b){M[a]=b.filter;N[a]=b.stemmer;return this};f.encode=function(a,b){return A[a](b)};f.prototype.init=function(a){this.B=[];a||(a=y);var b=a.profile,e=b?H[b]:{};if(b=a.worker)if(Worker){var c=this;b=parseInt(b,10)||4;c.l=-1;c.m=0;c.g=[];c.A=null;c.i=Array(b);
for(var d=0;d<b;d++)c.i[d]=V(c.id,d,a,function(a,b,e,d){if(c.m!==c.b)return c.g=c.g.concat(e),c.m++,d&&c.g.length>=d&&(c.m=c.b),c.A&&c.m===c.b&&(c.cache&&c.h.set(b,c.g),c.A(c.g),c.g=[]),c})}else a.worker=!1,this.i=null;this.mode=a.mode||e.mode||this.mode||y.mode;this.async=a.async||this.async||y.async;this.b=a.worker||this.b||y.b;this.threshold=a.threshold||e.threshold||this.threshold||y.threshold;this.depth=a.depth||e.depth||this.depth||y.depth;this.s=a.suggest||this.s||y.s;this.o=(b=a.encode||e.encode)&&
A[b]&&A[b].bind(A)||("function"===typeof b?b:this.o||!1);(b=a.matcher)&&this.addMatcher(b);if(b=a.filter)this.filter=Q(M[b]||b,this.o);if(b=a.stemmer)this.stemmer=R(N[b]||b,this.o);this.v=K(10);this.j={};this.a={};this.f={};this.c=[];this.C=0;this.u=!0;this.h=(this.cache=b=a.cache||this.cache||y.cache)?new W(b):!1;return this};f.prototype.encode=function(a){a&&G.length&&(a=x(a,G));a&&this.B.length&&(a=x(a,this.B));a&&this.o&&(a=this.o(a));a&&this.stemmer&&(a=x(a,this.stemmer));return a};f.prototype.addMatcher=
function(a){var b=this.B,e;for(e in a)a.hasOwnProperty(e)&&b.push(d(e),a[e]);return this};f.prototype.add=function(a,b,e){if(b&&"string"===typeof b&&(a||0===a))if(this.a[a]&&!e)this.update(a,b);else{if(this.b)return++this.l>=this.i.length&&(this.l=0),this.i[this.l].postMessage(this.l,{add:!0,id:a,content:b}),this.a[a]=""+this.l,this;if(this.async)return this.f[a]||(this.c[this.c.length]=a),this.f[a]=[D.add,a,b],F(this),this;b=this.encode(b);if(!b.length)return this;e=this.mode;b="function"===typeof e?
e(b):"ngram"===e?I(b):b.split(L);for(var c={_ctx:{}},d=this.threshold,u=this.depth,g=this.v,h=b.length,f=0;f<h;f++){var m=b[f];if(m){var n=m.length,p=(h-f)/h,l="";switch(e){case "reverse":case "both":for(var t=n-1;1<=t;t--)l=m[t]+l,z(g,c,l,a,(n-t)/n,p,d);l="";case "forward":for(t=0;t<n;t++)l+=m[t],z(g,c,l,a,1,p,d);break;case "full":for(t=0;t<n;t++)for(var q=(n-t)/n,r=n;r>t;r--)l=m.substring(t,r),z(g,c,l,a,q,p,d);break;default:if(n=z(g,c,m,a,1,p,d),u&&1<h&&n>=d)for(n=c._ctx[m]||(c._ctx[m]={}),m=this.j[m]||
(this.j[m]=K(10)),p=f-u,l=f+u+1,0>p&&(p=0),l>h&&(l=h);p<l;p++)p!==f&&z(m,n,b[p],a,0,10-(p<f?f-p:p-f),d)}}}this.a[a]="1";this.u=!1}return this};f.prototype.update=function(a,b){this.a[a]&&b&&"string"===typeof b&&(this.remove(a),this.add(a,b,!0));return this};f.prototype.remove=function(a){if(this.a[a]){if(this.b){var b=parseInt(this.a[a],10);this.i[b].postMessage(b,{remove:!0,id:a});delete this.a[a];return this}if(this.async)return this.f[a]||(this.c[this.c.length]=a),this.f[a]=[D.remove,a],F(this),
this;for(b=0;10>b;b++)q(this.v[b],a);this.depth&&q(this.j,a);delete this.a[a];this.u=!1}return this};f.prototype.search=function(a,b,e){var c=[];if("object"===typeof a){e=a.callback||b;b=a.limit;var d=a.threshold;a=a.query}d||(d=this.threshold||0);"function"===typeof b?(e=b,b=1E3):b||0===b||(b=1E3);if(this.b)for(this.A=e,this.m=0,this.g=[],c=0;c<this.b;c++)this.i[c].postMessage(c,{search:!0,limit:b,threshold:d,content:a});else if(e){var f=this;J(function(){e(f.search(a,b));f=null},1,"search-"+this.id)}else{if(!a||
"string"!==typeof a)return c;var g=a;if(this.cache)if(this.u){var h=this.h.get(a);if(h)return h}else this.h.clear(),this.u=!0;g=this.encode(g);if(!g.length)return c;h=this.mode;g="function"===typeof h?h(g):"ngram"===h?I(g):g.split(L);h=g.length;var q=!0,m=[],n={};if(1<h)if(this.depth){var p=!0;var l=g[0];n[l]="1"}else g.sort(S);var t;if(!p||(t=this.j)[l])for(var v=p?1:0;v<h;v++){var r=g[v];if(r&&!n[r]){for(var w=void 0,y=!1,x=[],z=0,A=9;A>=d;A--)w=(p?t[l]:this.v)[A],w[r]&&(x[z++]=w[r],y=!0);if(y)m[m.length]=
1<z?m.concat.apply([],x):x[0];else if(!this.s){q=!1;break}n[r]="1"}l=r}else q=!1;q&&(c=U(m,b,this.s));this.cache&&this.h.set(a,c);return c}};f.prototype.clear=function(){this.destroy();return this.init()};f.prototype.destroy=function(){this.cache&&(this.h.clear(),this.h=null);this.filter=this.stemmer=this.v=this.j=this.a=this.f=this.c=null;return this};var A={icase:function(a){return a.toLowerCase()},simple:function(){var a=[d("[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]"),"a",d("[\u00e8\u00e9\u00ea\u00eb]"),
"e",d("[\u00ec\u00ed\u00ee\u00ef]"),"i",d("[\u00f2\u00f3\u00f4\u00f5\u00f6\u0151]"),"o",d("[\u00f9\u00fa\u00fb\u00fc\u0171]"),"u",d("[\u00fd\u0177\u00ff]"),"y",d("\u00f1"),"n",d("\u00e7"),"c",d("\u00df"),"s",d(" & ")," and ",d("[-/]")," ",d("[^a-z0-9 ]"),"",d("\\s\\s+")," "];return function(b){b=x(b.toLowerCase(),a);return" "!==b?b:""}}(),advanced:function(){var a=[d("ae"),"a",d("ai"),"ei",d("ay"),"ei",d("ey"),"ei",d("oe"),"o",d("ue"),"u",d("ie"),"i",d("sz"),"s",d("zs"),"s",d("sh"),"s",d("ck"),"k",
d("cc"),"k",d("dt"),"t",d("ph"),"f",d("pf"),"f",d("ou"),"o",d("uo"),"u"];return function(b,d){if(!b)return b;b=this.simple(b);2<b.length&&(b=x(b,a));d||1<b.length&&(b=E(b));return b}}(),extra:function(){var a=[d("p"),"b",d("z"),"s",d("[cgq]"),"k",d("n"),"m",d("d"),"t",d("[vw]"),"f",d("[aeiouy]"),""];return function(b){if(!b)return b;b=this.advanced(b,!0);if(1<b.length){b=b.split(" ");for(var d=0;d<b.length;d++){var c=b[d];1<c.length&&(b[d]=c[0]+x(c.substring(1),a))}b=b.join(" ");b=E(b)}return b}}(),
balance:function(){var a=[d("[-/]")," ",d("[^a-z0-9 ]"),"",d("\\s\\s+")," "];return function(b){return E(x(b.toLowerCase(),a))}}()},J=function(){var a={};return function(b,d,c){var e=a[c];e&&clearTimeout(e);return a[c]=setTimeout(b,d)}}(),W=function(){function a(a){this.clear();this.w=!0!==a&&a}a.prototype.clear=function(){this.cache={};this.count={};this.index={};this.a=[]};a.prototype.set=function(a,d){if(this.w&&"undefined"===typeof this.cache[a]){var b=this.a.length;if(b===this.w){b--;var e=this.a[b];
delete this.cache[e];delete this.count[e];delete this.index[e]}this.index[a]=b;this.a[b]=a;this.count[a]=-1;this.cache[a]=d;this.get(a)}else this.cache[a]=d};a.prototype.get=function(a){var b=this.cache[a];if(this.w&&b){var c=++this.count[a],d=this.index,f=d[a];if(0<f){for(var g=this.a,h=f;this.count[g[--f]]<=c&&-1!==f;);f++;if(f!==h){for(c=h;c>f;c--)h=g[c-1],g[c]=h,d[h]=c;g[f]=a;d[a]=f}}}return b};return a}();return f}(function(){var v=Object.create(null),B=!("undefined"===typeof Blob||"undefined"===
typeof URL||!URL.createObjectURL);return function(f,w,d,x,z){var q=f;f=B?URL.createObjectURL(new Blob(["("+d.toString()+")()"],{type:"text/javascript"})):"../"+q+".min.js";q+="-"+w;v[q]||(v[q]=[]);v[q][z]=new Worker(f);v[q][z].onmessage=x;return{postMessage:function(d,f){v[q][d].postMessage(f)}}}}()),this);

View File

@@ -1,175 +1,178 @@
/** @define {boolean} */
var SUPPORT_LANG_DE = true;
/** @define {boolean} */ const SUPPORT_LANG_DE = true;
if(SUPPORT_LANG_DE) (function(root){
if(SUPPORT_LANG_DE) {
root['FlexSearch']['registerLanguage']('de', /** @const */ {
// noinspection ThisExpressionReferencesGlobalObjectJS
(function(root){
/**
* http://www.ranks.nl/stopwords
* @type {Array<string>}
* @export
*/
root["FlexSearch"]["registerLanguage"]("de", /** @const */ {
filter: [
/**
* http://www.ranks.nl/stopwords
* @type {Array<string>}
* @export
*/
"aber",
"als",
"am",
"an",
"auch",
"auf",
"aus",
"bei",
"bin",
"bis",
"bist",
"da",
"dadurch",
"daher",
"darum",
"das",
"daß",
"dass",
"dein",
"deine",
"dem",
"den",
"der",
"des",
"dessen",
"deshalb",
"die",
"dies",
"dieser",
"dieses",
"doch",
"dort",
"du",
"durch",
"ein",
"eine",
"einem",
"einen",
"einer",
"eines",
"er",
"es",
"euer",
"eure",
"für",
"hatte",
"hatten",
"hattest",
"hattet",
"hier",
"hinter",
"ich",
"ihr",
"ihre",
"im",
"in",
"ist",
"ja",
"jede",
"jedem",
"jeden",
"jeder",
"jedes",
"jener",
"jenes",
"jetzt",
"kann",
"kannst",
"können",
"könnt",
"machen",
"mein",
"meine",
"mit",
"muß",
"mußt",
"musst",
"müssen",
"müßt",
"nach",
"nachdem",
"nein",
"nicht",
"nun",
"oder",
"seid",
"sein",
"seine",
"sich",
"sie",
"sind",
"soll",
"sollen",
"sollst",
"sollt",
"sonst",
"soweit",
"sowie",
"und",
"unser",
"unsere",
"unter",
"vom",
"von",
"vor",
"wann",
"warum",
"was",
"weiter",
"weitere",
"wenn",
"wer",
"werde",
"werden",
"werdet",
"weshalb",
"wie",
"wieder",
"wieso",
"wir",
"wird",
"wirst",
"wo",
"woher",
"wohin",
"zu",
"zum",
"zur",
"über"
],
filter: [
/**
* @type {Object<string, string>}
* @export
*/
"aber",
"als",
"am",
"an",
"auch",
"auf",
"aus",
"bei",
"bin",
"bis",
"bist",
"da",
"dadurch",
"daher",
"darum",
"das",
"daß",
"dass",
"dein",
"deine",
"dem",
"den",
"der",
"des",
"dessen",
"deshalb",
"die",
"dies",
"dieser",
"dieses",
"doch",
"dort",
"du",
"durch",
"ein",
"eine",
"einem",
"einen",
"einer",
"eines",
"er",
"es",
"euer",
"eure",
"für",
"hatte",
"hatten",
"hattest",
"hattet",
"hier",
"hinter",
"ich",
"ihr",
"ihre",
"im",
"in",
"ist",
"ja",
"jede",
"jedem",
"jeden",
"jeder",
"jedes",
"jener",
"jenes",
"jetzt",
"kann",
"kannst",
"können",
"könnt",
"machen",
"mein",
"meine",
"mit",
"muß",
"mußt",
"musst",
"müssen",
"müßt",
"nach",
"nachdem",
"nein",
"nicht",
"nun",
"oder",
"seid",
"sein",
"seine",
"sich",
"sie",
"sind",
"soll",
"sollen",
"sollst",
"sollt",
"sonst",
"soweit",
"sowie",
"und",
"unser",
"unsere",
"unter",
"vom",
"von",
"vor",
"wann",
"warum",
"was",
"weiter",
"weitere",
"wenn",
"wer",
"werde",
"werden",
"werdet",
"weshalb",
"wie",
"wieder",
"wieso",
"wir",
"wird",
"wirst",
"wo",
"woher",
"wohin",
"zu",
"zum",
"zur",
"über"
],
stemmer: {
/**
* @type {Object<string, string>}
* @export
*/
"niss": "",
"isch": "",
"lich": "",
"heit": "",
"keit": "",
"end": "",
"ung": "",
"est": "",
"ern": "",
"em": "",
"er": "",
"en": "",
"es": "",
"st": "",
"ig": "",
"ik": "",
"e": "",
"s": ""
}
});
stemmer: {
})(this);
"niss": "",
"isch": "",
"lich": "",
"heit": "",
"keit": "",
"end": "",
"ung": "",
"est": "",
"ern": "",
"em": "",
"er": "",
"en": "",
"es": "",
"st": "",
"ig": "",
"ik": "",
"e": "",
"s": ""
}
});
})(this);
}

View File

@@ -1,279 +1,282 @@
/** @define {boolean} */
var SUPPORT_LANG_EN = true;
/** @define {boolean} */ const SUPPORT_LANG_EN = true;
if(SUPPORT_LANG_EN) (function(root){
if(SUPPORT_LANG_EN) {
root['FlexSearch']['registerLanguage']('en', /** @const */ {
// noinspection ThisExpressionReferencesGlobalObjectJS
(function(root){
/**
* http://www.ranks.nl/stopwords
* @type {Array<string>}
* @export
*/
root["FlexSearch"]["registerLanguage"]("en", /** @const */ {
filter: [
/**
* http://www.ranks.nl/stopwords
* @type {Array<string>}
* @export
*/
"a",
"about",
"above",
"after",
"again",
"against",
"all",
"also",
"am",
"an",
"and",
"any",
"are",
"aren't",
"as",
"at",
//"back",
"be",
"because",
"been",
"before",
"being",
"below",
//"between",
"both",
"but",
"by",
"can",
"cannot",
"can't",
"come",
"could",
"couldn't",
//"day",
"did",
"didn't",
"do",
"does",
"doesn't",
"doing",
"dont",
"down",
"during",
"each",
"even",
"few",
"first",
"for",
"from",
"further",
"get",
//"give",
"go",
//"good",
"had",
"hadn't",
"has",
"hasn't",
"have",
"haven't",
"having",
"he",
"hed",
//"hell",
"her",
"here",
"here's",
"hers",
"herself",
"hes",
"him",
"himself",
"his",
"how",
"how's",
"i",
"id",
"if",
"ill",
"im",
"in",
"into",
"is",
"isn't",
"it",
"it's",
"itself",
"i've",
"just",
"know",
"let's",
"like",
//"look",
"make",
"me",
"more",
"most",
"mustn't",
"my",
"myself",
"new",
"no",
"nor",
"not",
"now",
"of",
"off",
"on",
"once",
//"one",
"only",
"or",
"other",
"ought",
"our",
"our's",
"ourselves",
"out",
"over",
"own",
//"people",
"same",
"say",
"see",
"shan't",
"she",
"she'd",
"shell",
"shes",
"should",
"shouldn't",
"so",
"some",
"such",
//"take",
"than",
"that",
"that's",
"the",
"their",
"theirs",
"them",
"themselves",
"then",
"there",
"there's",
"these",
"they",
"they'd",
"they'll",
"they're",
"they've",
//"think",
"this",
"those",
"through",
"time",
"to",
"too",
//"two",
//"under",
"until",
"up",
"us",
//"use",
"very",
"want",
"was",
"wasn't",
"way",
"we",
"wed",
"well",
"were",
"weren't",
"we've",
"what",
"what's",
"when",
"when's",
"where",
"where's",
"which",
"while",
"who",
"whom",
"who's",
"why",
"why's",
"will",
"with",
"won't",
//"work",
"would",
"wouldn't",
//"year",
"you",
"you'd",
"you'll",
"your",
"you're",
"your's",
"yourself",
"yourselves",
"you've"
],
filter: [
/**
* @type {Object<string, string>}
* @export
*/
"a",
"about",
"above",
"after",
"again",
"against",
"all",
"also",
"am",
"an",
"and",
"any",
"are",
"aren't",
"as",
"at",
//"back",
"be",
"because",
"been",
"before",
"being",
"below",
//"between",
"both",
"but",
"by",
"can",
"cannot",
"can't",
"come",
"could",
"couldn't",
//"day",
"did",
"didn't",
"do",
"does",
"doesn't",
"doing",
"dont",
"down",
"during",
"each",
"even",
"few",
"first",
"for",
"from",
"further",
"get",
//"give",
"go",
//"good",
"had",
"hadn't",
"has",
"hasn't",
"have",
"haven't",
"having",
"he",
"hed",
//"hell",
"her",
"here",
"here's",
"hers",
"herself",
"hes",
"him",
"himself",
"his",
"how",
"how's",
"i",
"id",
"if",
"ill",
"im",
"in",
"into",
"is",
"isn't",
"it",
"it's",
"itself",
"i've",
"just",
"know",
"let's",
"like",
//"look",
"make",
"me",
"more",
"most",
"mustn't",
"my",
"myself",
"new",
"no",
"nor",
"not",
"now",
"of",
"off",
"on",
"once",
//"one",
"only",
"or",
"other",
"ought",
"our",
"our's",
"ourselves",
"out",
"over",
"own",
//"people",
"same",
"say",
"see",
"shan't",
"she",
"she'd",
"shell",
"shes",
"should",
"shouldn't",
"so",
"some",
"such",
//"take",
"than",
"that",
"that's",
"the",
"their",
"theirs",
"them",
"themselves",
"then",
"there",
"there's",
"these",
"they",
"they'd",
"they'll",
"they're",
"they've",
//"think",
"this",
"those",
"through",
"time",
"to",
"too",
//"two",
//"under",
"until",
"up",
"us",
//"use",
"very",
"want",
"was",
"wasn't",
"way",
"we",
"wed",
"well",
"were",
"weren't",
"we've",
"what",
"what's",
"when",
"when's",
"where",
"where's",
"which",
"while",
"who",
"whom",
"who's",
"why",
"why's",
"will",
"with",
"won't",
//"work",
"would",
"wouldn't",
//"year",
"you",
"you'd",
"you'll",
"your",
"you're",
"your's",
"yourself",
"yourselves",
"you've"
],
stemmer: {
/**
* @type {Object<string, string>}
* @export
*/
"ational": "ate",
"iveness": "ive",
"fulness": "ful",
"ousness": "ous",
"ization": "ize",
"tional": "tion",
"biliti": "ble",
"icate": "ic",
"ative": "",
"alize": "al",
"iciti": "ic",
"entli": "ent",
"ousli": "ous",
"alism": "al",
"ation": "ate",
"aliti": "al",
"iviti": "ive",
"ement": "",
"enci": "ence",
"anci": "ance",
"izer": "ize",
"alli": "al",
"ator": "ate",
"logi": "log",
"ical": "ic",
"ance": "",
"ence": "",
"ness": "",
"able": "",
"ible": "",
"ment": "",
"eli": "e",
"bli": "ble",
"ful": "",
"ant": "",
"ent": "",
"ism": "",
"ate": "",
"iti": "",
"ous": "",
"ive": "",
"ize": "",
"al": "",
"ou": "",
"er": "",
"ic": ""
}
});
stemmer: {
})(this);
"ational": "ate",
"iveness": "ive",
"fulness": "ful",
"ousness": "ous",
"ization": "ize",
"tional": "tion",
"biliti": "ble",
"icate": "ic",
"ative": "",
"alize": "al",
"iciti": "ic",
"entli": "ent",
"ousli": "ous",
"alism": "al",
"ation": "ate",
"aliti": "al",
"iviti": "ive",
"ement": "",
"enci": "ence",
"anci": "ance",
"izer": "ize",
"alli": "al",
"ator": "ate",
"logi": "log",
"ical": "ic",
"ance": "",
"ence": "",
"ness": "",
"able": "",
"ible": "",
"ment": "",
"eli": "e",
"bli": "ble",
"ful": "",
"ant": "",
"ent": "",
"ism": "",
"ate": "",
"iti": "",
"ous": "",
"ive": "",
"ize": "",
"al": "",
"ou": "",
"er": "",
"ic": ""
}
});
})(this);
}

View File

@@ -1,6 +1,6 @@
{
"name": "flexsearch",
"version": "0.2.70",
"version": "0.3.0",
"description": "Next-Generation full text search library with zero dependencies.",
"homepage": "https://github.com/nextapps-de/flexsearch/",
"author": "Thomas Wilkerling",
@@ -24,16 +24,17 @@
"url": "https://github.com/nextapps-de/flexsearch.git"
},
"scripts": {
"build": "node compile RELEASE=min SUPPORT_DEBUG=true SUPPORT_WORKER=true SUPPORT_BUILTINS=true SUPPORT_CACHE=true SUPPORT_ASYNC=true && exit 0",
"build-light": "node compile RELEASE=light && exit 0",
"build-custom": "node compile",
"build-lang": "node compile RELEASE=lang && exit 0",
"build-all": "npm run build && npm run build-light && npm run build-lang",
"build": "node compile RELEASE=min DEBUG=false PROFILER=false SUPPORT_WORKER=true SUPPORT_ENCODER=true SUPPORT_CACHE=true SUPPORT_ASYNC=true SUPPORT_PRESETS=true SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false",
"build-light": "node compile RELEASE=light DEBUG=false PROFILER=false SUPPORT_WORKER=false SUPPORT_ENCODER=false SUPPORT_CACHE=false SUPPORT_ASYNC=false SUPPORT_PRESETS=false SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false",
"build-compact": "node compile RELEASE=compact DEBUG=false PROFILER=false SUPPORT_WORKER=false SUPPORT_ENCODER=true SUPPORT_CACHE=true SUPPORT_ASYNC=false SUPPORT_PRESETS=true SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false",
"build-custom": "node compile RELEASE=custom DEBUG=false PROFILER=false SUPPORT_WORKER=false SUPPORT_ENCODER=false SUPPORT_CACHE=false SUPPORT_ASYNC=false SUPPORT_PRESETS=false SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false",
"build-lang": "node compile RELEASE=lang",
"build-all": "npm run build && npm run build-light && npm run build-compact && npm run build-lang",
"test-production": "nyc --reporter=html --reporter=text mocha --timeout=3000 test --exit",
"test-light": "nyc --reporter=html --reporter=text mocha --timeout=3000 test/ --exit",
"test-develop": "nyc --reporter=html --reporter=text mocha --timeout=3000 --exit",
"test-browser": "mocha-phantomjs test/index.html",
"test": "npm run test-develop && npm run test-production && npm run test-browser",
"test": "npm run test-develop && npm run test-production && npm run test-light && npm run test-browser",
"update": "node_modules/.bin/updtr --to non-breaking",
"coverage": "nyc report --reporter=lcov --reporter=text-lcov | coveralls"
},
@@ -49,11 +50,11 @@
"readme": "README.md",
"dependencies": {},
"devDependencies": {
"chai": "^4.1.2",
"codacy-coverage": "^3.0.0",
"coveralls": "^3.0.1",
"chai": "^4.2.0",
"codacy-coverage": "^3.4.0",
"coveralls": "^3.0.2",
"google-closure-compiler": "^20190124.0.0-nightly",
"mocha": "^5.1.1",
"mocha": "^5.2.0",
"mocha-lcov-reporter": "^1.3.0",
"mocha-phantomjs": "^4.1.0",
"nyc": "^13.1.0",

469
test/benchmark.html Normal file
View File

@@ -0,0 +1,469 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Benchmark</title>
<style>
body{
font-family: sans-serif;
}
table td{
padding: 1em 2em;
}
button{
padding: 5px 10px;
}
</style>
</head>
<body>
<h2>Benchmark Comparison</h2>
<button id="btn_start" onclick="start();" disabled>Start</button>
<h4>Indexed Text: "Gulliver's Travels" (Swift Jonathan 1726)</h4>
<hr>
<div id="container"></div>
<hr>
Test rules: 1. no cache allowed, 2. no async allowed, 3. should return at least 7 entries for the query "Gulliver".
<script src="https://rawgit.com/nextapps-de/flexsearch/master/flexsearch.light.js"></script>
<script src="https://rawgit.com/nextapps-de/bulksearch/master/bulksearch.light.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/elasticlunr/0.9.6/elasticlunr.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/olivernn/lunr.js@2.3.5/lunr.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/kbrsh/wade@0.3.3/dist/wade.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.3.0/fuse.min.js"></script>
<script src="https://unpkg.com/js-search@1.4.2/dist/umd/js-search.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/karussell/jsii@master/web/js/src/BitSet.js"></script>
<script src="https://cdn.jsdelivr.net/gh/karussell/jsii@master/web/js/src/JSii.js"></script>
<script src="https://rawgit.com/vlad-x/a25e0c5c1eeb6bf6aa38/raw/02d1a1703e4a99a7c733c85097f583579f6af4e2/bm25.js"></script>
<script src="../data/gulliver.js"></script>
<script>
//var data = [];
(function(){
var bulksearch;
var flexsearch;
// var flexsearch_cache;
// var flexsearch_worker;
// var flexsearch_cache_scale;
var elasticsearch;
var lunrsearch;
var wade;
//var wadesearch;
var fuse;
var jssearch;
var jsii;
var bm25;
var tests = {
flexsearch: {
init: function(){
flexsearch = new FlexSearch({
encode: "icase",
mode: "strict",
threshold: 9,
depth: 0,
async: false,
cache: false,
worker: false
});
},
add: function(index, content){
flexsearch.add(index, content);
},
query: function(query){
return flexsearch.search(query);
},
loops: 275000
},
/*
flexsearch_cache_unbound: {
init: function(){
flexsearch_cache = new FlexSearch({
encode: "icase",
mode: "strict",
threshold: 9,
depth: 1,
async: false,
cache: true,
worker: false
});
},
add: function(index, content){
flexsearch_cache.add(index, content);
},
query: function(query){
return flexsearch_cache.search(query);
},
loops: 1000000
},
*/
/*
flexsearch_cache_balanced: {
init: function(){
flexsearch_cache_scale = new FlexSearch({
encode: "icase",
mode: "strict",
threshold: 9,
depth: 1,
async: false,
cache: 100,
worker: false
});
},
add: function(index, content){
flexsearch_cache_scale.add(index, content);
},
query: function(query){
return flexsearch_cache_scale.search(query);
},
loops: 1000000
},
*/
/*
flexsearch_worker: {
init: function(){
flexsearch_worker = new FlexSearch({
encode: "icase",
mode: "strict",
threshold: 9,
depth: 1,
async: true,
cache: false,
worker: 4
});
},
add: function(index, content){
flexsearch_worker.add(index, content);
},
query: async function(query){
return await new Promise(function(resolve){
flexsearch_worker.search(query, resolve);
});
},
loops: 5000
},
*/
bulksearch: {
init: function(){
bulksearch = new BulkSearch({
type: "short", // this type specifies the maximum bitlength of assigned IDs!
encode: "icase",
multi: false,
async: false,
cache: false,
worker: false
});
},
add: function(index, content){
bulksearch.add(index, content);
},
query: function(query){
return bulksearch.search(query);
},
loops: 250
},
elasticlunr: {
init: function(){
elasticsearch = elasticlunr(function(){
this.setRef("id");
this.addField("content");
});
},
add: function(index, content){
elasticsearch.addDoc({id: index, content: content});
},
query: function(query){
return elasticsearch.search(query)/*.map(function(val){return val.ref})*/;
},
loops: 100
},
lunr: {
init: function(){
lunrsearch = lunr(function(){
this.ref("id");
this.field("content");
for(var i = 0; i < text_data.length; i++){
this.add({id: i, content: text_data[i]});
}
});
},
add: function(index, content){},
query: function(query){
return lunrsearch.search(query)/*.map(function(val){return val.ref})*/;
},
loops: 350
},
wade: {
init: function(){
// wadesearch = function(query){
// return wade(query)/*.sort(sort_by_score_down)*/;
// };
//
// function sort_by_score_down(a, b){
// var sum = a.score - b.score;
// return sum < 0 ? 1 : sum > 0 ? -1 : 0;
// }
wade = Wade(text_data.slice(0));
},
add: function(index, content){},
query: function(query){
return wade(query)/*.map(function(val){return val.index})*/;
},
loops: 1500
},
fuse: {
init: function(){
var payload = [];
for(var i = 0; i < text_data.length; i++){
payload[i] = {id: i, content: text_data[i]};
}
fuse = new Fuse(payload, {
keys: ["content"],
id: "id",
shouldSort: true,
threshold: 0.6,
location: 0,
distance: 100,
findAllMatches: true,
maxPatternLength: 32,
minMatchCharLength: 1
});
},
add: function(index, content){},
query: function(query){
return fuse.search(query);
},
loops: 1
},
jssearch: {
init: function(){
var payload = [];
for(var i = 0; i < text_data.length; i++){
payload[i] = {id: i, content: text_data[i]};
}
jssearch = new JsSearch.Search("id");
jssearch.addIndex("content");
jssearch.addDocuments(payload);
},
add: function(index, content){},
query: function(query){
return jssearch.search(query)/*.map(function(val){return val.id})*/;
},
loops: 800
},
jsii: {
init: function(){
var payload = [];
for(var i = 0; i < text_data.length; i++){
payload[i] = {id: i, text: text_data[i]};
}
jsii = new JSii();
jsii.feedDocs(payload);
},
add: function(index, content){},
query: function(query){
return jsii.search(query)/*.docs.map(function(val){return val.id})*/;
},
loops: 600
},
bm25: {
init: function(){
bm25 = new BM25();
for(var i = 0; i < text_data.length; i++){
bm25.addDocument({id: i, body: text_data[i]});
}
bm25.updateIdf();
},
add: function(index, content){},
query: function(query){
return bm25.search(query)/*.map(function(val){return val.id})*/;
},
loops: 95
}
};
function init_container(target){
var html = "<table>" +
"<tr>" +
"<th>Library</th>" +
"<th>Benchmark</th>" +
"</tr>";
for(var test in tests){
if(tests.hasOwnProperty(test)){
html += "<tr>" +
"<td>" + test + "</td>" +
"<td id=\"test-" + test + "\">wait ...</td>" +
"</tr>"
}
}
html += "</table>";
target.innerHTML = html;
}
function init_tests(index, keys){
var key = keys[index];
tests[key].init();
for(var i = 0; i < text_data.length; i++){
tests[key].add(i, text_data[i]);
}
document.getElementById("test-" + key).textContent = "ready ...";
if(++index < keys.length){
setTimeout(function(){
init_tests(index, keys);
}, 50);
}
else{
window.start = function(){
start_tests(0, Object.keys(tests));
};
document.getElementById("btn_start").disabled = false;
/*
setTimeout(function(){
start_tests(0, keys);
}, 50);
*/
}
}
function start_tests(index, keys){
var queries = text_queries;
var len = queries.length;
var key = keys[index];
var current = tests[key];
var loops = current.loops;
var query = current.query;
var start = Date.now();
for(var i = 0; i < len; i++){
var tmp = queries[i];
for(var x = 0; x < loops; x++){
query(tmp);
}
}
var duration = Date.now() - start;
console.log(key + ":", duration);
document.getElementById("test-" + key).textContent = format_number((1000 / duration * loops + 0.5) >> 0) + " op/s";
if(++index < keys.length){
setTimeout(function(){
start_tests(index, keys);
}, 50);
}
}
init_container(document.getElementById("container"));
setTimeout(function(){
init_tests(0, Object.keys(tests));
}, 50);
function format_number(num){
return ("" + num).replace(/(\d)(?=(\d{3})+\b)/g, '$1,');
}
// ---------------------------------------
window.tests = tests;
})();
</script>
</body>
</html>

View File

@@ -19,8 +19,9 @@
mocha.reporter('html');
mocha.setup('bdd');
var expect = chai.expect;
var env = "min";
</script>
<script src="../test/test.js"></script>
<script src="test.js"></script>
<script>
if(window.mochaPhantomJS) {

File diff suppressed because it is too large Load Diff