").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
+
+/*! nanoScrollerJS - v0.7.6 - 2013
+* http://jamesflorentino.github.com/nanoScrollerJS/
+* Copyright (c) 2013 James Florentino; Licensed MIT */
+(function($, window, document) {
+ "use strict";
+ var BROWSER_IS_IE7, BROWSER_SCROLLBAR_WIDTH, DOMSCROLL, DOWN, DRAG, KEYDOWN, KEYUP, MOUSEDOWN, MOUSEMOVE, MOUSEUP, MOUSEWHEEL, NanoScroll, PANEDOWN, RESIZE, SCROLL, SCROLLBAR, TOUCHMOVE, UP, WHEEL, cAF, defaults, getBrowserScrollbarWidth, hasTransform, isFFWithBuggyScrollbar, rAF, transform, _elementStyle, _prefixStyle, _vendor;
+ defaults = {
+ /**
+ a classname for the pane element.
+ @property paneClass
+ @type String
+ @default 'pane'
+ */
+
+ paneClass: 'pane',
+ /**
+ a classname for the slider element.
+ @property sliderClass
+ @type String
+ @default 'slider'
+ */
+
+ sliderClass: 'slider',
+ /**
+ a classname for the content element.
+ @property contentClass
+ @type String
+ @default 'content'
+ */
+
+ contentClass: 'content',
+ /**
+ a setting to enable native scrolling in iOS devices.
+ @property iOSNativeScrolling
+ @type Boolean
+ @default false
+ */
+
+ iOSNativeScrolling: false,
+ /**
+ a setting to prevent the rest of the page being
+ scrolled when user scrolls the `.content` element.
+ @property preventPageScrolling
+ @type Boolean
+ @default false
+ */
+
+ preventPageScrolling: false,
+ /**
+ a setting to disable binding to the resize event.
+ @property disableResize
+ @type Boolean
+ @default false
+ */
+
+ disableResize: false,
+ /**
+ a setting to make the scrollbar always visible.
+ @property alwaysVisible
+ @type Boolean
+ @default false
+ */
+
+ alwaysVisible: false,
+ /**
+ a default timeout for the `flash()` method.
+ @property flashDelay
+ @type Number
+ @default 1500
+ */
+
+ flashDelay: 1500,
+ /**
+ a minimum height for the `.slider` element.
+ @property sliderMinHeight
+ @type Number
+ @default 20
+ */
+
+ sliderMinHeight: 20,
+ /**
+ a maximum height for the `.slider` element.
+ @property sliderMaxHeight
+ @type Number
+ @default null
+ */
+
+ sliderMaxHeight: null,
+ /**
+ an alternate document context.
+ @property documentContext
+ @type Document
+ @default null
+ */
+
+ documentContext: null,
+ /**
+ an alternate window context.
+ @property windowContext
+ @type Window
+ @default null
+ */
+
+ windowContext: null
+ };
+ /**
+ @property SCROLLBAR
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ SCROLLBAR = 'scrollbar';
+ /**
+ @property SCROLL
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ SCROLL = 'scroll';
+ /**
+ @property MOUSEDOWN
+ @type String
+ @final
+ @private
+ */
+
+ MOUSEDOWN = 'mousedown';
+ /**
+ @property MOUSEMOVE
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ MOUSEMOVE = 'mousemove';
+ /**
+ @property MOUSEWHEEL
+ @type String
+ @final
+ @private
+ */
+
+ MOUSEWHEEL = 'mousewheel';
+ /**
+ @property MOUSEUP
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ MOUSEUP = 'mouseup';
+ /**
+ @property RESIZE
+ @type String
+ @final
+ @private
+ */
+
+ RESIZE = 'resize';
+ /**
+ @property DRAG
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ DRAG = 'drag';
+ /**
+ @property UP
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ UP = 'up';
+ /**
+ @property PANEDOWN
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ PANEDOWN = 'panedown';
+ /**
+ @property DOMSCROLL
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ DOMSCROLL = 'DOMMouseScroll';
+ /**
+ @property DOWN
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ DOWN = 'down';
+ /**
+ @property WHEEL
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ WHEEL = 'wheel';
+ /**
+ @property KEYDOWN
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ KEYDOWN = 'keydown';
+ /**
+ @property KEYUP
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ KEYUP = 'keyup';
+ /**
+ @property TOUCHMOVE
+ @type String
+ @static
+ @final
+ @private
+ */
+
+ TOUCHMOVE = 'touchmove';
+ /**
+ @property BROWSER_IS_IE7
+ @type Boolean
+ @static
+ @final
+ @private
+ */
+
+ BROWSER_IS_IE7 = window.navigator.appName === 'Microsoft Internet Explorer' && /msie 7./i.test(window.navigator.appVersion) && window.ActiveXObject;
+ /**
+ @property BROWSER_SCROLLBAR_WIDTH
+ @type Number
+ @static
+ @default null
+ @private
+ */
+
+ BROWSER_SCROLLBAR_WIDTH = null;
+ rAF = window.requestAnimationFrame;
+ cAF = window.cancelAnimationFrame;
+ _elementStyle = document.createElement('div').style;
+ _vendor = (function() {
+ var i, transform, vendor, vendors, _i, _len;
+ vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'];
+ for (i = _i = 0, _len = vendors.length; _i < _len; i = ++_i) {
+ vendor = vendors[i];
+ transform = vendors[i] + 'ransform';
+ if (transform in _elementStyle) {
+ return vendors[i].substr(0, vendors[i].length - 1);
+ }
+ }
+ return false;
+ })();
+ _prefixStyle = function(style) {
+ if (_vendor === false) {
+ return false;
+ }
+ if (_vendor === '') {
+ return style;
+ }
+ return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
+ };
+ transform = _prefixStyle('transform');
+ hasTransform = transform !== false;
+ /**
+ Returns browser's native scrollbar width
+ @method getBrowserScrollbarWidth
+ @return {Number} the scrollbar width in pixels
+ @static
+ @private
+ */
+
+ getBrowserScrollbarWidth = function() {
+ var outer, outerStyle, scrollbarWidth;
+ outer = document.createElement('div');
+ outerStyle = outer.style;
+ outerStyle.position = 'absolute';
+ outerStyle.width = '100px';
+ outerStyle.height = '100px';
+ outerStyle.overflow = SCROLL;
+ outerStyle.top = '-9999px';
+ document.body.appendChild(outer);
+ scrollbarWidth = outer.offsetWidth - outer.clientWidth;
+ document.body.removeChild(outer);
+ return scrollbarWidth;
+ };
+ isFFWithBuggyScrollbar = function() {
+ var isOSXFF, ua, version;
+ ua = window.navigator.userAgent;
+ isOSXFF = /(?=.+Mac OS X)(?=.+Firefox)/.test(ua);
+ if (!isOSXFF) {
+ return false;
+ }
+ version = /Firefox\/\d{2}\./.exec(ua);
+ if (version) {
+ version = version[0].replace(/\D+/g, '');
+ }
+ return isOSXFF && +version > 23;
+ };
+ /**
+ @class NanoScroll
+ @param element {HTMLElement|Node} the main element
+ @param options {Object} nanoScroller's options
+ @constructor
+ */
+
+ NanoScroll = (function() {
+ function NanoScroll(el, options) {
+ this.el = el;
+ this.options = options;
+ BROWSER_SCROLLBAR_WIDTH || (BROWSER_SCROLLBAR_WIDTH = getBrowserScrollbarWidth());
+ this.$el = $(this.el);
+ this.doc = $(this.options.documentContext || document);
+ this.win = $(this.options.windowContext || window);
+ this.$content = this.$el.children("." + options.contentClass);
+ this.$content.attr('tabindex', this.options.tabIndex || 0);
+ this.content = this.$content[0];
+ if (this.options.iOSNativeScrolling && (this.el.style.WebkitOverflowScrolling != null)) {
+ this.nativeScrolling();
+ } else {
+ this.generate();
+ }
+ this.createEvents();
+ this.addEvents();
+ this.reset();
+ }
+
+ /**
+ Prevents the rest of the page being scrolled
+ when user scrolls the `.content` element.
+ @method preventScrolling
+ @param event {Event}
+ @param direction {String} Scroll direction (up or down)
+ @private
+ */
+
+
+ NanoScroll.prototype.preventScrolling = function(e, direction) {
+ if (!this.isActive) {
+ return;
+ }
+ if (e.type === DOMSCROLL) {
+ if (direction === DOWN && e.originalEvent.detail > 0 || direction === UP && e.originalEvent.detail < 0) {
+ e.preventDefault();
+ }
+ } else if (e.type === MOUSEWHEEL) {
+ if (!e.originalEvent || !e.originalEvent.wheelDelta) {
+ return;
+ }
+ if (direction === DOWN && e.originalEvent.wheelDelta < 0 || direction === UP && e.originalEvent.wheelDelta > 0) {
+ e.preventDefault();
+ }
+ }
+ };
+
+ /**
+ Enable iOS native scrolling
+ @method nativeScrolling
+ @private
+ */
+
+
+ NanoScroll.prototype.nativeScrolling = function() {
+ this.$content.css({
+ WebkitOverflowScrolling: 'touch'
+ });
+ this.iOSNativeScrolling = true;
+ this.isActive = true;
+ };
+
+ /**
+ Updates those nanoScroller properties that
+ are related to current scrollbar position.
+ @method updateScrollValues
+ @private
+ */
+
+
+ NanoScroll.prototype.updateScrollValues = function() {
+ var content;
+ content = this.content;
+ this.maxScrollTop = content.scrollHeight - content.clientHeight;
+ this.prevScrollTop = this.contentScrollTop || 0;
+ this.contentScrollTop = content.scrollTop;
+ if (!this.iOSNativeScrolling) {
+ // console.log(this.maxScrollTop, this.contentScrollTop, this.maxSliderTop, this.maxScrollTop);
+ // console.trace();
+ this.maxSliderTop = this.paneHeight - this.sliderHeight;
+ this.sliderTop = this.maxScrollTop === 0 ? 0 : this.contentScrollTop * this.maxSliderTop / this.maxScrollTop;
+ }
+ };
+
+ /**
+ Updates CSS styles for current scroll position.
+ Uses CSS 2d transfroms and `window.requestAnimationFrame` if available.
+ @method setOnScrollStyles
+ @private
+ */
+
+
+ NanoScroll.prototype.setOnScrollStyles = function() {
+ var cssValue,
+ _this = this;
+ if (hasTransform) {
+ cssValue = {};
+ cssValue[transform] = "translate(0, " + this.sliderTop + "px)";
+
+ // console.log(this.sliderTop, cssValue, this.scrollRAF, rAF);
+ } else {
+ cssValue = {
+ top: this.sliderTop
+ };
+ }
+ if (rAF) {
+ if (!this.scrollRAF) {
+ this.scrollRAF = rAF(function() {
+ // console.log('raf called', cssValue);
+ _this.scrollRAF = null;
+ _this.slider.css(cssValue);
+ });
+ }
+ } else {
+ this.slider.css(cssValue);
+ }
+ };
+
+ /**
+ Creates event related methods
+ @method createEvents
+ @private
+ */
+
+
+ NanoScroll.prototype.createEvents = function() {
+ var _this = this;
+ this.events = {
+ down: function(e) {
+ _this.isBeingDragged = true;
+ _this.offsetY = e.pageY - _this.slider.offset().top;
+ _this.pane.addClass('active');
+ _this.doc.bind(MOUSEMOVE, _this.events[DRAG]).bind(MOUSEUP, _this.events[UP]);
+ return false;
+ },
+ drag: function(e) {
+ _this.sliderY = e.pageY - _this.$el.offset().top - _this.offsetY;
+ _this.scroll();
+ _this.updateScrollValues();
+ if (_this.contentScrollTop >= _this.maxScrollTop && _this.prevScrollTop !== _this.maxScrollTop) {
+ _this.$el.trigger('scrollend');
+ } else if (_this.contentScrollTop === 0 && _this.prevScrollTop !== 0) {
+ _this.$el.trigger('scrolltop');
+ }
+ return false;
+ },
+ up: function(e) {
+ _this.isBeingDragged = false;
+ _this.pane.removeClass('active');
+ _this.doc.unbind(MOUSEMOVE, _this.events[DRAG]).unbind(MOUSEUP, _this.events[UP]);
+ return false;
+ },
+ resize: function(e) {
+ _this.reset();
+ },
+ panedown: function(e) {
+ _this.sliderY = (e.offsetY || e.originalEvent.layerY) - (_this.sliderHeight * 0.5);
+ _this.scroll();
+ _this.events.down(e);
+ return false;
+ },
+ scroll: function(e) {
+ if (_this.isBeingDragged) {
+ return;
+ }
+ _this.updateScrollValues();
+ if (!_this.iOSNativeScrolling) {
+ _this.sliderY = _this.sliderTop;
+ _this.setOnScrollStyles();
+ }
+ if (e == null) {
+ return;
+ }
+ if (_this.contentScrollTop >= _this.maxScrollTop) {
+ if (_this.options.preventPageScrolling) {
+ _this.preventScrolling(e, DOWN);
+ }
+ if (_this.prevScrollTop !== _this.maxScrollTop) {
+ _this.$el.trigger('scrollend');
+ }
+ } else if (_this.contentScrollTop === 0) {
+ if (_this.options.preventPageScrolling) {
+ _this.preventScrolling(e, UP);
+ }
+ if (_this.prevScrollTop !== 0) {
+ _this.$el.trigger('scrolltop');
+ }
+ }
+ },
+ wheel: function(e) {
+ var delta;
+ if (e == null) {
+ return;
+ }
+ delta = e.delta || e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.detail || (e.originalEvent && -e.originalEvent.detail);
+ if (delta) {
+ _this.sliderY += -delta / 3;
+ }
+ _this.scroll();
+ return false;
+ }
+ };
+ };
+
+ /**
+ Adds event listeners with jQuery.
+ @method addEvents
+ @private
+ */
+
+
+ NanoScroll.prototype.addEvents = function() {
+ var events;
+ this.removeEvents();
+ events = this.events;
+ if (!this.options.disableResize) {
+ this.win.bind(RESIZE, events[RESIZE]);
+ }
+ if (!this.iOSNativeScrolling) {
+ this.slider.bind(MOUSEDOWN, events[DOWN]);
+ this.pane.bind(MOUSEDOWN, events[PANEDOWN]).bind("" + MOUSEWHEEL + " " + DOMSCROLL, events[WHEEL]);
+ }
+ this.$content.bind("" + SCROLL + " " + MOUSEWHEEL + " " + DOMSCROLL + " " + TOUCHMOVE, events[SCROLL]);
+ };
+
+ /**
+ Removes event listeners with jQuery.
+ @method removeEvents
+ @private
+ */
+
+
+ NanoScroll.prototype.removeEvents = function() {
+ var events;
+ events = this.events;
+ this.win.unbind(RESIZE, events[RESIZE]);
+ if (!this.iOSNativeScrolling) {
+ this.slider.unbind();
+ this.pane.unbind();
+ }
+ this.$content.unbind("" + SCROLL + " " + MOUSEWHEEL + " " + DOMSCROLL + " " + TOUCHMOVE, events[SCROLL]);
+ };
+
+ /**
+ Generates nanoScroller's scrollbar and elements for it.
+ @method generate
+ @chainable
+ @private
+ */
+
+
+ NanoScroll.prototype.generate = function() {
+ var contentClass, cssRule, currentPadding, options, paneClass, sliderClass;
+ options = this.options;
+ paneClass = options.paneClass, sliderClass = options.sliderClass, contentClass = options.contentClass;
+ if (!this.$el.find("." + paneClass).length && !this.$el.find("." + sliderClass).length) {
+ this.$el.append("
");
+ }
+ this.pane = this.$el.children("." + paneClass);
+ this.slider = this.pane.find("." + sliderClass);
+ if (BROWSER_SCROLLBAR_WIDTH === 0 && isFFWithBuggyScrollbar()) {
+ currentPadding = window.getComputedStyle(this.content, null).getPropertyValue('padding-right').replace(/\D+/g, '');
+ cssRule = {
+ right: -14,
+ paddingRight: +currentPadding + 14
+ };
+ } else if (BROWSER_SCROLLBAR_WIDTH) {
+ cssRule = {
+ right: -BROWSER_SCROLLBAR_WIDTH
+ };
+ this.$el.addClass('has-scrollbar');
+ }
+ if (cssRule != null) {
+ this.$content.css(cssRule);
+ }
+ return this;
+ };
+
+ /**
+ @method restore
+ @private
+ */
+
+
+ NanoScroll.prototype.restore = function() {
+ this.stopped = false;
+ if (!this.iOSNativeScrolling) {
+ this.pane.show();
+ }
+ this.addEvents();
+ };
+
+ /**
+ Resets nanoScroller's scrollbar.
+ @method reset
+ @chainable
+ @example
+ $(".nano").nanoScroller();
+ */
+
+
+ NanoScroll.prototype.reset = function() {
+ var content, contentHeight, contentStyle, contentStyleOverflowY, paneBottom, paneHeight, paneOuterHeight, paneTop, parentMaxHeight, sliderHeight;
+ if (this.iOSNativeScrolling) {
+ this.contentHeight = this.content.scrollHeight;
+ return;
+ }
+ if (!this.$el.find("." + this.options.paneClass).length) {
+ this.generate().stop();
+ }
+ if (this.stopped) {
+ this.restore();
+ }
+ content = this.content;
+ contentStyle = content.style;
+ contentStyleOverflowY = contentStyle.overflowY;
+ if (BROWSER_IS_IE7) {
+ this.$content.css({
+ height: this.$content.height()
+ });
+ }
+ contentHeight = content.scrollHeight + BROWSER_SCROLLBAR_WIDTH;
+ parentMaxHeight = parseInt(this.$el.css("max-height"), 10);
+ if (parentMaxHeight > 0) {
+ this.$el.height("");
+ this.$el.height(content.scrollHeight > parentMaxHeight ? parentMaxHeight : content.scrollHeight);
+ }
+ paneHeight = this.pane.outerHeight(false);
+ paneTop = parseInt(this.pane.css('top'), 10);
+ paneBottom = parseInt(this.pane.css('bottom'), 10);
+ paneOuterHeight = paneHeight + paneTop + paneBottom;
+ sliderHeight = Math.round(paneOuterHeight / contentHeight * paneOuterHeight);
+ if (sliderHeight < this.options.sliderMinHeight) {
+ sliderHeight = this.options.sliderMinHeight;
+ } else if ((this.options.sliderMaxHeight != null) && sliderHeight > this.options.sliderMaxHeight) {
+ sliderHeight = this.options.sliderMaxHeight;
+ }
+ if (contentStyleOverflowY === SCROLL && contentStyle.overflowX !== SCROLL) {
+ sliderHeight += BROWSER_SCROLLBAR_WIDTH;
+ }
+ this.maxSliderTop = paneOuterHeight - sliderHeight;
+ this.contentHeight = contentHeight;
+ this.paneHeight = paneHeight;
+ this.paneOuterHeight = paneOuterHeight;
+ this.sliderHeight = sliderHeight;
+ this.slider.height(sliderHeight);
+ this.events.scroll();
+ this.pane.show();
+ this.isActive = true;
+ if ((content.scrollHeight === content.clientHeight) || (this.pane.outerHeight(true) >= content.scrollHeight && contentStyleOverflowY !== SCROLL)) {
+ this.pane.hide();
+ this.isActive = false;
+ } else if (this.el.clientHeight === content.scrollHeight && contentStyleOverflowY === SCROLL) {
+ this.slider.hide();
+ } else {
+ this.slider.show();
+ }
+ this.pane.css({
+ opacity: (this.options.alwaysVisible ? 1 : ''),
+ visibility: (this.options.alwaysVisible ? 'visible' : '')
+ });
+ return this;
+ };
+
+ /**
+ @method scroll
+ @private
+ @example
+ $(".nano").nanoScroller({ scroll: 'top' });
+ */
+
+
+ NanoScroll.prototype.scroll = function() {
+ if (!this.isActive) {
+ return;
+ }
+ this.sliderY = Math.max(0, this.sliderY);
+ this.sliderY = Math.min(this.maxSliderTop, this.sliderY);
+ this.$content.scrollTop((this.paneHeight - this.contentHeight + BROWSER_SCROLLBAR_WIDTH) * this.sliderY / this.maxSliderTop * -1);
+ if (!this.iOSNativeScrolling) {
+ this.updateScrollValues();
+ this.setOnScrollStyles();
+ }
+ return this;
+ };
+
+ /**
+ Scroll at the bottom with an offset value
+ @method scrollBottom
+ @param offsetY {Number}
+ @chainable
+ @example
+ $(".nano").nanoScroller({ scrollBottom: value });
+ */
+
+
+ NanoScroll.prototype.scrollBottom = function(offsetY) {
+ if (!this.isActive) {
+ return;
+ }
+ this.reset();
+ this.$content.scrollTop(this.contentHeight - this.$content.height() - offsetY).trigger(MOUSEWHEEL);
+ return this;
+ };
+
+ /**
+ Scroll at the top with an offset value
+ @method scrollTop
+ @param offsetY {Number}
+ @chainable
+ @example
+ $(".nano").nanoScroller({ scrollTop: value });
+ */
+
+
+ NanoScroll.prototype.scrollTop = function(offsetY) {
+ if (!this.isActive) {
+ return;
+ }
+ this.reset();
+ this.$content.scrollTop(+offsetY).trigger(MOUSEWHEEL);
+ return this;
+ };
+
+ /**
+ Scroll to an element
+ @method scrollTo
+ @param node {Node} A node to scroll to.
+ @chainable
+ @example
+ $(".nano").nanoScroller({ scrollTo: $('#a_node') });
+ */
+
+
+ NanoScroll.prototype.scrollTo = function(node) {
+ if (!this.isActive) {
+ return;
+ }
+ this.reset();
+ this.scrollTop($(node).get(0).offsetTop);
+ return this;
+ };
+
+ /**
+ To stop the operation.
+ This option will tell the plugin to disable all event bindings and hide the gadget scrollbar from the UI.
+ @method stop
+ @chainable
+ @example
+ $(".nano").nanoScroller({ stop: true });
+ */
+
+
+ NanoScroll.prototype.stop = function() {
+ if (cAF) {
+ cAF(this.scrollRAF);
+ }
+ this.stopped = true;
+ this.removeEvents();
+ if (!this.iOSNativeScrolling) {
+ this.pane.hide();
+ }
+ return this;
+ };
+
+ /**
+ Destroys nanoScroller and restores browser's native scrollbar.
+ @method destroy
+ @chainable
+ @example
+ $(".nano").nanoScroller({ destroy: true });
+ */
+
+
+ NanoScroll.prototype.destroy = function() {
+ if (!this.stopped) {
+ this.stop();
+ }
+ if (!this.iOSNativeScrolling && this.pane.length) {
+ this.pane.remove();
+ }
+ if (BROWSER_IS_IE7) {
+ this.$content.height('');
+ }
+ this.$content.removeAttr('tabindex');
+ if (this.$el.hasClass('has-scrollbar')) {
+ this.$el.removeClass('has-scrollbar');
+ this.$content.css({
+ right: ''
+ });
+ }
+ return this;
+ };
+
+ /**
+ To flash the scrollbar gadget for an amount of time defined in plugin settings (defaults to 1,5s).
+ Useful if you want to show the user (e.g. on pageload) that there is more content waiting for him.
+ @method flash
+ @chainable
+ @example
+ $(".nano").nanoScroller({ flash: true });
+ */
+
+
+ NanoScroll.prototype.flash = function() {
+ var _this = this;
+ if (this.iOSNativeScrolling) {
+ return;
+ }
+ if (!this.isActive) {
+ return;
+ }
+ this.reset();
+ this.pane.addClass('flashed');
+ setTimeout(function() {
+ _this.pane.removeClass('flashed');
+ }, this.options.flashDelay);
+ return this;
+ };
+
+ return NanoScroll;
+
+ })();
+ $.fn.nanoScroller = function(settings) {
+ return this.each(function() {
+ var options, scrollbar;
+ if (!(scrollbar = this.nanoscroller)) {
+ options = $.extend({}, defaults, settings);
+ this.nanoscroller = scrollbar = new NanoScroll(this, options);
+ }
+ if (settings && typeof settings === "object") {
+ $.extend(scrollbar.options, settings);
+ if (settings.scrollBottom != null) {
+ return scrollbar.scrollBottom(settings.scrollBottom);
+ }
+ if (settings.scrollTop != null) {
+ return scrollbar.scrollTop(settings.scrollTop);
+ }
+ if (settings.scrollTo) {
+ return scrollbar.scrollTo(settings.scrollTo);
+ }
+ if (settings.scroll === 'bottom') {
+ return scrollbar.scrollBottom(0);
+ }
+ if (settings.scroll === 'top') {
+ return scrollbar.scrollTop(0);
+ }
+ if (settings.scroll && settings.scroll instanceof $) {
+ return scrollbar.scrollTo(settings.scroll);
+ }
+ if (settings.stop) {
+ return scrollbar.stop();
+ }
+ if (settings.destroy) {
+ return scrollbar.destroy();
+ }
+ if (settings.flash) {
+ return scrollbar.flash();
+ }
+ }
+ return scrollbar.reset();
+ });
+ };
+ $.fn.nanoScroller.Constructor = NanoScroll;
+})(jQuery, window, document);
+
+/**
+ * emojiarea - A rich textarea control that supports emojis, WYSIWYG-style.
+ * Copyright (c) 2012 DIY Co
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License. You may obtain a copy of the License at:
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ *
+ * @author Brian Reavis
+ */
+
+ /**
+ * This file also contains some modifications by Igor Zhukov in order to add custom scrollbars to EmojiMenu
+ * See keyword `MODIFICATION` in source code.
+ */
+
+(function($, window, document) {
+
+ var ELEMENT_NODE = 1;
+ var TEXT_NODE = 3;
+ var TAGS_BLOCK = ['p', 'div', 'pre', 'form'];
+ var KEY_ESC = 27;
+ var KEY_TAB = 9;
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ /*! MODIFICATION START
+ Options 'spritesheetPath', 'spritesheetDimens', 'iconSize' added by Andre Staltz.
+ */
+ $.emojiarea = {
+ path: '',
+ spritesheetPath: '',
+ spritesheetDimens: [],
+ iconSize: 20,
+ icons: {},
+ defaults: {
+ button: null,
+ buttonLabel: 'Emojis',
+ buttonPosition: 'after'
+ }
+ };
+ /*! MODIFICATION END */
+
+ $.fn.emojiarea = function(options) {
+ options = $.extend({}, $.emojiarea.defaults, options);
+ return this.each(function() {
+ var $textarea = $(this);
+ if ('contentEditable' in document.body && options.wysiwyg !== false) {
+ new EmojiArea_WYSIWYG($textarea, options);
+ } else {
+ new EmojiArea_Plain($textarea, options);
+ }
+ });
+ };
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ var util = {};
+
+ util.restoreSelection = (function() {
+ if (window.getSelection) {
+ return function(savedSelection) {
+ var sel = window.getSelection();
+ sel.removeAllRanges();
+ for (var i = 0, len = savedSelection.length; i < len; ++i) {
+ sel.addRange(savedSelection[i]);
+ }
+ };
+ } else if (document.selection && document.selection.createRange) {
+ return function(savedSelection) {
+ if (savedSelection) {
+ savedSelection.select();
+ }
+ };
+ }
+ })();
+
+ util.saveSelection = (function() {
+ if (window.getSelection) {
+ return function() {
+ var sel = window.getSelection(), ranges = [];
+ if (sel.rangeCount) {
+ for (var i = 0, len = sel.rangeCount; i < len; ++i) {
+ ranges.push(sel.getRangeAt(i));
+ }
+ }
+ return ranges;
+ };
+ } else if (document.selection && document.selection.createRange) {
+ return function() {
+ var sel = document.selection;
+ return (sel.type.toLowerCase() !== 'none') ? sel.createRange() : null;
+ };
+ }
+ })();
+
+ util.replaceSelection = (function() {
+ if (window.getSelection) {
+ return function(content) {
+ var range, sel = window.getSelection();
+ var node = typeof content === 'string' ? document.createTextNode(content) : content;
+ if (sel.getRangeAt && sel.rangeCount) {
+ range = sel.getRangeAt(0);
+ range.deleteContents();
+ range.insertNode(document.createTextNode(' '));
+ range.insertNode(node);
+ range.setStart(node, 0);
+
+ window.setTimeout(function() {
+ range = document.createRange();
+ range.setStartAfter(node);
+ range.collapse(true);
+ sel.removeAllRanges();
+ sel.addRange(range);
+ }, 0);
+ }
+ }
+ } else if (document.selection && document.selection.createRange) {
+ return function(content) {
+ var range = document.selection.createRange();
+ if (typeof content === 'string') {
+ range.text = content;
+ } else {
+ range.pasteHTML(content.outerHTML);
+ }
+ }
+ }
+ })();
+
+ util.insertAtCursor = function(text, el) {
+ text = ' ' + text;
+ var val = el.value, endIndex, startIndex, range;
+ if (typeof el.selectionStart != 'undefined' && typeof el.selectionEnd != 'undefined') {
+ startIndex = el.selectionStart;
+ endIndex = el.selectionEnd;
+ el.value = val.substring(0, startIndex) + text + val.substring(el.selectionEnd);
+ el.selectionStart = el.selectionEnd = startIndex + text.length;
+ } else if (typeof document.selection != 'undefined' && typeof document.selection.createRange != 'undefined') {
+ el.focus();
+ range = document.selection.createRange();
+ range.text = text;
+ range.select();
+ }
+ };
+
+ util.extend = function(a, b) {
+ if (typeof a === 'undefined' || !a) { a = {}; }
+ if (typeof b === 'object') {
+ for (var key in b) {
+ if (b.hasOwnProperty(key)) {
+ a[key] = b[key];
+ }
+ }
+ }
+ return a;
+ };
+
+ util.escapeRegex = function(str) {
+ return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
+ };
+
+ util.htmlEntities = function(str) {
+ return String(str).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"');
+ };
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ var EmojiArea = function() {};
+
+ EmojiArea.prototype.setup = function() {
+ var self = this;
+
+ this.$editor.on('focus', function() { self.hasFocus = true; });
+ this.$editor.on('blur', function() { self.hasFocus = false; });
+
+ this.setupButton();
+ };
+
+ EmojiArea.prototype.setupButton = function() {
+ var self = this;
+ var $button;
+
+ if (this.options.button) {
+ $button = $(this.options.button);
+ } else if (this.options.button !== false) {
+ $button = $('');
+ $button.html(this.options.buttonLabel);
+ $button.addClass('emoji-button');
+ $button.attr({title: this.options.buttonLabel});
+ this.$editor[this.options.buttonPosition]($button);
+ } else {
+ $button = $('');
+ }
+
+ $button.on('click', function(e) {
+ EmojiMenu.show(self);
+ e.stopPropagation();
+ });
+
+ this.$button = $button;
+ };
+
+ /*! MODIFICATION START
+ This function was modified by Andre Staltz so that the icon is created from a spritesheet.
+ */
+ EmojiArea.createIcon = function(emoji) {
+ var category = emoji[0];
+ var row = emoji[1];
+ var column = emoji[2];
+ var name = emoji[3];
+ var filename = $.emojiarea.spritesheetPath;
+ var xoffset = -($.emojiarea.iconSize * column);
+ var yoffset = -($.emojiarea.iconSize * row);
+ var scaledWidth = ($.emojiarea.spritesheetDimens[category][1] * $.emojiarea.iconSize);
+ var scaledHeight = ($.emojiarea.spritesheetDimens[category][0] * $.emojiarea.iconSize);
+
+ var style = 'display:inline-block;';
+ style += 'width:' + $.emojiarea.iconSize + 'px;';
+ style += 'height:' + $.emojiarea.iconSize + 'px;';
+ style += 'background:url(\'' + filename.replace('!',category) + '\') ' + xoffset + 'px ' + yoffset + 'px no-repeat;';
+ style += 'background-size:' + scaledWidth + 'px ' + scaledHeight + 'px;';
+ return '
';
+ };
+ /*! MODIFICATION END */
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ /**
+ * Editor (plain-text)
+ *
+ * @constructor
+ * @param {object} $textarea
+ * @param {object} options
+ */
+
+ var EmojiArea_Plain = function($textarea, options) {
+ this.options = options;
+ this.$textarea = $textarea;
+ this.$editor = $textarea;
+ this.setup();
+ };
+
+ EmojiArea_Plain.prototype.insert = function(emoji) {
+ if (!$.emojiarea.icons.hasOwnProperty(emoji)) return;
+ util.insertAtCursor(emoji, this.$textarea[0]);
+ this.$textarea.trigger('change');
+ };
+
+ EmojiArea_Plain.prototype.val = function() {
+ return this.$textarea.val();
+ };
+
+ util.extend(EmojiArea_Plain.prototype, EmojiArea.prototype);
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ /**
+ * Editor (rich)
+ *
+ * @constructor
+ * @param {object} $textarea
+ * @param {object} options
+ */
+
+ var EmojiArea_WYSIWYG = function($textarea, options) {
+ var self = this;
+
+ this.options = options || {};
+ this.$textarea = $textarea;
+ this.$editor = $('').addClass('emoji-wysiwyg-editor');
+ this.$editor.text($textarea.val());
+ this.$editor.attr({contenteditable: 'true'});
+ /*! MODIFICATION START
+ Following code was modified by Igor Zhukov, in order to improve rich text paste
+ */
+ var changeEvents = 'blur change';
+ if (!this.options.norealTime) {
+ changeEvents += ' keyup';
+ }
+ this.$editor.on(changeEvents, function(e) { return self.onChange.apply(self, [e]); });
+ this.$editor.on('paste', function(e) { return self.onPaste.apply(self, [e]); });
+ /*! MODIFICATION END */
+
+ this.$editor.on('mousedown focus', function() { document.execCommand('enableObjectResizing', false, false); });
+ this.$editor.on('blur', function() { document.execCommand('enableObjectResizing', true, true); });
+
+ var html = this.$editor.text();
+ var emojis = $.emojiarea.icons;
+ for (var key in emojis) {
+ if (emojis.hasOwnProperty(key)) {
+ /* MODIFICATION: Following line was modified by Andre Staltz, to use new implementation of createIcon function.*/
+ html = html.replace(new RegExp(util.escapeRegex(key), 'g'), EmojiArea.createIcon(emojis[key]));
+ }
+ }
+ this.$editor.html(html);
+
+ $textarea.hide().after(this.$editor);
+
+ this.setup();
+
+ /* MODIFICATION: Following line was modified by Igor Zhukov, in order to improve emoji insert behaviour */
+ $(document.body).on('mousedown', function() {
+ if (self.hasFocus) {
+ self.selection = util.saveSelection();
+ }
+ });
+ };
+
+ /*! MODIFICATION START
+ Following code was modified by Igor Zhukov, in order to improve rich text paste
+ */
+ EmojiArea_WYSIWYG.prototype.onPaste = function(e) {
+ var cData = (e.originalEvent || e).clipboardData,
+ items = cData && cData.items || [],
+ i;
+ for (i = 0; i < items.length; i++) {
+ if (items[i].kind == 'file') {
+ e.preventDefault();
+ return true;
+ }
+ }
+
+ var text = (e.originalEvent || e).clipboardData.getData('text/plain'),
+ self = this;
+ setTimeout(function () {
+ self.onChange();
+ }, 0);
+ if (text.length) {
+ document.execCommand('insertText', false, text);
+ return cancelEvent(e);
+ }
+ return true;
+ };
+ /*! MODIFICATION END */
+
+ EmojiArea_WYSIWYG.prototype.onChange = function(e) {
+ this.$textarea.val(this.val()).trigger('change');
+ };
+
+ EmojiArea_WYSIWYG.prototype.insert = function(emoji) {
+ var content;
+ /* MODIFICATION: Following line was modified by Andre Staltz, to use new implementation of createIcon function.*/
+ var $img = $(EmojiArea.createIcon($.emojiarea.icons[emoji]));
+ if ($img[0].attachEvent) {
+ $img[0].attachEvent('onresizestart', function(e) { e.returnValue = false; }, false);
+ }
+
+ this.$editor.trigger('focus');
+ if (this.selection) {
+ util.restoreSelection(this.selection);
+ }
+ try { util.replaceSelection($img[0]); } catch (e) {}
+
+ /*! MODIFICATION START
+ Following code was modified by Igor Zhukov, in order to improve selection handling
+ */
+ var self = this;
+ setTimeout(function () {
+ self.selection = util.saveSelection();
+ }, 100);
+ /*! MODIFICATION END */
+
+ this.onChange();
+ };
+
+ EmojiArea_WYSIWYG.prototype.val = function() {
+ var lines = [];
+ var line = [];
+
+ var flush = function() {
+ lines.push(line.join(''));
+ line = [];
+ };
+
+ var sanitizeNode = function(node) {
+ if (node.nodeType === TEXT_NODE) {
+ line.push(node.nodeValue);
+ } else if (node.nodeType === ELEMENT_NODE) {
+ var tagName = node.tagName.toLowerCase();
+ var isBlock = TAGS_BLOCK.indexOf(tagName) !== -1;
+
+ if (isBlock && line.length) flush();
+
+ if (tagName === 'img') {
+ var alt = node.getAttribute('alt') || '';
+ if (alt) line.push(alt);
+ return;
+ } else if (tagName === 'br') {
+ flush();
+ }
+
+ var children = node.childNodes;
+ for (var i = 0; i < children.length; i++) {
+ sanitizeNode(children[i]);
+ }
+
+ if (isBlock && line.length) flush();
+ }
+ };
+
+ var children = this.$editor[0].childNodes;
+ for (var i = 0; i < children.length; i++) {
+ sanitizeNode(children[i]);
+ }
+
+ if (line.length) flush();
+
+ return lines.join('\n');
+ };
+
+ util.extend(EmojiArea_WYSIWYG.prototype, EmojiArea.prototype);
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ /**
+ * Emoji Dropdown Menu
+ *
+ * @constructor
+ * @param {object} emojiarea
+ */
+ var EmojiMenu = function() {
+ var self = this;
+ var $body = $(document.body);
+ var $window = $(window);
+
+ this.visible = false;
+ this.emojiarea = null;
+ this.$menu = $('
');
+ this.$menu.addClass('emoji-menu');
+ this.$menu.hide();
+
+ /*! MODIFICATION START
+ Following code was modified by Igor Zhukov, in order to add scrollbars and tail to EmojiMenu
+ Also modified by Andre Staltz, to include tabs for categories, on the menu header.
+ */
+ this.$itemsTailWrap = $('
').appendTo(this.$menu);
+ this.$categoryTabs = $('').appendTo(this.$itemsTailWrap);
+ this.$itemsWrap = $('
').appendTo(this.$itemsTailWrap);
+ this.$items = $('
').appendTo(this.$itemsWrap);
+ $('