(function($){$.suggest=function(input,options){var $input,$results,timeout,prevLength,cache,cacheSize;$input=$(input).attr("autocomplete","off");$results=$("
");timeout=false;prevLength=0;cache=[];cacheSize=0;$results.addClass(options.resultsClass).appendTo('body');resetPosition();$(window).load(resetPosition).resize(resetPosition);$input.blur(function(){setTimeout(function(){$results.hide()},200);});$input.keydown(processKey);function resetPosition(){var offset=$input.offset();$results.css({top:(offset.top+ input.offsetHeight)+'px',left:offset.left+'px'});}
function processKey(e){if((/27$|38$|40$/.test(e.keyCode)&&$results.is(':visible'))||(/^13$|^9$/.test(e.keyCode)&&getCurrentResult())){if(e.preventDefault)
e.preventDefault();if(e.stopPropagation)
e.stopPropagation();e.cancelBubble=true;e.returnValue=false;switch(e.keyCode){case 38:prevResult();break;case 40:nextResult();break;case 9:case 13:selectCurrentResult();break;case 27:$results.hide();break;}}else if($input.val().length!=prevLength){if(timeout)
clearTimeout(timeout);timeout=setTimeout(suggest,options.delay);prevLength=$input.val().length;}}
function suggest(){var q=$.trim($input.val()),multipleSepPos,items;if(options.multiple){multipleSepPos=q.lastIndexOf(options.multipleSep);if(multipleSepPos!=-1){q=$.trim(q.substr(multipleSepPos+ options.multipleSep.length));}}
if(q.length>=options.minchars){cached=checkCache(q);if(cached){displayItems(cached['items']);}else{$.get(options.source,{q:q},function(txt){$results.hide();items=parseTxt(txt,q);displayItems(items);addToCache(q,items,txt.length);});}}else{$results.hide();}}
function checkCache(q){var i;for(i=0;ioptions.maxCacheSize)){cached=cache.pop();cacheSize-=cached['size'];}
cache.push({q:q,size:size,items:items});cacheSize+=size;}
function displayItems(items){var html='',i;if(!items)
return;if(!items.length){$results.hide();return;}
resetPosition();for(i=0;i'+ items[i]+'';$results.html(html).show();$results.children('li').mouseover(function(){$results.children('li').removeClass(options.selectClass);$(this).addClass(options.selectClass);}).click(function(e){e.preventDefault();e.stopPropagation();selectCurrentResult();});}
function parseTxt(txt,q){var items=[],tokens=txt.split(options.delimiter),i,token;for(i=0;i'+ q+''});items[items.length]=token;}}
return items;}
function getCurrentResult(){var $currentResult;if(!$results.is(':visible'))
return false;$currentResult=$results.children('li.'+ options.selectClass);if(!$currentResult.length)
$currentResult=false;return $currentResult;}
function selectCurrentResult(){$currentResult=getCurrentResult();if($currentResult){if(options.multiple){if($input.val().indexOf(options.multipleSep)!=-1){$currentVal=$input.val().substr(0,($input.val().lastIndexOf(options.multipleSep)+ options.multipleSep.length))+' ';}else{$currentVal="";}
$input.val($currentVal+ $currentResult.text()+ options.multipleSep+' ');$input.focus();}else{$input.val($currentResult.text());}
$results.hide();$input.trigger('change');if(options.onSelect)
options.onSelect.apply($input[0]);}}
function nextResult(){$currentResult=getCurrentResult();if($currentResult)
$currentResult.removeClass(options.selectClass).next().addClass(options.selectClass);else
$results.children('li:first-child').addClass(options.selectClass);}
function prevResult(){var $currentResult=getCurrentResult();if($currentResult)
$currentResult.removeClass(options.selectClass).prev().addClass(options.selectClass);else
$results.children('li:last-child').addClass(options.selectClass);}}
$.fn.suggest=function(source,options){if(!source)
return;options=options||{};options.multiple=options.multiple||false;options.multipleSep=options.multipleSep||",";options.source=source;options.delay=options.delay||100;options.resultsClass=options.resultsClass||'ac_results';options.selectClass=options.selectClass||'ac_over';options.matchClass=options.matchClass||'ac_match';options.minchars=options.minchars||2;options.delimiter=options.delimiter||'\n';options.onSelect=options.onSelect||false;options.maxCacheSize=options.maxCacheSize||65536;this.each(function(){new $.suggest(this,options);});return this;};})(jQuery);