kea-rails 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kea-rails/version.rb +1 -1
- data/vendor/assets/components/Keypress/LICENSE +191 -0
- data/vendor/assets/components/Keypress/README.md +78 -0
- data/vendor/assets/components/Keypress/bower.json +28 -0
- data/vendor/assets/components/Keypress/keypress-2.1.0.min.js +33 -0
- data/vendor/assets/components/Keypress/keypress.coffee +921 -0
- data/vendor/assets/components/Keypress/keypress.js +1132 -0
- data/vendor/assets/components/Keypress/package.json +15 -0
- data/vendor/assets/components/attachejs/attache-jquery.js +47 -0
- data/vendor/assets/components/attachejs/attache-knockout.js +56 -0
- data/vendor/assets/components/attachejs/attache.css +10 -0
- data/vendor/assets/components/attachejs/attache.js +589 -0
- data/vendor/assets/components/attachejs/bower.json +36 -0
- data/vendor/assets/components/humane-js/bower.json +8 -0
- data/vendor/assets/components/humane-js/changelog.md +165 -0
- data/vendor/assets/components/humane-js/humane.js +238 -0
- data/vendor/assets/components/humane-js/humane.min.js +11 -0
- data/vendor/assets/components/humane-js/index.html +190 -0
- data/vendor/assets/components/humane-js/package.json +25 -0
- data/vendor/assets/components/humane-js/readme.md +85 -0
- data/vendor/assets/components/humane-js/test/issue23.html +11 -0
- data/vendor/assets/components/humane-js/test/issue36.html +9 -0
- data/vendor/assets/components/humane-js/test/issue38.html +15 -0
- data/vendor/assets/components/humane-js/test/issue49.html +9 -0
- data/vendor/assets/components/humane-js/theme-src/bigbox.styl +65 -0
- data/vendor/assets/components/humane-js/theme-src/boldlight.styl +64 -0
- data/vendor/assets/components/humane-js/theme-src/jackedup.styl +69 -0
- data/vendor/assets/components/humane-js/theme-src/libnotify.styl +61 -0
- data/vendor/assets/components/humane-js/theme-src/original.styl +51 -0
- data/vendor/assets/components/humane-js/themes/bigbox.css +123 -0
- data/vendor/assets/components/humane-js/themes/boldlight.css +122 -0
- data/vendor/assets/components/humane-js/themes/flatty.css +94 -0
- data/vendor/assets/components/humane-js/themes/jackedup.css +123 -0
- data/vendor/assets/components/humane-js/themes/libnotify.css +115 -0
- data/vendor/assets/components/humane-js/themes/original.css +72 -0
- data/vendor/assets/components/knockout-sortable/README.md +129 -0
- data/vendor/assets/components/knockout-sortable/bower.json +15 -0
- data/vendor/assets/components/knockout-sortable/build/knockout-sortable.js +358 -0
- data/vendor/assets/components/knockout-sortable/build/knockout-sortable.min.js +2 -0
- data/vendor/assets/components/uri.js/README.md +437 -0
- data/vendor/assets/components/uri.js/URI.jquery.json +38 -0
- data/vendor/assets/components/uri.js/about-uris.html +156 -0
- data/vendor/assets/components/uri.js/build.html +66 -0
- data/vendor/assets/components/uri.js/build.js +78 -0
- data/vendor/assets/components/uri.js/component.json +15 -0
- data/vendor/assets/components/uri.js/contribute.md +11 -0
- data/vendor/assets/components/uri.js/docs.html +1280 -0
- data/vendor/assets/components/uri.js/index.html +173 -0
- data/vendor/assets/components/uri.js/jquery-1.10.2.min.js +6 -0
- data/vendor/assets/components/uri.js/jquery-1.7.2.min.js +4 -0
- data/vendor/assets/components/uri.js/jquery-1.8.2.min.js +2 -0
- data/vendor/assets/components/uri.js/jquery-1.9.1.min.js +5 -0
- data/vendor/assets/components/uri.js/jquery-uri-plugin.html +203 -0
- data/vendor/assets/components/uri.js/package.json +75 -0
- data/vendor/assets/components/uri.js/prettify/lang-apollo.js +2 -0
- data/vendor/assets/components/uri.js/prettify/lang-clj.js +18 -0
- data/vendor/assets/components/uri.js/prettify/lang-css.js +2 -0
- data/vendor/assets/components/uri.js/prettify/lang-go.js +1 -0
- data/vendor/assets/components/uri.js/prettify/lang-hs.js +2 -0
- data/vendor/assets/components/uri.js/prettify/lang-lisp.js +3 -0
- data/vendor/assets/components/uri.js/prettify/lang-lua.js +2 -0
- data/vendor/assets/components/uri.js/prettify/lang-ml.js +2 -0
- data/vendor/assets/components/uri.js/prettify/lang-n.js +4 -0
- data/vendor/assets/components/uri.js/prettify/lang-proto.js +1 -0
- data/vendor/assets/components/uri.js/prettify/lang-scala.js +2 -0
- data/vendor/assets/components/uri.js/prettify/lang-sql.js +2 -0
- data/vendor/assets/components/uri.js/prettify/lang-tex.js +1 -0
- data/vendor/assets/components/uri.js/prettify/lang-vb.js +2 -0
- data/vendor/assets/components/uri.js/prettify/lang-vhdl.js +3 -0
- data/vendor/assets/components/uri.js/prettify/lang-wiki.js +2 -0
- data/vendor/assets/components/uri.js/prettify/lang-xq.js +3 -0
- data/vendor/assets/components/uri.js/prettify/lang-yaml.js +2 -0
- data/vendor/assets/components/uri.js/prettify/prettify.css +1 -0
- data/vendor/assets/components/uri.js/prettify/prettify.js +28 -0
- data/vendor/assets/components/uri.js/prettify/prettify.sunburst.css +52 -0
- data/vendor/assets/components/uri.js/screen.css +167 -0
- data/vendor/assets/components/uri.js/screen.js +39 -0
- data/vendor/assets/components/uri.js/src/IPv6.js +185 -0
- data/vendor/assets/components/uri.js/src/SecondLevelDomains.js +220 -0
- data/vendor/assets/components/uri.js/src/URI.fragmentQuery.js +103 -0
- data/vendor/assets/components/uri.js/src/URI.fragmentURI.js +96 -0
- data/vendor/assets/components/uri.js/src/URI.js +1938 -0
- data/vendor/assets/components/uri.js/src/URI.min.js +81 -0
- data/vendor/assets/components/uri.js/src/URITemplate.js +494 -0
- data/vendor/assets/components/uri.js/src/jquery.URI.js +232 -0
- data/vendor/assets/components/uri.js/src/jquery.URI.min.js +7 -0
- data/vendor/assets/components/uri.js/src/punycode.js +508 -0
- data/vendor/assets/components/uri.js/test/index.html +26 -0
- data/vendor/assets/components/uri.js/test/pre_libs.js +4 -0
- data/vendor/assets/components/uri.js/test/qunit/qunit-composite.css +13 -0
- data/vendor/assets/components/uri.js/test/qunit/qunit-composite.js +167 -0
- data/vendor/assets/components/uri.js/test/qunit/qunit.css +244 -0
- data/vendor/assets/components/uri.js/test/qunit/qunit.js +2212 -0
- data/vendor/assets/components/uri.js/test/test.URI.html +26 -0
- data/vendor/assets/components/uri.js/test/test.fragmentQuery.html +31 -0
- data/vendor/assets/components/uri.js/test/test.fragmentURI.html +31 -0
- data/vendor/assets/components/uri.js/test/test.jQuery-1.10.html +31 -0
- data/vendor/assets/components/uri.js/test/test.jQuery-1.7.html +31 -0
- data/vendor/assets/components/uri.js/test/test.jQuery-1.8.html +31 -0
- data/vendor/assets/components/uri.js/test/test.jQuery-1.9.html +31 -0
- data/vendor/assets/components/uri.js/test/test.js +1409 -0
- data/vendor/assets/components/uri.js/test/test_fragmentQuery.js +57 -0
- data/vendor/assets/components/uri.js/test/test_fragmentURI.js +59 -0
- data/vendor/assets/components/uri.js/test/test_jim.js +143 -0
- data/vendor/assets/components/uri.js/test/test_jquery.js +138 -0
- data/vendor/assets/components/uri.js/test/test_template.js +385 -0
- data/vendor/assets/components/uri.js/test/urls.js +1236 -0
- data/vendor/assets/components/uri.js/uri-template.html +234 -0
- data/vendor/assets/components/uri.js/utils/SLDs.php +37 -0
- data/vendor/assets/components/uri.js/utils/sld.js +101 -0
- data/vendor/assets/components/veiljs/bower.json +36 -0
- data/vendor/assets/components/veiljs/veil-jquery.js +47 -0
- data/vendor/assets/components/veiljs/veil-knockout.js +55 -0
- data/vendor/assets/components/veiljs/veil.js +465 -0
- data/vendor/assets/javascripts/fuse.js +472 -0
- data/vendor/assets/javascripts/jquery-ui.js +3844 -0
- data/vendor/assets/javascripts/knockout-3.2.0-debug.js +5299 -0
- data/vendor/assets/javascripts/moment.js +1902 -0
- data/vendor/assets/javascripts/pikaday.js +896 -0
- data/vendor/assets/stylesheets/pikaday.css +171 -0
- metadata +120 -1
@@ -0,0 +1,472 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Fuse - Lightweight fuzzy-search
|
4
|
+
*
|
5
|
+
* Copyright (c) 2012 Kirollos Risk <kirollos@gmail.com>.
|
6
|
+
* All Rights Reserved. Apache Software License 2.0
|
7
|
+
*
|
8
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
* you may not use this file except in compliance with the License.
|
10
|
+
* You may obtain a copy of the License at
|
11
|
+
*
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
*
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
* See the License for the specific language governing permissions and
|
18
|
+
* limitations under the License.
|
19
|
+
*/
|
20
|
+
(function(global) {
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Adapted from "Diff, Match and Patch", by Google
|
24
|
+
*
|
25
|
+
* http://code.google.com/p/google-diff-match-patch/
|
26
|
+
*
|
27
|
+
* Modified by: Kirollos Risk <kirollos@gmail.com>
|
28
|
+
* -----------------------------------------------
|
29
|
+
* Details: the algorithm and structure was modified to allow the creation of
|
30
|
+
* <Searcher> instances with a <search> method which does the actual
|
31
|
+
* bitap search. The <pattern> (the string that is searched for) is only defined
|
32
|
+
* once per instance and thus it eliminates redundant re-creation when searching
|
33
|
+
* over a list of strings.
|
34
|
+
*
|
35
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
36
|
+
* you may not use this file except in compliance with the License.
|
37
|
+
*/
|
38
|
+
var BitapSearcher = function(pattern, options) {
|
39
|
+
options = options || {};
|
40
|
+
this.options = options;
|
41
|
+
this.options.location = options.location || BitapSearcher.defaultOptions.location;
|
42
|
+
this.options.distance = 'distance' in options ? options.distance : BitapSearcher.defaultOptions.distance;
|
43
|
+
this.options.threshold = 'threshold' in options ? options.threshold : BitapSearcher.defaultOptions.threshold;
|
44
|
+
this.options.maxPatternLength = options.maxPatternLength || BitapSearcher.defaultOptions.maxPatternLength;
|
45
|
+
|
46
|
+
this.pattern = options.caseSensitive ? pattern : pattern.toLowerCase();
|
47
|
+
this.patternLen = pattern.length;
|
48
|
+
|
49
|
+
if (this.patternLen > this.options.maxPatternLength) {
|
50
|
+
throw new Error('Pattern length is too long');
|
51
|
+
}
|
52
|
+
|
53
|
+
this.matchmask = 1 << (this.patternLen - 1);
|
54
|
+
this.patternAlphabet = this._calculatePatternAlphabet();
|
55
|
+
};
|
56
|
+
|
57
|
+
BitapSearcher.defaultOptions = {
|
58
|
+
// Approximately where in the text is the pattern expected to be found?
|
59
|
+
location: 0,
|
60
|
+
|
61
|
+
// Determines how close the match must be to the fuzzy location (specified above).
|
62
|
+
// An exact letter match which is 'distance' characters away from the fuzzy location
|
63
|
+
// would score as a complete mismatch. A distance of '0' requires the match be at
|
64
|
+
// the exact location specified, a threshold of '1000' would require a perfect match
|
65
|
+
// to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.
|
66
|
+
distance: 100,
|
67
|
+
|
68
|
+
// At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match
|
69
|
+
// (of both letters and location), a threshold of '1.0' would match anything.
|
70
|
+
threshold: 0.6,
|
71
|
+
|
72
|
+
// Machine word size
|
73
|
+
maxPatternLength: 32
|
74
|
+
};
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Initialize the alphabet for the Bitap algorithm.
|
78
|
+
* @return {Object} Hash of character locations.
|
79
|
+
* @private
|
80
|
+
*/
|
81
|
+
BitapSearcher.prototype._calculatePatternAlphabet = function() {
|
82
|
+
var mask = {},
|
83
|
+
i = 0;
|
84
|
+
|
85
|
+
for (i = 0; i < this.patternLen; i++) {
|
86
|
+
mask[this.pattern.charAt(i)] = 0;
|
87
|
+
}
|
88
|
+
|
89
|
+
for (i = 0; i < this.patternLen; i++) {
|
90
|
+
mask[this.pattern.charAt(i)] |= 1 << (this.pattern.length - i - 1);
|
91
|
+
}
|
92
|
+
|
93
|
+
return mask;
|
94
|
+
};
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Compute and return the score for a match with `e` errors and `x` location.
|
98
|
+
* @param {number} errors Number of errors in match.
|
99
|
+
* @param {number} location Location of match.
|
100
|
+
* @return {number} Overall score for match (0.0 = good, 1.0 = bad).
|
101
|
+
* @private
|
102
|
+
*/
|
103
|
+
BitapSearcher.prototype._bitapScore = function(errors, location) {
|
104
|
+
var accuracy = errors / this.patternLen,
|
105
|
+
proximity = Math.abs(this.options.location - location);
|
106
|
+
|
107
|
+
if (!this.options.distance) {
|
108
|
+
// Dodge divide by zero error.
|
109
|
+
return proximity ? 1.0 : accuracy;
|
110
|
+
}
|
111
|
+
return accuracy + (proximity / this.options.distance);
|
112
|
+
};
|
113
|
+
|
114
|
+
/**
|
115
|
+
* Compute and return the result of the search
|
116
|
+
* @param {String} text The text to search in
|
117
|
+
* @return {Object} Literal containing:
|
118
|
+
* {Boolean} isMatch Whether the text is a match or not
|
119
|
+
* {Decimal} score Overall score for the match
|
120
|
+
* @public
|
121
|
+
*/
|
122
|
+
BitapSearcher.prototype.search = function(text) {
|
123
|
+
text = this.options.caseSensitive ? text : text.toLowerCase();
|
124
|
+
|
125
|
+
if (this.pattern === text) {
|
126
|
+
// Exact match
|
127
|
+
return {
|
128
|
+
isMatch: true,
|
129
|
+
score: 0
|
130
|
+
};
|
131
|
+
}
|
132
|
+
|
133
|
+
var i, j,
|
134
|
+
// Set starting location at beginning text and initialize the alphabet.
|
135
|
+
textLen = text.length,
|
136
|
+
LOCATION = this.options.location,
|
137
|
+
// Highest score beyond which we give up.
|
138
|
+
THRESHOLD = this.options.threshold,
|
139
|
+
// Is there a nearby exact match? (speedup)
|
140
|
+
bestLoc = text.indexOf(this.pattern, LOCATION),
|
141
|
+
binMin, binMid,
|
142
|
+
binMax = this.patternLen + textLen,
|
143
|
+
start, finish,
|
144
|
+
bitArr, lastBitArr,
|
145
|
+
charMatch,
|
146
|
+
score = 1,
|
147
|
+
locations = [];
|
148
|
+
|
149
|
+
if (bestLoc != -1) {
|
150
|
+
THRESHOLD = Math.min(this._bitapScore(0, bestLoc), THRESHOLD);
|
151
|
+
// What about in the other direction? (speedup)
|
152
|
+
bestLoc = text.lastIndexOf(this.pattern, LOCATION + this.patternLen);
|
153
|
+
|
154
|
+
if (bestLoc != -1) {
|
155
|
+
THRESHOLD = Math.min(this._bitapScore(0, bestLoc), THRESHOLD);
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
bestLoc = -1;
|
160
|
+
|
161
|
+
for (i = 0; i < this.patternLen; i++) {
|
162
|
+
// Scan for the best match; each iteration allows for one more error.
|
163
|
+
// Run a binary search to determine how far from 'MATCH_LOCATION' we can stray at this
|
164
|
+
// error level.
|
165
|
+
binMin = 0;
|
166
|
+
binMid = binMax;
|
167
|
+
while (binMin < binMid) {
|
168
|
+
if (this._bitapScore(i, LOCATION + binMid) <= THRESHOLD) {
|
169
|
+
binMin = binMid;
|
170
|
+
} else {
|
171
|
+
binMax = binMid;
|
172
|
+
}
|
173
|
+
binMid = Math.floor((binMax - binMin) / 2 + binMin);
|
174
|
+
}
|
175
|
+
|
176
|
+
// Use the result from this iteration as the maximum for the next.
|
177
|
+
binMax = binMid;
|
178
|
+
start = Math.max(1, LOCATION - binMid + 1);
|
179
|
+
finish = Math.min(LOCATION + binMid, textLen) + this.patternLen;
|
180
|
+
|
181
|
+
// Initialize the bit array
|
182
|
+
bitArr = Array(finish + 2);
|
183
|
+
|
184
|
+
bitArr[finish + 1] = (1 << i) - 1;
|
185
|
+
|
186
|
+
for (j = finish; j >= start; j--) {
|
187
|
+
// The alphabet <patternAlphabet> is a sparse hash, so the following line generates warnings.
|
188
|
+
charMatch = this.patternAlphabet[text.charAt(j - 1)];
|
189
|
+
|
190
|
+
if (i === 0) {
|
191
|
+
// First pass: exact match.
|
192
|
+
bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch;
|
193
|
+
} else {
|
194
|
+
// Subsequent passes: fuzzy match.
|
195
|
+
bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch | (((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1) | lastBitArr[j + 1];
|
196
|
+
}
|
197
|
+
if (bitArr[j] & this.matchmask) {
|
198
|
+
score = this._bitapScore(i, j - 1);
|
199
|
+
// This match will almost certainly be better than any existing match.
|
200
|
+
// But check anyway.
|
201
|
+
if (score <= THRESHOLD) {
|
202
|
+
// Told you so.
|
203
|
+
THRESHOLD = score;
|
204
|
+
bestLoc = j - 1;
|
205
|
+
locations.push(bestLoc);
|
206
|
+
|
207
|
+
if (bestLoc > LOCATION) {
|
208
|
+
// When passing loc, don't exceed our current distance from loc.
|
209
|
+
start = Math.max(1, 2 * LOCATION - bestLoc);
|
210
|
+
} else {
|
211
|
+
// Already passed loc, downhill from here on in.
|
212
|
+
break;
|
213
|
+
}
|
214
|
+
}
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
// No hope for a (better) match at greater error levels.
|
219
|
+
if (this._bitapScore(i + 1, LOCATION) > THRESHOLD) {
|
220
|
+
break;
|
221
|
+
}
|
222
|
+
lastBitArr = bitArr;
|
223
|
+
}
|
224
|
+
|
225
|
+
return {
|
226
|
+
isMatch: bestLoc >= 0,
|
227
|
+
score: score
|
228
|
+
};
|
229
|
+
};
|
230
|
+
|
231
|
+
var deepValueHelper = function(obj, path, list) {
|
232
|
+
var firstSegment, remaining, dotIndex;
|
233
|
+
|
234
|
+
if (!path) {
|
235
|
+
// If there's no path left, we've gotten to the object we care about.
|
236
|
+
list.push(obj);
|
237
|
+
} else {
|
238
|
+
dotIndex = path.indexOf('.');
|
239
|
+
if (dotIndex !== -1) {
|
240
|
+
firstSegment = path.slice(0, dotIndex);
|
241
|
+
remaining = path.slice(dotIndex + 1);
|
242
|
+
} else {
|
243
|
+
firstSegment = path;
|
244
|
+
}
|
245
|
+
|
246
|
+
var value = obj[firstSegment];
|
247
|
+
if (value) {
|
248
|
+
if (!remaining && (typeof value === 'string' || typeof value === 'number')) {
|
249
|
+
list.push(value);
|
250
|
+
} else if (Utils.isArray(value)) {
|
251
|
+
// Search each item in the array.
|
252
|
+
for (var i = 0, len = value.length; i < len; i++) {
|
253
|
+
deepValueHelper(value[i], remaining, list);
|
254
|
+
}
|
255
|
+
} else if (remaining) {
|
256
|
+
// An object. Recurse further.
|
257
|
+
deepValueHelper(value, remaining, list);
|
258
|
+
}
|
259
|
+
}
|
260
|
+
}
|
261
|
+
|
262
|
+
return list;
|
263
|
+
};
|
264
|
+
|
265
|
+
var Utils = {
|
266
|
+
/**
|
267
|
+
* Traverse an object
|
268
|
+
* @param {Object} obj The object to traverse
|
269
|
+
* @param {String} path A . separated path to a key in the object. Example 'Data.Object.Somevalue'
|
270
|
+
* @return {Object}
|
271
|
+
*/
|
272
|
+
deepValue: function(obj, path) {
|
273
|
+
return deepValueHelper(obj, path, []);
|
274
|
+
},
|
275
|
+
isArray: function(obj) {
|
276
|
+
return Object.prototype.toString.call(obj) === '[object Array]';
|
277
|
+
}
|
278
|
+
};
|
279
|
+
|
280
|
+
/**
|
281
|
+
* @param {Array} list
|
282
|
+
* @param {Object} options
|
283
|
+
* @public
|
284
|
+
*/
|
285
|
+
function Fuse(list, options) {
|
286
|
+
this.list = list;
|
287
|
+
this.options = options = options || {};
|
288
|
+
|
289
|
+
var i, len, key, keys;
|
290
|
+
// Add boolean type options
|
291
|
+
for (i = 0, keys = ['sort', 'includeScore', 'shouldSort'], len = keys.length; i < len; i++) {
|
292
|
+
key = keys[i];
|
293
|
+
this.options[key] = key in options ? options[key] : Fuse.defaultOptions[key];
|
294
|
+
}
|
295
|
+
// Add all other options
|
296
|
+
for (i = 0, keys = ['searchFn', 'sortFn', 'keys', 'getFn'], len = keys.length; i < len; i++) {
|
297
|
+
key = keys[i];
|
298
|
+
this.options[key] = options[key] || Fuse.defaultOptions[key];
|
299
|
+
}
|
300
|
+
};
|
301
|
+
|
302
|
+
Fuse.defaultOptions = {
|
303
|
+
id: null,
|
304
|
+
|
305
|
+
caseSensitive: false,
|
306
|
+
|
307
|
+
// Whether the score should be included in the result set.
|
308
|
+
// When <true>, each result in the list will be of the form: `{ item: ..., score: ... }`
|
309
|
+
includeScore: false,
|
310
|
+
|
311
|
+
// Whether to sort the result list, by score
|
312
|
+
shouldSort: true,
|
313
|
+
|
314
|
+
// The search function to use
|
315
|
+
// Note that the default search function ([[Function]]) must conform to the following API:
|
316
|
+
//
|
317
|
+
// @param pattern The pattern string to search
|
318
|
+
// @param options The search option
|
319
|
+
// [[Function]].constructor = function(pattern, options)
|
320
|
+
//
|
321
|
+
// @param text: the string to search in for the pattern
|
322
|
+
// @return Object in the form of:
|
323
|
+
// - isMatch: boolean
|
324
|
+
// - score: Int
|
325
|
+
// [[Function]].prototype.search = function(text)
|
326
|
+
searchFn: BitapSearcher,
|
327
|
+
|
328
|
+
// Default sort function
|
329
|
+
sortFn: function(a, b) {
|
330
|
+
return a.score - b.score;
|
331
|
+
},
|
332
|
+
|
333
|
+
// Default get function
|
334
|
+
getFn: Utils.deepValue,
|
335
|
+
|
336
|
+
keys: []
|
337
|
+
};
|
338
|
+
|
339
|
+
/**
|
340
|
+
* Searches for all the items whose keys (fuzzy) match the pattern.
|
341
|
+
* @param {String} pattern The pattern string to fuzzy search on.
|
342
|
+
* @return {Array} A list of all serch matches.
|
343
|
+
* @public
|
344
|
+
*/
|
345
|
+
Fuse.prototype.search = function(pattern) {
|
346
|
+
var searcher = new(this.options.searchFn)(pattern, this.options),
|
347
|
+
j, item,
|
348
|
+
list = this.list,
|
349
|
+
dataLen = list.length,
|
350
|
+
options = this.options,
|
351
|
+
searchKeys = this.options.keys,
|
352
|
+
searchKeysLen = searchKeys.length,
|
353
|
+
bitapResult,
|
354
|
+
rawResults = [],
|
355
|
+
resultMap = {},
|
356
|
+
existingResult,
|
357
|
+
results = [];
|
358
|
+
|
359
|
+
/**
|
360
|
+
* Calls <Searcher::search> for bitap analysis. Builds the raw result list.
|
361
|
+
* @param {String} text The pattern string to fuzzy search on.
|
362
|
+
* @param {String|Number} entity If the <data> is an Array, then entity will be an index,
|
363
|
+
* otherwise it's the item object.
|
364
|
+
* @param {Number} index
|
365
|
+
* @private
|
366
|
+
*/
|
367
|
+
var analyzeText = function(text, entity, index) {
|
368
|
+
// Check if the text can be searched
|
369
|
+
if (text === undefined || text === null) {
|
370
|
+
return;
|
371
|
+
}
|
372
|
+
|
373
|
+
if (typeof text === 'string') {
|
374
|
+
|
375
|
+
// Get the result
|
376
|
+
bitapResult = searcher.search(text);
|
377
|
+
|
378
|
+
// If a match is found, add the item to <rawResults>, including its score
|
379
|
+
if (bitapResult.isMatch) {
|
380
|
+
|
381
|
+
// Check if the item already exists in our results
|
382
|
+
existingResult = resultMap[index];
|
383
|
+
if (existingResult) {
|
384
|
+
// Use the lowest score
|
385
|
+
existingResult.score = Math.min(existingResult.score, bitapResult.score);
|
386
|
+
} else {
|
387
|
+
// Add it to the raw result list
|
388
|
+
resultMap[index] = {
|
389
|
+
item: entity,
|
390
|
+
score: bitapResult.score
|
391
|
+
};
|
392
|
+
rawResults.push(resultMap[index]);
|
393
|
+
}
|
394
|
+
}
|
395
|
+
} else if (Utils.isArray(text)) {
|
396
|
+
for (var i = 0; i < text.length; i++) {
|
397
|
+
analyzeText(text[i], entity, index);
|
398
|
+
}
|
399
|
+
}
|
400
|
+
};
|
401
|
+
|
402
|
+
// Check the first item in the list, if it's a string, then we assume
|
403
|
+
// that every item in the list is also a string, and thus it's a flattened array.
|
404
|
+
if (typeof list[0] === 'string') {
|
405
|
+
// Iterate over every item
|
406
|
+
for (var i = 0; i < dataLen; i++) {
|
407
|
+
analyzeText(list[i], i, i);
|
408
|
+
}
|
409
|
+
} else {
|
410
|
+
// Otherwise, the first item is an Object (hopefully), and thus the searching
|
411
|
+
// is done on the values of the keys of each item.
|
412
|
+
|
413
|
+
// Iterate over every item
|
414
|
+
for (var i = 0; i < dataLen; i++) {
|
415
|
+
item = list[i];
|
416
|
+
// Iterate over every key
|
417
|
+
for (j = 0; j < searchKeysLen; j++) {
|
418
|
+
analyzeText(options.getFn(item, searchKeys[j]), item, i);
|
419
|
+
}
|
420
|
+
}
|
421
|
+
}
|
422
|
+
|
423
|
+
if (options.shouldSort) {
|
424
|
+
rawResults.sort(options.sortFn);
|
425
|
+
}
|
426
|
+
|
427
|
+
// Helper function, here for speed-up, which returns the
|
428
|
+
// the raw item, including the score, or simply the item itself, depending
|
429
|
+
// on the specified option
|
430
|
+
var getItem = options.includeScore ? function(i) {
|
431
|
+
return rawResults[i];
|
432
|
+
} : function(i) {
|
433
|
+
return rawResults[i].item;
|
434
|
+
};
|
435
|
+
|
436
|
+
// Helper function, here for speed-up, which replaces the item with its value,
|
437
|
+
// if the options specifies it,
|
438
|
+
var replaceValue = options.id ? function(i) {
|
439
|
+
rawResults[i].item = options.getFn(rawResults[i].item, options.id)[0];
|
440
|
+
} : function() {
|
441
|
+
return; // no-op
|
442
|
+
};
|
443
|
+
|
444
|
+
// From the results, push into a new array only the item identifier (if specified)
|
445
|
+
// of the entire item. This is because we don't want to return the <rawResults>,
|
446
|
+
// since it contains other metadata;
|
447
|
+
for (var i = 0, len = rawResults.length; i < len; i++) {
|
448
|
+
// replace the item with its value, which can be its id if the options specifies it
|
449
|
+
replaceValue(i);
|
450
|
+
results.push(getItem(i));
|
451
|
+
}
|
452
|
+
|
453
|
+
return results;
|
454
|
+
};
|
455
|
+
|
456
|
+
// Export to Common JS Loader
|
457
|
+
if (typeof exports === 'object') {
|
458
|
+
// Node. Does not work with strict CommonJS, but
|
459
|
+
// only CommonJS-like environments that support module.exports,
|
460
|
+
// like Node.
|
461
|
+
module.exports = Fuse;
|
462
|
+
} else if (typeof define === 'function' && define.amd) {
|
463
|
+
// AMD. Register as an anonymous module.
|
464
|
+
define(function() {
|
465
|
+
return Fuse;
|
466
|
+
});
|
467
|
+
} else {
|
468
|
+
// Browser globals (root is window)
|
469
|
+
global.Fuse = Fuse;
|
470
|
+
}
|
471
|
+
|
472
|
+
})(this);
|