jazzy 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/CHANGELOG.md +72 -0
  4. data/CONTRIBUTING.md +3 -1
  5. data/Gemfile.lock +31 -29
  6. data/README.md +11 -10
  7. data/circle.yml +12 -0
  8. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Resources +1 -0
  9. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/SourceKittenFramework +1 -0
  10. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Commandant +1 -0
  11. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Resources +1 -0
  12. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Versions/Current +1 -0
  13. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Resources +1 -0
  14. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Result +1 -0
  15. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Versions/Current +1 -0
  16. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/Resources +1 -0
  17. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/SWXMLHash +1 -0
  18. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/Versions/Current +1 -0
  19. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Yams.framework/Resources +1 -0
  20. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Yams.framework/Versions/Current +1 -0
  21. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Yams.framework/Yams +1 -0
  22. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/Current +1 -0
  23. data/lib/jazzy/config.rb +16 -2
  24. data/lib/jazzy/doc_builder.rb +60 -8
  25. data/lib/jazzy/gem_version.rb +1 -1
  26. data/lib/jazzy/jazzy_markdown.rb +37 -25
  27. data/lib/jazzy/podspec_documenter.rb +3 -4
  28. data/lib/jazzy/search_builder.rb +21 -0
  29. data/lib/jazzy/source_declaration.rb +1 -1
  30. data/lib/jazzy/source_declaration/type.rb +7 -0
  31. data/lib/jazzy/source_document.rb +9 -0
  32. data/lib/jazzy/sourcekitten.rb +112 -60
  33. data/lib/jazzy/themes/apple/assets/js/jazzy.js +6 -0
  34. data/lib/jazzy/themes/fullwidth/assets/css/jazzy.css.scss +62 -0
  35. data/lib/jazzy/themes/fullwidth/assets/img/spinner.gif +0 -0
  36. data/lib/jazzy/themes/fullwidth/assets/js/jazzy.js +6 -0
  37. data/lib/jazzy/themes/fullwidth/assets/js/jazzy.search.js +62 -0
  38. data/lib/jazzy/themes/fullwidth/assets/js/lunr.min.js +6 -0
  39. data/lib/jazzy/themes/fullwidth/assets/js/typeahead.jquery.js +1538 -0
  40. data/lib/jazzy/themes/fullwidth/templates/doc.mustache +5 -0
  41. data/lib/jazzy/themes/fullwidth/templates/header.mustache +8 -0
  42. data/spec/integration_spec.rb +11 -9
  43. metadata +19 -4
  44. data/.travis.yml +0 -17
  45. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/SourceKittenFramework +0 -0
  46. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Commandant.framework/Commandant +0 -0
  47. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Result.framework/Result +0 -0
  48. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/SWXMLHash.framework/SWXMLHash +0 -0
  49. data/lib/jazzy/SourceKitten/Frameworks/SourceKittenFramework.framework/Versions/A/Frameworks/Yams.framework/Yams +0 -0
@@ -551,3 +551,65 @@ html.dash {
551
551
  display: block;
552
552
  }
553
553
  }
554
+
555
+ // ===========================================================================
556
+ //
557
+ // Search
558
+ //
559
+ // ===========================================================================
560
+ form[role=search] {
561
+ input {
562
+ font: $body_font;
563
+ font-size: 14px;
564
+ line-height: 24px;
565
+ padding: 0 10px;
566
+ margin: 0;
567
+ border: none;
568
+ border-radius: 1em;
569
+ .loading & {
570
+ background: white url(../img/spinner.gif) center right 4px no-repeat;
571
+ }
572
+ }
573
+
574
+ // Typeahead elements
575
+
576
+ .tt-menu {
577
+ margin: 0;
578
+ min-width: 300px;
579
+ background: $navigation_bg_color;
580
+ color: $text_color;
581
+ border: 1px solid $navigation_border_color;
582
+ }
583
+
584
+ .tt-highlight {
585
+ font-weight: bold;
586
+ }
587
+
588
+ .tt-suggestion {
589
+ font: $body_font;
590
+ padding: 0 $gutter/2;
591
+ span {
592
+ display: table-cell;
593
+ white-space: nowrap;
594
+ }
595
+ .doc-parent-name {
596
+ width: 100%;
597
+ text-align: right;
598
+ font-weight: normal;
599
+ font-size: 0.9em;
600
+ padding-left: $gutter;
601
+ }
602
+ }
603
+
604
+ .tt-suggestion:hover,
605
+ .tt-suggestion.tt-cursor {
606
+ cursor: pointer;
607
+ background-color: $link_color;
608
+ color: #fff;
609
+ }
610
+
611
+ .tt-suggestion:hover .doc-parent-name,
612
+ .tt-suggestion.tt-cursor .doc-parent-name {
613
+ color: #fff;
614
+ }
615
+ }
@@ -35,3 +35,9 @@ $(".token").click(function(event) {
35
35
  }
36
36
  event.preventDefault();
37
37
  });
38
+
39
+ // Dumb down quotes within code blocks that delimit strings instead of quotations
40
+ // https://github.com/realm/jazzy/issues/714
41
+ $("code q").replaceWith(function () {
42
+ return ["\"", $(this).contents(), "\""];
43
+ });
@@ -0,0 +1,62 @@
1
+ $(function(){
2
+ var searchIndex = lunr(function() {
3
+ this.ref('url');
4
+ this.field('name');
5
+ });
6
+
7
+ var $typeahead = $('[data-typeahead]');
8
+ var $form = $typeahead.parents('form');
9
+ var searchURL = $form.attr('action');
10
+
11
+ function displayTemplate(result) {
12
+ return result.name;
13
+ }
14
+
15
+ function suggestionTemplate(result) {
16
+ var t = '<div class="list-group-item clearfix">';
17
+ t += '<span class="doc-name">' + result.name + '</span>';
18
+ if (result.parent_name) {
19
+ t += '<span class="doc-parent-name label">' + result.parent_name + '</span>';
20
+ }
21
+ t += '</div>';
22
+ return t;
23
+ }
24
+
25
+ $typeahead.one('focus', function() {
26
+ $form.addClass('loading');
27
+
28
+ $.getJSON(searchURL).then(function(searchData) {
29
+ $.each(searchData, function (url, doc) {
30
+ searchIndex.add({url: url, name: doc.name});
31
+ });
32
+
33
+ $typeahead.typeahead(
34
+ {
35
+ highlight: true,
36
+ minLength: 3
37
+ },
38
+ {
39
+ limit: 10,
40
+ display: displayTemplate,
41
+ templates: { suggestion: suggestionTemplate },
42
+ source: function(query, sync) {
43
+ var results = searchIndex.search(query).map(function(result) {
44
+ var doc = searchData[result.ref];
45
+ doc.url = result.ref;
46
+ return doc;
47
+ });
48
+ sync(results);
49
+ }
50
+ }
51
+ );
52
+ $form.removeClass('loading');
53
+ $typeahead.trigger('focus');
54
+ });
55
+ });
56
+
57
+ var baseURL = searchURL.slice(0, -"search.json".length);
58
+
59
+ $typeahead.on('typeahead:select', function(e, result) {
60
+ window.location = baseURL + result.url;
61
+ });
62
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.7.2
3
+ * Copyright (C) 2016 Oliver Nightingale
4
+ * @license MIT
5
+ */
6
+ !function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.7.2",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.utils.asString=function(t){return void 0===t||null===t?"":t.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(e){if(!arguments.length||null==e||void 0==e)return[];if(Array.isArray(e))return e.map(function(e){return t.utils.asString(e).toLowerCase()});var n=t.tokenizer.seperator||t.tokenizer.separator;return e.toString().trim().toLowerCase().split(n)},t.tokenizer.seperator=!1,t.tokenizer.separator=/[\s\-]+/,t.tokenizer.load=function(t){var e=this.registeredFunctions[t];if(!e)throw new Error("Cannot load un-registered function: "+t);return e},t.tokenizer.label="default",t.tokenizer.registeredFunctions={"default":t.tokenizer},t.tokenizer.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing tokenizer: "+n),e.label=n,this.registeredFunctions[n]=e},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,r=0;n>r;r++){for(var o=t[r],s=0;i>s&&(o=this._stack[s](o,r,t),void 0!==o&&""!==o);s++);void 0!==o&&""!==o&&e.push(o)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(e<i.idx)return this.list=new t.Vector.Node(e,n,i),this.length++;for(var r=i,o=i.next;void 0!=o;){if(e<o.idx)return r.next=new t.Vector.Node(e,n,o),this.length++;r=o,o=o.next}return r.next=new t.Vector.Node(e,n,o),this.length++},t.Vector.prototype.magnitude=function(){if(this._magnitude)return this._magnitude;for(var t,e=this.list,n=0;e;)t=e.val,n+=t*t,e=e.next;return this._magnitude=Math.sqrt(n)},t.Vector.prototype.dot=function(t){for(var e=this.list,n=t.list,i=0;e&&n;)e.idx<n.idx?e=e.next:e.idx>n.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t<arguments.length;t++)e=arguments[t],~this.indexOf(e)||this.elements.splice(this.locationFor(e),0,e);this.length=this.elements.length},t.SortedSet.prototype.toArray=function(){return this.elements.slice()},t.SortedSet.prototype.map=function(t,e){return this.elements.map(t,e)},t.SortedSet.prototype.forEach=function(t,e){return this.elements.forEach(t,e)},t.SortedSet.prototype.indexOf=function(t){for(var e=0,n=this.elements.length,i=n-e,r=e+Math.floor(i/2),o=this.elements[r];i>1;){if(o===t)return r;t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r]}return o===t?r:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,r=e+Math.floor(i/2),o=this.elements[r];i>1;)t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r];return o>t?r:t>o?r+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,r=0,o=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>o-1||r>s-1)break;a[i]!==h[r]?a[i]<h[r]?i++:a[i]>h[r]&&r++:(n.add(a[i]),i++,r++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone();for(var r=0,o=n.toArray();r<o.length;r++)i.add(o[r]);return i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this.tokenizerFn=t.tokenizer,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.tokenizer(t.tokenizer.load(e.tokenizer)),n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.tokenizer=function(e){var n=e.label&&e.label in t.tokenizer.registeredFunctions;return n||t.utils.warn("Function is not a registered tokenizer. This may cause problems when serialising the index"),this.tokenizerFn=e,this},t.Index.prototype.add=function(e,n){var i={},r=new t.SortedSet,o=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(t){var n=this.pipeline.run(this.tokenizerFn(e[t.name]));i[t.name]=n;for(var o=0;o<n.length;o++){var s=n[o];r.add(s),this.corpusTokens.add(s)}},this),this.documentStore.set(o,r);for(var s=0;s<r.length;s++){for(var a=r.elements[s],h=0,u=0;u<this._fields.length;u++){var l=this._fields[u],c=i[l.name],f=c.length;if(f){for(var d=0,p=0;f>p;p++)c[p]===a&&d++;h+=d/f*l.boost}}this.tokenStore.add(a,{ref:o,tf:h})}n&&this.eventEmitter.emit("add",e,this)},t.Index.prototype.remove=function(t,e){var n=t[this._ref],e=void 0===e?!0:e;if(this.documentStore.has(n)){var i=this.documentStore.get(n);this.documentStore.remove(n),i.forEach(function(t){this.tokenStore.remove(t,n)},this),e&&this.eventEmitter.emit("remove",t,this)}},t.Index.prototype.update=function(t,e){var e=void 0===e?!0:e;this.remove(t,!1),this.add(t,!1),e&&this.eventEmitter.emit("update",t,this)},t.Index.prototype.idf=function(t){var e="@"+t;if(Object.prototype.hasOwnProperty.call(this._idfCache,e))return this._idfCache[e];var n=this.tokenStore.count(t),i=1;return n>0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(this.tokenizerFn(e)),i=new t.Vector,r=[],o=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*o,h=this,u=this.tokenStore.expand(e).reduce(function(n,r){var o=h.corpusTokens.indexOf(r),s=h.idf(r),u=1,l=new t.SortedSet;if(r!==e){var c=Math.max(3,r.length-e.length);u=1/Math.log(c)}o>-1&&i.insert(o,a*s*u);for(var f=h.tokenStore.get(r),d=Object.keys(f),p=d.length,v=0;p>v;v++)l.add(f[d[v]].ref);return n.union(l)},new t.SortedSet);r.push(u)},this);var a=r.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,r=new t.Vector,o=0;i>o;o++){var s=n.elements[o],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);r.insert(this.corpusTokens.indexOf(s),a*h)}return r},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,tokenizer:this.tokenizerFn.label,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",r=n+"[^aeiouy]*",o=i+"[aeiou]*",s="^("+r+")?"+o+r,a="^("+r+")?"+o+r+"("+o+")?$",h="^("+r+")?"+o+r+o+r,u="^("+r+")?"+i,l=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(u),p=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,g=/^(.+?)eed$/,m=/^(.+?)(ed|ing)$/,y=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),k=new RegExp("^"+r+i+"[^aeiouwxy]$"),x=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,F=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,_=/^(.+?)(s|t)(ion)$/,z=/^(.+?)e$/,O=/ll$/,P=new RegExp("^"+r+i+"[^aeiouwxy]$"),T=function(n){var i,r,o,s,a,h,u;if(n.length<3)return n;if(o=n.substr(0,1),"y"==o&&(n=o.toUpperCase()+n.substr(1)),s=p,a=v,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=g,a=m,s.test(n)){var T=s.exec(n);s=l,s.test(T[1])&&(s=y,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,u=k,a.test(n)?n+="e":h.test(n)?(s=y,n=n.replace(s,"")):u.test(n)&&(n+="e"))}if(s=x,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+t[r])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+e[r])}if(s=F,a=_,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=z,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=P,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=O,a=c,s.test(n)&&a.test(n)&&(s=y,n=n.replace(s,"")),"y"==o&&(n=o.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.generateStopWordFilter=function(t){var e=t.reduce(function(t,e){return t[e]=e,t},{});return function(t){return t&&e[t]!==t?t:void 0}},t.stopWordFilter=t.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){return t.replace(/^\W+/,"").replace(/\W+$/,"")},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t.charAt(0),r=t.slice(1);return i in n||(n[i]={docs:{}}),0===r.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(r,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n<t.length;n++){if(!e[t.charAt(n)])return!1;e=e[t.charAt(n)]}return!0},t.TokenStore.prototype.getNode=function(t){if(!t)return{};for(var e=this.root,n=0;n<t.length;n++){if(!e[t.charAt(n)])return{};e=e[t.charAt(n)]}return e},t.TokenStore.prototype.get=function(t,e){return this.getNode(t,e).docs||{}},t.TokenStore.prototype.count=function(t,e){return Object.keys(this.get(t,e)).length},t.TokenStore.prototype.remove=function(t,e){if(t){for(var n=this.root,i=0;i<t.length;i++){if(!(t.charAt(i)in n))return;n=n[t.charAt(i)]}delete n.docs[e]}},t.TokenStore.prototype.expand=function(t,e){var n=this.getNode(t),i=n.docs||{},e=e||[];return Object.keys(i).length&&e.push(t),Object.keys(n).forEach(function(n){"docs"!==n&&e.concat(this.expand(t+n,e))},this),e},t.TokenStore.prototype.toJSON=function(){return{root:this.root,length:this.length}},function(t,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():t.lunr=e()}(this,function(){return t})}();
@@ -0,0 +1,1538 @@
1
+ /*!
2
+ * typeahead.js 0.11.1
3
+ * https://github.com/twitter/typeahead.js
4
+ * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
5
+ */
6
+
7
+ (function(root, factory) {
8
+ if (typeof define === "function" && define.amd) {
9
+ define("typeahead.js", [ "jquery" ], function(a0) {
10
+ return factory(a0);
11
+ });
12
+ } else if (typeof exports === "object") {
13
+ module.exports = factory(require("jquery"));
14
+ } else {
15
+ factory(jQuery);
16
+ }
17
+ })(this, function($) {
18
+ var _ = function() {
19
+ "use strict";
20
+ return {
21
+ isMsie: function() {
22
+ return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
23
+ },
24
+ isBlankString: function(str) {
25
+ return !str || /^\s*$/.test(str);
26
+ },
27
+ escapeRegExChars: function(str) {
28
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
29
+ },
30
+ isString: function(obj) {
31
+ return typeof obj === "string";
32
+ },
33
+ isNumber: function(obj) {
34
+ return typeof obj === "number";
35
+ },
36
+ isArray: $.isArray,
37
+ isFunction: $.isFunction,
38
+ isObject: $.isPlainObject,
39
+ isUndefined: function(obj) {
40
+ return typeof obj === "undefined";
41
+ },
42
+ isElement: function(obj) {
43
+ return !!(obj && obj.nodeType === 1);
44
+ },
45
+ isJQuery: function(obj) {
46
+ return obj instanceof $;
47
+ },
48
+ toStr: function toStr(s) {
49
+ return _.isUndefined(s) || s === null ? "" : s + "";
50
+ },
51
+ bind: $.proxy,
52
+ each: function(collection, cb) {
53
+ $.each(collection, reverseArgs);
54
+ function reverseArgs(index, value) {
55
+ return cb(value, index);
56
+ }
57
+ },
58
+ map: $.map,
59
+ filter: $.grep,
60
+ every: function(obj, test) {
61
+ var result = true;
62
+ if (!obj) {
63
+ return result;
64
+ }
65
+ $.each(obj, function(key, val) {
66
+ if (!(result = test.call(null, val, key, obj))) {
67
+ return false;
68
+ }
69
+ });
70
+ return !!result;
71
+ },
72
+ some: function(obj, test) {
73
+ var result = false;
74
+ if (!obj) {
75
+ return result;
76
+ }
77
+ $.each(obj, function(key, val) {
78
+ if (result = test.call(null, val, key, obj)) {
79
+ return false;
80
+ }
81
+ });
82
+ return !!result;
83
+ },
84
+ mixin: $.extend,
85
+ identity: function(x) {
86
+ return x;
87
+ },
88
+ clone: function(obj) {
89
+ return $.extend(true, {}, obj);
90
+ },
91
+ getIdGenerator: function() {
92
+ var counter = 0;
93
+ return function() {
94
+ return counter++;
95
+ };
96
+ },
97
+ templatify: function templatify(obj) {
98
+ return $.isFunction(obj) ? obj : template;
99
+ function template() {
100
+ return String(obj);
101
+ }
102
+ },
103
+ defer: function(fn) {
104
+ setTimeout(fn, 0);
105
+ },
106
+ debounce: function(func, wait, immediate) {
107
+ var timeout, result;
108
+ return function() {
109
+ var context = this, args = arguments, later, callNow;
110
+ later = function() {
111
+ timeout = null;
112
+ if (!immediate) {
113
+ result = func.apply(context, args);
114
+ }
115
+ };
116
+ callNow = immediate && !timeout;
117
+ clearTimeout(timeout);
118
+ timeout = setTimeout(later, wait);
119
+ if (callNow) {
120
+ result = func.apply(context, args);
121
+ }
122
+ return result;
123
+ };
124
+ },
125
+ throttle: function(func, wait) {
126
+ var context, args, timeout, result, previous, later;
127
+ previous = 0;
128
+ later = function() {
129
+ previous = new Date();
130
+ timeout = null;
131
+ result = func.apply(context, args);
132
+ };
133
+ return function() {
134
+ var now = new Date(), remaining = wait - (now - previous);
135
+ context = this;
136
+ args = arguments;
137
+ if (remaining <= 0) {
138
+ clearTimeout(timeout);
139
+ timeout = null;
140
+ previous = now;
141
+ result = func.apply(context, args);
142
+ } else if (!timeout) {
143
+ timeout = setTimeout(later, remaining);
144
+ }
145
+ return result;
146
+ };
147
+ },
148
+ stringify: function(val) {
149
+ return _.isString(val) ? val : JSON.stringify(val);
150
+ },
151
+ noop: function() {}
152
+ };
153
+ }();
154
+ var WWW = function() {
155
+ "use strict";
156
+ var defaultClassNames = {
157
+ wrapper: "twitter-typeahead",
158
+ input: "tt-input",
159
+ hint: "tt-hint",
160
+ menu: "tt-menu",
161
+ dataset: "tt-dataset",
162
+ suggestion: "tt-suggestion",
163
+ selectable: "tt-selectable",
164
+ empty: "tt-empty",
165
+ open: "tt-open",
166
+ cursor: "tt-cursor",
167
+ highlight: "tt-highlight"
168
+ };
169
+ return build;
170
+ function build(o) {
171
+ var www, classes;
172
+ classes = _.mixin({}, defaultClassNames, o);
173
+ www = {
174
+ css: buildCss(),
175
+ classes: classes,
176
+ html: buildHtml(classes),
177
+ selectors: buildSelectors(classes)
178
+ };
179
+ return {
180
+ css: www.css,
181
+ html: www.html,
182
+ classes: www.classes,
183
+ selectors: www.selectors,
184
+ mixin: function(o) {
185
+ _.mixin(o, www);
186
+ }
187
+ };
188
+ }
189
+ function buildHtml(c) {
190
+ return {
191
+ wrapper: '<span class="' + c.wrapper + '"></span>',
192
+ menu: '<div class="' + c.menu + '"></div>'
193
+ };
194
+ }
195
+ function buildSelectors(classes) {
196
+ var selectors = {};
197
+ _.each(classes, function(v, k) {
198
+ selectors[k] = "." + v;
199
+ });
200
+ return selectors;
201
+ }
202
+ function buildCss() {
203
+ var css = {
204
+ wrapper: {
205
+ position: "relative",
206
+ display: "inline-block"
207
+ },
208
+ hint: {
209
+ position: "absolute",
210
+ top: "0",
211
+ left: "0",
212
+ borderColor: "transparent",
213
+ boxShadow: "none",
214
+ opacity: "1"
215
+ },
216
+ input: {
217
+ position: "relative",
218
+ verticalAlign: "top",
219
+ backgroundColor: "transparent"
220
+ },
221
+ inputWithNoHint: {
222
+ position: "relative",
223
+ verticalAlign: "top"
224
+ },
225
+ menu: {
226
+ position: "absolute",
227
+ top: "100%",
228
+ left: "0",
229
+ zIndex: "100",
230
+ display: "none"
231
+ },
232
+ ltr: {
233
+ left: "0",
234
+ right: "auto"
235
+ },
236
+ rtl: {
237
+ left: "auto",
238
+ right: " 0"
239
+ }
240
+ };
241
+ if (_.isMsie()) {
242
+ _.mixin(css.input, {
243
+ backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
244
+ });
245
+ }
246
+ return css;
247
+ }
248
+ }();
249
+ var EventBus = function() {
250
+ "use strict";
251
+ var namespace, deprecationMap;
252
+ namespace = "typeahead:";
253
+ deprecationMap = {
254
+ render: "rendered",
255
+ cursorchange: "cursorchanged",
256
+ select: "selected",
257
+ autocomplete: "autocompleted"
258
+ };
259
+ function EventBus(o) {
260
+ if (!o || !o.el) {
261
+ $.error("EventBus initialized without el");
262
+ }
263
+ this.$el = $(o.el);
264
+ }
265
+ _.mixin(EventBus.prototype, {
266
+ _trigger: function(type, args) {
267
+ var $e;
268
+ $e = $.Event(namespace + type);
269
+ (args = args || []).unshift($e);
270
+ this.$el.trigger.apply(this.$el, args);
271
+ return $e;
272
+ },
273
+ before: function(type) {
274
+ var args, $e;
275
+ args = [].slice.call(arguments, 1);
276
+ $e = this._trigger("before" + type, args);
277
+ return $e.isDefaultPrevented();
278
+ },
279
+ trigger: function(type) {
280
+ var deprecatedType;
281
+ this._trigger(type, [].slice.call(arguments, 1));
282
+ if (deprecatedType = deprecationMap[type]) {
283
+ this._trigger(deprecatedType, [].slice.call(arguments, 1));
284
+ }
285
+ }
286
+ });
287
+ return EventBus;
288
+ }();
289
+ var EventEmitter = function() {
290
+ "use strict";
291
+ var splitter = /\s+/, nextTick = getNextTick();
292
+ return {
293
+ onSync: onSync,
294
+ onAsync: onAsync,
295
+ off: off,
296
+ trigger: trigger
297
+ };
298
+ function on(method, types, cb, context) {
299
+ var type;
300
+ if (!cb) {
301
+ return this;
302
+ }
303
+ types = types.split(splitter);
304
+ cb = context ? bindContext(cb, context) : cb;
305
+ this._callbacks = this._callbacks || {};
306
+ while (type = types.shift()) {
307
+ this._callbacks[type] = this._callbacks[type] || {
308
+ sync: [],
309
+ async: []
310
+ };
311
+ this._callbacks[type][method].push(cb);
312
+ }
313
+ return this;
314
+ }
315
+ function onAsync(types, cb, context) {
316
+ return on.call(this, "async", types, cb, context);
317
+ }
318
+ function onSync(types, cb, context) {
319
+ return on.call(this, "sync", types, cb, context);
320
+ }
321
+ function off(types) {
322
+ var type;
323
+ if (!this._callbacks) {
324
+ return this;
325
+ }
326
+ types = types.split(splitter);
327
+ while (type = types.shift()) {
328
+ delete this._callbacks[type];
329
+ }
330
+ return this;
331
+ }
332
+ function trigger(types) {
333
+ var type, callbacks, args, syncFlush, asyncFlush;
334
+ if (!this._callbacks) {
335
+ return this;
336
+ }
337
+ types = types.split(splitter);
338
+ args = [].slice.call(arguments, 1);
339
+ while ((type = types.shift()) && (callbacks = this._callbacks[type])) {
340
+ syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));
341
+ asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));
342
+ syncFlush() && nextTick(asyncFlush);
343
+ }
344
+ return this;
345
+ }
346
+ function getFlush(callbacks, context, args) {
347
+ return flush;
348
+ function flush() {
349
+ var cancelled;
350
+ for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
351
+ cancelled = callbacks[i].apply(context, args) === false;
352
+ }
353
+ return !cancelled;
354
+ }
355
+ }
356
+ function getNextTick() {
357
+ var nextTickFn;
358
+ if (window.setImmediate) {
359
+ nextTickFn = function nextTickSetImmediate(fn) {
360
+ setImmediate(function() {
361
+ fn();
362
+ });
363
+ };
364
+ } else {
365
+ nextTickFn = function nextTickSetTimeout(fn) {
366
+ setTimeout(function() {
367
+ fn();
368
+ }, 0);
369
+ };
370
+ }
371
+ return nextTickFn;
372
+ }
373
+ function bindContext(fn, context) {
374
+ return fn.bind ? fn.bind(context) : function() {
375
+ fn.apply(context, [].slice.call(arguments, 0));
376
+ };
377
+ }
378
+ }();
379
+ var highlight = function(doc) {
380
+ "use strict";
381
+ var defaults = {
382
+ node: null,
383
+ pattern: null,
384
+ tagName: "strong",
385
+ className: null,
386
+ wordsOnly: false,
387
+ caseSensitive: false
388
+ };
389
+ return function hightlight(o) {
390
+ var regex;
391
+ o = _.mixin({}, defaults, o);
392
+ if (!o.node || !o.pattern) {
393
+ return;
394
+ }
395
+ o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
396
+ regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
397
+ traverse(o.node, hightlightTextNode);
398
+ function hightlightTextNode(textNode) {
399
+ var match, patternNode, wrapperNode;
400
+ if (match = regex.exec(textNode.data)) {
401
+ wrapperNode = doc.createElement(o.tagName);
402
+ o.className && (wrapperNode.className = o.className);
403
+ patternNode = textNode.splitText(match.index);
404
+ patternNode.splitText(match[0].length);
405
+ wrapperNode.appendChild(patternNode.cloneNode(true));
406
+ textNode.parentNode.replaceChild(wrapperNode, patternNode);
407
+ }
408
+ return !!match;
409
+ }
410
+ function traverse(el, hightlightTextNode) {
411
+ var childNode, TEXT_NODE_TYPE = 3;
412
+ for (var i = 0; i < el.childNodes.length; i++) {
413
+ childNode = el.childNodes[i];
414
+ if (childNode.nodeType === TEXT_NODE_TYPE) {
415
+ i += hightlightTextNode(childNode) ? 1 : 0;
416
+ } else {
417
+ traverse(childNode, hightlightTextNode);
418
+ }
419
+ }
420
+ }
421
+ };
422
+ function getRegex(patterns, caseSensitive, wordsOnly) {
423
+ var escapedPatterns = [], regexStr;
424
+ for (var i = 0, len = patterns.length; i < len; i++) {
425
+ escapedPatterns.push(_.escapeRegExChars(patterns[i]));
426
+ }
427
+ regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
428
+ return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
429
+ }
430
+ }(window.document);
431
+ var Input = function() {
432
+ "use strict";
433
+ var specialKeyCodeMap;
434
+ specialKeyCodeMap = {
435
+ 9: "tab",
436
+ 27: "esc",
437
+ 37: "left",
438
+ 39: "right",
439
+ 13: "enter",
440
+ 38: "up",
441
+ 40: "down"
442
+ };
443
+ function Input(o, www) {
444
+ o = o || {};
445
+ if (!o.input) {
446
+ $.error("input is missing");
447
+ }
448
+ www.mixin(this);
449
+ this.$hint = $(o.hint);
450
+ this.$input = $(o.input);
451
+ this.query = this.$input.val();
452
+ this.queryWhenFocused = this.hasFocus() ? this.query : null;
453
+ this.$overflowHelper = buildOverflowHelper(this.$input);
454
+ this._checkLanguageDirection();
455
+ if (this.$hint.length === 0) {
456
+ this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
457
+ }
458
+ }
459
+ Input.normalizeQuery = function(str) {
460
+ return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
461
+ };
462
+ _.mixin(Input.prototype, EventEmitter, {
463
+ _onBlur: function onBlur() {
464
+ this.resetInputValue();
465
+ this.trigger("blurred");
466
+ },
467
+ _onFocus: function onFocus() {
468
+ this.queryWhenFocused = this.query;
469
+ this.trigger("focused");
470
+ },
471
+ _onKeydown: function onKeydown($e) {
472
+ var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
473
+ this._managePreventDefault(keyName, $e);
474
+ if (keyName && this._shouldTrigger(keyName, $e)) {
475
+ this.trigger(keyName + "Keyed", $e);
476
+ }
477
+ },
478
+ _onInput: function onInput() {
479
+ this._setQuery(this.getInputValue());
480
+ this.clearHintIfInvalid();
481
+ this._checkLanguageDirection();
482
+ },
483
+ _managePreventDefault: function managePreventDefault(keyName, $e) {
484
+ var preventDefault;
485
+ switch (keyName) {
486
+ case "up":
487
+ case "down":
488
+ preventDefault = !withModifier($e);
489
+ break;
490
+
491
+ default:
492
+ preventDefault = false;
493
+ }
494
+ preventDefault && $e.preventDefault();
495
+ },
496
+ _shouldTrigger: function shouldTrigger(keyName, $e) {
497
+ var trigger;
498
+ switch (keyName) {
499
+ case "tab":
500
+ trigger = !withModifier($e);
501
+ break;
502
+
503
+ default:
504
+ trigger = true;
505
+ }
506
+ return trigger;
507
+ },
508
+ _checkLanguageDirection: function checkLanguageDirection() {
509
+ var dir = (this.$input.css("direction") || "ltr").toLowerCase();
510
+ if (this.dir !== dir) {
511
+ this.dir = dir;
512
+ this.$hint.attr("dir", dir);
513
+ this.trigger("langDirChanged", dir);
514
+ }
515
+ },
516
+ _setQuery: function setQuery(val, silent) {
517
+ var areEquivalent, hasDifferentWhitespace;
518
+ areEquivalent = areQueriesEquivalent(val, this.query);
519
+ hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false;
520
+ this.query = val;
521
+ if (!silent && !areEquivalent) {
522
+ this.trigger("queryChanged", this.query);
523
+ } else if (!silent && hasDifferentWhitespace) {
524
+ this.trigger("whitespaceChanged", this.query);
525
+ }
526
+ },
527
+ bind: function() {
528
+ var that = this, onBlur, onFocus, onKeydown, onInput;
529
+ onBlur = _.bind(this._onBlur, this);
530
+ onFocus = _.bind(this._onFocus, this);
531
+ onKeydown = _.bind(this._onKeydown, this);
532
+ onInput = _.bind(this._onInput, this);
533
+ this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
534
+ if (!_.isMsie() || _.isMsie() > 9) {
535
+ this.$input.on("input.tt", onInput);
536
+ } else {
537
+ this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) {
538
+ if (specialKeyCodeMap[$e.which || $e.keyCode]) {
539
+ return;
540
+ }
541
+ _.defer(_.bind(that._onInput, that, $e));
542
+ });
543
+ }
544
+ return this;
545
+ },
546
+ focus: function focus() {
547
+ this.$input.focus();
548
+ },
549
+ blur: function blur() {
550
+ this.$input.blur();
551
+ },
552
+ getLangDir: function getLangDir() {
553
+ return this.dir;
554
+ },
555
+ getQuery: function getQuery() {
556
+ return this.query || "";
557
+ },
558
+ setQuery: function setQuery(val, silent) {
559
+ this.setInputValue(val);
560
+ this._setQuery(val, silent);
561
+ },
562
+ hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() {
563
+ return this.query !== this.queryWhenFocused;
564
+ },
565
+ getInputValue: function getInputValue() {
566
+ return this.$input.val();
567
+ },
568
+ setInputValue: function setInputValue(value) {
569
+ this.$input.val(value);
570
+ this.clearHintIfInvalid();
571
+ this._checkLanguageDirection();
572
+ },
573
+ resetInputValue: function resetInputValue() {
574
+ this.setInputValue(this.query);
575
+ },
576
+ getHint: function getHint() {
577
+ return this.$hint.val();
578
+ },
579
+ setHint: function setHint(value) {
580
+ this.$hint.val(value);
581
+ },
582
+ clearHint: function clearHint() {
583
+ this.setHint("");
584
+ },
585
+ clearHintIfInvalid: function clearHintIfInvalid() {
586
+ var val, hint, valIsPrefixOfHint, isValid;
587
+ val = this.getInputValue();
588
+ hint = this.getHint();
589
+ valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
590
+ isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
591
+ !isValid && this.clearHint();
592
+ },
593
+ hasFocus: function hasFocus() {
594
+ return this.$input.is(":focus");
595
+ },
596
+ hasOverflow: function hasOverflow() {
597
+ var constraint = this.$input.width() - 2;
598
+ this.$overflowHelper.text(this.getInputValue());
599
+ return this.$overflowHelper.width() >= constraint;
600
+ },
601
+ isCursorAtEnd: function() {
602
+ var valueLength, selectionStart, range;
603
+ valueLength = this.$input.val().length;
604
+ selectionStart = this.$input[0].selectionStart;
605
+ if (_.isNumber(selectionStart)) {
606
+ return selectionStart === valueLength;
607
+ } else if (document.selection) {
608
+ range = document.selection.createRange();
609
+ range.moveStart("character", -valueLength);
610
+ return valueLength === range.text.length;
611
+ }
612
+ return true;
613
+ },
614
+ destroy: function destroy() {
615
+ this.$hint.off(".tt");
616
+ this.$input.off(".tt");
617
+ this.$overflowHelper.remove();
618
+ this.$hint = this.$input = this.$overflowHelper = $("<div>");
619
+ }
620
+ });
621
+ return Input;
622
+ function buildOverflowHelper($input) {
623
+ return $('<pre aria-hidden="true"></pre>').css({
624
+ position: "absolute",
625
+ visibility: "hidden",
626
+ whiteSpace: "pre",
627
+ fontFamily: $input.css("font-family"),
628
+ fontSize: $input.css("font-size"),
629
+ fontStyle: $input.css("font-style"),
630
+ fontVariant: $input.css("font-variant"),
631
+ fontWeight: $input.css("font-weight"),
632
+ wordSpacing: $input.css("word-spacing"),
633
+ letterSpacing: $input.css("letter-spacing"),
634
+ textIndent: $input.css("text-indent"),
635
+ textRendering: $input.css("text-rendering"),
636
+ textTransform: $input.css("text-transform")
637
+ }).insertAfter($input);
638
+ }
639
+ function areQueriesEquivalent(a, b) {
640
+ return Input.normalizeQuery(a) === Input.normalizeQuery(b);
641
+ }
642
+ function withModifier($e) {
643
+ return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
644
+ }
645
+ }();
646
+ var Dataset = function() {
647
+ "use strict";
648
+ var keys, nameGenerator;
649
+ keys = {
650
+ val: "tt-selectable-display",
651
+ obj: "tt-selectable-object"
652
+ };
653
+ nameGenerator = _.getIdGenerator();
654
+ function Dataset(o, www) {
655
+ o = o || {};
656
+ o.templates = o.templates || {};
657
+ o.templates.notFound = o.templates.notFound || o.templates.empty;
658
+ if (!o.source) {
659
+ $.error("missing source");
660
+ }
661
+ if (!o.node) {
662
+ $.error("missing node");
663
+ }
664
+ if (o.name && !isValidName(o.name)) {
665
+ $.error("invalid dataset name: " + o.name);
666
+ }
667
+ www.mixin(this);
668
+ this.highlight = !!o.highlight;
669
+ this.name = o.name || nameGenerator();
670
+ this.limit = o.limit || 5;
671
+ this.displayFn = getDisplayFn(o.display || o.displayKey);
672
+ this.templates = getTemplates(o.templates, this.displayFn);
673
+ this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;
674
+ this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;
675
+ this._resetLastSuggestion();
676
+ this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name);
677
+ }
678
+ Dataset.extractData = function extractData(el) {
679
+ var $el = $(el);
680
+ if ($el.data(keys.obj)) {
681
+ return {
682
+ val: $el.data(keys.val) || "",
683
+ obj: $el.data(keys.obj) || null
684
+ };
685
+ }
686
+ return null;
687
+ };
688
+ _.mixin(Dataset.prototype, EventEmitter, {
689
+ _overwrite: function overwrite(query, suggestions) {
690
+ suggestions = suggestions || [];
691
+ if (suggestions.length) {
692
+ this._renderSuggestions(query, suggestions);
693
+ } else if (this.async && this.templates.pending) {
694
+ this._renderPending(query);
695
+ } else if (!this.async && this.templates.notFound) {
696
+ this._renderNotFound(query);
697
+ } else {
698
+ this._empty();
699
+ }
700
+ this.trigger("rendered", this.name, suggestions, false);
701
+ },
702
+ _append: function append(query, suggestions) {
703
+ suggestions = suggestions || [];
704
+ if (suggestions.length && this.$lastSuggestion.length) {
705
+ this._appendSuggestions(query, suggestions);
706
+ } else if (suggestions.length) {
707
+ this._renderSuggestions(query, suggestions);
708
+ } else if (!this.$lastSuggestion.length && this.templates.notFound) {
709
+ this._renderNotFound(query);
710
+ }
711
+ this.trigger("rendered", this.name, suggestions, true);
712
+ },
713
+ _renderSuggestions: function renderSuggestions(query, suggestions) {
714
+ var $fragment;
715
+ $fragment = this._getSuggestionsFragment(query, suggestions);
716
+ this.$lastSuggestion = $fragment.children().last();
717
+ this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions));
718
+ },
719
+ _appendSuggestions: function appendSuggestions(query, suggestions) {
720
+ var $fragment, $lastSuggestion;
721
+ $fragment = this._getSuggestionsFragment(query, suggestions);
722
+ $lastSuggestion = $fragment.children().last();
723
+ this.$lastSuggestion.after($fragment);
724
+ this.$lastSuggestion = $lastSuggestion;
725
+ },
726
+ _renderPending: function renderPending(query) {
727
+ var template = this.templates.pending;
728
+ this._resetLastSuggestion();
729
+ template && this.$el.html(template({
730
+ query: query,
731
+ dataset: this.name
732
+ }));
733
+ },
734
+ _renderNotFound: function renderNotFound(query) {
735
+ var template = this.templates.notFound;
736
+ this._resetLastSuggestion();
737
+ template && this.$el.html(template({
738
+ query: query,
739
+ dataset: this.name
740
+ }));
741
+ },
742
+ _empty: function empty() {
743
+ this.$el.empty();
744
+ this._resetLastSuggestion();
745
+ },
746
+ _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) {
747
+ var that = this, fragment;
748
+ fragment = document.createDocumentFragment();
749
+ _.each(suggestions, function getSuggestionNode(suggestion) {
750
+ var $el, context;
751
+ context = that._injectQuery(query, suggestion);
752
+ $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable);
753
+ fragment.appendChild($el[0]);
754
+ });
755
+ this.highlight && highlight({
756
+ className: this.classes.highlight,
757
+ node: fragment,
758
+ pattern: query
759
+ });
760
+ return $(fragment);
761
+ },
762
+ _getFooter: function getFooter(query, suggestions) {
763
+ return this.templates.footer ? this.templates.footer({
764
+ query: query,
765
+ suggestions: suggestions,
766
+ dataset: this.name
767
+ }) : null;
768
+ },
769
+ _getHeader: function getHeader(query, suggestions) {
770
+ return this.templates.header ? this.templates.header({
771
+ query: query,
772
+ suggestions: suggestions,
773
+ dataset: this.name
774
+ }) : null;
775
+ },
776
+ _resetLastSuggestion: function resetLastSuggestion() {
777
+ this.$lastSuggestion = $();
778
+ },
779
+ _injectQuery: function injectQuery(query, obj) {
780
+ return _.isObject(obj) ? _.mixin({
781
+ _query: query
782
+ }, obj) : obj;
783
+ },
784
+ update: function update(query) {
785
+ var that = this, canceled = false, syncCalled = false, rendered = 0;
786
+ this.cancel();
787
+ this.cancel = function cancel() {
788
+ canceled = true;
789
+ that.cancel = $.noop;
790
+ that.async && that.trigger("asyncCanceled", query);
791
+ };
792
+ this.source(query, sync, async);
793
+ !syncCalled && sync([]);
794
+ function sync(suggestions) {
795
+ if (syncCalled) {
796
+ return;
797
+ }
798
+ syncCalled = true;
799
+ suggestions = (suggestions || []).slice(0, that.limit);
800
+ rendered = suggestions.length;
801
+ that._overwrite(query, suggestions);
802
+ if (rendered < that.limit && that.async) {
803
+ that.trigger("asyncRequested", query);
804
+ }
805
+ }
806
+ function async(suggestions) {
807
+ suggestions = suggestions || [];
808
+ if (!canceled && rendered < that.limit) {
809
+ that.cancel = $.noop;
810
+ rendered += suggestions.length;
811
+ that._append(query, suggestions.slice(0, that.limit - rendered));
812
+ that.async && that.trigger("asyncReceived", query);
813
+ }
814
+ }
815
+ },
816
+ cancel: $.noop,
817
+ clear: function clear() {
818
+ this._empty();
819
+ this.cancel();
820
+ this.trigger("cleared");
821
+ },
822
+ isEmpty: function isEmpty() {
823
+ return this.$el.is(":empty");
824
+ },
825
+ destroy: function destroy() {
826
+ this.$el = $("<div>");
827
+ }
828
+ });
829
+ return Dataset;
830
+ function getDisplayFn(display) {
831
+ display = display || _.stringify;
832
+ return _.isFunction(display) ? display : displayFn;
833
+ function displayFn(obj) {
834
+ return obj[display];
835
+ }
836
+ }
837
+ function getTemplates(templates, displayFn) {
838
+ return {
839
+ notFound: templates.notFound && _.templatify(templates.notFound),
840
+ pending: templates.pending && _.templatify(templates.pending),
841
+ header: templates.header && _.templatify(templates.header),
842
+ footer: templates.footer && _.templatify(templates.footer),
843
+ suggestion: templates.suggestion || suggestionTemplate
844
+ };
845
+ function suggestionTemplate(context) {
846
+ return $("<div>").text(displayFn(context));
847
+ }
848
+ }
849
+ function isValidName(str) {
850
+ return /^[_a-zA-Z0-9-]+$/.test(str);
851
+ }
852
+ }();
853
+ var Menu = function() {
854
+ "use strict";
855
+ function Menu(o, www) {
856
+ var that = this;
857
+ o = o || {};
858
+ if (!o.node) {
859
+ $.error("node is required");
860
+ }
861
+ www.mixin(this);
862
+ this.$node = $(o.node);
863
+ this.query = null;
864
+ this.datasets = _.map(o.datasets, initializeDataset);
865
+ function initializeDataset(oDataset) {
866
+ var node = that.$node.find(oDataset.node).first();
867
+ oDataset.node = node.length ? node : $("<div>").appendTo(that.$node);
868
+ return new Dataset(oDataset, www);
869
+ }
870
+ }
871
+ _.mixin(Menu.prototype, EventEmitter, {
872
+ _onSelectableClick: function onSelectableClick($e) {
873
+ this.trigger("selectableClicked", $($e.currentTarget));
874
+ },
875
+ _onRendered: function onRendered(type, dataset, suggestions, async) {
876
+ this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
877
+ this.trigger("datasetRendered", dataset, suggestions, async);
878
+ },
879
+ _onCleared: function onCleared() {
880
+ this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
881
+ this.trigger("datasetCleared");
882
+ },
883
+ _propagate: function propagate() {
884
+ this.trigger.apply(this, arguments);
885
+ },
886
+ _allDatasetsEmpty: function allDatasetsEmpty() {
887
+ return _.every(this.datasets, isDatasetEmpty);
888
+ function isDatasetEmpty(dataset) {
889
+ return dataset.isEmpty();
890
+ }
891
+ },
892
+ _getSelectables: function getSelectables() {
893
+ return this.$node.find(this.selectors.selectable);
894
+ },
895
+ _removeCursor: function _removeCursor() {
896
+ var $selectable = this.getActiveSelectable();
897
+ $selectable && $selectable.removeClass(this.classes.cursor);
898
+ },
899
+ _ensureVisible: function ensureVisible($el) {
900
+ var elTop, elBottom, nodeScrollTop, nodeHeight;
901
+ elTop = $el.position().top;
902
+ elBottom = elTop + $el.outerHeight(true);
903
+ nodeScrollTop = this.$node.scrollTop();
904
+ nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10);
905
+ if (elTop < 0) {
906
+ this.$node.scrollTop(nodeScrollTop + elTop);
907
+ } else if (nodeHeight < elBottom) {
908
+ this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight));
909
+ }
910
+ },
911
+ bind: function() {
912
+ var that = this, onSelectableClick;
913
+ onSelectableClick = _.bind(this._onSelectableClick, this);
914
+ this.$node.on("click.tt", this.selectors.selectable, onSelectableClick);
915
+ _.each(this.datasets, function(dataset) {
916
+ dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that);
917
+ });
918
+ return this;
919
+ },
920
+ isOpen: function isOpen() {
921
+ return this.$node.hasClass(this.classes.open);
922
+ },
923
+ open: function open() {
924
+ this.$node.addClass(this.classes.open);
925
+ },
926
+ close: function close() {
927
+ this.$node.removeClass(this.classes.open);
928
+ this._removeCursor();
929
+ },
930
+ setLanguageDirection: function setLanguageDirection(dir) {
931
+ this.$node.attr("dir", dir);
932
+ },
933
+ selectableRelativeToCursor: function selectableRelativeToCursor(delta) {
934
+ var $selectables, $oldCursor, oldIndex, newIndex;
935
+ $oldCursor = this.getActiveSelectable();
936
+ $selectables = this._getSelectables();
937
+ oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1;
938
+ newIndex = oldIndex + delta;
939
+ newIndex = (newIndex + 1) % ($selectables.length + 1) - 1;
940
+ newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex;
941
+ return newIndex === -1 ? null : $selectables.eq(newIndex);
942
+ },
943
+ setCursor: function setCursor($selectable) {
944
+ this._removeCursor();
945
+ if ($selectable = $selectable && $selectable.first()) {
946
+ $selectable.addClass(this.classes.cursor);
947
+ this._ensureVisible($selectable);
948
+ }
949
+ },
950
+ getSelectableData: function getSelectableData($el) {
951
+ return $el && $el.length ? Dataset.extractData($el) : null;
952
+ },
953
+ getActiveSelectable: function getActiveSelectable() {
954
+ var $selectable = this._getSelectables().filter(this.selectors.cursor).first();
955
+ return $selectable.length ? $selectable : null;
956
+ },
957
+ getTopSelectable: function getTopSelectable() {
958
+ var $selectable = this._getSelectables().first();
959
+ return $selectable.length ? $selectable : null;
960
+ },
961
+ update: function update(query) {
962
+ var isValidUpdate = query !== this.query;
963
+ if (isValidUpdate) {
964
+ this.query = query;
965
+ _.each(this.datasets, updateDataset);
966
+ }
967
+ return isValidUpdate;
968
+ function updateDataset(dataset) {
969
+ dataset.update(query);
970
+ }
971
+ },
972
+ empty: function empty() {
973
+ _.each(this.datasets, clearDataset);
974
+ this.query = null;
975
+ this.$node.addClass(this.classes.empty);
976
+ function clearDataset(dataset) {
977
+ dataset.clear();
978
+ }
979
+ },
980
+ destroy: function destroy() {
981
+ this.$node.off(".tt");
982
+ this.$node = $("<div>");
983
+ _.each(this.datasets, destroyDataset);
984
+ function destroyDataset(dataset) {
985
+ dataset.destroy();
986
+ }
987
+ }
988
+ });
989
+ return Menu;
990
+ }();
991
+ var DefaultMenu = function() {
992
+ "use strict";
993
+ var s = Menu.prototype;
994
+ function DefaultMenu() {
995
+ Menu.apply(this, [].slice.call(arguments, 0));
996
+ }
997
+ _.mixin(DefaultMenu.prototype, Menu.prototype, {
998
+ open: function open() {
999
+ !this._allDatasetsEmpty() && this._show();
1000
+ return s.open.apply(this, [].slice.call(arguments, 0));
1001
+ },
1002
+ close: function close() {
1003
+ this._hide();
1004
+ return s.close.apply(this, [].slice.call(arguments, 0));
1005
+ },
1006
+ _onRendered: function onRendered() {
1007
+ if (this._allDatasetsEmpty()) {
1008
+ this._hide();
1009
+ } else {
1010
+ this.isOpen() && this._show();
1011
+ }
1012
+ return s._onRendered.apply(this, [].slice.call(arguments, 0));
1013
+ },
1014
+ _onCleared: function onCleared() {
1015
+ if (this._allDatasetsEmpty()) {
1016
+ this._hide();
1017
+ } else {
1018
+ this.isOpen() && this._show();
1019
+ }
1020
+ return s._onCleared.apply(this, [].slice.call(arguments, 0));
1021
+ },
1022
+ setLanguageDirection: function setLanguageDirection(dir) {
1023
+ this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl);
1024
+ return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0));
1025
+ },
1026
+ _hide: function hide() {
1027
+ this.$node.hide();
1028
+ },
1029
+ _show: function show() {
1030
+ this.$node.css("display", "block");
1031
+ }
1032
+ });
1033
+ return DefaultMenu;
1034
+ }();
1035
+ var Typeahead = function() {
1036
+ "use strict";
1037
+ function Typeahead(o, www) {
1038
+ var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged;
1039
+ o = o || {};
1040
+ if (!o.input) {
1041
+ $.error("missing input");
1042
+ }
1043
+ if (!o.menu) {
1044
+ $.error("missing menu");
1045
+ }
1046
+ if (!o.eventBus) {
1047
+ $.error("missing event bus");
1048
+ }
1049
+ www.mixin(this);
1050
+ this.eventBus = o.eventBus;
1051
+ this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
1052
+ this.input = o.input;
1053
+ this.menu = o.menu;
1054
+ this.enabled = true;
1055
+ this.active = false;
1056
+ this.input.hasFocus() && this.activate();
1057
+ this.dir = this.input.getLangDir();
1058
+ this._hacks();
1059
+ this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this);
1060
+ onFocused = c(this, "activate", "open", "_onFocused");
1061
+ onBlurred = c(this, "deactivate", "_onBlurred");
1062
+ onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed");
1063
+ onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed");
1064
+ onEscKeyed = c(this, "isActive", "_onEscKeyed");
1065
+ onUpKeyed = c(this, "isActive", "open", "_onUpKeyed");
1066
+ onDownKeyed = c(this, "isActive", "open", "_onDownKeyed");
1067
+ onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed");
1068
+ onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed");
1069
+ onQueryChanged = c(this, "_openIfActive", "_onQueryChanged");
1070
+ onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged");
1071
+ this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this);
1072
+ }
1073
+ _.mixin(Typeahead.prototype, {
1074
+ _hacks: function hacks() {
1075
+ var $input, $menu;
1076
+ $input = this.input.$input || $("<div>");
1077
+ $menu = this.menu.$node || $("<div>");
1078
+ $input.on("blur.tt", function($e) {
1079
+ var active, isActive, hasActive;
1080
+ active = document.activeElement;
1081
+ isActive = $menu.is(active);
1082
+ hasActive = $menu.has(active).length > 0;
1083
+ if (_.isMsie() && (isActive || hasActive)) {
1084
+ $e.preventDefault();
1085
+ $e.stopImmediatePropagation();
1086
+ _.defer(function() {
1087
+ $input.focus();
1088
+ });
1089
+ }
1090
+ });
1091
+ $menu.on("mousedown.tt", function($e) {
1092
+ $e.preventDefault();
1093
+ });
1094
+ },
1095
+ _onSelectableClicked: function onSelectableClicked(type, $el) {
1096
+ this.select($el);
1097
+ },
1098
+ _onDatasetCleared: function onDatasetCleared() {
1099
+ this._updateHint();
1100
+ },
1101
+ _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) {
1102
+ this._updateHint();
1103
+ this.eventBus.trigger("render", suggestions, async, dataset);
1104
+ },
1105
+ _onAsyncRequested: function onAsyncRequested(type, dataset, query) {
1106
+ this.eventBus.trigger("asyncrequest", query, dataset);
1107
+ },
1108
+ _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) {
1109
+ this.eventBus.trigger("asynccancel", query, dataset);
1110
+ },
1111
+ _onAsyncReceived: function onAsyncReceived(type, dataset, query) {
1112
+ this.eventBus.trigger("asyncreceive", query, dataset);
1113
+ },
1114
+ _onFocused: function onFocused() {
1115
+ this._minLengthMet() && this.menu.update(this.input.getQuery());
1116
+ },
1117
+ _onBlurred: function onBlurred() {
1118
+ if (this.input.hasQueryChangedSinceLastFocus()) {
1119
+ this.eventBus.trigger("change", this.input.getQuery());
1120
+ }
1121
+ },
1122
+ _onEnterKeyed: function onEnterKeyed(type, $e) {
1123
+ var $selectable;
1124
+ if ($selectable = this.menu.getActiveSelectable()) {
1125
+ this.select($selectable) && $e.preventDefault();
1126
+ }
1127
+ },
1128
+ _onTabKeyed: function onTabKeyed(type, $e) {
1129
+ var $selectable;
1130
+ if ($selectable = this.menu.getActiveSelectable()) {
1131
+ this.select($selectable) && $e.preventDefault();
1132
+ } else if ($selectable = this.menu.getTopSelectable()) {
1133
+ this.autocomplete($selectable) && $e.preventDefault();
1134
+ }
1135
+ },
1136
+ _onEscKeyed: function onEscKeyed() {
1137
+ this.close();
1138
+ },
1139
+ _onUpKeyed: function onUpKeyed() {
1140
+ this.moveCursor(-1);
1141
+ },
1142
+ _onDownKeyed: function onDownKeyed() {
1143
+ this.moveCursor(+1);
1144
+ },
1145
+ _onLeftKeyed: function onLeftKeyed() {
1146
+ if (this.dir === "rtl" && this.input.isCursorAtEnd()) {
1147
+ this.autocomplete(this.menu.getTopSelectable());
1148
+ }
1149
+ },
1150
+ _onRightKeyed: function onRightKeyed() {
1151
+ if (this.dir === "ltr" && this.input.isCursorAtEnd()) {
1152
+ this.autocomplete(this.menu.getTopSelectable());
1153
+ }
1154
+ },
1155
+ _onQueryChanged: function onQueryChanged(e, query) {
1156
+ this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty();
1157
+ },
1158
+ _onWhitespaceChanged: function onWhitespaceChanged() {
1159
+ this._updateHint();
1160
+ },
1161
+ _onLangDirChanged: function onLangDirChanged(e, dir) {
1162
+ if (this.dir !== dir) {
1163
+ this.dir = dir;
1164
+ this.menu.setLanguageDirection(dir);
1165
+ }
1166
+ },
1167
+ _openIfActive: function openIfActive() {
1168
+ this.isActive() && this.open();
1169
+ },
1170
+ _minLengthMet: function minLengthMet(query) {
1171
+ query = _.isString(query) ? query : this.input.getQuery() || "";
1172
+ return query.length >= this.minLength;
1173
+ },
1174
+ _updateHint: function updateHint() {
1175
+ var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match;
1176
+ $selectable = this.menu.getTopSelectable();
1177
+ data = this.menu.getSelectableData($selectable);
1178
+ val = this.input.getInputValue();
1179
+ if (data && !_.isBlankString(val) && !this.input.hasOverflow()) {
1180
+ query = Input.normalizeQuery(val);
1181
+ escapedQuery = _.escapeRegExChars(query);
1182
+ frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
1183
+ match = frontMatchRegEx.exec(data.val);
1184
+ match && this.input.setHint(val + match[1]);
1185
+ } else {
1186
+ this.input.clearHint();
1187
+ }
1188
+ },
1189
+ isEnabled: function isEnabled() {
1190
+ return this.enabled;
1191
+ },
1192
+ enable: function enable() {
1193
+ this.enabled = true;
1194
+ },
1195
+ disable: function disable() {
1196
+ this.enabled = false;
1197
+ },
1198
+ isActive: function isActive() {
1199
+ return this.active;
1200
+ },
1201
+ activate: function activate() {
1202
+ if (this.isActive()) {
1203
+ return true;
1204
+ } else if (!this.isEnabled() || this.eventBus.before("active")) {
1205
+ return false;
1206
+ } else {
1207
+ this.active = true;
1208
+ this.eventBus.trigger("active");
1209
+ return true;
1210
+ }
1211
+ },
1212
+ deactivate: function deactivate() {
1213
+ if (!this.isActive()) {
1214
+ return true;
1215
+ } else if (this.eventBus.before("idle")) {
1216
+ return false;
1217
+ } else {
1218
+ this.active = false;
1219
+ this.close();
1220
+ this.eventBus.trigger("idle");
1221
+ return true;
1222
+ }
1223
+ },
1224
+ isOpen: function isOpen() {
1225
+ return this.menu.isOpen();
1226
+ },
1227
+ open: function open() {
1228
+ if (!this.isOpen() && !this.eventBus.before("open")) {
1229
+ this.menu.open();
1230
+ this._updateHint();
1231
+ this.eventBus.trigger("open");
1232
+ }
1233
+ return this.isOpen();
1234
+ },
1235
+ close: function close() {
1236
+ if (this.isOpen() && !this.eventBus.before("close")) {
1237
+ this.menu.close();
1238
+ this.input.clearHint();
1239
+ this.input.resetInputValue();
1240
+ this.eventBus.trigger("close");
1241
+ }
1242
+ return !this.isOpen();
1243
+ },
1244
+ setVal: function setVal(val) {
1245
+ this.input.setQuery(_.toStr(val));
1246
+ },
1247
+ getVal: function getVal() {
1248
+ return this.input.getQuery();
1249
+ },
1250
+ select: function select($selectable) {
1251
+ var data = this.menu.getSelectableData($selectable);
1252
+ if (data && !this.eventBus.before("select", data.obj)) {
1253
+ this.input.setQuery(data.val, true);
1254
+ this.eventBus.trigger("select", data.obj);
1255
+ this.close();
1256
+ return true;
1257
+ }
1258
+ return false;
1259
+ },
1260
+ autocomplete: function autocomplete($selectable) {
1261
+ var query, data, isValid;
1262
+ query = this.input.getQuery();
1263
+ data = this.menu.getSelectableData($selectable);
1264
+ isValid = data && query !== data.val;
1265
+ if (isValid && !this.eventBus.before("autocomplete", data.obj)) {
1266
+ this.input.setQuery(data.val);
1267
+ this.eventBus.trigger("autocomplete", data.obj);
1268
+ return true;
1269
+ }
1270
+ return false;
1271
+ },
1272
+ moveCursor: function moveCursor(delta) {
1273
+ var query, $candidate, data, payload, cancelMove;
1274
+ query = this.input.getQuery();
1275
+ $candidate = this.menu.selectableRelativeToCursor(delta);
1276
+ data = this.menu.getSelectableData($candidate);
1277
+ payload = data ? data.obj : null;
1278
+ cancelMove = this._minLengthMet() && this.menu.update(query);
1279
+ if (!cancelMove && !this.eventBus.before("cursorchange", payload)) {
1280
+ this.menu.setCursor($candidate);
1281
+ if (data) {
1282
+ this.input.setInputValue(data.val);
1283
+ } else {
1284
+ this.input.resetInputValue();
1285
+ this._updateHint();
1286
+ }
1287
+ this.eventBus.trigger("cursorchange", payload);
1288
+ return true;
1289
+ }
1290
+ return false;
1291
+ },
1292
+ destroy: function destroy() {
1293
+ this.input.destroy();
1294
+ this.menu.destroy();
1295
+ }
1296
+ });
1297
+ return Typeahead;
1298
+ function c(ctx) {
1299
+ var methods = [].slice.call(arguments, 1);
1300
+ return function() {
1301
+ var args = [].slice.call(arguments);
1302
+ _.each(methods, function(method) {
1303
+ return ctx[method].apply(ctx, args);
1304
+ });
1305
+ };
1306
+ }
1307
+ }();
1308
+ (function() {
1309
+ "use strict";
1310
+ var old, keys, methods;
1311
+ old = $.fn.typeahead;
1312
+ keys = {
1313
+ www: "tt-www",
1314
+ attrs: "tt-attrs",
1315
+ typeahead: "tt-typeahead"
1316
+ };
1317
+ methods = {
1318
+ initialize: function initialize(o, datasets) {
1319
+ var www;
1320
+ datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
1321
+ o = o || {};
1322
+ www = WWW(o.classNames);
1323
+ return this.each(attach);
1324
+ function attach() {
1325
+ var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor;
1326
+ _.each(datasets, function(d) {
1327
+ d.highlight = !!o.highlight;
1328
+ });
1329
+ $input = $(this);
1330
+ $wrapper = $(www.html.wrapper);
1331
+ $hint = $elOrNull(o.hint);
1332
+ $menu = $elOrNull(o.menu);
1333
+ defaultHint = o.hint !== false && !$hint;
1334
+ defaultMenu = o.menu !== false && !$menu;
1335
+ defaultHint && ($hint = buildHintFromInput($input, www));
1336
+ defaultMenu && ($menu = $(www.html.menu).css(www.css.menu));
1337
+ $hint && $hint.val("");
1338
+ $input = prepInput($input, www);
1339
+ if (defaultHint || defaultMenu) {
1340
+ $wrapper.css(www.css.wrapper);
1341
+ $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint);
1342
+ $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null);
1343
+ }
1344
+ MenuConstructor = defaultMenu ? DefaultMenu : Menu;
1345
+ eventBus = new EventBus({
1346
+ el: $input
1347
+ });
1348
+ input = new Input({
1349
+ hint: $hint,
1350
+ input: $input
1351
+ }, www);
1352
+ menu = new MenuConstructor({
1353
+ node: $menu,
1354
+ datasets: datasets
1355
+ }, www);
1356
+ typeahead = new Typeahead({
1357
+ input: input,
1358
+ menu: menu,
1359
+ eventBus: eventBus,
1360
+ minLength: o.minLength
1361
+ }, www);
1362
+ $input.data(keys.www, www);
1363
+ $input.data(keys.typeahead, typeahead);
1364
+ }
1365
+ },
1366
+ isEnabled: function isEnabled() {
1367
+ var enabled;
1368
+ ttEach(this.first(), function(t) {
1369
+ enabled = t.isEnabled();
1370
+ });
1371
+ return enabled;
1372
+ },
1373
+ enable: function enable() {
1374
+ ttEach(this, function(t) {
1375
+ t.enable();
1376
+ });
1377
+ return this;
1378
+ },
1379
+ disable: function disable() {
1380
+ ttEach(this, function(t) {
1381
+ t.disable();
1382
+ });
1383
+ return this;
1384
+ },
1385
+ isActive: function isActive() {
1386
+ var active;
1387
+ ttEach(this.first(), function(t) {
1388
+ active = t.isActive();
1389
+ });
1390
+ return active;
1391
+ },
1392
+ activate: function activate() {
1393
+ ttEach(this, function(t) {
1394
+ t.activate();
1395
+ });
1396
+ return this;
1397
+ },
1398
+ deactivate: function deactivate() {
1399
+ ttEach(this, function(t) {
1400
+ t.deactivate();
1401
+ });
1402
+ return this;
1403
+ },
1404
+ isOpen: function isOpen() {
1405
+ var open;
1406
+ ttEach(this.first(), function(t) {
1407
+ open = t.isOpen();
1408
+ });
1409
+ return open;
1410
+ },
1411
+ open: function open() {
1412
+ ttEach(this, function(t) {
1413
+ t.open();
1414
+ });
1415
+ return this;
1416
+ },
1417
+ close: function close() {
1418
+ ttEach(this, function(t) {
1419
+ t.close();
1420
+ });
1421
+ return this;
1422
+ },
1423
+ select: function select(el) {
1424
+ var success = false, $el = $(el);
1425
+ ttEach(this.first(), function(t) {
1426
+ success = t.select($el);
1427
+ });
1428
+ return success;
1429
+ },
1430
+ autocomplete: function autocomplete(el) {
1431
+ var success = false, $el = $(el);
1432
+ ttEach(this.first(), function(t) {
1433
+ success = t.autocomplete($el);
1434
+ });
1435
+ return success;
1436
+ },
1437
+ moveCursor: function moveCursoe(delta) {
1438
+ var success = false;
1439
+ ttEach(this.first(), function(t) {
1440
+ success = t.moveCursor(delta);
1441
+ });
1442
+ return success;
1443
+ },
1444
+ val: function val(newVal) {
1445
+ var query;
1446
+ if (!arguments.length) {
1447
+ ttEach(this.first(), function(t) {
1448
+ query = t.getVal();
1449
+ });
1450
+ return query;
1451
+ } else {
1452
+ ttEach(this, function(t) {
1453
+ t.setVal(newVal);
1454
+ });
1455
+ return this;
1456
+ }
1457
+ },
1458
+ destroy: function destroy() {
1459
+ ttEach(this, function(typeahead, $input) {
1460
+ revert($input);
1461
+ typeahead.destroy();
1462
+ });
1463
+ return this;
1464
+ }
1465
+ };
1466
+ $.fn.typeahead = function(method) {
1467
+ if (methods[method]) {
1468
+ return methods[method].apply(this, [].slice.call(arguments, 1));
1469
+ } else {
1470
+ return methods.initialize.apply(this, arguments);
1471
+ }
1472
+ };
1473
+ $.fn.typeahead.noConflict = function noConflict() {
1474
+ $.fn.typeahead = old;
1475
+ return this;
1476
+ };
1477
+ function ttEach($els, fn) {
1478
+ $els.each(function() {
1479
+ var $input = $(this), typeahead;
1480
+ (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input);
1481
+ });
1482
+ }
1483
+ function buildHintFromInput($input, www) {
1484
+ return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({
1485
+ autocomplete: "off",
1486
+ spellcheck: "false",
1487
+ tabindex: -1
1488
+ });
1489
+ }
1490
+ function prepInput($input, www) {
1491
+ $input.data(keys.attrs, {
1492
+ dir: $input.attr("dir"),
1493
+ autocomplete: $input.attr("autocomplete"),
1494
+ spellcheck: $input.attr("spellcheck"),
1495
+ style: $input.attr("style")
1496
+ });
1497
+ $input.addClass(www.classes.input).attr({
1498
+ autocomplete: "off",
1499
+ spellcheck: false
1500
+ });
1501
+ try {
1502
+ !$input.attr("dir") && $input.attr("dir", "auto");
1503
+ } catch (e) {}
1504
+ return $input;
1505
+ }
1506
+ function getBackgroundStyles($el) {
1507
+ return {
1508
+ backgroundAttachment: $el.css("background-attachment"),
1509
+ backgroundClip: $el.css("background-clip"),
1510
+ backgroundColor: $el.css("background-color"),
1511
+ backgroundImage: $el.css("background-image"),
1512
+ backgroundOrigin: $el.css("background-origin"),
1513
+ backgroundPosition: $el.css("background-position"),
1514
+ backgroundRepeat: $el.css("background-repeat"),
1515
+ backgroundSize: $el.css("background-size")
1516
+ };
1517
+ }
1518
+ function revert($input) {
1519
+ var www, $wrapper;
1520
+ www = $input.data(keys.www);
1521
+ $wrapper = $input.parent().filter(www.selectors.wrapper);
1522
+ _.each($input.data(keys.attrs), function(val, key) {
1523
+ _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
1524
+ });
1525
+ $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input);
1526
+ if ($wrapper.length) {
1527
+ $input.detach().insertAfter($wrapper);
1528
+ $wrapper.remove();
1529
+ }
1530
+ }
1531
+ function $elOrNull(obj) {
1532
+ var isValid, $el;
1533
+ isValid = _.isJQuery(obj) || _.isElement(obj);
1534
+ $el = isValid ? $(obj).first() : [];
1535
+ return $el.length ? $el : null;
1536
+ }
1537
+ })();
1538
+ });