fuzzaldrin-plus.js (31588B)
1 /* fuzzaldrin-plus - v0.5.0 - @license: MIT; @author: Jean Christophe Roy; @site: https://github.com/jeancroy/fuzzaldrin-plus */ 2 3 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.fuzzaldrin = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 4 (function() { 5 var Query, pathScorer, pluckCandidates, scorer, sortCandidates; 6 7 scorer = require('./scorer'); 8 9 pathScorer = require('./pathScorer'); 10 11 Query = require('./query'); 12 13 pluckCandidates = function(a) { 14 return a.candidate; 15 }; 16 17 sortCandidates = function(a, b) { 18 return b.score - a.score; 19 }; 20 21 module.exports = function(candidates, query, options) { 22 var bKey, candidate, key, maxInners, maxResults, score, scoreProvider, scoredCandidates, spotLeft, string, usePathScoring, _i, _len; 23 scoredCandidates = []; 24 key = options.key, maxResults = options.maxResults, maxInners = options.maxInners, usePathScoring = options.usePathScoring; 25 spotLeft = (maxInners != null) && maxInners > 0 ? maxInners : candidates.length + 1; 26 bKey = key != null; 27 scoreProvider = usePathScoring ? pathScorer : scorer; 28 for (_i = 0, _len = candidates.length; _i < _len; _i++) { 29 candidate = candidates[_i]; 30 string = bKey ? candidate[key] : candidate; 31 if (!string) { 32 continue; 33 } 34 score = scoreProvider.score(string, query, options); 35 if (score > 0) { 36 scoredCandidates.push({ 37 candidate: candidate, 38 score: score 39 }); 40 if (!--spotLeft) { 41 break; 42 } 43 } 44 } 45 scoredCandidates.sort(sortCandidates); 46 candidates = scoredCandidates.map(pluckCandidates); 47 if (maxResults != null) { 48 candidates = candidates.slice(0, maxResults); 49 } 50 return candidates; 51 }; 52 53 }).call(this); 54 55 },{"./pathScorer":4,"./query":5,"./scorer":6}],2:[function(require,module,exports){ 56 (function (process){ 57 (function() { 58 var Query, defaultPathSeparator, filter, matcher, parseOptions, pathScorer, preparedQueryCache, scorer; 59 60 filter = require('./filter'); 61 62 matcher = require('./matcher'); 63 64 scorer = require('./scorer'); 65 66 pathScorer = require('./pathScorer'); 67 68 Query = require('./query'); 69 70 preparedQueryCache = null; 71 72 defaultPathSeparator = (typeof process !== "undefined" && process !== null ? process.platform : void 0) === "win32" ? '\\' : '/'; 73 74 module.exports = { 75 filter: function(candidates, query, options) { 76 if (options == null) { 77 options = {}; 78 } 79 if (!((query != null ? query.length : void 0) && (candidates != null ? candidates.length : void 0))) { 80 return []; 81 } 82 options = parseOptions(options, query); 83 return filter(candidates, query, options); 84 }, 85 score: function(string, query, options) { 86 if (options == null) { 87 options = {}; 88 } 89 if (!((string != null ? string.length : void 0) && (query != null ? query.length : void 0))) { 90 return 0; 91 } 92 options = parseOptions(options, query); 93 if (options.usePathScoring) { 94 return pathScorer.score(string, query, options); 95 } else { 96 return scorer.score(string, query, options); 97 } 98 }, 99 match: function(string, query, options) { 100 var _i, _ref, _results; 101 if (options == null) { 102 options = {}; 103 } 104 if (!string) { 105 return []; 106 } 107 if (!query) { 108 return []; 109 } 110 if (string === query) { 111 return (function() { 112 _results = []; 113 for (var _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); } 114 return _results; 115 }).apply(this); 116 } 117 options = parseOptions(options, query); 118 return matcher.match(string, query, options); 119 }, 120 wrap: function(string, query, options) { 121 if (options == null) { 122 options = {}; 123 } 124 if (!string) { 125 return []; 126 } 127 if (!query) { 128 return []; 129 } 130 options = parseOptions(options, query); 131 return matcher.wrap(string, query, options); 132 }, 133 prepareQuery: function(query, options) { 134 if (options == null) { 135 options = {}; 136 } 137 options = parseOptions(options, query); 138 return options.preparedQuery; 139 } 140 }; 141 142 parseOptions = function(options, query) { 143 if (options.allowErrors == null) { 144 options.allowErrors = false; 145 } 146 if (options.usePathScoring == null) { 147 options.usePathScoring = true; 148 } 149 if (options.useExtensionBonus == null) { 150 options.useExtensionBonus = false; 151 } 152 if (options.pathSeparator == null) { 153 options.pathSeparator = defaultPathSeparator; 154 } 155 if (options.optCharRegEx == null) { 156 options.optCharRegEx = null; 157 } 158 if (options.wrap == null) { 159 options.wrap = null; 160 } 161 if (options.preparedQuery == null) { 162 options.preparedQuery = preparedQueryCache && preparedQueryCache.query === query ? preparedQueryCache : (preparedQueryCache = new Query(query, options)); 163 } 164 return options; 165 }; 166 167 }).call(this); 168 169 }).call(this,require('_process')) 170 },{"./filter":1,"./matcher":3,"./pathScorer":4,"./query":5,"./scorer":6,"_process":7}],3:[function(require,module,exports){ 171 (function() { 172 var basenameMatch, computeMatch, isMatch, isWordStart, match, mergeMatches, scoreAcronyms, scoreCharacter, scoreConsecutives, _ref; 173 174 _ref = require('./scorer'), isMatch = _ref.isMatch, isWordStart = _ref.isWordStart, scoreConsecutives = _ref.scoreConsecutives, scoreCharacter = _ref.scoreCharacter, scoreAcronyms = _ref.scoreAcronyms; 175 176 exports.match = match = function(string, query, options) { 177 var allowErrors, baseMatches, matches, pathSeparator, preparedQuery, string_lw; 178 allowErrors = options.allowErrors, preparedQuery = options.preparedQuery, pathSeparator = options.pathSeparator; 179 if (!(allowErrors || isMatch(string, preparedQuery.core_lw, preparedQuery.core_up))) { 180 return []; 181 } 182 string_lw = string.toLowerCase(); 183 matches = computeMatch(string, string_lw, preparedQuery); 184 if (matches.length === 0) { 185 return matches; 186 } 187 if (string.indexOf(pathSeparator) > -1) { 188 baseMatches = basenameMatch(string, string_lw, preparedQuery, pathSeparator); 189 matches = mergeMatches(matches, baseMatches); 190 } 191 return matches; 192 }; 193 194 exports.wrap = function(string, query, options) { 195 var matchIndex, matchPos, matchPositions, output, strPos, tagClass, tagClose, tagOpen, _ref1; 196 if ((options.wrap != null)) { 197 _ref1 = options.wrap, tagClass = _ref1.tagClass, tagOpen = _ref1.tagOpen, tagClose = _ref1.tagClose; 198 } 199 if (tagClass == null) { 200 tagClass = 'highlight'; 201 } 202 if (tagOpen == null) { 203 tagOpen = '<strong class="' + tagClass + '">'; 204 } 205 if (tagClose == null) { 206 tagClose = '</strong>'; 207 } 208 if (string === query) { 209 return tagOpen + string + tagClose; 210 } 211 matchPositions = match(string, query, options); 212 if (matchPositions.length === 0) { 213 return string; 214 } 215 output = ''; 216 matchIndex = -1; 217 strPos = 0; 218 while (++matchIndex < matchPositions.length) { 219 matchPos = matchPositions[matchIndex]; 220 if (matchPos > strPos) { 221 output += string.substring(strPos, matchPos); 222 strPos = matchPos; 223 } 224 while (++matchIndex < matchPositions.length) { 225 if (matchPositions[matchIndex] === matchPos + 1) { 226 matchPos++; 227 } else { 228 matchIndex--; 229 break; 230 } 231 } 232 matchPos++; 233 if (matchPos > strPos) { 234 output += tagOpen; 235 output += string.substring(strPos, matchPos); 236 output += tagClose; 237 strPos = matchPos; 238 } 239 } 240 if (strPos <= string.length - 1) { 241 output += string.substring(strPos); 242 } 243 return output; 244 }; 245 246 basenameMatch = function(subject, subject_lw, preparedQuery, pathSeparator) { 247 var basePos, depth, end; 248 end = subject.length - 1; 249 while (subject[end] === pathSeparator) { 250 end--; 251 } 252 basePos = subject.lastIndexOf(pathSeparator, end); 253 if (basePos === -1) { 254 return []; 255 } 256 depth = preparedQuery.depth; 257 while (depth-- > 0) { 258 basePos = subject.lastIndexOf(pathSeparator, basePos - 1); 259 if (basePos === -1) { 260 return []; 261 } 262 } 263 basePos++; 264 end++; 265 return computeMatch(subject.slice(basePos, end), subject_lw.slice(basePos, end), preparedQuery, basePos); 266 }; 267 268 mergeMatches = function(a, b) { 269 var ai, bj, i, j, m, n, out; 270 m = a.length; 271 n = b.length; 272 if (n === 0) { 273 return a.slice(); 274 } 275 if (m === 0) { 276 return b.slice(); 277 } 278 i = -1; 279 j = 0; 280 bj = b[j]; 281 out = []; 282 while (++i < m) { 283 ai = a[i]; 284 while (bj <= ai && ++j < n) { 285 if (bj < ai) { 286 out.push(bj); 287 } 288 bj = b[j]; 289 } 290 out.push(ai); 291 } 292 while (j < n) { 293 out.push(b[j++]); 294 } 295 return out; 296 }; 297 298 computeMatch = function(subject, subject_lw, preparedQuery, offset) { 299 var DIAGONAL, LEFT, STOP, UP, acro_score, align, backtrack, csc_diag, csc_row, csc_score, i, j, m, matches, move, n, pos, query, query_lw, score, score_diag, score_row, score_up, si_lw, start, trace; 300 if (offset == null) { 301 offset = 0; 302 } 303 query = preparedQuery.query; 304 query_lw = preparedQuery.query_lw; 305 m = subject.length; 306 n = query.length; 307 acro_score = scoreAcronyms(subject, subject_lw, query, query_lw).score; 308 score_row = new Array(n); 309 csc_row = new Array(n); 310 STOP = 0; 311 UP = 1; 312 LEFT = 2; 313 DIAGONAL = 3; 314 trace = new Array(m * n); 315 pos = -1; 316 j = -1; 317 while (++j < n) { 318 score_row[j] = 0; 319 csc_row[j] = 0; 320 } 321 i = -1; 322 while (++i < m) { 323 score = 0; 324 score_up = 0; 325 csc_diag = 0; 326 si_lw = subject_lw[i]; 327 j = -1; 328 while (++j < n) { 329 csc_score = 0; 330 align = 0; 331 score_diag = score_up; 332 if (query_lw[j] === si_lw) { 333 start = isWordStart(i, subject, subject_lw); 334 csc_score = csc_diag > 0 ? csc_diag : scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start); 335 align = score_diag + scoreCharacter(i, j, start, acro_score, csc_score); 336 } 337 score_up = score_row[j]; 338 csc_diag = csc_row[j]; 339 if (score > score_up) { 340 move = LEFT; 341 } else { 342 score = score_up; 343 move = UP; 344 } 345 if (align > score) { 346 score = align; 347 move = DIAGONAL; 348 } else { 349 csc_score = 0; 350 } 351 score_row[j] = score; 352 csc_row[j] = csc_score; 353 trace[++pos] = score > 0 ? move : STOP; 354 } 355 } 356 i = m - 1; 357 j = n - 1; 358 pos = i * n + j; 359 backtrack = true; 360 matches = []; 361 while (backtrack && i >= 0 && j >= 0) { 362 switch (trace[pos]) { 363 case UP: 364 i--; 365 pos -= n; 366 break; 367 case LEFT: 368 j--; 369 pos--; 370 break; 371 case DIAGONAL: 372 matches.push(i + offset); 373 j--; 374 i--; 375 pos -= n + 1; 376 break; 377 default: 378 backtrack = false; 379 } 380 } 381 matches.reverse(); 382 return matches; 383 }; 384 385 }).call(this); 386 387 },{"./scorer":6}],4:[function(require,module,exports){ 388 (function() { 389 var computeScore, countDir, file_coeff, getExtension, getExtensionScore, isMatch, scorePath, scoreSize, tau_depth, _ref; 390 391 _ref = require('./scorer'), isMatch = _ref.isMatch, computeScore = _ref.computeScore, scoreSize = _ref.scoreSize; 392 393 tau_depth = 13; 394 395 file_coeff = 1.5; 396 397 exports.score = function(string, query, options) { 398 var allowErrors, preparedQuery, score, string_lw; 399 preparedQuery = options.preparedQuery, allowErrors = options.allowErrors; 400 if (!(allowErrors || isMatch(string, preparedQuery.core_lw, preparedQuery.core_up))) { 401 return 0; 402 } 403 string_lw = string.toLowerCase(); 404 score = computeScore(string, string_lw, preparedQuery); 405 score = scorePath(string, string_lw, score, options); 406 return Math.ceil(score); 407 }; 408 409 scorePath = function(subject, subject_lw, fullPathScore, options) { 410 var alpha, basePathScore, basePos, depth, end, extAdjust, fileLength, pathSeparator, preparedQuery, useExtensionBonus; 411 if (fullPathScore === 0) { 412 return 0; 413 } 414 preparedQuery = options.preparedQuery, useExtensionBonus = options.useExtensionBonus, pathSeparator = options.pathSeparator; 415 end = subject.length - 1; 416 while (subject[end] === pathSeparator) { 417 end--; 418 } 419 basePos = subject.lastIndexOf(pathSeparator, end); 420 fileLength = end - basePos; 421 extAdjust = 1.0; 422 if (useExtensionBonus) { 423 extAdjust += getExtensionScore(subject_lw, preparedQuery.ext, basePos, end, 2); 424 fullPathScore *= extAdjust; 425 } 426 if (basePos === -1) { 427 return fullPathScore; 428 } 429 depth = preparedQuery.depth; 430 while (basePos > -1 && depth-- > 0) { 431 basePos = subject.lastIndexOf(pathSeparator, basePos - 1); 432 } 433 basePathScore = basePos === -1 ? fullPathScore : extAdjust * computeScore(subject.slice(basePos + 1, end + 1), subject_lw.slice(basePos + 1, end + 1), preparedQuery); 434 alpha = 0.5 * tau_depth / (tau_depth + countDir(subject, end + 1, pathSeparator)); 435 return alpha * basePathScore + (1 - alpha) * fullPathScore * scoreSize(0, file_coeff * fileLength); 436 }; 437 438 exports.countDir = countDir = function(path, end, pathSeparator) { 439 var count, i; 440 if (end < 1) { 441 return 0; 442 } 443 count = 0; 444 i = -1; 445 while (++i < end && path[i] === pathSeparator) { 446 continue; 447 } 448 while (++i < end) { 449 if (path[i] === pathSeparator) { 450 count++; 451 while (++i < end && path[i] === pathSeparator) { 452 continue; 453 } 454 } 455 } 456 return count; 457 }; 458 459 exports.getExtension = getExtension = function(str) { 460 var pos; 461 pos = str.lastIndexOf("."); 462 if (pos < 0) { 463 return ""; 464 } else { 465 return str.substr(pos + 1); 466 } 467 }; 468 469 getExtensionScore = function(candidate, ext, startPos, endPos, maxDepth) { 470 var m, matched, n, pos; 471 if (!ext.length) { 472 return 0; 473 } 474 pos = candidate.lastIndexOf(".", endPos); 475 if (!(pos > startPos)) { 476 return 0; 477 } 478 n = ext.length; 479 m = endPos - pos; 480 if (m < n) { 481 n = m; 482 m = ext.length; 483 } 484 pos++; 485 matched = -1; 486 while (++matched < n) { 487 if (candidate[pos + matched] !== ext[matched]) { 488 break; 489 } 490 } 491 if (matched === 0 && maxDepth > 0) { 492 return 0.9 * getExtensionScore(candidate, ext, startPos, pos - 2, maxDepth - 1); 493 } 494 return matched / m; 495 }; 496 497 }).call(this); 498 499 },{"./scorer":6}],5:[function(require,module,exports){ 500 (function() { 501 var Query, coreChars, countDir, getCharCodes, getExtension, opt_char_re, truncatedUpperCase, _ref; 502 503 _ref = require("./pathScorer"), countDir = _ref.countDir, getExtension = _ref.getExtension; 504 505 module.exports = Query = (function() { 506 function Query(query, _arg) { 507 var optCharRegEx, pathSeparator, _ref1; 508 _ref1 = _arg != null ? _arg : {}, optCharRegEx = _ref1.optCharRegEx, pathSeparator = _ref1.pathSeparator; 509 if (!(query && query.length)) { 510 return null; 511 } 512 this.query = query; 513 this.query_lw = query.toLowerCase(); 514 this.core = coreChars(query, optCharRegEx); 515 this.core_lw = this.core.toLowerCase(); 516 this.core_up = truncatedUpperCase(this.core); 517 this.depth = countDir(query, query.length, pathSeparator); 518 this.ext = getExtension(this.query_lw); 519 this.charCodes = getCharCodes(this.query_lw); 520 } 521 522 return Query; 523 524 })(); 525 526 opt_char_re = /[ _\-:\/\\]/g; 527 528 coreChars = function(query, optCharRegEx) { 529 if (optCharRegEx == null) { 530 optCharRegEx = opt_char_re; 531 } 532 return query.replace(optCharRegEx, ''); 533 }; 534 535 truncatedUpperCase = function(str) { 536 var char, upper, _i, _len; 537 upper = ""; 538 for (_i = 0, _len = str.length; _i < _len; _i++) { 539 char = str[_i]; 540 upper += char.toUpperCase()[0]; 541 } 542 return upper; 543 }; 544 545 getCharCodes = function(str) { 546 var charCodes, i, len; 547 len = str.length; 548 i = -1; 549 charCodes = []; 550 while (++i < len) { 551 charCodes[str.charCodeAt(i)] = true; 552 } 553 return charCodes; 554 }; 555 556 }).call(this); 557 558 },{"./pathScorer":4}],6:[function(require,module,exports){ 559 (function() { 560 var AcronymResult, computeScore, emptyAcronymResult, isAcronymFullWord, isMatch, isSeparator, isWordEnd, isWordStart, miss_coeff, pos_bonus, scoreAcronyms, scoreCharacter, scoreConsecutives, scoreExact, scoreExactMatch, scorePattern, scorePosition, scoreSize, tau_size, wm; 561 562 wm = 150; 563 564 pos_bonus = 20; 565 566 tau_size = 85; 567 568 miss_coeff = 0.75; 569 570 exports.score = function(string, query, options) { 571 var allowErrors, preparedQuery, score, string_lw; 572 preparedQuery = options.preparedQuery, allowErrors = options.allowErrors; 573 if (!(allowErrors || isMatch(string, preparedQuery.core_lw, preparedQuery.core_up))) { 574 return 0; 575 } 576 string_lw = string.toLowerCase(); 577 score = computeScore(string, string_lw, preparedQuery); 578 return Math.ceil(score); 579 }; 580 581 exports.isMatch = isMatch = function(subject, query_lw, query_up) { 582 var i, j, m, n, qj_lw, qj_up, si; 583 m = subject.length; 584 n = query_lw.length; 585 if (!m || n > m) { 586 return false; 587 } 588 i = -1; 589 j = -1; 590 while (++j < n) { 591 qj_lw = query_lw.charCodeAt(j); 592 qj_up = query_up.charCodeAt(j); 593 while (++i < m) { 594 si = subject.charCodeAt(i); 595 if (si === qj_lw || si === qj_up) { 596 break; 597 } 598 } 599 if (i === m) { 600 return false; 601 } 602 } 603 return true; 604 }; 605 606 exports.computeScore = computeScore = function(subject, subject_lw, preparedQuery) { 607 var acro, acro_score, align, csc_diag, csc_row, csc_score, csc_should_rebuild, i, j, m, miss_budget, miss_left, n, pos, query, query_lw, record_miss, score, score_diag, score_row, score_up, si_lw, start, sz; 608 query = preparedQuery.query; 609 query_lw = preparedQuery.query_lw; 610 m = subject.length; 611 n = query.length; 612 acro = scoreAcronyms(subject, subject_lw, query, query_lw); 613 acro_score = acro.score; 614 if (acro.count === n) { 615 return scoreExact(n, m, acro_score, acro.pos); 616 } 617 pos = subject_lw.indexOf(query_lw); 618 if (pos > -1) { 619 return scoreExactMatch(subject, subject_lw, query, query_lw, pos, n, m); 620 } 621 score_row = new Array(n); 622 csc_row = new Array(n); 623 sz = scoreSize(n, m); 624 miss_budget = Math.ceil(miss_coeff * n) + 5; 625 miss_left = miss_budget; 626 csc_should_rebuild = true; 627 j = -1; 628 while (++j < n) { 629 score_row[j] = 0; 630 csc_row[j] = 0; 631 } 632 i = -1; 633 while (++i < m) { 634 si_lw = subject_lw[i]; 635 if (!si_lw.charCodeAt(0) in preparedQuery.charCodes) { 636 if (csc_should_rebuild) { 637 j = -1; 638 while (++j < n) { 639 csc_row[j] = 0; 640 } 641 csc_should_rebuild = false; 642 } 643 continue; 644 } 645 score = 0; 646 score_diag = 0; 647 csc_diag = 0; 648 record_miss = true; 649 csc_should_rebuild = true; 650 j = -1; 651 while (++j < n) { 652 score_up = score_row[j]; 653 if (score_up > score) { 654 score = score_up; 655 } 656 csc_score = 0; 657 if (query_lw[j] === si_lw) { 658 start = isWordStart(i, subject, subject_lw); 659 csc_score = csc_diag > 0 ? csc_diag : scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start); 660 align = score_diag + scoreCharacter(i, j, start, acro_score, csc_score); 661 if (align > score) { 662 score = align; 663 miss_left = miss_budget; 664 } else { 665 if (record_miss && --miss_left <= 0) { 666 return Math.max(score, score_row[n - 1]) * sz; 667 } 668 record_miss = false; 669 } 670 } 671 score_diag = score_up; 672 csc_diag = csc_row[j]; 673 csc_row[j] = csc_score; 674 score_row[j] = score; 675 } 676 } 677 score = score_row[n - 1]; 678 return score * sz; 679 }; 680 681 exports.isWordStart = isWordStart = function(pos, subject, subject_lw) { 682 var curr_s, prev_s; 683 if (pos === 0) { 684 return true; 685 } 686 curr_s = subject[pos]; 687 prev_s = subject[pos - 1]; 688 return isSeparator(prev_s) || (curr_s !== subject_lw[pos] && prev_s === subject_lw[pos - 1]); 689 }; 690 691 exports.isWordEnd = isWordEnd = function(pos, subject, subject_lw, len) { 692 var curr_s, next_s; 693 if (pos === len - 1) { 694 return true; 695 } 696 curr_s = subject[pos]; 697 next_s = subject[pos + 1]; 698 return isSeparator(next_s) || (curr_s === subject_lw[pos] && next_s !== subject_lw[pos + 1]); 699 }; 700 701 isSeparator = function(c) { 702 return c === ' ' || c === '.' || c === '-' || c === '_' || c === '/' || c === '\\'; 703 }; 704 705 scorePosition = function(pos) { 706 var sc; 707 if (pos < pos_bonus) { 708 sc = pos_bonus - pos; 709 return 100 + sc * sc; 710 } else { 711 return Math.max(100 + pos_bonus - pos, 0); 712 } 713 }; 714 715 exports.scoreSize = scoreSize = function(n, m) { 716 return tau_size / (tau_size + Math.abs(m - n)); 717 }; 718 719 scoreExact = function(n, m, quality, pos) { 720 return 2 * n * (wm * quality + scorePosition(pos)) * scoreSize(n, m); 721 }; 722 723 exports.scorePattern = scorePattern = function(count, len, sameCase, start, end) { 724 var bonus, sz; 725 sz = count; 726 bonus = 6; 727 if (sameCase === count) { 728 bonus += 2; 729 } 730 if (start) { 731 bonus += 3; 732 } 733 if (end) { 734 bonus += 1; 735 } 736 if (count === len) { 737 if (start) { 738 if (sameCase === len) { 739 sz += 2; 740 } else { 741 sz += 1; 742 } 743 } 744 if (end) { 745 bonus += 1; 746 } 747 } 748 return sameCase + sz * (sz + bonus); 749 }; 750 751 exports.scoreCharacter = scoreCharacter = function(i, j, start, acro_score, csc_score) { 752 var posBonus; 753 posBonus = scorePosition(i); 754 if (start) { 755 return posBonus + wm * ((acro_score > csc_score ? acro_score : csc_score) + 10); 756 } 757 return posBonus + wm * csc_score; 758 }; 759 760 exports.scoreConsecutives = scoreConsecutives = function(subject, subject_lw, query, query_lw, i, j, startOfWord) { 761 var k, m, mi, n, nj, sameCase, sz; 762 m = subject.length; 763 n = query.length; 764 mi = m - i; 765 nj = n - j; 766 k = mi < nj ? mi : nj; 767 sameCase = 0; 768 sz = 0; 769 if (query[j] === subject[i]) { 770 sameCase++; 771 } 772 while (++sz < k && query_lw[++j] === subject_lw[++i]) { 773 if (query[j] === subject[i]) { 774 sameCase++; 775 } 776 } 777 if (sz < k) { 778 i--; 779 } 780 if (sz === 1) { 781 return 1 + 2 * sameCase; 782 } 783 return scorePattern(sz, n, sameCase, startOfWord, isWordEnd(i, subject, subject_lw, m)); 784 }; 785 786 exports.scoreExactMatch = scoreExactMatch = function(subject, subject_lw, query, query_lw, pos, n, m) { 787 var end, i, pos2, sameCase, start; 788 start = isWordStart(pos, subject, subject_lw); 789 if (!start) { 790 pos2 = subject_lw.indexOf(query_lw, pos + 1); 791 if (pos2 > -1) { 792 start = isWordStart(pos2, subject, subject_lw); 793 if (start) { 794 pos = pos2; 795 } 796 } 797 } 798 i = -1; 799 sameCase = 0; 800 while (++i < n) { 801 if (query[pos + i] === subject[i]) { 802 sameCase++; 803 } 804 } 805 end = isWordEnd(pos + n - 1, subject, subject_lw, m); 806 return scoreExact(n, m, scorePattern(n, n, sameCase, start, end), pos); 807 }; 808 809 AcronymResult = (function() { 810 function AcronymResult(score, pos, count) { 811 this.score = score; 812 this.pos = pos; 813 this.count = count; 814 } 815 816 return AcronymResult; 817 818 })(); 819 820 emptyAcronymResult = new AcronymResult(0, 0.1, 0); 821 822 exports.scoreAcronyms = scoreAcronyms = function(subject, subject_lw, query, query_lw) { 823 var count, fullWord, i, j, m, n, qj_lw, sameCase, score, sepCount, sumPos; 824 m = subject.length; 825 n = query.length; 826 if (!(m > 1 && n > 1)) { 827 return emptyAcronymResult; 828 } 829 count = 0; 830 sepCount = 0; 831 sumPos = 0; 832 sameCase = 0; 833 i = -1; 834 j = -1; 835 while (++j < n) { 836 qj_lw = query_lw[j]; 837 if (isSeparator(qj_lw)) { 838 i = subject_lw.indexOf(qj_lw, i + 1); 839 if (i > -1) { 840 sepCount++; 841 continue; 842 } else { 843 break; 844 } 845 } 846 while (++i < m) { 847 if (qj_lw === subject_lw[i] && isWordStart(i, subject, subject_lw)) { 848 if (query[j] === subject[i]) { 849 sameCase++; 850 } 851 sumPos += i; 852 count++; 853 break; 854 } 855 } 856 if (i === m) { 857 break; 858 } 859 } 860 if (count < 2) { 861 return emptyAcronymResult; 862 } 863 fullWord = count === n ? isAcronymFullWord(subject, subject_lw, query, count) : false; 864 score = scorePattern(count, n, sameCase, true, fullWord); 865 return new AcronymResult(score, sumPos / count, count + sepCount); 866 }; 867 868 isAcronymFullWord = function(subject, subject_lw, query, nbAcronymInQuery) { 869 var count, i, m, n; 870 m = subject.length; 871 n = query.length; 872 count = 0; 873 if (m > 12 * n) { 874 return false; 875 } 876 i = -1; 877 while (++i < m) { 878 if (isWordStart(i, subject, subject_lw) && ++count > nbAcronymInQuery) { 879 return false; 880 } 881 } 882 return true; 883 }; 884 885 }).call(this); 886 887 },{}],7:[function(require,module,exports){ 888 // shim for using process in browser 889 var process = module.exports = {}; 890 891 // cached from whatever global is present so that test runners that stub it 892 // don't break things. But we need to wrap it in a try catch in case it is 893 // wrapped in strict mode code which doesn't define any globals. It's inside a 894 // function because try/catches deoptimize in certain engines. 895 896 var cachedSetTimeout; 897 var cachedClearTimeout; 898 899 function defaultSetTimout() { 900 throw new Error('setTimeout has not been defined'); 901 } 902 function defaultClearTimeout () { 903 throw new Error('clearTimeout has not been defined'); 904 } 905 (function () { 906 try { 907 if (typeof setTimeout === 'function') { 908 cachedSetTimeout = setTimeout; 909 } else { 910 cachedSetTimeout = defaultSetTimout; 911 } 912 } catch (e) { 913 cachedSetTimeout = defaultSetTimout; 914 } 915 try { 916 if (typeof clearTimeout === 'function') { 917 cachedClearTimeout = clearTimeout; 918 } else { 919 cachedClearTimeout = defaultClearTimeout; 920 } 921 } catch (e) { 922 cachedClearTimeout = defaultClearTimeout; 923 } 924 } ()) 925 function runTimeout(fun) { 926 if (cachedSetTimeout === setTimeout) { 927 //normal enviroments in sane situations 928 return setTimeout(fun, 0); 929 } 930 // if setTimeout wasn't available but was latter defined 931 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { 932 cachedSetTimeout = setTimeout; 933 return setTimeout(fun, 0); 934 } 935 try { 936 // when when somebody has screwed with setTimeout but no I.E. maddness 937 return cachedSetTimeout(fun, 0); 938 } catch(e){ 939 try { 940 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 941 return cachedSetTimeout.call(null, fun, 0); 942 } catch(e){ 943 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error 944 return cachedSetTimeout.call(this, fun, 0); 945 } 946 } 947 948 949 } 950 function runClearTimeout(marker) { 951 if (cachedClearTimeout === clearTimeout) { 952 //normal enviroments in sane situations 953 return clearTimeout(marker); 954 } 955 // if clearTimeout wasn't available but was latter defined 956 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { 957 cachedClearTimeout = clearTimeout; 958 return clearTimeout(marker); 959 } 960 try { 961 // when when somebody has screwed with setTimeout but no I.E. maddness 962 return cachedClearTimeout(marker); 963 } catch (e){ 964 try { 965 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 966 return cachedClearTimeout.call(null, marker); 967 } catch (e){ 968 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. 969 // Some versions of I.E. have different rules for clearTimeout vs setTimeout 970 return cachedClearTimeout.call(this, marker); 971 } 972 } 973 974 975 976 } 977 var queue = []; 978 var draining = false; 979 var currentQueue; 980 var queueIndex = -1; 981 982 function cleanUpNextTick() { 983 if (!draining || !currentQueue) { 984 return; 985 } 986 draining = false; 987 if (currentQueue.length) { 988 queue = currentQueue.concat(queue); 989 } else { 990 queueIndex = -1; 991 } 992 if (queue.length) { 993 drainQueue(); 994 } 995 } 996 997 function drainQueue() { 998 if (draining) { 999 return; 1000 } 1001 var timeout = runTimeout(cleanUpNextTick); 1002 draining = true; 1003 1004 var len = queue.length; 1005 while(len) { 1006 currentQueue = queue; 1007 queue = []; 1008 while (++queueIndex < len) { 1009 if (currentQueue) { 1010 currentQueue[queueIndex].run(); 1011 } 1012 } 1013 queueIndex = -1; 1014 len = queue.length; 1015 } 1016 currentQueue = null; 1017 draining = false; 1018 runClearTimeout(timeout); 1019 } 1020 1021 process.nextTick = function (fun) { 1022 var args = new Array(arguments.length - 1); 1023 if (arguments.length > 1) { 1024 for (var i = 1; i < arguments.length; i++) { 1025 args[i - 1] = arguments[i]; 1026 } 1027 } 1028 queue.push(new Item(fun, args)); 1029 if (queue.length === 1 && !draining) { 1030 runTimeout(drainQueue); 1031 } 1032 }; 1033 1034 // v8 likes predictible objects 1035 function Item(fun, array) { 1036 this.fun = fun; 1037 this.array = array; 1038 } 1039 Item.prototype.run = function () { 1040 this.fun.apply(null, this.array); 1041 }; 1042 process.title = 'browser'; 1043 process.browser = true; 1044 process.env = {}; 1045 process.argv = []; 1046 process.version = ''; // empty string to avoid regexp issues 1047 process.versions = {}; 1048 1049 function noop() {} 1050 1051 process.on = noop; 1052 process.addListener = noop; 1053 process.once = noop; 1054 process.off = noop; 1055 process.removeListener = noop; 1056 process.removeAllListeners = noop; 1057 process.emit = noop; 1058 process.prependListener = noop; 1059 process.prependOnceListener = noop; 1060 1061 process.listeners = function (name) { return [] } 1062 1063 process.binding = function (name) { 1064 throw new Error('process.binding is not supported'); 1065 }; 1066 1067 process.cwd = function () { return '/' }; 1068 process.chdir = function (dir) { 1069 throw new Error('process.chdir is not supported'); 1070 }; 1071 process.umask = function() { return 0; }; 1072 1073 },{}]},{},[2])(2) 1074 });