PageSourceSearch

https://www.newsviewsnetwork.com/wp-content/themes/zox-news/js/scripts.js?ver=7.0.6

js newsviewsnetwork.com collected 2026-09-25 10:50:03 UTC 127,088 bytes, 3,711 lines download raw bytes

1jQuery(document).ready(function($) {
2"use strict";
3
4  	// Fly-Out Navigation
5	$(".mvp-fly-but-click").on('click', function(){
6		$("#mvp-fly-wrap").toggleClass("mvp-fly-menu");
7		$("#mvp-fly-wrap").toggleClass("mvp-fly-shadow");
8  		$(".mvp-fly-but-wrap").toggleClass("mvp-fly-open");
9  		$(".mvp-fly-fade").toggleClass("mvp-fly-fade-trans");
10	});
11
12	// Back to Top Button
13    	var duration = 500;
14    	$('.back-to-top').on('click', function(event) {
15          event.preventDefault();
16          $('html, body').animate({scrollTop: 0}, duration);
17          return false;
18    	});
19
20 	// Search Toggle
21 	$(".mvp-search-click").on('click', function(){
22 	  $("#mvp-search-wrap").toggleClass("mvp-search-toggle");
23  	});
24
25 	// Mobile Social Toggle
26 	$(".mvp-mob-soc-click").on('click', function(){
27 	  $(".mvp-mob-soc-list").toggleClass("mvp-mob-soc-tog");
28  	});
29
30 	// Trending Toggle
31 	$(".mvp-post-trend-but-click").on('click', function(){
32 	  $("#mvp-post-trend-wrap").toggleClass("mvp-post-trend-tog");
33  	});
34
35   	// Comments Toggle
36   	$(".mvp-com-click").on('click', function(){
37	  $("#comments").show();
38  	  $("#disqus_thread").show();
39  	  $("#mvp-comments-button").hide();
40  	});
41
42   	// Continue Reading Toggle
43   	$(".mvp-ad-rel-click").on('click', function(){
44	  $("#mvp-content-main").css('max-height','none');
45  	  $('#mvp-ad-rel-wrap').css('margin-top','20px');
46  	  $("#mvp-ad-rel-top").hide();
47  	});
48
49	// Columns Toggle
50	$('.mvp-feat1-right-wrap').each(function() {
51		$(this).find(".mvp-tab-col-cont").hide(); //Hide all content
52		$(this).find("ul.mvp-feat1-list-buts li.mvp-feat-col-tab").addClass("active").show(); //Activate first tab
53		$(this).find(".mvp-tab-col-cont:first").show(); //Show first tab content
54	});
55
56	$("ul.mvp-feat1-list-buts li").on('click', function(e) {
57		$(this).parents('.mvp-feat1-right-wrap').find("ul.mvp-feat1-list-buts li").removeClass("active"); //Remove any "active" class
58		$(this).addClass("active"); //Add "active" class to selected tab
59		$(this).parents('.mvp-feat1-right-wrap').find(".mvp-tab-col-cont").hide(); //Hide all tab content
60
61		var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
62		$(this).parents('.mvp-feat1-right-wrap').find(activeTab).fadeIn(); //Fade in the active ID content
63
64		e.preventDefault();
65	});
66
67	$("ul.mvp-feat1-list-buts li a").on('click', function(e) {
68		e.preventDefault();
69	});
70
71	// Widget Columns Toggle
72	$('.mvp-widget-tab-wrap').each(function() {
73		$(this).find(".mvp-tab-col-cont").hide(); //Hide all content
74		$(this).find("ul.mvp-feat1-list-buts li.mvp-feat-col-tab").addClass("active").show(); //Activate first tab
75		$(this).find(".mvp-tab-col-cont:first").show(); //Show first tab content
76	});
77
78	$("ul.mvp-feat1-list-buts li").on('click', function(e) {
79		$(this).parents('.mvp-widget-tab-wrap').find("ul.mvp-feat1-list-buts li").removeClass("active"); //Remove any "active" class
80		$(this).addClass("active"); //Add "active" class to selected tab
81		$(this).parents('.mvp-widget-tab-wrap').find(".mvp-tab-col-cont").hide(); //Hide all tab content
82
83		var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
84		$(this).parents('.mvp-widget-tab-wrap').find(activeTab).fadeIn(); //Fade in the active ID content
85
86		e.preventDefault();
87	});
88
89	$("ul.mvp-feat1-list-buts li a").on('click', function(e) {
90		e.preventDefault();
91	});
92
93});
94
95
96	// Scoreboard
97
98(function( window, $, undefined ) {
99
100	$.fn.touchwipe 				= function(settings) {
101
102		var config = {
103			min_move_x: 20,
104			min_move_y: 20,
105			wipeLeft: function() { },
106			wipeRight: function() { },
107			wipeUp: function() { },
108			wipeDown: function() { },
109			preventDefaultEvents: true
110		};
111
112		if (settings) $.extend(config, settings);
113
114		this.each(function() {
115			var startX;
116			var startY;
117			var isMoving = false;
118
119			function cancelTouch() {
120				this.removeEventListener('touchmove', onTouchMove, {passive: true});
121				startX = null;
122				isMoving = false;
123			}
124
125			function onTouchMove(e) {
126				if(config.preventDefaultEvents) {
127					e.preventDefault();
128				}
129				if(isMoving) {
130					var x = e.touches[0].pageX;
131					var y = e.touches[0].pageY;
132					var dx = startX - x;
133					var dy = startY - y;
134					if(Math.abs(dx) >= config.min_move_x) {
135						cancelTouch();
136						if(dx > 0) {
137							config.wipeLeft();
138						}
139						else {
140							config.wipeRight();
141						}
142					}
143					else if(Math.abs(dy) >= config.min_move_y) {
144						cancelTouch();
145						if(dy > 0) {
146							config.wipeDown();
147						}
148						else {
149							config.wipeUp();
150						}
151					}
152				}
153			}
154
155			function onTouchStart(e)
156			{
157				if (e.touches.length == 1) {
158					startX = e.touches[0].pageX;
159					startY = e.touches[0].pageY;
160					isMoving = true;
161					this.addEventListener('touchmove', onTouchMove, false);
162				}
163			}
164			if ('ontouchstart' in document.documentElement) {
165				this.addEventListener('touchstart', onTouchStart, false);
166			}
167		});
168
169		return this;
170	};
171
172	$.elastislide 				= function( options, element ) {
173		this.$el	= $( element );
174		this._init( options );
175	};
176
177	$.elastislide.defaults 		= {
178		speed		: 450,	// animation speed
179		easing		: '',	// animation easing effect
180		imageW		: 190,	// the images width
181		margin		: 0,	// image margin right
182		border		: 0,	// image border
183		minItems	: 1,	// the minimum number of items to show.
184							// when we resize the window, this will make sure minItems are always shown
185							// (unless of course minItems is higher than the total number of elements)
186		current		: 0,	// index of the current item
187							// when we resize the window, the carousel will make sure this item is visible
188		onClick		: function() { return false; } // click item callback
189    };
190
191	$.elastislide.prototype 	= {
192		_init 				: function( options ) {
193
194			this.options 		= $.extend( true, {}, $.elastislide.defaults, options );
195
196			// <ul>
197			this.$slider		= this.$el.find('ul');
198
199			// <li>
200			this.$items			= this.$slider.children('li');
201
202			// total number of elements / images
203			this.itemsCount		= this.$items.length;
204
205			// cache the <ul>'s parent, since we will eventually need to recalculate its width on window resize
206			this.$esCarousel	= this.$slider.parent();
207
208			// validate options
209			this._validateOptions();
210
211			// set sizes and initialize some vars...
212			this._configure();
213
214			// add navigation buttons
215			this._addControls();
216
217			// initialize the events
218			this._initEvents();
219
220			// show the <ul>
221			this.$slider.show();
222
223			// slide to current's position
224			this._slideToCurrent( false );
225
226		},
227		_validateOptions	: function() {
228
229			if( this.options.speed < 0 )
230				this.options.speed = 450;
231			if( this.options.margin < 0 )
232				this.options.margin = 4;
233			if( this.options.border < 0 )
234				this.options.border = 1;
235			if( this.options.minItems < 1 || this.options.minItems > this.itemsCount )
236				this.options.minItems = 1;
237			if( this.options.current > this.itemsCount - 1 )
238				this.options.current = 0;
239
240		},
241		_configure			: function() {
242
243			// current item's index
244			this.current		= this.options.current;
245
246			// the ul's parent's (div.es-carousel) width is the "visible" width
247			this.visibleWidth	= this.$esCarousel.width();
248
249			// test to see if we need to initially resize the items
250			if( this.visibleWidth < this.options.minItems * ( this.options.imageW + 2 * this.options.border ) + ( this.options.minItems - 1 ) * this.options.margin ) {
251				this._setDim( ( this.visibleWidth - ( this.options.minItems - 1 ) * this.options.margin ) / this.options.minItems );
252				this._setCurrentValues();
253				// how many items fit with the current width
254				this.fitCount	= this.options.minItems;
255			}
256			else {
257				this._setDim();
258				this._setCurrentValues();
259			}
260
261			// set the <ul> width
262			this.$slider.css({
263				width	: this.sliderW
264			});
265
266		},
267		_setDim				: function( elW ) {
268
269			// <li> style
270			this.$items.css({
271				marginRight	: this.options.margin,
272				width		: ( elW ) ? elW : this.options.imageW + 2 * this.options.border
273			}).children('a').css({ // <a> style
274				borderWidth		: this.options.border
275			});
276
277		},
278		_setCurrentValues	: function() {
279
280			// the total space occupied by one item
281			this.itemW			= this.$items.outerWidth(true);
282
283			// total width of the slider / <ul>
284			// this will eventually change on window resize
285			this.sliderW		= this.itemW * this.itemsCount;
286
287			// the ul parent's (div.es-carousel) width is the "visible" width
288			this.visibleWidth	= this.$esCarousel.width();
289
290			// how many items fit with the current width
291			this.fitCount		= Math.floor( this.visibleWidth / this.itemW );
292
293		},
294		_addControls		: function() {
295
296			this.$navNext	= $('<span class="es-nav-next"><a>&gt;</a></span>');
297			this.$navPrev	= $('<span class="es-nav-prev"><a>&lt;</a></span>');
298			$('<div class="es-nav"/>')
299			.append( this.$navPrev )
300			.append( this.$navNext )
301			.appendTo( this.$el );
302
303			//this._toggleControls();
304
305		},
306		_toggleControls		: function( dir, status ) {
307
308			// show / hide navigation buttons
309			if( dir && status ) {
310				if( status === 1 )
311					( dir === 'right' ) ? this.$navNext.show() : this.$navPrev.show();
312				else
313					( dir === 'right' ) ? this.$navNext.hide() : this.$navPrev.hide();
314			}
315			else if( this.current === this.itemsCount - 1 || this.fitCount >= this.itemsCount )
316					this.$navNext.hide();
317
318		},
319		_initEvents			: function() {
320
321			var instance	= this;
322
323			// window resize
324			$(window).bind('resize.elastislide', function( event ) {
325
326				// set values again
327				instance._setCurrentValues();
328
329				// need to resize items
330				if( instance.visibleWidth < instance.options.minItems * ( instance.options.imageW + 2 * instance.options.border ) + ( instance.options.minItems - 1 ) * instance.options.margin ) {
331					instance._setDim( ( instance.visibleWidth - ( instance.options.minItems - 1 ) * instance.options.margin ) / instance.options.minItems );
332					instance._setCurrentValues();
333					instance.fitCount	= instance.options.minItems;
334				}
335				else{
336					instance._setDim();
337					instance._setCurrentValues();
338				}
339
340				instance.$slider.css({
341					width	: instance.sliderW + 10 // TODO: +10px seems to solve a firefox "bug" :S
342				});
343
344				// slide to the current element
345				clearTimeout( instance.resetTimeout );
346				instance.resetTimeout	= setTimeout(function() {
347					instance._slideToCurrent();
348				}, 200);
349
350			});
351
352			// navigation buttons events
353			this.$navNext.bind('click.elastislide', function( event ) {
354				instance._slide('right');
355			});
356
357			this.$navPrev.bind('click.elastislide', function( event ) {
358				instance._slide('left');
359			});
360
361			// item click event
362			this.$items.bind('click.elastislide', function( event ) {
363				instance.options.onClick( $(this) );
364				//return false;
365			});
366
367			// touch events
368			instance.$slider.touchwipe({
369				wipeLeft			: function() {
370					instance._slide('right');
371				},
372				wipeRight			: function() {
373					instance._slide('left');
374				}
375			});
376
377		},
378		_slide				: function( dir, val, anim, callback ) {
379
380			// if animating return
381			if( this.$slider.is(':animated') )
382				return false;
383
384			// current margin left
385			var ml		= parseFloat( this.$slider.css('margin-left') );
386
387			// val is just passed when we want an exact value for the margin left (used in the _slideToCurrent function)
388			if( val === undefined ) {
389
390				// how much to slide?
391				var amount	= this.fitCount * this.itemW, val;
392
393				if( amount < 0 ) return false;
394
395				// make sure not to leave a space between the last item / first item and the end / beggining of the slider available width
396				if( dir === 'right' && this.sliderW - ( Math.abs( ml ) + amount ) < this.visibleWidth ) {
397					amount	= this.sliderW - ( Math.abs( ml ) + this.visibleWidth ) - this.options.margin; // decrease the margin left
398					// show / hide navigation buttons
399					this._toggleControls( 'right', -1 );
400					this._toggleControls( 'left', 1 );
401				}
402				else if( dir === 'left' && Math.abs( ml ) - amount < 0 ) {
403					amount	= Math.abs( ml );
404					// show / hide navigation buttons
405					this._toggleControls( 'left', -1 );
406					this._toggleControls( 'right', 1 );
407				}
408				else {
409					var fml; // future margin left
410					( dir === 'right' )
411						? fml = Math.abs( ml ) + this.options.margin + Math.abs( amount )
412						: fml = Math.abs( ml ) - this.options.margin - Math.abs( amount );
413
414					// show / hide navigation buttons
415					if( fml > 0 )
416						this._toggleControls( 'left', 1 );
417					else
418						this._toggleControls( 'left', -1 );
419
420					if( fml < this.sliderW - this.visibleWidth )
421						this._toggleControls( 'right', 1 );
422					else
423						this._toggleControls( 'right', -1 );
424
425				}
426
427				( dir === 'right' ) ? val = '-=' + amount : val = '+=' + amount
428
429			}
430			else {
431				var fml		= Math.abs( val ); // future margin left
432
433				if( Math.max( this.sliderW, this.visibleWidth ) - fml < this.visibleWidth ) {
434					val	= - ( Math.max( this.sliderW, this.visibleWidth ) - this.visibleWidth );
435					if( val !== 0 )
436						val += this.options.margin;	// decrease the margin left if not on the first position
437
438					// show / hide navigation buttons
439					this._toggleControls( 'right', -1 );
440					fml	= Math.abs( val );
441				}
442
443				// show / hide navigation buttons
444				if( fml > 0 )
445					this._toggleControls( 'left', 1 );
446				else
447					this._toggleControls( 'left', -1 );
448
449				if( Math.max( this.sliderW, this.visibleWidth ) - this.visibleWidth > fml + this.options.margin )
450					this._toggleControls( 'right', 1 );
451				else
452					this._toggleControls( 'right', -1 );
453
454			}
455
456			$.fn.applyStyle = ( anim === undefined ) ? $.fn.animate : $.fn.css;
457
458			var sliderCSS	= { marginLeft : val };
459
460			var instance	= this;
461
462			this.$slider.applyStyle( sliderCSS, $.extend( true, [], { duration : this.options.speed, easing : this.options.easing, complete : function() {
463				if( callback ) callback.call();
464			} } ) );
465
466		},
467		_slideToCurrent		: function( anim ) {
468
469			// how much to slide?
470			var amount	= this.current * this.itemW;
471			this._slide('', -amount, anim );
472
473		},
474		add					: function( $newelems, callback ) {
475
476			// adds new items to the carousel
477			this.$items 		= this.$items.add( $newelems );
478			this.itemsCount		= this.$items.length;
479			this._setDim();
480			this._setCurrentValues();
481			this.$slider.css({
482				width	: this.sliderW
483			});
484			this._slideToCurrent();
485
486			if ( callback ) callback.call( $newelems );
487
488		},
489		destroy				: function( callback ) {
490			this._destroy( callback );
491		},
492		_destroy 			: function( callback ) {
493			this.$el.unbind('.elastislide').removeData('elastislide');
494			$(window).unbind('.elastislide');
495			if ( callback ) callback.call();
496		}
497	};
498
499	var logError 				= function( message ) {
500		if ( this.console ) {
501			console.error( message );
502		}
503	};
504
505	$.fn.elastislide 				= function( options ) {
506		if ( typeof options === 'string' ) {
507			var args = Array.prototype.slice.call( arguments, 1 );
508
509			this.each(function() {
510				var instance = $.data( this, 'elastislide' );
511				if ( !instance ) {
512					logError( "cannot call methods on elastislide prior to initialization; " +
513					"attempted to call method '" + options + "'" );
514					return;
515				}
516				if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
517					logError( "no such method '" + options + "' for elastislide instance" );
518					return;
519				}
520				instance[ options ].apply( instance, args );
521			});
522		}
523		else {
524			this.each(function() {
525				var instance = $.data( this, 'elastislide' );
526				if ( !instance ) {
527					$.data( this, 'elastislide', new $.elastislide( options, this ) );
528				}
529			});
530		}
531		return this;
532	};
533
534})( window, jQuery );
535
536
537	// Nicescroll
538
539(function(jQuery){
540
541  // globals
542  var domfocus = false;
543  var mousefocus = false;
544  var zoomactive = false;
545  var tabindexcounter = 5000;
546  var ascrailcounter = 2000;
547  var globalmaxzindex = 0;
548
549  var $ = jQuery;  // sandbox
550
551  // http://stackoverflow.com/questions/2161159/get-script-path
552  function getScriptPath() {
553    var scripts=document.getElementsByTagName('script');
554    var path=scripts[scripts.length-1].src.split('?')[0];
555    return (path.split('/').length>0) ? path.split('/').slice(0,-1).join('/')+'/' : '';
556  }
557  var scriptpath = getScriptPath();
558
559  var vendors = ['ms','moz','webkit','o'];
560
561  var setAnimationFrame = window.requestAnimationFrame||false;
562  var clearAnimationFrame = window.cancelAnimationFrame||false;
563
564  if (!setAnimationFrame) {
565    for(var vx in vendors) {
566      var v = vendors[vx];
567      if (!setAnimationFrame) setAnimationFrame = window[v+'RequestAnimationFrame'];
568      if (!clearAnimationFrame) clearAnimationFrame = window[v+'CancelAnimationFrame']||window[v+'CancelRequestAnimationFrame'];
569    }
570  }
571
572  var clsMutationObserver = window.MutationObserver || window.WebKitMutationObserver || false;
573
574  var _globaloptions = {
575      zindex:"auto",
576      cursoropacitymin:0,
577      cursoropacitymax:1,
578      cursorcolor:"#424242",
579      cursorwidth:"5px",
580      cursorborder:"1px solid #fff",
581      cursorborderradius:"5px",
582      scrollspeed:60,
583      mousescrollstep:8*3,
584      touchbehavior:false,
585      hwacceleration:true,
586      usetransition:true,
587      boxzoom:false,
588      dblclickzoom:true,
589      gesturezoom:true,
590      grabcursorenabled:true,
591      autohidemode:true,
592      background:"",
593      iframeautoresize:true,
594      cursorminheight:32,
595      preservenativescrolling:true,
596      railoffset:false,
597      bouncescroll:true,
598      spacebarenabled:true,
599      railpadding:{top:0,right:0,left:0,bottom:0},
600      disableoutline:true,
601      horizrailenabled:true,
602      railalign:"right",
603      railvalign:"bottom",
604      enabletranslate3d:true,
605      enablemousewheel:true,
606      enablekeyboard:true,
607      smoothscroll:true,
608      sensitiverail:true,
609      enablemouselockapi:true,
610//      cursormaxheight:false,
611      cursorfixedheight:false,
612      directionlockdeadzone:6,
613      hidecursordelay:400,
614      nativeparentscrolling:true,
615      enablescrollonselection:true,
616      overflowx:true,
617      overflowy:true,
618      cursordragspeed:0.3,
619      rtlmode:false,
620      cursordragontouch:false,
621      oneaxismousemode:"auto"
622  }
623
624  var browserdetected = false;
625
626  var getBrowserDetection = function() {
627
628    if (browserdetected) return browserdetected;
629
630    var domtest = document.createElement('DIV');
631
632    var d = {};
633
634		d.haspointerlock = "pointerLockElement" in document || "mozPointerLockElement" in document || "webkitPointerLockElement" in document;
635
636    d.isopera = ("opera" in window);
637    d.isopera12 = (d.isopera&&("getUserMedia" in navigator));
638    d.isoperamini = (Object.prototype.toString.call(window.operamini) === "[object OperaMini]");
639
640    d.isie = (("all" in document) && ("attachEvent" in domtest) && !d.isopera);
641    d.isieold = (d.isie && !("msInterpolationMode" in domtest.style));  // IE6 and older
642    d.isie7 = d.isie&&!d.isieold&&(!("documentMode" in document)||(
642document.documentMode==7));
643    d.isie8 = d.isie&&("documentMode" in document)&&(document.documentMode==8);
644    d.isie9 = d.isie&&("performance" in window)&&(document.documentMode>=9);
645    d.isie10 = d.isie&&("performance" in window)&&(document.documentMode>=10);
646
647    d.isie9mobile = /iemobile.9/i.test(navigator.userAgent);  //wp 7.1 mango
648    if (d.isie9mobile) d.isie9 = false;
649    d.isie7mobile = (!d.isie9mobile&&d.isie7) && /iemobile/i.test(navigator.userAgent);  //wp 7.0
650
651    d.ismozilla = ("MozAppearance" in domtest.style);
652
653    d.iswebkit = ("WebkitAppearance" in domtest.style);
654
655    d.ischrome = ("chrome" in window);
656		d.ischrome22 = (d.ischrome&&d.haspointerlock);
657    d.ischrome26 = (d.ischrome&&("transition" in domtest.style));  // issue with transform detection (maintain prefix)
658
659    d.cantouch = ("ontouchstart" in document.documentElement)||("ontouchstart" in window);  // detection for Chrome Touch Emulation
660    d.hasmstouch = (window.navigator.msPointerEnabled||false);  // IE10+ pointer events
661
662    d.ismac = /^mac$/i.test(navigator.platform);
663
664    d.isios = (d.cantouch && /iphone|ipad|ipod/i.test(navigator.platform));
665    d.isios4 = ((d.isios)&&!("seal" in Object));
666
667    d.isandroid = (/android/i.test(navigator.userAgent));
668
669    d.trstyle = false;
670    d.hastransform = false;
671    d.hastranslate3d = false;
672    d.transitionstyle = false;
673    d.hastransition = false;
674    d.transitionend = false;
675
676    var check = ['transform','msTransform','webkitTransform','MozTransform','OTransform'];
677    for(var a=0;a<check.length;a++){
678      if (typeof domtest.style[check[a]] != "undefined") {
679        d.trstyle = check[a];
680        break;
681      }
682    }
683    d.hastransform = (d.trstyle != false);
684    if (d.hastransform) {
685      domtest.style[d.trstyle] = "translate3d(1px,2px,3px)";
686      d.hastranslate3d = /translate3d/.test(domtest.style[d.trstyle]);
687    }
688
689    d.transitionstyle = false;
690    d.prefixstyle = '';
691    d.transitionend = false;
692    var check = ['transition','webkitTransition','MozTransition','OTransition','OTransition','msTransition','KhtmlTransition'];
693    var prefix = ['','-webkit-','-moz-','-o-','-o','-ms-','-khtml-'];
694    var evs = ['transitionend','webkitTransitionEnd','transitionend','otransitionend','oTransitionEnd','msTransitionEnd','KhtmlTransitionEnd'];
695    for(var a=0;a<check.length;a++) {
696      if (check[a] in domtest.style) {
697        d.transitionstyle = check[a];
698        d.prefixstyle = prefix[a];
699        d.transitionend = evs[a];
700        break;
701      }
702    }
703    if (d.ischrome26) {  // use always prefix
704      d.prefixstyle = prefix[1];
705    }
706
707    d.hastransition = (d.transitionstyle);
708
709    function detectCursorGrab() {
710      var lst = ['-moz-grab','-webkit-grab','grab'];
711      if ((d.ischrome&&!d.ischrome22)||d.isie) lst=[];  // force setting for IE returns false positive and chrome cursor bug
712      for(var a=0;a<lst.length;a++) {
713        var p = lst[a];
714        domtest.style['cursor']=p;
715        if (domtest.style['cursor']==p) return p;
716      }
717      return 'url(http://www.google.com/intl/en_ALL/mapfiles/openhand.cur),n-resize';  // thank you google for custom cursor!
718    }
719    d.cursorgrabvalue = detectCursorGrab();
720
721    d.hasmousecapture = ("setCapture" in domtest);
722
723    d.hasMutationObserver = (clsMutationObserver !== false);
724
725    domtest = null;  //memory released
726
727    browserdetected = d;
728
729    return d;
730  }
731
732  var NiceScrollClass = function(myopt,me) {
733
734    var self = this;
735
736    this.version = '3.5.0 BETA5';
737    this.name = 'nicescroll';
738
739    this.me = me;
740
741    this.opt = {
742      doc:$("body"),
743      win:false
744    };
745
746    $.extend(this.opt,_globaloptions);
747
748// Options for internal use
749    this.opt.snapbackspeed = 80;
750
751    if (myopt||false) {
752      for(var a in self.opt) {
753        if (typeof myopt[a] != "undefined") self.opt[a] = myopt[a];
754      }
755    }
756
757    this.doc = self.opt.doc;
758    this.iddoc = (this.doc&&this.doc[0])?this.doc[0].id||'':'';
759    this.ispage = /BODY|HTML/.test((self.opt.win)?self.opt.win[0].nodeName:this.doc[0].nodeName);
760    this.haswrapper = (self.opt.win!==false);
761    this.win = self.opt.win||(this.ispage?$(window):this.doc);
762    this.docscroll = (this.ispage&&!this.haswrapper)?$(window):this.win;
763    this.body = $("body");
764    this.viewport = false;
765
766    this.isfixed = false;
767
768    this.iframe = false;
769    this.isiframe = ((this.doc[0].nodeName == 'IFRAME') && (this.win[0].nodeName == 'IFRAME'));
770
771    this.istextarea = (this.win[0].nodeName == 'TEXTAREA');
772
773    this.forcescreen = false; //force to use screen position on events
774
775    this.canshowonmouseevent = (self.opt.autohidemode!="scroll");
776
777// Events jump table
778    this.onmousedown = false;
779    this.onmouseup = false;
780    this.onmousemove = false;
781    this.onmousewheel = false;
782    this.onkeypress = false;
783    this.ongesturezoom = false;
784    this.onclick = false;
785
786// Nicescroll custom events
787    this.onscrollstart = false;
788    this.onscrollend = false;
789    this.onscrollcancel = false;
790
791    this.onzoomin = false;
792    this.onzoomout = false;
793
794// Let's start!
795    this.view = false;
796    this.page = false;
797
798    this.scroll = {x:0,y:0};
799    this.scrollratio = {x:0,y:0};
800    this.cursorheight = 20;
801    this.scrollvaluemax = 0;
802
803    this.checkrtlmode = false;
804
805    this.scrollrunning = false;
806
807    this.scrollmom = false;
808
809    this.observer = false;
810    this.observerremover = false;  // observer on parent for remove detection
811
812    do {
813      this.id = "ascrail"+(ascrailcounter++);
814    } while (document.getElementById(this.id));
815
816    this.rail = false;
817    this.cursor = false;
818    this.cursorfreezed = false;
819    this.selectiondrag = false;
820
821    this.zoom = false;
822    this.zoomactive = false;
823
824    this.hasfocus = false;
825    this.hasmousefocus = false;
826
827    this.visibility = true;
828    this.locked = false;
829    this.hidden = false; // rails always hidden
830    this.cursoractive = true; // user can interact with cursors
831
832    this.overflowx = self.opt.overflowx;
833    this.overflowy = self.opt.overflowy;
834
835    this.nativescrollingarea = false;
836    this.checkarea = 0;
837
838    this.events = [];  // event list for unbind
839
840    this.saved = {};
841
842    this.delaylist = {};
843    this.synclist = {};
844
845    this.lastdeltax = 0;
846    this.lastdeltay = 0;
847
848    this.detected = getBrowserDetection();
849
850    var cap = $.extend({},this.detected);
851
852    this.canhwscroll = (cap.hastransform&&self.opt.hwacceleration);
853    this.ishwscroll = (this.canhwscroll&&self.haswrapper);
854
855    this.istouchcapable = false;  // desktop devices with touch screen support
856
857//## Check Chrome desktop with touch support
858    if (cap.cantouch&&cap.ischrome&&!cap.isios&&!cap.isandroid) {
859      this.istouchcapable = true;
860      cap.cantouch = false;  // parse normal desktop events
861    }
862
863//## Firefox 18 nightly build (desktop) false positive (or desktop with touch support)
864    if (cap.cantouch&&cap.ismozilla&&!cap.isios&&!cap.isandroid) {
865      this.istouchcapable = true;
866      cap.cantouch = false;  // parse normal desktop events
867    }
868
869//## disable MouseLock API on user request
870
871    if (!self.opt.enablemouselockapi) {
872      cap.hasmousecapture = false;
873      cap.haspointerlock = false;
874    }
875
876    this.delayed = function(name,fn,tm,lazy) {
877      var dd = self.delaylist[name];
878      var nw = (new Date()).getTime();
879      if (!lazy&&dd&&dd.tt) return false;
880      if (dd&&dd.tt) clearTimeout(dd.tt);
881      if (dd&&dd.last+tm>nw&&!dd.tt) {
882        self.delaylist[name] = {
883          last:nw+tm,
884          tt:setTimeout(function(){self.delaylist[name].tt=0;fn.call();},tm)
885        }
886      }
887      else if (!dd||!dd.tt) {
888        self.delaylist[name] = {
889          last:nw,
890          tt:0
891        }
892        setTimeout(function(){fn.call();},0);
893      }
894    };
895
896    this.debounced = function(name,fn,tm) {
897      var dd = self.delaylist[name];
898      var nw = (new Date()).getTime();
899      self.delaylist[name] = fn;
900      if (!dd) {
901        setTimeout(function(){var fn=self.delaylist[name];self.delaylist[name]=false;fn.call();},tm);
902      }
903    }
904
905    this.synched = function(name,fn) {
906
907      function requestSync() {
908        if (self.onsync) return;
909        setAnimationFrame(function(){
910          self.onsync = false;
911          for(name in self.synclist){
912            var fn = self.synclist[name];
913            if (fn) fn.call(self);
914            self.synclist[name] = false;
915          }
916        });
917        self.onsync = true;
918      };
919
920      self.synclist[name] = fn;
921      requestSync();
922      return name;
923    };
924
925    this.unsynched = function(name) {
926      if (self.synclist[name]) self.synclist[name] = false;
927    }
928
929    this.css = function(el,pars) {  // save & set
930      for(var n in pars) {
931        self.saved.css.push([el,n,el.css(n)]);
932        el.css(n,pars[n]);
933      }
934    };
935
936    this.scrollTop = function(val) {
937      return (typeof val == "undefined") ? self.getScrollTop() : self.setScrollTop(val);
938    };
939
940    this.scrollLeft = function(val) {
941      return (typeof val == "undefined") ? self.getScrollLeft() : self.setScrollLeft(val);
942    };
943
944// derived by by Dan Pupius www.pupius.net
945    BezierClass = function(st,ed,spd,p1,p2,p3,p4) {
946      this.st = st;
947      this.ed = ed;
948      this.spd = spd;
949
950      this.p1 = p1||0;
951      this.p2 = p2||1;
952      this.p3 = p3||0;
953      this.p4 = p4||1;
954
955      this.ts = (new Date()).getTime();
956      this.df = this.ed-this.st;
957    };
958    BezierClass.prototype = {
959      B2:function(t){ return 3*t*t*(1-t) },
960      B3:function(t){ return 3*t*(1-t)*(1-t) },
961      B4:function(t){ return (1-t)*(1-t)*(1-t) },
962      getNow:function(){
963        var nw = (new Date()).getTime();
964        var pc = 1-((nw-this.ts)/this.spd);
965        var bz = this.B2(pc) + this.B3(pc) + this.B4(pc);
966        return (pc<0) ? this.ed : this.st+Math.round(this.df*bz);
967      },
968      update:function(ed,spd){
969        this.st = this.getNow();
970        this.ed = ed;
971        this.spd = spd;
972        this.ts = (new Date()).getTime();
973        this.df = this.ed-this.st;
974        return this;
975      }
976    };
977
978    if (this.ishwscroll) {
979    // hw accelerated scroll
980      this.doc.translate = {x:0,y:0,tx:"0px",ty:"0px"};
981
982      //this one can help to enable hw accel on ios6 http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/
983      if (cap.hastranslate3d&&cap.isios) this.doc.css("-webkit-backface-visibility","hidden");  // prevent flickering http://stackoverflow.com/questions/3461441/
984
985      //derived from http://stackoverflow.com/questions/11236090/
986      function getMatrixValues() {
987        var tr = self.doc.css(cap.trstyle);
988        if (tr&&(tr.substr(0,6)=="matrix")) {
989          return tr.replace(/^.*\((.*)\)$/g, "$1").replace(/px/g,'').split(/, +/);
990        }
991        return false;
992      }
993
994      this.getScrollTop = function(last) {
995        if (!last) {
996          var mtx = getMatrixValues();
997          if (mtx) return (mtx.length==16) ? -mtx[13] : -mtx[5];  //matrix3d 16 on IE10
998          if (self.timerscroll&&self.timerscroll.bz) return self.timerscroll.bz.getNow();
999        }
1000        return self.doc.translate.y;
1001      };
1002
1003      this.getScrollLeft = function(last) {
1004        if (!last) {
1005          var mtx = getMatrixValues();
1006          if (mtx) return (mtx.length==16) ? -mtx[12] : -mtx[4];  //matrix3d 16 on IE10
1007          if (self.timerscroll&&self.timerscroll.bh) return self.timerscroll.bh.getNow();
1008        }
1009        return self.doc.translate.x;
1010      };
1011
1012      if (document.createEvent) {
1013        this.notifyScrollEvent = function(el) {
1014          var e = document.createEvent("UIEvents");
1015          e.initUIEvent("scroll", false, true, window, 1);
1016          el.dispatchEvent(e);
1017        };
1018      }
1019      else if (document.fireEvent) {
1020        this.notifyScrollEvent = function(el) {
1021          var e = document.createEventObject();
1022          el.fireEvent("onscroll");
1023          e.cancelBubble = true;
1024        };
1025      }
1026      else {
1027        this.notifyScrollEvent = function(el,add) {}; //NOPE
1028      }
1029
1030      if (cap.hastranslate3d&&self.opt.enabletranslate3d) {
1031        this.setScrollTop = function(val,silent) {
1032          self.doc.translate.y = val;
1033          self.doc.translate.ty = (val*-1)+"px";
1034          self.doc.css(cap.trstyle,"translate3d("+self.doc.translate.tx+","+self.doc.translate.ty+",0px)");
1035          if (!silent) self.notifyScrollEvent(self.win[0]);
1036        };
1037        this.setScrollLeft = function(val,silent) {
1038          self.doc.translate.x = val;
1039          self.doc.translate.tx = (val*-1)+"px";
1040          self.doc.css(cap.trstyle,"translate3d("+self.doc.translate.tx+","+self.doc.translate.ty+",0px)");
1041          if (!silent) self.notifyScrollEvent(self.win[0]);
1042        };
1043      } else {
1044        this.setScrollTop = function(val,silent) {
1045          self.doc.translate.y = val;
1046          self.doc.translate.ty = (val*-1)+"px";
1047          self.doc.css(cap.trstyle,"translate("+self.doc.translate.tx+","+self.doc.translate.ty+")");
1048          if (!silent) self.notifyScrollEvent(self.win[0]);
1049        };
1050        this.setScrollLeft = function(val,silent) {
1051          self.doc.translate.x = val;
1052          self.doc.translate.tx = (val*-1)+"px";
1053          self.doc.css(cap.trstyle,"translate("+self.doc.translate.tx+","+self.doc.translate.ty+")");
1054          if (!silent) self.notifyScrollEvent(self.win[0]);
1055        };
1056      }
1057    } else {
1058    // native scroll
1059      this.getScrollTop = function() {
1060        return self.docscroll.scrollTop();
1061      };
1062      this.setScrollTop = function(val) {
1063        return self.docscroll.scrollTop(val);
1064      };
1065      this.getScrollLeft = function() {
1066        return self.docscroll.scrollLeft();
1067      };
1068      this.setScrollLeft = function(val) {
1069        return self.docscroll.scrollLeft(val);
1070      };
1071    }
1072
1073    this.getTarget = function(e) {
1074      if (!e) return false;
1075      if (e.target) return e.target;
1076      if (e.srcElement) return e.srcElement;
1077      return false;
1078    };
1079
1080    this.hasParent = function(e,id) {
1081      if (!e) return false;
1082      var el = e.target||e.srcElement||e||false;
1083      while (el && el.id != id) {
1084        el = el.parentNode||false;
1085      }
1086      return (el!==false);
1087    };
1088
1089    function getZIndex() {
1090      var dom = self.win;
1091      if ("zIndex" in dom) return dom.zIndex();  // use jQuery UI method when available
1092      while (dom.length>0) {
1093        if (dom[0].nodeType==9) return false;
1094        var zi = dom.css('zIndex');
1095        if (!isNaN(zi)&&zi!=0) return parseInt(zi);
1096        dom = dom.parent();
1097      }
1098      return false;
1099    };
1100
1101//inspired by http://forum.jquery.com/topic/width-includes-border-width-when-set-to-thin-medium-thick-in-ie
1102    var _convertBorderWidth = {"thin":1,"medium":3,"thick":5};
1103    function getWidthToPixel(dom,prop,chkheight) {
1104      var wd = dom.css(prop);
1105      var px = parseFloat(wd);
1106      if (isNaN(px)) {
1107        px = _convertBorderWidth[wd]||0;
1108        var brd = (px==3) ? ((chkheight)?(self.win.outerHeight() - self.win.innerHeight()):(self.win.outerWidth() - self.win.innerWidth())) : 1; //DON'T TRUST CSS
1109        if (self.isie8&&px) px+=1;
1110        return (brd) ? px : 0;
1111      }
1112      return px;
1113    };
1114
1115    this.getOffset = function() {
1116      if (self.isfixed) return {top:parseFloat(self.win.css('top')),left:parseFloat(self.win.css('left'))};
1117      if (!self.viewport) return self.win.offset();
1118      var ww = self.win.offset();
1119      var vp = self.viewport.offset();
1120      return {top:ww.top-vp.top+self.viewport.scrollTop(),left:ww.left-vp.left+self.viewport.scrollLeft()};
1121    };
1122
1123    this.updateScrollBar = function(len) {
1124      if (self.ishwscroll) {
1125        self.rail.css({height:self.win.innerHeight()});
1126        if (self.railh) self.railh.css({width:self.win.innerWidth()});
1127      } else {
1128        var wpos = self.getOffset();
1129        var pos = {top:wpos.top,left:wpos.left};
1130        pos.top+= getWidthToPixel(self.win,'border-top-width',true);
1131        var brd = (self.win.outerWidth() - self.win.innerWidth())/2;
1132        pos.left+= (self.rail.align) ? self.win.outerWidth() - getWidthToPixel(self.win,'border-right-width') - self.rail.width : getWidthToPixel(self.win,'border-left-width');
1133
1134        var off = self.opt.railoffset;
1135        if (off) {
1136          if (off.top) pos.top+=off.top;
1137          if (self.rail.align&&off.left) pos.left+=off.left;
1138        }
1139
1140				if (!self.locked) self.rail.css({top:pos.top,left:pos.left,height:(len)?len.h:self.win.innerHeight()});
1141
1142				if (self.zoom) {
1143				  self.zoom.css({top:pos.top+1,left:(self.rail.align==1) ? pos.left-20 : pos.left+self.rail.width+4});
1144			  }
1145
1146				if (self.railh&&!self.locked) {
1147					var pos = {top:wpos.top,left:wpos.left};
1148					var y = (self.railh.align) ? pos.top + getWidthToPixel(self.win,'border-top-width',true) + self.win.innerHeight() - self.railh.height : pos.top + getWidthToPixel(self.win,'border-top-width',true);
1149					var x = pos.left + getWidthToPixel(self.win,'border-left-width');
1150					self.railh.css({top:y,left:x,width:self.railh.width});
1151				}
1152
1153
1154      }
1155    };
1156
1157    this.doRailClick = function(e,dbl,hr) {
1158
1159      var fn,pg,cur,pos;
1160
1161//      if (self.rail.drag&&self.rail.drag.pt!=1) return;
1162      if (self.locked) return;
1163//      if (self.rail.drag) return;
1164
1165//      self.cancelScroll();
1166
1167      self.cancelEvent(e);
1168
1169      if (dbl) {
1170        fn = (hr) ? self.doScrollLeft : self.doScrollTop;
1171        cur = (hr) ? ((e.pageX - self.railh.offset().left - (self.cursorwidth/2)) * 
1171self.scrollratio.x) : ((e.pageY - self.rail.offset().top - (self.cursorheight/2)) * self.scrollratio.y);
1172        fn(cur);
1173      } else {
1174//        console.log(e.pageY);
1175        fn = (hr) ? self.doScrollLeftBy : self.doScrollBy;
1176        cur = (hr) ? self.scroll.x : self.scroll.y;
1177        pos = (hr) ? e.pageX - self.railh.offset().left : e.pageY - self.rail.offset().top;
1178        pg = (hr) ? self.view.w : self.view.h;
1179        (cur>=pos) ? fn(pg) : fn(-pg);
1180      }
1181
1182    }
1183
1184    self.hasanimationframe = (setAnimationFrame);
1185    self.hascancelanimationframe = (clearAnimationFrame);
1186
1187    if (!self.hasanimationframe) {
1188      setAnimationFrame=function(fn){return setTimeout(fn,15-Math.floor((+new Date)/1000)%16)}; // 1000/60)};
1189      clearAnimationFrame=clearInterval;
1190    }
1191    else if (!self.hascancelanimationframe) clearAnimationFrame=function(){self.cancelAnimationFrame=true};
1192
1193    this.init = function() {
1194
1195      self.saved.css = [];
1196
1197      if (cap.isie7mobile) return true; // SORRY, DO NOT WORK!
1198      if (cap.isoperamini) return true; // SORRY, DO NOT WORK!
1199
1200      if (cap.hasmstouch) self.css((self.ispage)?$("html"):self.win,{'-ms-touch-action':'none'});
1201
1202      self.zindex = "auto";
1203      if (!self.ispage&&self.opt.zindex=="auto") {
1204        self.zindex = getZIndex()||"auto";
1205      } else {
1206        self.zindex = self.opt.zindex;
1207      }
1208
1209      if (!self.ispage&&self.zindex!="auto") {
1210        if (self.zindex>globalmaxzindex) globalmaxzindex=self.zindex;
1211      }
1212
1213      if (self.isie&&self.zindex==0&&self.opt.zindex=="auto") {  // fix IE auto == 0
1214        self.zindex="auto";
1215      }
1216
1217/*
1218      self.ispage = true;
1219      self.haswrapper = true;
1220//      self.win = $(window);
1221      self.docscroll = $("body");
1222//      self.doc = $("body");
1223*/
1224
1225      if (!self.ispage || (!cap.cantouch && !cap.isieold && !cap.isie9mobile)) {
1226
1227        var cont = self.docscroll;
1228        if (self.ispage) cont = (self.haswrapper)?self.win:self.doc;
1229
1230        if (!cap.isie9mobile) self.css(cont,{'overflow-y':'hidden'});
1231
1232        if (self.ispage&&cap.isie7) {
1233          if (self.doc[0].nodeName=='BODY') self.css($("html"),{'overflow-y':'hidden'});  //IE7 double scrollbar issue
1234          else if (self.doc[0].nodeName=='HTML') self.css($("body"),{'overflow-y':'hidden'});  //IE7 double scrollbar issue
1235        }
1236
1237        if (cap.isios&&!self.ispage&&!self.haswrapper) self.css($("body"),{"-webkit-overflow-scrolling":"touch"});  //force hw acceleration
1238
1239        var cursor = $(document.createElement('div'));
1240        cursor.css({
1241          position:"relative",top:0,"float":"right",width:self.opt.cursorwidth,height:"0px",
1242          'background-color':self.opt.cursorcolor,
1243          border:self.opt.cursorborder,
1244          'background-clip':'padding-box',
1245          '-webkit-border-radius':self.opt.cursorborderradius,
1246          '-moz-border-radius':self.opt.cursorborderradius,
1247          'border-radius':self.opt.cursorborderradius
1248        });
1249
1250        cursor.hborder = parseFloat(cursor.outerHeight() - cursor.innerHe
1250ight());
1251        self.cursor = cursor;
1252
1253        var rail = $(document.createElement('div'));
1254        rail.attr('id',self.id);
1255        rail.addClass('nicescroll-rails');
1256
1257        var v,a,kp = ["left","right"];  //"top","bottom"
1258        for(var n in kp) {
1259          a=kp[n];
1260          v = self.opt.railpadding[a];
1261          (v) ? rail.css("padding-"+a,v+"px") : self.opt.railpadding[a] = 0;
1262        }
1263
1264        rail.append(cursor);
1265
1266        rail.width = Math.max(parseFloat(self.opt.cursorwidth),cursor.outerWidth()) + self.opt.railpadding['left'] + self.opt.railpadding['right'];
1267        rail.css({width:rail.width+"px",'zIndex':self.zindex,"background":self.opt.background,cursor:"default"});
1268
1269        rail.visibility = true;
1270        rail.scrollable = true;
1271
1272        rail.align = (self.opt.railalign=="left") ? 0 : 1;
1273
1274        self.rail = rail;
1275
1276        self.rail.drag = false;
1277
1278        var zoom = false;
1279        if (self.opt.boxzoom&&!self.ispage&&!cap.isieold) {
1280          zoom = document.createElement('div');
1281          self.bind(zoom,"click",self.doZoom);
1282          self.zoom = $(zoom);
1283          self.zoom.css({"cursor":"pointer",'z-index':self.zindex,'backgroundImage':'url('+scriptpath+'zoomico.png)','height':18,'width':18,'backgroundPosition':'0px 0px'});
1284          if (self.opt.dblclickzoom) self.bind(self.win,"dblclick",self.doZoom);
1285          if (cap.cantouch&&self.opt.gesturezoom) {
1286            self.ongesturezoom = function(e) {
1287              if (e.scale>1.5) self.doZoomIn(e);
1288              if (e.scale<0.8) self.doZoomOut(e);
1289              return self.cancelEvent(e);
1290            };
1291            self.bind(self.win,"gestureend",self.ongesturezoom);
1292          }
1293        }
1294
1295// init HORIZ
1296
1297        self.railh = false;
1298
1299        if (self.opt.horizrailenabled) {
1300
1301          self.css(cont,{'overflow-x':'hidden'});
1302
1303          var cursor = $(document.createElement('div'));
1304          cursor.css({
1305            position:"relative",top:0,height:self.opt.cursorwidth,width:"0px",
1306            'background-color':self.opt.cursorcolor,
1307            border:self.opt.cursorborder,
1308            'background-clip':'padding-box',
1309            '-webkit-border-radius':self.opt.cursorborderradius,
1310            '-moz-border-radius':self.opt.cursorborderradius,
1311            'border-radius':self.opt.cursorborderradius
1312          });
1313
1314          cursor.wborder = parseFloat(cursor.outerWidth() - cursor.innerWidth());
1315          self.cursorh = cursor;
1316
1317          var railh = $(document.createElement('div'));
1318          railh.attr('id',self.id+'-hr');
1319          railh.addClass('nicescroll-rails');
1320          railh.height = Math.max(parseFloat(self.opt.cursorwidth),cursor.outerHeight());
1321          railh.css({height:railh.height+"px",'zIndex':self.zindex,"background":self.opt.background});
1322
1323          railh.append(cursor);
1324
1325          railh.visibility = true;
1326          railh.scrollable = true;
1327
1328          railh.align = (self.opt.railvalign=="top") ? 0 : 1;
1329
1330          self.railh = railh;
1331
1332          self.railh.drag = false;
1333
1334        }
1335
1336//
1337
1338        if (self.ispage) {
1339          rail.css({position:"fixed",top:"0px",height:"100%"});
1340          (rail.align) ? rail.css({right:"0px"}) : rail.css({left:"0px"});
1341          self.body.append(rail);
1342          if (self.railh) {
1343            railh.css({position:"fixed",left:"0px",width:"100%"});
1344            (railh.align) ? railh.css({bottom:"0px"}) : railh.css({top:"0px"});
1345            self.body.append(railh);
1346          }
1347        } else {
1348          if (self.ishwscroll) {
1349            if (self.win.css('position')=='static') self.css(self.win,{'position':'relative'});
1350            var bd = (self.win[0].nodeName == 'HTML') ? self.body : self.win;
1351            if (self.zoom) {
1352              self.zoom.css({position:"absolute",top:1,right:0,"margin-right":rail.width+4});
1353              bd.append(self.zoom);
1354            }
1355            rail.css({position:"absolute",top:0});
1356            (rail.align) ? rail.css({right:0}) : rail.css({left:0});
1357            bd.append(rail);
1358            if (railh) {
1359              railh.css({position:"absolute",left:0,bottom:0});
1360              (railh.align) ? railh.css({bottom:0}) : railh.css({top:0});
1361              bd.append(railh);
1362            }
1363          } else {
1364            self.isfixed = (self.win.css("position")=="fixed");
1365            var rlpos = (self.isfixed) ? "fixed" : "absolute";
1366
1367            if (!self.isfixed) self.viewport = self.getViewport(self.win[0]);
1368            if (self.viewport) {
1369              self.body = self.viewport;
1370              if ((/relative|absolute/.test(self.viewport.css("position")))==false) self.css(self.viewport,{"position":"relative"});
1371            }
1372
1373            rail.css({position:rlpos});
1374            if (self.zoom) self.zoom.css({position:rlpos});
1375            self.updateScrollBar();
1376            self.body.append(rail);
1377            if (self.zoom) self.body.append(self.zoom);
1378            if (self.railh) {
1379              railh.css({position:rlpos});
1380              self.body.append(railh);
1381            }
1382          }
1383
1384          if (cap.isios) self.css(self.win,{'-webkit-tap-highlight-color':'rgba(0,0,0,0)','-webkit-touch-callout':'none'});  // prevent grey layer on click
1385
1386					if (cap.isie&&self.opt.disableoutline) self.win.attr("hideFocus","true");  // IE, prevent dotted rectangle on focused div
1387					if (cap.iswebkit&&self.opt.disableoutline) self.win.css({"outline":"none"});
1388//          if (cap.isopera&&self.opt.disableoutline) self.win.css({"outline":"0"});  // Opera to test [TODO]
1389
1390        }
1391
1392        if (self.opt.autohidemode===false) {
1393          self.autohidedom = false;
1394          self.rail.css({opacity:self.opt.cursoropacitymax});
1395          if (self.railh) self.railh.css({opacity:self.opt.cursoropacitymax});
1396        }
1397        else if (self.opt.autohidemode===true) {
1398          self.autohidedom = $().add(self.rail);
1399          if (cap.isie8) self.autohidedom=self.autohidedom.add(self.cursor);
1400          if (self.railh) self.autohidedom=self.autohidedom.add(self.railh);
1401          if (self.railh&&cap.isie8) self.autohidedom=self.autohidedom.add(self.cursorh);
1402        }
1403        else if (self.opt.autohidemode=="scroll") {
1404          self.autohidedom = $().add(self.rail);
1405          if (self.railh) self.autohidedom=self.autohidedom.add(self.railh);
1406        }
1407        else if (self.opt.autohidemode=="cursor") {
1408          self.autohidedom = $().add(self.cursor);
1409          if (self.railh) self.autohidedom=self.autohidedom.add(self.cursorh);
1410        }
1411        else if (self.opt.autohidemode=="hidden") {
1412          self.autohidedom = false;
1413          self.hide();
1414          self.locked = false;
1415        }
1416
1417        if (cap.isie9mobile) {
1418
1419          self.scrollmom = new ScrollMomentumClass2D(self);
1420
1421          /*
1422          var trace = function(msg) {
1423            var db = $("#debug");
1424            if (isNaN(msg)&&(typeof msg != "string")) {
1425              var x = [];
1426              for(var a in msg) {
1427                x.push(a+":"+msg[a]);
1428              }
1429              msg ="{"+x.join(",")+"}";
1430            }
1431            if (db.children().length>0) {
1432              db.children().eq(0).before("<div>"+msg+"</div>");
1433            } else {
1434              db.append("<div>"+msg+"</div>");
1435            }
1436          }
1437          window.onerror = function(msg,url,ln) {
1438            trace("ERR: "+msg+" at "+ln);
1439          }
1440*/
1441
1442          self.onmangotouch = function(e) {
1443            var py = self.getScrollTop();
1444            var px = self.getScrollLeft();
1445
1446            if ((py == self.scrollmom.lastscrolly)&&(px == self.scrollmom.lastscrollx)) return true;
1447//            $("#debug").html('DRAG:'+py);
1448
1449            var dfy = py-self.mangotouch.sy;
1450            var dfx = px-self.mangotouch.sx;
1451            var df = Math.round(Math.sqrt(Math.pow(dfx,2)+Math.pow(dfy,2)));
1452            if (df==0) return;
1453
1454            var dry = (dfy<0)?-1:1;
1455            var drx = (dfx<0)?-1:1;
1456
1457            var tm = +new Date();
1458            if (self.mangotouch.lazy) clearTimeout(self.mangotouch.lazy);
1459
1460            if (((tm-self.mangotouch.tm)>80)||(self.mangotouch.dry!=dry)||(self.mangotouch.drx!=drx)) {
1461//              trace('RESET+'+(tm-self.mangotouch.tm));
1462              self.scrollmom.stop();
1463              self.scrollmom.reset(px,py);
1464              self.mangotouch.sy = py;
1465              self.mangotouch.ly = py;
1466              self.mangotouch.sx = px;
1467              self.mangotouch.lx = px;
1468              self.mangotouch.dry = dry;
1469              self.mangotouch.drx = drx;
1470              self.mangotouch.tm = tm;
1471            } else {
1472
1473              self.scrollmom.stop();
1474              self.scrollmom.update(self.mangotouch.sx-dfx,self.mangotouch.sy-dfy);
1475              var gap = tm - self.mangotouch.tm;
1476              self.mangotouch.tm = tm;
1477
1478//              trace('MOVE:'+df+" - "+gap);
1479
1480              var ds = Math.max(Math.abs(self.mangotouch.ly-py),Math.abs(self.mangotouch.lx-px));
1481              self.mangotouch.ly = py;
1482              self.mangotouch.lx = px;
1483
1484              if (ds>2) {
1485                self.mangotouch.lazy = setTimeout(function(){
1486//                  trace('END:'+ds+'+'+gap);
1487                  self.mangotouch.lazy = false;
1488                  self.mangotouch.dry = 0;
1489                  self.mangotouch.drx = 0;
1490                  self.mangotouch.tm = 0;
1491                  self.scrollmom.doMomentum(30);
1492                },100);
1493              }
1494            }
1495          }
1496
1497          var top = self.getScrollTop();
1498          var lef = self.getScrollLeft();
1499          self.mangotouch = {sy:top,ly:top,dry:0,sx:lef,lx:lef,drx:0,lazy:false,tm:0};
1500
1501          self.bind(self.docscroll,"scroll",self.onmangotouch);
1502
1503        } else {
1504
1505          if (cap.cantouch||self.istouchcapable||self.opt.touchbehavior||cap.hasmstouch) {
1506
1507            self.scrollmom = new ScrollMomentumClass2D(self);
1508
1509            self.ontouchstart = function(e) {
1510              if (e.pointerType&&e.pointerType!=2) return false;
1511
1512              if (!self.locked) {
1513
1514                if (cap.hasmstouch) {
1515                  var tg = (e.target) ? e.target : false;
1516                  while (tg) {
1517                    var nc = $(tg).getNiceScroll();
1518                    if ((nc.length>0)&&(nc[0].me == self.me)) break;
1519                    if (nc.length>0) return false;
1520                    if ((tg.nodeName=='DIV')&&(tg.id==self.id)) break;
1521                    tg = (tg.parentNode) ? tg.parentNode : false;
1522                  }
1523                }
1524
1525                self.cancelScroll();
1526
1527                var tg = self.getTarget(e);
1528
1529                if (tg) {
1530                  var skp = (/INPUT/i.test(tg.nodeName))&&(/range/i.test(tg.type));
1531                  if (skp) return self.stopPropagation(e);
1532                }
1533
1534                if (!("clientX" in e) && ("changedTouches" in e)) {
1535                  e.clientX = e.changedTouches[0].clientX;
1536                  e.clientY = e.changedTouches[0].clientY;
1537                }
1538
1539                if (self.forcescreen) {
1540                  var le = e;
1541                  var e = {"original":(e.original)?e.original:e};
1542                  e.clientX = le.screenX;
1543                  e.clientY = le.screenY;
1544                }
1545
1546                self.rail.drag = {x:e.clientX,y:e.clientY,sx:self.scroll.x,sy:self.scroll.y,st:self.getScrollTop(),sl:self.getScrollLeft(),pt:2,dl:false};
1547
1548                if (self.ispage||!self.opt.directionlockdeadzone) {
1549                  self.rail.drag.dl = "f";
1550                } else {
1551
1552                  var view = {
1553                    w:$(window).width(),
1554                    h:$(window).height()
1555                  };
1556
1557                  var page = {
1558                    w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),
1559                    h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)
1560                  }
1561
1562                  var maxh = Math.max(0,page.h - view.h);
1563                  var maxw = Math.max(0,page.w - view.w);
1564
1565                  if (!self.rail.scrollable&&self.railh.scrollable) self.rail.drag.ck = (maxh>0) ? "v" : false;
1566                  else if (self.rail.scrollable&&!self.railh.scrollable) self.rail.drag.ck = (maxw>0) ? "h" : false;
1567                  else self.rail.drag.ck = false;
1568                  if (!self.rail.drag.ck) self.rail.drag.dl = "f";
1569                }
1570
1571                if (self.opt.touchbehavior&&self.isiframe&&cap.isie) {
1572                  var wp = self.win.position();
1573                  self.rail.drag.x+=wp.left;
1574                  self.rail.drag.y+=wp.top;
1575                }
1576
1577                self.hasmoving = false;
1578                self.lastmouseup = false;
1579                self.scrollmom.reset(e.clientX,e.clientY);
1580                if (!cap.cantouch&&!this.istouchcapable&&!cap.hasmstouch) {
1581
1582                  var ip = (tg)?/INPUT|SELECT|TEXTAREA/i.test(tg.nodeName):false;
1583                  if (!ip) {
1584                    if (!self.ispage&&cap.hasmousecapture) tg.setCapture();
1585//                  return self.cancelEvent(e);
1586                    return (self.opt.touchbehavior) ? self.cancelEvent(e) : self.stopPropagation(e);
1587                  }
1588                  if (/SUBMIT|CANCEL|BUTTON/i.test($(tg).attr('type'))) {
1589                    pc = {"tg":tg,"click":false};
1590                    self.preventclick = pc;
1591                  }
1592
1593                }
1594              }
1595
1596            };
1597
1598            self.ontouchend = function(e) {
1599              if (e.pointerType&&e.pointerType!=2) return false;
1600              if (self.rail.drag&&(self.rail.drag.pt==2)) {
1601                self.scrollmom.doMomentum();
1602                self.rail.drag = false;
1603                if (self.hasmoving) {
1604                  self.hasmoving = false;
1605                  self.lastmouseup = true;
1606                  self.hideCursor();
1607                  if (cap.hasmousecapture) document.releaseCapture();
1608                  if (!cap.cantouch) return self.cancelEvent(e);
1609                }
1610              }
1611
1612            };
1613
1614            var moveneedoffset = (self.opt.touchbehavior&&self.isiframe&&!cap.hasmousecapture);
1615
1616            self.ontouchmove = function(e,byiframe) {
1617
1618              if (e.pointerType&&e.pointerType!=2) return false;
1619
1620              if (self.rail.drag&&(self.rail.drag.pt==2)) {
1621                if (cap.cantouch&&(typeof e.original == "undefined")) return true;  // prevent ios "ghost" events by clickable elements
1622
1623                self.hasmoving = true;
1624
1625                if (self.preventclick&&!self.preventclick.click) {
1626                  self.preventclick.click = self.preventclick.tg.oncl
1626ick||false;
1627                  self.preventclick.tg.onclick = self.onpreventclick;
1628                }
1629
1630                var ev = $.extend({"original":e},e);
1631                e = ev;
1632
1633                if (("changedTouches" in e)) {
1634                  e.clientX = e.changedTouches[0].clientX;
1635                  e.clientY = e.changedTouches[0].clientY;
1636                }
1637
1638                if (self.forcescreen) {
1639                  var le = e;
1640                  var e = {"original":(e.original)?e.original:e};
1641                  e.clientX = le.screenX;
1642                  e.clientY = le.screenY;
1643                }
1644
1645                var ofx = ofy = 0;
1646
1647                if (moveneedoffset&&!byiframe) {
1648                  var wp = self.win.position();
1649                  ofx=-wp.left;
1650                  ofy=-wp.top;
1651                }
1652
1653                var fy = e.clientY + ofy;
1654                var my = (fy-self.rail.drag.y);
1655                var fx = e.clientX + ofx;
1656                var mx = (fx-self.rail.drag.x);
1657
1658                var ny = self.rail.drag.st-my;
1659
1660                if (self.ishwscroll&&self.opt.bouncescroll) {
1661                  if (ny<0) {
1662                    ny = Math.round(ny/2);
1663//                    fy = 0;
1664                  }
1665                  else if (ny>self.page.maxh) {
1666                    ny = self.page.maxh+Math.round((ny-self.page.maxh)/2);
1667//                    fy = 0;
1668                  }
1669                } else {
1670                  if (ny<0) {ny=0;fy=0}
1671                  if (ny>self.page.maxh) {ny=self.page.maxh;fy=0}
1672                }
1673
1674                if (self.railh&&self.railh.scrollable) {
1675                  var nx = self.rail.drag.sl-mx;
1676
1677                  if (self.ishwscroll&&self.opt.bouncescroll) {
1678                    if (nx<0) {
1679                      nx = Math.round(nx/2);
1680//                      fx = 0;
1681                    }
1682                    else if (nx>self.page.maxw) {
1683                      nx = self.page.maxw+Math.round((nx-self.page.maxw)/2);
1684//                      fx = 0;
1685                    }
1686                  } else {
1687                    if (nx<0) {nx=0;fx=0}
1688                    if (nx>self.page.maxw) {nx=self.page.maxw;fx=0}
1689                  }
1690
1691                }
1692
1693                var grabbed = false;
1694                if (self.rail.drag.dl) {
1695                  grabbed = true;
1696                  if (self.rail.drag.dl=="v") nx = self.rail.drag.sl;
1697                  else if (self.rail.drag.dl=="h") ny = self.rail.drag.st;
1698                } else {
1699                  var ay = Math.abs(my);
1700                  var ax = Math.abs(mx);
1701                  var dz = self.opt.directionlockdeadzone;
1702                  if (self.rail.drag.ck=="v") {
1703                    if (ay>dz&&(ax<=(ay*0.3))) {
1704                      self.rail.drag = false;
1705                      return true;
1706                    }
1707                    else if (ax>dz) {
1708                      self.rail.drag.dl="f";
1709                      $("body").scrollTop($("body").scrollTop());  // stop iOS native scrolling (when active javascript has blocked)
1710                    }
1711                  }
1712                  else if (self.rail.drag.ck=="h") {
1713                    if (ax>dz&&(ay<=(ax*0.3))) {
1714                      self.rail.drag = false;
1715                      return true;
1716                    }
1717                    else if (ay>dz) {
1718                      self.rail.drag.dl="f";
1719                      $("body").scrollLeft($("body").scrollLeft());  // stop iOS native scrolling (when active javascript has blocked)
1720                    }
1721                  }
1722                }
1723
1724                self.synched("touchmove",function(){
1725                  if (self.rail.drag&&(self.rail.drag.pt==2)) {
1726                    if (self.prepareTransition) self.prepareTransition(0);
1727                    if (self.rail.scrollable) self.setScrollTop(ny);
1728                    self.scrollmom.update(fx,fy);
1729                    if (self.railh&&self.railh.scrollable) {
1730                      self.setScrollLeft(nx);
1731                      self.showCursor(ny,nx);
1732                    } else {
1733                      self.showCursor(ny);
1734                    }
1735                    if (cap.isie10) document.selection.clear();
1736                  }
1737                });
1738
1739                if (cap.ischrome&&self.istouchcapable) grabbed=false;  //chrome touch emulation doesn't like!
1740                if (grabbed) return self.cancelEvent(e);
1741              }
1742
1743            };
1744
1745          }
1746
1747          self.onmousedown = function(e,hronly) {
1748            if (self.rail.drag&&self.rail.drag.pt!=1) return;
1749            if (self.locked) return self.cancelEvent(e);
1750            self.cancelScroll();
1751            self.rail.drag = {x:e.clientX,y:e.clientY,sx:self.scroll.x,sy:self.scroll.y,pt:1,hr:(!!hronly)};
1752            var tg = self.getTarget(e);
1753            if (!self.ispage&&cap.hasmousecapture) tg.setCapture();
1754            if (self.isiframe&&!cap.hasmousecapture) {
1755              self.saved["csspointerevents"] = self.doc.css("pointer-events");
1756              self.css(self.doc,{"pointer-events":"none"});
1757            }
1758            return self.cancelEvent(e);
1759          };
1760
1761          self.onmouseup = function(e) {
1762            if (self.rail.drag) {
1763              if (cap.hasmousecapture) document.releaseCapture();
1764              if (self.isiframe&&!cap.hasmousecapture) self.doc.css("pointer-events",self.saved["csspointerevents"]);
1765              if(self.rail.drag.pt!=1)return;
1766              self.rail.drag = false;
1767              //if (!self.rail.active) self.hideCursor();
1768              return self.cancelEvent(e);
1769            }
1770          };
1771
1772          self.onmousemove = function(e) {
1773            if (self.rail.drag) {
1774              if(self.rail.drag.pt!=1)return;
1775
1776              if (cap.ischrome&&e.which==0) return self.onmouseup(e);
1777
1778              self.cursorfreezed = true;
1779
1780              if (self.rail.drag.hr) {
1781                self.scroll.x = self.rail.drag.sx + (e.clientX-self.rail.drag.x);
1782                if (self.scroll.x<0) self.scroll.x=0;
1783                var mw = self.scrollvaluemaxw;
1784                if (self.scroll.x>mw) self.scroll.x=mw;
1785              } else {
1786                self.scroll.y = self.rail.drag.sy + (e.clientY-self.rail.drag.y);
1787                if (self.scroll.y<0) self.scroll.y=0;
1788                var my = self.scrollvaluemax;
1789                if (self.scroll.y>my) self.scroll.y=my;
1790              }
1791
1792              self.synched('mousemove',function(){
1793                if (self.rail.drag&&(self.rail.drag.pt==1)) {
1794                  self.showCursor();
1795                  if (self.rail.drag.hr) self.doScrollLeft(Math.round(self.scroll.x*self.scrollratio.x),self.opt.cursordragspeed);
1796                  else self.doScrollTop(Math.round(self.scroll.y*self.scrollratio.y),self.opt.cursordragspeed);
1797                }
1798              });
1799
1800              return self.cancelEvent(e);
1801            }
1802/*
1803            else {
1804              self.checkarea = true;
1805            }
1806*/
1807          };
1808
1809          if (cap.cantouch||self.opt.touchbehavior) {
1810
1811            self.onpreventclick = function(e) {
1812              if (self.preventclick) {
1813                self.preventclick.tg.onclick = self.preventclick.click;
1814                self.preventclick = false;
1815                return self.cancelEvent(e);
1816              }
1817            }
1818
1819//            self.onmousedown = self.ontouchstart;
1820//            self.onmouseup = self.ontouchend;
1821//            self.onmousemove = self.ontouchmove;
1822
1823            self.bind(self.win,"mousedown",self.ontouchstart);  // control content dragging
1824
1825            self.onclick = (cap.isios) ? false : function(e) {
1826              if (self.lastmouseup) {
1827                self.lastmouseup = false;
1828                return self.cancelEvent(e);
1829              } else {
1830                return true;
1831              }
1832            };
1833
1834            if (self.opt.grabcursorenabled&&cap.cursorgrabvalue) {
1835              self.css((self.ispage)?self.doc:self.win,{'cursor':cap.cursorgrabvalue});
1836              self.css(self.rail,{'cursor':cap.cursorgrabvalue});
1837            }
1838
1839          } else {
1840
1841            function checkSelectionScroll(e) {
1842              if (!self.selectiondrag) return;
1843
1844              if (e) {
1845                var ww = self.win.outerHeight();
1846                var df = (e.pageY - self.selectiondrag.top);
1847                if (df>0&&df<ww) df=0;
1848                if (df>=ww) df-=ww;
1849                self.selectiondrag.df = df;
1850              }
1851              if (self.selectiondrag.df==0) return;
1852
1853              var rt = -Math.floor(self.selectiondrag.df/6)*2;
1854//              self.doScrollTop(self.getScrollTop(true)+rt);
1855              self.doScrollBy(rt);
1856
1857              self.debounced("doselectionscroll",function(){checkSelectionScroll()},50);
1858            }
1859
1860            if ("getSelection" in document) {  // A grade - Major browsers
1861              self.hasTextSelected = function() {
1862                return (document.getSelection().rangeCount>0);
1863              }
1864            }
1865            else if ("selection" in document) {  //IE9-
1866              self.hasTextSelected = function() {
1867                return (document.selection.type != "None");
1868              }
1869            }
1870            else {
1871              self.hasTextSelected = function() {  // no support
1872                return false;
1873              }
1874            }
1875
1876            self.onselectionstart = function(e) {
1877              if (self.ispage) return;
1878              self.selectiondrag = self.win.offset();
1879            }
1880            self.onselectionend = function(e) {
1881              self.selectiondrag = false;
1882            }
1883            self.onselectiondrag = function(e) {
1884              if (!self.selectiondrag) return;
1885              if (self.hasTextSelected()) self.debounced("selectionscroll",function(){checkSelectionScroll(e)},250);
1886            }
1887
1888
1889          }
1890
1891          if (cap.hasmstouch) {
1892            self.css(self.rail,{'-ms-touch-action':'none'});
1893            self.css(self.cursor,{'-ms-touch-action':'none'});
1894
1895            self.bind(self.win,"MSPointerDown",self.ontouchstart);
1896            self.bind(document,"MSPointerUp",self.ontouchend);
1897            self.bind(document,"MSPointerMove",self.ontouchmove);
1898            self.bind(self.cursor,"MSGestureHold",function(e){e.preventDefault()});
1899            self.bind(self.cursor,"contextmenu",function(e){e.preventDefault()});
1900          }
1901
1902          if (this.istouchcapable) {  //desktop with screen touch enabled
1903            self.bind(self.win,"touchstart",self.ontouchstart);
1904            self.bind(document,"touchend",self.ontouchend);
1905            self.bind(document,"touchcancel",self.ontouchend);
1906            self.bind(document,"touchmove",self.ontouchmove);
1907          }
1908
1909          self.bind(self.cursor,"mousedown",self.onmousedown);
1910          self.bind(self.cursor,"mouseup",self.onmouseup);
1911
1912          if (self.railh) {
1913            self.bind(self.cursorh,"mousedown",function(e){self.onmousedown(e,true)});
1914            self.bind(self.cursorh,"mouseup",function(e){
1915              if (self.rail.drag&&self.rail.drag.pt==2) return;
1916              self.rail.drag = false;
1917              self.hasmoving = false;
1918              self.hideCursor();
1919              if (cap.hasmousecapture) document.releaseCapture();
1920              return self.cancelEvent(e);
1921            });
1922          }
1923
1924          if (self.opt.cursordragontouch||!cap.cantouch&&!self.opt.touchbehavior) {
1925
1926            self.rail.css({"cursor":"default"});
1927            self.railh&&self.railh.css({"cursor":"default"});
1928
1929            self.jqbind(self.rail,"mouseenter",function() {
1930              if (self.canshowonmouseevent) self.showCursor();
1931              self.rail.active = true;
1932            });
1933            self.jqbind(self.rail,"mouseleave",function() {
1934              self.rail.active = false;
1935              if (!self.rail.drag) self.hideCursor();
1936            });
1937
1938            if (self.opt.sensitiverail) {
1939              self.bind(self.rail,"click",function(e){self.doRailClick(e,false,false)});
1940              self.bind(self.rail,"dblclick",function(e){self.doRailClick(e,true,false)});
1941              self.bind(self.cursor,"click",function(e){self.cancelEvent(e)});
1942              self.bind(self.cursor,"dblclick",function(e){self.cancelEvent(e)});
1943            }
1944
1945            if (self.railh) {
1946              self.jqbind(self.railh,"mouseenter",function() {
1947                if (self.canshowonmouseevent) self.showCursor();
1948                self.rail.active = true;
1949              });
1950              self.jqbind(self.railh,"mouseleave",function() {
1951                self.rail.active = false;
1952                if (!self.rail.drag) self.hideCursor();
1953              });
1954
1955              if (self.opt.sensitiverail) {
1956                self.bind(self.railh, "click", function(e){self.doRailClick(e,false,true)});
1957                self.bind(self.railh, "dblclick", function(e){self.doRailClick(e, true, true) });
1958                self.bind(self.cursorh, "click", function (e) { self.cancelEvent(e) });
1959                self.bind(self.cursorh, "dblclick", function (e) { self.cancelEvent(e) });
1960              }
1961
1962            }
1963
1964          }
1965
1966          if (!cap.cantouch&&!self.opt.touchbehavior) {
1967
1968            self.bind((cap.hasmousecapture)?self.win:document,"mouseup",self.onmouseup);
1969            self.bind(document,"mousemove",self.onmousemove);
1970            if (self.onclick) self.bind(document,"click",self.onclick);
1971
1972            if (!self.ispage&&self.opt.enablescrollonselection) {
1973              self.bind(self.win[0],"mousedown",self.onselectionstart);
1974              self.bind(document,"mouseup",self.onselectionend);
1975              self.bind(self.cursor,"mouseup",self.onselectionend);
1976              if (self.cursorh) self.bind(self.cursorh,"mouseup",self.onselectionend);
1977              self.bind(document,"mousemove",self.onselectiondrag);
1978            }
1979
1980						if (self.zoom) {
1981							self.jqbind(self.zoom,"mouseenter",function() {
1982								if (self.canshowonmouseevent) self.showCursor();
1983								self.rail.active = true;
1984							});
1985							self.jqbind(self.zoom,"mouseleave",function() {
1986								self.rail.active = false;
1987								if (!self.rail.drag) self.hideCursor();
1988							});
1989						}
1990
1991          } else {
1992
1993            self.bind((cap.hasmousecapture)?self.win:document,"mouseup",self.ontouchend);
1994            self.bind(document,"mousemove",self.ontouchmove);
1995            if (self.onclick) self.bind(document,"click",self.onclick);
1996
1997            if (self.opt.cursordragontouch) {
1998              self.bind(self.cursor,"mousedown",self.onmousedown);
1999              self.bind(self.cursor,"mousemove",self.onmousemove);
2000              self.cursorh&&self.bind(self.cursorh,"mousedown",self.onmousedown);
2001              self.cursorh&&self.bind(self.cursorh,"mousemove",self.onmousemove);
2002            }
2003
2004          }
2005
2006					if (self.opt.enablemousewheel) {
2007						if (!self.isiframe) self.bind((cap.isie&&self.ispage) ? document : self.win /*self.docscroll*/ ,"mousewheel",self.onmousewheel);
2008						self.bind(self.rail,"mousewheel",self.onmousewheel);
2009						if (self.railh) self.bind(self.railh,"mousewheel",self.onmousewheelhr);
2010					}
2011
2012          if (!self.ispage&&!cap.cantouch&&!(/HTML|BODY/.test(self.win[0].nodeName))) {
2013            if (!self.win.attr("tabindex")) self.win.attr({"tabindex":tabindexcounter++});
2014
2015            self.jqbind(self.win,"focus",function(e) {
2016              domfocus = (self.getTarget(e)).id||true;
2017              self.hasfocus = true;
2018              if (self.canshowonmouseevent) self.noticeCursor();
2019            });
2020            self.jqbind(self.win,"blur",function(e) {
2021              domfocus = false;
2022              self.hasfocus = false;
2023            });
2024
2025            self.jqbind(self.win,"mouseenter",function(e) {
2026              mousefocus = (self.getTarget(e)).id||true;
2027              self.hasmousefocus = true;
2028              if (self.canshowonmouseevent) self.noticeCursor();
2029            });
2030            self.jqbind(self.win,"mouseleave",function() {
2031              mousefocus = false;
2032              self.hasmousefocus = false;
2033            });
2034
2035          };
2036
2037        }  // !ie9mobile
2038
2039        //Thanks to http://www.quirksmode.org !!
2040        self.onkeypress = function(e) {
2041          if (self.locked&&self.page.maxh==0) return true;
2042
2043          e = (e) ? e : window.e;
2044          var tg = self.getTarget(e);
2045          if (tg&&/INPUT|TEXTAREA|SELECT|OPTION/.test(tg.nodeName)) {
2046            var tp = tg.getAttribute('type')||tg.type||false;
2047            if ((!tp)||!(/submit|button|cancel/i.tp)) return true;
2048          }
2049
2050          if (self.hasfocus||(self.hasmousefocus&&!domfocus)||(self.ispage&&!domfocus&&!mousefocus)) {
2051            var key = e.keyCode;
2052
2053            if (self.locked&&key!=27) return self.cancelEvent(e);
2054
2055            var ctrl = e.ctrlKey||false;
2056            var shift = e.shiftKey || false;
2057
2058            var ret = false;
2059            switch (key) {
2060              case 38:
2061              case 63233: //safari
2062                self.doScrollBy(24*3);
2063                ret = true;
2064                break;
2065              case 40:
2066              case 63235: //safari
2067                self.doScrollBy(-24*3);
2068                ret = true;
2069                break;
2070              case 37:
2071              case 63232: //safari
2072                if (self.railh) {
2073                  (ctrl) ? self.doScrollLeft(0) : self.doScrollLeftBy(24*3);
2074                  ret = true;
2075                }
2076                break;
2077              case 39:
2078              case 63234: //safari
2079                if (self.railh) {
2080                  (ctrl) ? self.doScrollLeft(self.page.maxw) : self.doScrollLeftBy(-24*3);
2081                  ret = true;
2082                }
2083                break;
2084              case 33:
2085              case 63276: // safari
2086                self.doScrollBy(self.view.h);
2087                ret = true;
2088                break;
2089              case 34:
2090              case 63277: // safari
2091                self.doScrollBy(-self.view.h);
2092                ret = true;
2093                break;
2094              case 36:
2095              case 63273: // safari
2096                (self.railh&&ctrl) ? self.doScrollPos(0,0) : self.doScrollTo(0);
2097                ret = true;
2098                break;
2099              case 35:
2100              case 63275: // safari
2101                (self.railh&&ctrl) ? self.doScrollPos(self.page.maxw,self.page.maxh) : self.doScrollTo(self.page.maxh);
2102                ret = true;
2103                break;
2104              case 32:
2105                if (self.opt.spacebarenabled) {
2106                  (shift) ? self.doScrollBy(self.view.h) : self.doScrollBy(-self.view.h);
2107                  ret = true;
2108                }
2109                break;
2110              case 27: // ESC
2111                if (self.zoomactive) {
2112                  self.doZoom();
2113                  ret = true;
2114                }
2115                break;
2116            }
2117            if (ret) return self.cancelEvent(e);
2118          }
2119        };
2120
2121        if (self.opt.enablekeyboard) self.bind(document,(cap.isopera&&!cap.isopera12)?"keypress":"keydown",self.onkeypress);
2122
2123        self.bind(window,'resize',self.lazyResize);
2124        self.bind(window,'orientationchange',self.lazyResize);
2125
2126        self.bind(window,"load",self.lazyResize);
2127
2128        if (cap.ischrome&&!self.ispage&&!self.haswrapper) { //chrome void scrollbar bug - it persists in version 26
2129          var tmp=self.win.attr("style");
2130					var ww = parseFloat(self.win.css("width"))+1;
2131          self.win.css('width',ww);
2132          self.synched("chromefix",function(){self.win.attr("style",tmp)});
2133        }
2134
2135
2136// Trying a cross-browser implementation - good luck!
2137
2138        self.onAttributeChange = function(e) {
2139          self.lazyResize(250);
2140        }
2141
2142        if (!self.ispage&&!self.haswrapper) {
2143          // redesigned MutationObserver for Chrome18+/Firefox14+/iOS6+ with support for: remove div, add/remove content
2144          if (clsMutationObserver !== false) {
2145            self.observer = new clsMutationObserver(function(mutations) {
2146              mutations.forEach(self.onAttributeChange);
2147            });
2148            self.observer.observe(self.win[0],{childList: true, characterData: false, attributes: true, subtree: false});
2149
2150            self.observerremover = new clsMutationObserver(function(mutations) {
2151               mutations.forEach(function(mo){
2152                 if (mo.removedNodes.length>0) {
2153                   for (var dd in mo.removedNodes) {
2154                     if (mo.removedNodes[dd]==self.win[0]) return self.remove();
2155                   }
2156                 }
2157               });
2158            });
2159            self.observerremover.observe(self.win[0].parentNode,{childList: true, characterData: false, attributes: false, subtree: false});
2160
2161          } else {
2162            self.bind(self.win,(cap.isie&&!cap.isie9)?"propertychange":"DOMAttrModified",self.onAttributeChange);
2163            if (cap.isie9) self.win[0].attachEvent("onpropertychange",self.onAttributeChange); //IE9 DOMAttrModified bug
2164            self.bind(self.win,"DOMNodeRemoved",function(e){
2165              if (e.target==self.win[0]) self.remove();
2166            });
2167          }
2168        }
2169
2170//
2171
2172        if (!self.ispage&&self.opt.boxzoom) self.bind(window,"resize",self.resizeZoom);
2173        if (self.istextarea) self.bind(self.win,"mouseup",self.lazyResize);
2174
2175        self.checkrtlmode = true;
2176        self.lazyResize(30);
2177
2178      }
2179
2180      if (this.doc[0].nodeName == 'IFRAME') {
2181        function oniframeload(e) {
2182          self.iframexd = false;
2183          try {
2184            var doc = 'contentDocument' in this ? this.contentDocument : this.contentWindow.document;
2185            var a = doc.domain;
2186          } catch(e){self.iframexd = true;doc=false};
2187
2188          if (self.iframexd) {
2189            if ("console" in window) console.log('NiceScroll error: policy restriced iframe');
2190            return true;  //cross-domain - I can't manage this
2191          }
2192
2193          self.forcescreen = true;
2194
2195          if (self.isiframe) {
2196            self.iframe = {
2197              "doc":$(doc),
2198              "html":self.doc.contents().find('html')[0],
2199              "body":self.doc.contents().find('body')[0]
2200            };
2201            self.getContentSize = function(){
2202              return {
2203                w:Math.max(self.iframe.html.scrollWidth,self.iframe.body.scrollWidth),
2204                h:Math.max(self.iframe.html.scrollHeight,self.iframe.body.scrollHeight)
2205              }
2206            }
2207            self.docscroll = $(self.iframe.body);//$(this.contentWindow);
2208          }
2209
2210          if (!cap.isios&&self.opt.iframeautoresize&&!self.isiframe) {
2211            self.win.scrollTop(0); // reset position
2212            self.doc.height("");  //reset height to fix browser bug
2213            var hh=Math.max(doc.getElementsByTagName('html')[0].scrollHeight,doc.body.scrollHeight);
2214            self.doc.height(hh);
2215          }
2216          self.lazyResize(30);
2217
2218          if (cap.isie7) self.css($(self.iframe.html),{'overflow-y':'hidden'});
2219          //self.css($(doc.body),{'overflow-y':'hidden'});
2220          self.css($(self.iframe.body),{'overflow-y':'hidden'});
2221
2222          if (cap.isios&&self.haswrapper) {
2223            self.css($(doc.body),{'-webkit-transform':'translate3d(0,0,0)'});  // avoid iFrame content clipping - thanks to http://blog.derraab.com/2012/04/02/avoid-iframe-content-clipping-with-css-transform-on-ios/
2224
2225            console.log(1);
2226
2227          }
2228
2229          if ('contentWindow' in this) {
2230            self.bind(this.contentWindow,"scroll",self.onscroll);  //IE8 & minor
2231          } else {
2232            self.bind(doc,"scroll",self.onscroll);
2233          }
2234
2235          if (self.opt.enablemousewheel) {
2236            self.bind(doc,"mousewheel",self.onmousewheel);
2237          }
2238
2239          if (self.opt.enablekeyboard) self.bind(doc,(cap.isopera)?"keypress":"keydown",self.onkeypress);
2240
2241          if (cap.cantouch||self.opt.touchbehavior) {
2242            self.bind(doc,"mousedown",self.ontouchstart);
2243            self.bind(doc,"mousemove",function(e){self.ontouchmove(e,true)});
2244            if (self.opt.grabcursorenabled&&cap.cursorgrabvalue) self.css($(doc.body),{'cursor':cap.cursorgrabvalue});
2245          }
2246
2247          self.bind(doc,"mouseup",self.ontouchend);
2248
2249          if (self.zoom) {
2250            if (self.opt.dblclickzoom) self.bind(doc,'dblclick',self.doZoom);
2251            if (self.ongesturezoom) self.bind(doc,"gestureend",self.ongesturezoom);
2252          }
2253        };
2254
2255        if (this.doc[0].readyState&&this.doc[0].readyState=="complete"){
2256          setTimeout(function(){oniframeload.call(self.doc[0],false)},500);
2257        }
2258        self.bind(this.doc,"load",oniframeload);
2259
2260      }
2261
2262    };
2263
2264    this.showCursor = function(py,px) {
2265      if (self.cursortimeout) {
2266        clearTimeout(self.cursortimeout);
2267        self.cursortimeout = 0;
2268      }
2269      if (!self.rail) return;
2270      if (self.autohidedom) {
2271        self.autohidedom.stop().css({opacity:self.opt.cursoropacitymax});
2272        self.cursoractive = true;
2273      }
2274
2275      if (!self.rail.drag||self.rail.drag.pt!=1) {
2276        if ((typeof py != "undefined")&&(py!==false)) {
2277          self.scroll.y = Math.round(py * 1/self.scrollratio.y);
2278        }
2279        if (typeof px != "undefined") {
2280          self.scroll.x = Math.round(px * 1/self.scrollratio.x);
2281        }
2282      }
2283
2284      self.cursor.css({height:self.cursorheight,top:self.scroll.y});
2285      if (self.cursorh) {
2286        (!self.rail.align&&self.rail.visibility) ? self.cursorh.css({width:self.cursorwidth,left:self.scroll.x+self.rail.width}) : self.cursorh.css({width:self.cursorwidth,left:self.scroll.x});
2287        self.cursoractive = true;
2288      }
2289
2290      if (self.zoom) self.zoom.stop().css({opacity:self.opt.cursoropacitymax});
2291    };
2292
2293    this.hideCursor = function(tm) {
2294      if (self.cursortimeout) return;
2295      if (!self.rail) return;
2296      if (!self.autohidedom) return;
2297      self.cursortimeout = setTimeout(function() {
2298         if (!self.rail.active||!self.showonmouseevent) {
2299           self.autohidedom.stop().animate({opacity:self.opt.cursoropacitymin});
2300           if (self.zoom) self.zoom.stop().animate({opacity:self.opt.cursoropacitymin});
2301           self.cursoractive = false;
2302         }
2303         self.cursortimeout = 0;
2304      }
2304,tm||self.opt.hidecursordelay);
2305    };
2306
2307    this.noticeCursor = function(tm,py,px) {
2308      self.showCursor(py,px);
2309      if (!self.rail.active) self.hideCursor(tm);
2310    };
2311
2312    this.getContentSize =
2313      (self.ispage) ?
2314        function(){
2315          return {
2316            w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),
2317            h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)
2318          }
2319        }
2320      : (self.haswrapper) ?
2321        function(){
2322          return {
2323            w:self.doc.outerWidth()+parseInt(self.win.css('paddingLeft'))+parseInt(self.win.css('paddingRight')),
2324            h:self.doc.outerHeight()+parseInt(self.win.css('paddingTop'))+parseInt(self.win.css('paddingBottom'))
2325          }
2326        }
2327      : function() {
2328        return {
2329          w:self.docscroll[0].scrollWidth,
2330          h:self.docscroll[0].scrollHeight
2331        }
2332      };
2333
2334    this.onResize = function(e,page) {
2335
2336	  if (!self.win) return false;
2337
2338      if (!self.haswrapper&&!self.ispage) {
2339        if (self.win.css('display')=='none') {
2340          if (self.visibility) self.hideRail().hideRailHr();
2341          return false;
2342        } else {
2343          if (!self.hidden&&!self.visibility) self.showRail().showRailHr();
2344        }
2345      }
2346
2347      var premaxh = self.page.maxh;
2348      var premaxw = self.page.maxw;
2349
2350      var preview = {h:self.view.h,w:self.view.w};
2351
2352      self.view = {
2353        w:(self.ispage) ? self.win.width() : parseInt(self.win[0].clientWidth),
2354        h:(self.ispage) ? self.win.height() : parseInt(self.win[0].clientHeight)
2355      };
2356
2357      self.page = (page) ? page : self.getContentSize();
2358
2359      self.page.maxh = Math.max(0,self.page.h - self.view.h);
2360      self.page.maxw = Math.max(0,self.page.w - self.view.w);
2361
2362      if ((self.page.maxh==premaxh)&&(self.page.maxw==premaxw)&&(self.view.w==preview.w)) {
2363        // test position
2364        if (!self.ispage) {
2365          var pos = self.win.offset();
2366          if (self.lastposition) {
2367            var lst = self.lastposition;
2368            if ((lst.top==pos.top)&&(lst.left==pos.left)) return self; //nothing to do
2369          }
2370          self.lastposition = pos;
2371        } else {
2372          return self; //nothing to do
2373        }
2374      }
2375
2376      if (self.page.maxh==0) {
2377        self.hideRail();
2378        self.scrollvaluemax = 0;
2379        self.scroll.y = 0;
2380        self.scrollratio.y = 0;
2381        self.cursorheight = 0;
2382        self.setScrollTop(0);
2383        self.rail.scrollable = false;
2384      } else {
2385        self.rail.scrollable = true;
2386      }
2387
2388      if (self.page.maxw==0) {
2389        self.hideRailHr();
2390        self.scrollvaluemaxw = 0;
2391        self.scroll.x = 0;
2392        self.scrollratio.x = 0;
2393        self.cursorwidth = 0;
2394        self.setScrollLeft(0);
2395        self.railh.scrollable = false;
2396      } else {
2397        self.railh.scrollable = true;
2398      }
2399
2400      self.locked = (self.page.maxh==0)&&(self.page.maxw==0);
2401      if (self.locked) {
2402				if (!self.ispage) self.updateScrollBar(self.view);
2403			  return false;
2404		  }
2405
2406      if (!self.hidden&&!self.visibility) {
2407        self.showRail().showRailHr();
2408      }
2409      else if (!self.hidden&&!self.railh.visibility) self.showRailHr();
2410
2411      if (self.istextarea&&self.win.css('resize')&&self.win.css('resize')!='none') self.view.h-=20;
2412
2413      self.cursorheight = Math.min(self.view.h,Math.round(self.view.h * (self.view.h / self.page.h)));
2414      self.cursorheight = (self.opt.cursorfixedheight) ? self.opt.cursorfixedheight : Math.max(self.opt.cursorminheight,self.cursorheight);
2415
2416      self.cursorwidth = Math.min(self.view.w,Math.round(self.view.w * (self.view.w / self.page.w)));
2417      self.cursorwidth = (self.opt.cursorfixedheight) ? self.opt.cursorfixedheight : Math.max(self.opt.cursorminheight,self.cursorwidth);
2418
2419      self.scrollvaluemax = self.view.h-self.cursorheight-self.cursor.hborder;
2420
2421      if (self.railh) {
2422        self.railh.width = (self.page.maxh>0) ? (self.view.w-self.rail.width) : self.view.w;
2423        self.scrollvaluemaxw = self.railh.width-self.cursorwidth-self.cursorh.wborder;
2424      }
2425
2426      if (self.checkrtlmode&&self.railh) {
2427        self.checkrtlmode = false;
2428        if (self.opt.rtlmode&&self.scroll.x==0) self.setScrollLeft(self.page.maxw);
2429      }
2430
2431      if (!self.ispage) self.updateScrollBar(self.view);
2432
2433      self.scrollratio = {
2434        x:(self.page.maxw/self.scrollvaluemaxw),
2435        y:(self.page.maxh/self.scrollvaluemax)
2436      };
2437
2438      var sy = self.getScrollTop();
2439      if (sy>self.page.maxh) {
2440        self.doScrollTop(self.page.maxh);
2441      } else {
2442        self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y));
2443        self.scroll.x = Math.round(self.getScrollLeft() * (1/self.scrollratio.x));
2444        if (self.cursoractive) self.noticeCursor();
2445      }
2446
2447      if (self.scroll.y&&(self.getScrollTop()==0)) self.doScrollTo(Math.floor(self.scroll.y*self.scrollratio.y));
2448
2449      return self;
2450    };
2451
2452    this.resize = self.onResize;
2453
2454    this.lazyResize = function(tm) {   // event debounce
2455      tm = (isNaN(tm)) ? 30 : tm;
2456      self.delayed('resize',self.resize,tm);
2457      return self;
2458    }
2459
2460// modified by MDN https://developer.mozilla.org/en-US/docs/DOM/Mozilla_event_reference/wheel
2461    function _modernWheelEvent(dom,name,fn,bubble) {
2462      self._bind(dom,name,function(e){
2463        var  e = (e) ? e : window.event;
2464        var event = {
2465          original: e,
2466          target: e.target || e.srcElement,
2467          type: "wheel",
2468          deltaMode: e.type == "MozMousePixelScroll" ? 0 : 1,
2469          deltaX: 0,
2470          deltaZ: 0,
2471          preventDefault: function() {
2472            e.preventDefault ? e.preventDefault() : e.returnValue = false;
2473            return false;
2474          },
2475          stopImmediatePropagation: function() {
2476            (e.stopImmediatePropagation) ? e.stopImmediatePropagation() : e.cancelBubble = true;
2477          }
2478        };
2479
2480        if (name=="mousewheel") {
2481          event.deltaY = - 1/40 * e.wheelDelta;
2482          e.wheelDeltaX && (event.deltaX = - 1/40 * e.wheelDeltaX);
2483        } else {
2484          event.deltaY = e.detail;
2485        }
2486
2487        return fn.call(dom,event);
2488      },bubble);
2489    };
2490
2491    this._bind = function(el,name,fn,bubble) {  // primitive bind
2492      self.events.push({e:el,n:name,f:fn,b:bubble,q:false});
2493      if (el.addEventListener) {
2494        el.addEventListener(name,fn,bubble||false);
2495      }
2496      else if (el.attachEvent) {
2497        el.attachEvent("on"+name,fn);
2498      }
2499      else {
2500        el["on"+name] = fn;
2501      }
2502    };
2503
2504    this.jqbind = function(dom,name,fn) {  // use jquery bind for non-native events (mouseenter/mouseleave)
2505      self.events.push({e:dom,n:name,f:fn,q:true});
2506      $(dom).bind(name,fn);
2507    }
2508
2509    this.bind = function(dom,name,fn,bubble) {  // touch-oriented & fixing jquery bind
2510      var el = ("jquery" in dom) ? dom[0] : dom;
2511
2512      if (name=='mousewheel') {
2513        if ("onwheel" in self.win) {
2514          self._bind(el,"wheel",fn,bubble||false);
2515        } else {
2516          var wname = (typeof document.onmousewheel != "undefined") ? "mousewheel" : "DOMMouseScroll";  // older IE/Firefox
2517          _modernWheelEvent(el,wname,fn,bubble||false);
2518          if (wname=="DOMMouseScroll") _modernWheelEvent(el,"MozMousePixelScroll",fn,bubble||false);  // Firefox legacy
2519        }
2520      }
2521      else if (el.addEventListener) {
2522        if (cap.cantouch && /mouseup|mousedown|mousemove/.test(name)) {  // touch device support
2523          var tt=(name=='mousedown')?'touchstart':(name=='mouseup')?'touchend':'touchmove';
2524          self._bind(el,tt,function(e){
2525            if (e.touches) {
2526              if (e.touches.length<2) {var ev=(e.touches.length)?e.touches[0]:e;ev.original=e;fn.call(this,ev);}
2527            }
2528            else if (e.changedTouches) {var ev=e.changedTouches[0];ev.original=e;fn.call(this,ev);}  //blackberry
2529          },bubble||false);
2530        }
2531        self._bind(el,name,fn,bubble||false);
2532        if (cap.cantouch && name=="mouseup") self._bind(el,"touchcancel",fn,bubble||false);
2533      }
2534      else {
2535        self._bind(el,name,function(e) {
2536          e = e||window.event||false;
2537          if (e) {
2538            if (e.srcElement) e.target=e.srcElement;
2539          }
2540          if (!("pageY" in e)) {
2541            e.pageX = e.clientX + document.documentElement.scrollLeft;
2542            e.pageY = e.clientY + document.documentElement.scrollTop;
2543          }
2544          return ((fn.call(el,e)===false)||bubble===false) ? self.cancelEvent(e) : true;
2545        });
2546      }
2547    };
2548
2549    this._unbind = function(el,name,fn,bub) {  // primitive unbind
2550      if (el.removeEventListener) {
2551        el.removeEventListener(name,fn,bub);
2552      }
2553      else if (el.detachEvent) {
2554        el.detachEvent('on'+name,fn);
2555      } else {
2556        el['on'+name] = false;
2557      }
2558    };
2559
2560    this.unbindAll = function() {
2561      for(var a=0;a<self.events.length;a++) {
2562        var r = self.events[a];
2563        (r.q) ? r.e.unbind(r.n,r.f) : self._unbind(r.e,r.n,r.f,r.b);
2564      }
2565    };
2566
2567    // Thanks to http://www.switchonthecode.com !!
2568    this.cancelEvent = function(e) {
2569      var e = (e.original) ? e.original : (e) ? e : window.event||false;
2570      if (!e) return false;
2571      if(e.preventDefault) e.preventDefault();
2572      if(e.stopPropagation) e.stopPropagation();
2573      if(e.preventManipulation) e.preventManipulation();  //IE10
2574      e.cancelBubble = true;
2575      e.cancel = true;
2576      e.returnValue = false;
2577      return false;
2578    };
2579
2580    this.stopPropagation = function(e) {
2581      var e = (e.original) ? e.original : (e) ? e : window.event||false;
2582      if (!e) return false;
2583      if (e.stopPropagation) return e.stopPropagation();
2584      if (e.cancelBubble) e.cancelBubble=true;
2585      return false;
2586    }
2587
2588    this.showRail = function() {
2589      if ((self.page.maxh!=0)&&(self.ispage||self.win.css('display')!='none')) {
2590        self.visibility = true;
2591        self.rail.visibility = true;
2592        self.rail.css('display','block');
2593      }
2594      return self;
2595    };
2596
2597    this.showRailHr = function() {
2598      if (!self.railh) return self;
2599      if ((self.page.maxw!=0)&&(self.ispage||self.win.css('display')!='none')) {
2600        self.railh.visibility = true;
2601        self.railh.css('display','block');
2602      }
2603      return self;
2604    };
2605
2606    this.hideRail = function() {
2607      self.visibility = false;
2608      self.rail.visibility = false;
2609      self.rail.css('display','none');
2610      return self;
2611    };
2612
2613    this.hideRailHr = function() {
2614      if (!self.railh) return self;
2615      self.railh.visibility = false;
2616      self.railh.css('display','none');
2617      return self;
2618    };
2619
2620    this.show = function() {
2621      self.hidden = false;
2622      self.locked = false;
2623      return self.showRail().showRailHr();
2624    };
2625
2626    this.hide = function() {
2627      self.hidden = true;
2628      self.locked = true;
2629      return self.hideRail().hideRailHr();
2630    };
2631
2632    this.toggle = function() {
2633      return (self.hidden) ? self.show() : self.hide();
2634    };
2635
2636    this.remove = function() {
2637      self.stop();
2638      if (self.cursortimeout) clearTimeout(self.cursortimeout);
2639      self.doZoomOut();
2640      self.unbindAll();
2641
2642      if (cap.isie9) self.win[0].detachEvent("onpropertychange",self.onAttributeChange); //IE9 DOMAttrModified bug
2643
2644      if (self.observer !== false) self.observer.disconnect();
2645      if (self.observerremover !== false) self.observerremover.disconnect();
2646
2647      self.events = null;
2648
2649      if (self.cursor) {
2650        self.cursor.remove();
2651      }
2652      if (self.cursorh) {
2653        self.cursorh.remove();
2654      }
2655      if (self.rail) {
2656        self.rail.remove();
2657      }
2658      if (self.railh) {
2659        self.railh.remove();
2660      }
2661      if (self.zoom) {
2662        self.zoom.remove();
2663      }
2664      for(var a=0;a<self.saved.css.length;a++) {
2665        var d=self.saved.css[a];
2666        d[0].css(d[1],(typeof d[2]=="undefined") ? '' : d[2]);
2667      }
2668      self.saved = false;
2669      self.me.data('__nicescroll',''); //erase all traces
2670
2671      // memory leak fixed by GianlucaGuarini - thanks a lot!
2672      // remove the current nicescroll from the $.nicescroll array & normalize array
2673      var lst = $.nicescroll;
2674      lst.each(function(i){
2675        if (!this) return;
2676        if(this.id === self.id) {
2677          delete lst[i];
2678          for(var b=++i;b<lst.length;b++,i++) lst[i]=lst[b];
2679          lst.length--;
2680          if (lst.length) delete lst[lst.length];
2681        }
2682      });
2683
2684      for (var i in self) {
2685        self[i] = null;
2686        delete self[i];
2687      }
2688
2689      self = null;
2690
2691    };
2692
2693    this.scrollstart = function(fn) {
2694      this.onscrollstart = fn;
2695      return self;
2696    }
2697    this.scrollend = function(fn) {
2698      this.onscrollend = fn;
2699      return self;
2700    }
2701    this.scrollcancel = function(fn) {
2702      this.onscrollcancel = fn;
2703      return self;
2704    }
2705
2706    this.zoomin = function(fn) {
2707      this.onzoomin = fn;
2708      return self;
2709    }
2710    this.zoomout = function(fn) {
2711      this.onzoomout = fn;
2712      return self;
2713    }
2714
2715    this.isScrollable = function(e) {
2716      var dom = (e.target) ? e.target : e;
2717      if (dom.nodeName == 'OPTION') return true;
2718      while (dom&&(dom.nodeType==1)&&!(/BODY|HTML/.test(dom.nodeName))) {
2719        var dd = $(dom);
2720        var ov = dd.css('overflowY')||dd.css('overflowX')||dd.css('overflow')||'';
2721        if (/scroll|auto/.test(ov)) return (dom.clientHeight!=dom.scrollHeight);
2722        dom = (dom.parentNode) ? dom.parentNode : false;
2723      }
2724      return false;
2725    };
2726
2727    this.getViewport = function(me) {
2728      var dom = (me&&me.parentNode) ? me.parentNode : false;
2729      while (dom&&(dom.nodeType==1)&&!(/BODY|HTML/.test(dom.nodeName))) {
2730        var dd = $(dom);
2731        var ov = dd.css('overflowY')||dd.css('overflowX')||dd.css('overflow')||'';
2732        if ((/scroll|auto/.test(ov))&&(dom.clientHeight!=dom.scrollHeight)) return dd;
2733        if (dd.getNiceScroll().length>0) return dd;
2734        dom = (dom.parentNode) ? dom.parentNode : false;
2735      }
2736      return false;
2737    };
2738
2739    function execScrollWheel(e,hr,chkscroll) {
2740      var px,py;
2741      var rt = 1;
2742
2743      if (e.deltaMode==0) {  // PIXEL
2744        px = -Math.floor(e.deltaX*(self.opt.mousescrollstep/(18*3)));
2745        py = -Math.floor(e.deltaY*(self.opt.mousescrollstep/(18*3)));
2746      }
2747      else if (e.deltaMode==1) {  // LINE
2748        px = -Math.floor(e.deltaX*self.opt.mousescrollstep);
2749        py = -Math.floor(e.deltaY*self.opt.mousescrollstep);
2750      }
2751
2752      if (hr&&self.opt.oneaxismousemode&&(px==0)&&py) {  // classic vertical-only mousewheel + browser with x/y support
2753        px = py;
2754        py = 0;
2755      }
2756
2757      if (px) {
2758        if (self.scrollmom) {self.scrollmom.stop()}
2759        self.lastdeltax+=px;
2760        self.debounced("mousewheelx",function(){var dt=self.lastdeltax;self.lastdeltax=0;if(!self.rail.drag){self.doScrollLeftBy(dt)}},120);
2761      }
2762      if (py) {
2763        if (self.opt.nativeparentscrolling&&chkscroll&&!self.ispage&&!self.zoomactive) {
2764          if (py<0) {
2765            if (self.getScrollTop()>=self.page.maxh) return true;
2766          } else {
2767            if (self.getScrollTop()<=0) return true;
2768          }
2769        }
2770        if (self.scrollmom) {self.scrollmom.stop()}
2771        self.lastdeltay+=py;
2772        self.debounced("mousewheely",function(){var dt=self.lastdeltay;self.lastdeltay=0;if(!self.rail.drag){self.doScrollBy(dt)}},120);
2773      }
2774
2775      e.stopImmediatePropagation();
2776      return e.preventDefault();
2777//      return self.cancelEvent(e);
2778    };
2779
2780    this.onmousewheel = function(e) {
2781      if (self.locked) {
2782        self.debounced("checkunlock",self.resize,250);
2783        return true;
2784      }
2785      if (self.rail.drag) return self.cancelEvent(e);
2786
2787      if (self.opt.oneaxismousemode=="auto"&&e.deltaX!=0) self.opt.oneaxismousemode = false;  // check two-axis mouse support (not very elegant)
2788
2789      if (self.opt.oneaxismousemode&&e.deltaX==0) {
2790        if (!self.rail.scrollable) {
2791          if (self.railh&&self.railh.scrollable) {
2792            return self.onmousewheelhr(e);
2793          } else {
2794            return true;
2795          }
2796        }
2797      }
2798
2799      var nw = +(new Date());
2800      var chk = false;
2801      if (self.opt.preservenativescrolling&&((self.checkarea+600)<nw)) {
2802//        self.checkarea = false;
2803        self.nativescrollingarea = self.isScrollable(e);
2804        chk = true;
2805      }
2806      self.checkarea = nw;
2807      if (self.nativescrollingarea) return true; // this isn't my business
2808//      if (self.locked) return self.cancelEvent(e);
2809      var ret = execScrollWheel(e,false,chk);
2810      if (ret) self.checkarea = 0;
2811      return ret;
2812    };
2813
2814    this.onmousewheelhr = function(e) {
2815      if (self.locked||!self.railh.scrollable) return true;
2816      if (self.rail.drag) return self.cancelEvent(e);
2817
2818      var nw = +(new Date());
2819      var chk = false;
2820      if (self.opt.preservenativescrolling&&((self.checkarea+600)<nw)) {
2821//        self.checkarea = false;
2822        self.nativescrollingarea = self.isScrollable(e);
2823        chk = true;
2824      }
2825      self.checkarea = nw;
2826      if (self.nativescrollingarea) return true; // this isn't my business
2827      if (self.locked) return self.cancelEvent(e);
2828
2829      return execScrollWheel(e,true,chk);
2830    };
2831
2832    this.stop = function() {
2833      self.cancelScroll();
2834      if (self.scrollmon) self.scrollmon.stop();
2835      self.cursorfreezed = false;
2836      self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y));
2837      self.noticeCursor();
2838      return self;
2839    };
2840
2841    this.getTransitionSpeed = function(dif) {
2842      var sp = Math.round(self.opt.scrollspeed*10);
2843      var ex = Math.min(sp,Math.round((dif / 20) * self.opt.scrollspeed));
2844      return (ex>
284420) ? ex : 0;
2845    }
2846
2847    if (!self.opt.smoothscroll) {
2848      this.doScrollLeft = function(x,spd) {  //direct
2849        var y = self.getScrollTop();
2850        self.doScrollPos(x,y,spd);
2851      }
2852      this.doScrollTop = function(y,spd) {   //direct
2853        var x = self.getScrollLeft();
2854        self.doScrollPos(x,y,spd);
2855      }
2856      this.doScrollPos = function(x,y,spd) {  //direct
2857        var nx = (x>self.page.maxw) ? self.page.maxw : x;
2858        if (nx<0) nx=0;
2859        var ny = (y>self.page.maxh) ? self.page.maxh : y;
2860        if (ny<0) ny=0;
2861        self.synched('scroll',function(){
2862          self.setScrollTop(ny);
2863          self.setScrollLeft(nx);
2864        });
2865      }
2866      this.cancelScroll = function() {}; // direct
2867    }
2868    else if (self.ishwscroll&&cap.hastransition&&self.opt.usetransition) {
2869      this.prepareTransition = function(dif,istime) {
2870        var ex = (istime) ? ((dif>20)?dif:0) : self.getTransitionSpeed(dif);
2871        var trans = (ex) ? cap.prefixstyle+'transform '+ex+'ms ease-out' : '';
2872        if (!self.lasttransitionstyle||self.lasttransitionstyle!=trans) {
2873          self.lasttransitionstyle = trans;
2874          self.doc.css(cap.transitionstyle,trans);
2875        }
2876        return ex;
2877      };
2878
2879      this.doScrollLeft = function(x,spd) {  //trans
2880        var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop();
2881        self.doScrollPos(x,y,spd);
2882      }
2883
2884      this.doScrollTop = function(y,spd) {   //trans
2885        var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft();
2886        self.doScrollPos(x,y,spd);
2887      }
2888
2889      this.doScrollPos = function(x,y,spd) {  //trans
2890
2891        var py = self.getScrollTop();
2892        var px = self.getScrollLeft();
2893
2894        if (((self.newscrolly-py)*(y-py)<0)||((self.newscrollx-px)*(x-px)<0)) self.cancelScroll();  //inverted movement detection
2895
2896        if (self.opt.bouncescroll==false) {
2897          if (y<0) y=0;
2898          else if (y>self.page.maxh) y=self.page.maxh;
2899          if (x<0) x=0;
2900          else if (x>self.page.maxw) x=self.page.maxw;
2901        }
2902
2903        if (self.scrollrunning&&x==self.newscrollx&&y==self.newscrolly) return false;
2904
2905        self.newscrolly = y;
2906        self.newscrollx = x;
2907
2908        self.newscrollspeed = spd||false;
2909
2910        if (self.timer) return false;
2911
2912        self.timer = setTimeout(function(){
2913
2914          var top = self.getScrollTop();
2915          var lft = self.getScrollLeft();
2916
2917          var dst = {};
2918          dst.x = x-lft;
2919          dst.y = y-top;
2920          dst.px = lft;
2921          dst.py = top;
2922
2923          var dd = Math.round(Math.sqrt(Math.pow(dst.x,2)+Math.pow(dst.y,2)));
2924
2925//          var df = (self.newscrollspeed) ? self.newscrollspeed : dd;
2926
2927          var ms = (self.newscrollspeed && self.newscrollspeed>1) ? self.newscrollspeed : self.getTransitionSpeed(dd);
2928          if (self.newscrollspeed&&self.newscrollspeed<=1) ms*=self.newscrollspeed;
2929
2930          self.prepareTransition(ms,true);
2931
2932          if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm);
2933
2934          if (ms>0) {
2935
2936            if (!self.scrollrunning&&self.onscrollstart) {
2937              var info = {"type":"scrollstart","current":{"x":lft,"y":top},"request":{"x":x,"y":y},"end":{"x":self.newscrollx,"y":self.newscrolly},"speed":ms};
2938              self.onscrollstart.call(self,info);
2939            }
2940
2941            if (cap.transitionend) {
2942              if (!self.scrollendtrapped) {
2943                self.scrollendtrapped = true;
2944                self.bind(self.doc,cap.transitionend,self.onScrollEnd,false); //I have got to do something usefull!!
2945              }
2946            } else {
2947              if (self.scrollendtrapped) clearTimeout(self.scrollendtrapped);
2948              self.scrollendtrapped = setTimeout(self.onScrollEnd,ms);  // simulate transitionend event
2949            }
2950
2951            var py = top;
2952            var px = lft;
2953            self.timerscroll = {
2954              bz: new BezierClass(py,self.newscrolly,ms,0,0,0.58,1),
2955              bh: new BezierClass(px,self.newscrollx,ms,0,0,0.58,1)
2956            };
2957            if (!self.cursorfreezed) self.timerscroll.tm=setInterval(function(){self.showCursor(self.getScrollTop(),self.getScrollLeft())},60);
2958
2959          }
2960
2961          self.synched("doScroll-set",function(){
2962            self.timer = 0;
2963            if (self.scrollendtrapped) self.scrollrunning = true;
2964            self.setScrollTop(self.newscrolly);
2965            self.setScrollLeft(self.newscrollx);
2966            if (!self.scrollendtrapped) self.onScrollEnd();
2967          });
2968
2969
2970        },50);
2971
2972      };
2973
2974      this.cancelScroll = function() {
2975        if (!self.scrollendtrapped) return true;
2976        var py = self.getScrollTop();
2977        var px = self.getScrollLeft();
2978        self.scrollrunning = false;
2979        if (!cap.transitionend) clearTimeout(cap.transitionend);
2980        self.scrollendtrapped = false;
2981        self._unbind(self.doc,cap.transitionend,self.onScrollEnd);
2982        self.prepareTransition(0);
2983        self.setScrollTop(py); // fire event onscroll
2984        if (self.railh) self.setScrollLeft(px);
2985        if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm);
2986        self.timerscroll = false;
2987
2988        self.cursorfreezed = false;
2989
2990        //self.noticeCursor(false,py,px);
2991        self.showCursor(py,px);
2992        return self;
2993      };
2994      this.onScrollEnd = function() {
2995        if (self.scrollendtrapped) self._unbind(self.doc,cap.transitionend,self.onScrollEnd);
2996        self.scrollendtrapped = false;
2997        self.prepareTransition(0);
2998        if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm);
2999        self.timerscroll = false;
3000        var py = self.getScrollTop();
3001        var px = self.getScrollLeft();
3002        self.setScrollTop(py);  // fire event onscroll
3003        if (self.railh) self.setScrollLeft(px);  // fire event onscroll left
3004
3005        self.noticeCursor(false,py,px);
3006
3007        self.cursorfreezed = false;
3008
3009        if (py<0) py=0
3010        else if (py>self.page.maxh) py=self.page.maxh;
3011        if (px<0) px=0
3012        else if (px>self.page.maxw) px=self.page.maxw;
3013        if((py!=self.newscrolly)||(px!=self.newscrollx)) return self.doScrollPos(px,py,self.opt.snapbackspeed);
3014
3015        if (self.onscrollend&&self.scrollrunning) {
3016          var info = {"type":"scrollend","current":{"x":px,"y":py},"end":{"x":self.newscrollx,"y":self.newscrolly}};
3017          self.onscrollend.call(self,info);
3018        }
3019        self.scrollrunning = false;
3020
3021      };
3022
3023    } else {
3024
3025      this.doScrollLeft = function(x,spd) {  //no-trans
3026        var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop();
3027        self.doScrollPos(x,y,spd);
3028      }
3029
3030      this.doScrollTop = function(y,spd) {  //no-trans
3031        var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft();
3032        self.doScrollPos(x,y,spd);
3033      }
3034
3035      this.doScrollPos = function(x,y,spd) {  //no-trans
3036        var y = ((typeof y == "undefined")||(y===false)) ? self.getScrollTop(true) : y;
3037
3038        if  ((self.timer)&&(self.newscrolly==y)&&(self.newscrollx==x)) return true;
3039
3040        if (self.timer) clearAnimationFrame(self.timer);
3041        self.timer = 0;
3042
3043        var py = self.getScrollTop();
3044        var px = self.getScrollLeft();
3045
3046        if (((self.newscrolly-py)*(y-py)<0)||((self.newscrollx-px)*(x-px)<0)) self.cancelScroll();  //inverted movement detection
3047
3048        self.newscrolly = y;
3049        self.newscrollx = x;
3050
3051        if (!self.bouncescroll||!self.rail.visibility) {
3052          if (self.newscrolly<0) {
3053            self.newscrolly = 0;
3054          }
3055          else if (self.newscrolly>self.page.maxh) {
3056            self.newscrolly = self.page.maxh;
3057          }
3058        }
3059        if (!self.bouncescroll||!self.railh.visibility) {
3060          if (self.newscrollx<0) {
3061            self.newscrollx = 0;
3062          }
3063          else if (self.newscrollx>self.page.maxw) {
3064            self.newscrollx = self.page.maxw;
3065          }
3066        }
3067
3068        self.dst = {};
3069        self.dst.x = x-px;
3070        self.dst.y = y-py;
3071        self.dst.px = px;
3072        self.dst.py = py;
3073
3074        var dst = Math.round(Math.sqrt(Math.pow(self.dst.x,2)+Math.pow(self.dst.y,2)));
3075
3076        self.dst.ax = self.dst.x / dst;
3077        self.dst.ay = self.dst.y / dst;
3078
3079        var pa = 0;
3080        var pe = dst;
3081
3082        if (self.dst.x==0) {
3083          pa = py;
3084          pe = y;
3085          self.dst.ay = 1;
3086          self.dst.py = 0;
3087        } else if (self.dst.y==0) {
3088          pa = px;
3089          pe = x;
3090          self.dst.ax = 1;
3091          self.dst.px = 0;
3092        }
3093
3094        var ms = self.getTransitionSpeed(dst);
3095        if (spd&&spd<=1) ms*=spd;
3096        if (ms>0) {
3097          self.bzscroll = (self.bzscroll) ? self.bzscroll.update(pe,ms) : new BezierClass(pa,pe,ms,0,1,0,1);
3098        } else {
3099          self.bzscroll = false;
3100        }
3101
3102        if (self.timer) return;
3103
3104        if ((py==self.page.maxh&&y>=self.page.maxh)||(px==self.page.maxw&&x>=self.page.maxw)) self.checkContentSize();
3105
3106        var sync = 1;
3107
3108        function scrolling() {
3109          if (self.cancelAnimationFrame) return true;
3110
3111          self.scrollrunning = true;
3112
3113          sync = 1-sync;
3114          if (sync) return (self.timer = setAnimationFrame(scrolling)||1);
3115
3116          var done = 0;
3117
3118          var sc = sy = self.getScrollTop();
3119          if (self.dst.ay) {
3120            sc = (self.bzscroll) ? self.dst.py + (self.bzscroll.getNow()*self.dst.ay) : self.newscrolly;
3121            var dr=sc-sy;
3122            if ((dr<0&&sc<self.newscrolly)||(dr>0&&sc>self.newscrolly)) sc = self.newscrolly;
3123            self.setScrollTop(sc);
3124            if (sc == self.newscrolly) done=1;
3125          } else {
3126            done=1;
3127          }
3128
3129          var scx = sx = self.getScrollLeft();
3130          if (self.dst.ax) {
3131            scx = (self.bzscroll) ? self.dst.px + (self.bzscroll.getNow()*self.dst.ax) : self.newscrollx;
3132            var dr=scx-sx;
3133            if ((dr<0&&scx<self.newscrollx)||(dr>0&&scx>self.newscrollx)) scx = self.newscrollx;
3134            self.setScrollLeft(scx);
3135            if (scx == self.newscrollx) done+=1;
3136          } else {
3137            done+=1;
3138          }
3139
3140          if (done==2) {
3141            self.timer = 0;
3142            self.cursorfreezed = false;
3143            self.bzscroll = false;
3144            self.scrollrunning = false;
3145            if (sc<0) sc=0;
3146            else if (sc>self.page.maxh) sc=self.page.maxh;
3147            if (scx<0) scx=0;
3148            else if (scx>self.page.maxw) scx=self.page.maxw;
3149            if ((scx!=self.newscrollx)||(sc!=self.newscrolly)) self.doScrollPos(scx,sc);
3150            else {
3151              if (self.onscrollend) {
3152                var info = {"type":"scrollend","current":{"x":sx,"y":sy},"end":{"x":self.newscrollx,"y":self.newscrolly}};
3153                self.onscrollend.call(self,info);
3154              }
3155            }
3156          } else {
3157            self.timer = setAnimationFrame(scrolling)||1;
3158          }
3159        };
3160        self.cancelAnimationFrame=false;
3161        self.timer = 1;
3162
3163        if (self.onscrollstart&&!self.scrollrunning) {
3164          var info = {"type":"scrollstart","current":{"x":px,"y":py},"request":{"x":x,"y":y},"end":{"x":self.newscrollx,"y":self.newscrolly},"speed":ms};
3165          self.onscrollstart.call(self,info);
3166        }
3167
3168        scrolling();
3169
3170        if ((py==self.page.maxh&&y>=py)||(px==self.page.maxw&&x>=px)) self.checkContentSize();
3171
3172        self.noticeCursor();
3173      };
3174
3175      this.cancelScroll = function() {
3176        if (self.timer) clearAnimationFrame(self.timer);
3177        self.timer = 0;
3178        self.bzscroll = false;
3179        self.scrollrunning = false;
3180        return self;
3181      };
3182
3183    }
3184
3185    this.doScrollBy = function(stp,relative) {
3186      var ny = 0;
3187      if (relative) {
3188        ny = Math.floor((self.scroll.y-stp)*self.scrollratio.y)
3189      } else {
3190        var sy = (self.timer) ? self.newscrolly : self.getScrollTop(true);
3191        ny = sy-stp;
3192      }
3193      if (self.bouncescroll) {
3194        var haf = Math.round(self.view.h/2);
3195        if (ny<-haf) ny=-haf
3196        else if (ny>(self.page.maxh+haf)) ny = (self.page.maxh+haf);
3197      }
3198      self.cursorfreezed = false;
3199
3200      py = self.getScrollTop(true);
3201      if (ny<0&&py<=0) return self.noticeCursor();
3202      else if (ny>self.page.maxh&&py>=self.page.maxh) {
3203        self.checkContentSize();
3204        return self.noticeCursor();
3205      }
3206
3207      self.doScrollTop(ny);
3208    };
3209
3210    this.doScrollLeftBy = function(stp,relative) {
3211      var nx = 0;
3212      if (relative) {
3213        nx = Math.floor((self.scroll.x-stp)*self.scrollratio.x)
3214      } else {
3215        var sx = (self.timer) ? self.newscrollx : self.getScrollLeft(true);
3216        nx = sx-stp;
3217      }
3218      if (self.bouncescroll) {
3219        var haf = Math.round(self.view.w/2);
3220        if (nx<-haf) nx=-haf
3221        else if (nx>(self.page.maxw+haf)) nx = (self.page.maxw+haf);
3222      }
3223      self.cursorfreezed = false;
3224
3225      px = self.getScrollLeft(true);
3226      if (nx<0&&px<=0) return self.noticeCursor();
3227      else if (nx>self.page.maxw&&px>=self.page.maxw) return self.noticeCursor();
3228
3229      self.doScrollLeft(nx);
3230    };
3231
3232    this.doScrollTo = function(pos,relative) {
3233      var ny = (relative) ? Math.round(pos*self.scrollratio.y) : pos;
3234      if (ny<0) ny=0
3235      else if (ny>self.page.maxh) ny = self.page.maxh;
3236      self.cursorfreezed = false;
3237      self.doScrollTop(pos);
3238    };
3239
3240    this.checkContentSize = function() {
3241      var pg = self.getContentSize();
3242      if ((pg.h!=self.page.h)||(pg.w!=self.page.w)) self.resize(false,pg);
3243    };
3244
3245    self.onscroll = function(e) {
3246      if (self.rail.drag) return;
3247      if (!self.cursorfreezed) {
3248        self.synched('scroll',function(){
3249          self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y));
3250          if (self.railh) self.scroll.x = Math.round(self.getScrollLeft() * (1/self.scrollratio.x));
3251          self.noticeCursor();
3252        });
3253      }
3254    };
3255    self.bind(self.docscroll,"scroll",self.onscroll);
3256
3257    this.doZoomIn = function(e) {
3258      if (self.zoomactive) return;
3259      self.zoomactive = true;
3260
3261      self.zoomrestore = {
3262        style:{}
3263      };
3264      var lst = ['position','top','left','zIndex','backgroundColor','marginTop','marginBottom','marginLeft','marginRight'];
3265      var win = self.win[0].style;
3266      for(var a in lst) {
3267        var pp = lst[a];
3268        self.zoomrestore.style[pp] = (typeof win[pp] != "undefined") ? win[pp] : '';
3269      }
3270
3271      self.zoomrestore.style.width = self.win.css('width');
3272      self.zoomrestore.style.height = self.win.css('height');
3273
3274      self.zoomrestore.padding = {
3275        w:self.win.outerWidth()-self.win.width(),
3276        h:self.win.outerHeight()-self.win.height()
3277      };
3278
3279      if (cap.isios4) {
3280        self.zoomrestore.scrollTop = $(window).scrollTop();
3281        $(window).scrollTop(0);
3282      }
3283
3284      self.win.css({
3285        "position":(cap.isios4)?"absolute":"fixed",
3286        "top":0,
3287        "left":0,
3288        "z-index":globalmaxzindex+100,
3289        "margin":"0px"
3290      });
3291      var bkg = self.win.css("backgroundColor");
3292      if (bkg==""||/transparent|rgba\(0, 0, 0, 0\)|rgba\(0,0,0,0\)/.test(bkg)) self.win.css("backgroundColor","#fff");
3293      self.rail.css({"z-index":globalmaxzindex+101});
3294      self.zoom.css({"z-index":globalmaxzindex+102});
3295      self.zoom.css('backgroundPosition','0px -18px');
3296      self.resizeZoom();
3297
3298      if (self.onzoomin) self.onzoomin.call(self);
3299
3300      return self.cancelEvent(e);
3301    };
3302
3303    this.doZoomOut = function(e) {
3304      if (!self.zoomactive) return;
3305      self.zoomactive = false;
3306
3307      self.win.css("margin","");
3308      self.win.css(self.zoomrestore.style);
3309
3310      if (cap.isios4) {
3311        $(window).scrollTop(self.zoomrestore.scrollTop);
3312      }
3313
3314      self.rail.css({"z-index":self.zindex});
3315      self.zoom.css({"z-index":self.zindex});
3316      self.zoomrestore = false;
3317      self.zoom.css('backgroundPosition','0px 0px');
3318      self.onResize();
3319
3320      if (self.onzoomout) self.onzoomout.call(self);
3321
3322      return self.cancelEvent(e);
3323    };
3324
3325    this.doZoom = function(e) {
3326      return (self.zoomactive) ? self.doZoomOut(e) : self.doZoomIn(e);
3327    };
3328
3329    this.resizeZoom = function() {
3330      if (!self.zoomactive) return;
3331
3332      var py = self.getScrollTop(); //preserve scrolling position
3333      self.win.css({
3334        width:$(window).width()-self.zoomrestore.padding.w+"px",
3335        height:$(window).height()-self.zoomrestore.padding.h+"px"
3336      });
3337      self.onResize();
3338
3339      self.setScrollTop(Math.min(self.page.maxh,py));
3340    };
3341
3342    this.init();
3343
3344    $.nicescroll.push(this);
3345
3346  };
3347
3348// Inspired by the work of Kin Blas
3349// http://webpro.host.adobe.com/people/jblas/momentum/includes/jquery.momentum.0.7.js
3350
3351
3352  var ScrollMomentumClass2D = function(nc) {
3353    var self = this;
3354    this.nc = nc;
3355
3356    this.lastx = 0;
3357    this.lasty = 0;
3358    this.speedx = 0;
3359    this.speedy = 0;
3360    this.lasttime = 0;
3361    this.steptime = 0;
3362    this.snapx = false;
3363    this.snapy = false;
3364    this.demulx = 0;
3365    this.demuly = 0;
3366
3367    this.lastscrollx = -1;
3368    this.lastscrolly = -1;
3369
3370    this.chkx = 0;
3371    this.chky = 0;
3372
3373    this.timer = 0;
3374
3375    this.time = function() {
3376      return +new Date();//beautifull hack
3377    };
3378
3379    this.reset = function(px,py) {
3380      self.stop();
3381      var now = self.time();
3382      self.steptime = 0;
3383      self.lasttime = now;
3384      self.speedx = 0;
3385      self.speedy = 0;
3386      self.lastx = px;
3387      self.lasty = py;
3388      self.lastscrollx = -1;
3389      self.lastscrolly = -1;
3390    };
3391
3392    this.update = function(px,py) {
3393      var now = self.time();
vendor: 1,665 bytes, lines 3394-3457
3394      self.steptime = now - self.lasttime;
3395      self.lasttime = now;
3396      var dy = py - self.lasty;
3397      var dx = px - self.lastx;
3398      var sy = self.nc.getScrollTop();
3399      var sx = self.nc.getScrollLeft();
3400      var newy = sy + dy;
3401      var newx = sx + dx;
3402      self.snapx = (newx<0)||(newx>self.nc.page.maxw);
3403      self.snapy = (newy<0)||(newy>self.nc.page.maxh);
3404      self.speedx = dx;
3405      self.speedy = dy;
3406      self.lastx = px;
3407      self.lasty = py;
3408    };
3409
3410    this.stop = function() {
3411      self.nc.unsynched("domomentum2d");
3412      if (self.timer) clearTimeout(self.timer);
3413      self.timer = 0;
3414      self.lastscrollx = -1;
3415      self.lastscrolly = -1;
3416    };
3417
3418    this.doSnapy = function(nx,ny) {
3419      var snap = false;
3420
3421      if (ny<0) {
3422        ny=0;
3423        snap=true;
3424      }
3425      else if (ny>self.nc.page.maxh) {
3426        ny=self.nc.page.maxh;
3427        snap=true;
3428      }
3429
3430      if (nx<0) {
3431        nx=0;
3432        snap=true;
3433      }
3434      else if (nx>self.nc.page.maxw) {
3435        nx=self.nc.page.maxw;
3436        snap=true;
3437      }
3438
3439      if (snap) self.nc.doScrollPos(nx,ny,self.nc.opt.snapbackspeed);
3440    };
3441
3442    this.doMomentum = function(gp) {
3443      var t = self.time();
3444      var l = (gp) ? t+gp : self.lasttime;
3445
3446      var sl = self.nc.getScrollLeft();
3447      var st = self.nc.getScrollTop();
3448
3449      var pageh = self.nc.page.maxh;
3450      var pagew = self.nc.page.maxw;
3451
3452      self.speedx = (pagew>0) ? Math.min(60,self.speedx) : 0;
3453      self.speedy = (pageh>0) ? Math.min(60,self.speedy) : 0;
3454
3455      var chk = l && (t - l) <= 60;
3456
3457      if ((st<0)||(st>pageh)||(sl<0)||(sl>
3457pagew)) chk = false;
3458
3459      var sy = (self.speedy && chk) ? self.speedy : false;
3460      var sx = (self.speedx && chk) ? self.speedx : false;
3461
3462      if (sy||sx) {
3463        var tm = Math.max(16,self.steptime); //timeout granularity
3464
3465        if (tm>50) {  // do smooth
3466          var xm = tm/50;
3467          self.speedx*=xm;
3468          self.speedy*=xm;
3469          tm = 50;
3470        }
3471
3472        self.demulxy = 0;
3473
3474        self.lastscrollx = self.nc.getScrollLeft();
3475        self.chkx = self.lastscrollx;
3476        self.lastscrolly = self.nc.getScrollTop();
3477        self.chky = self.lastscrolly;
3478
3479        var nx = self.lastscrollx;
3480        var ny = self.lastscrolly;
3481
3482        var onscroll = function(){
3483          var df = ((self.time()-t)>600) ? 0.04 : 0.02;
3484
3485          if (self.speedx) {
3486            nx = Math.floor(self.lastscrollx - (self.speedx*(1-self.demulxy)));
3487            self.lastscrollx = nx;
3488            if ((nx<0)||(nx>pagew)) df=0.10;
3489          }
3490
3491          if (self.speedy) {
3492            ny = Math.floor(self.lastscrolly - (self.speedy*(1-self.demulxy)));
3493            self.lastscrolly = ny;
3494            if ((ny<0)||(ny>pageh)) df=0.10;
3495          }
3496
3497          self.demulxy = Math.min(1,self.demulxy+df);
3498
3499          self.nc.synched("domomentum2d",function(){
3500
3501            if (self.speedx) {
3502              var scx = self.nc.getScrollLeft();
3503              if (scx!=self.chkx) self.stop();
3504              self.chkx=nx;
3505              self.nc.setScrollLeft(nx);
3506            }
3507
3508            if (self.speedy) {
3509              var scy = self.nc.getScrollTop();
3510              if (scy!=self.chky) self.stop();
3511              self.chky=ny;
3512              self.nc.setScrollTop(ny);
3513            }
3514
3515            if(!self.timer) {
3516              self.nc.hideCursor();
3517              self.doSnapy(nx,ny);
3518            }
3519
3520          });
3521
3522          if (self.demulxy<1) {
3523            self.timer = setTimeout(onscroll,tm);
3524          } else {
3525            self.stop();
3526            self.nc.hideCursor();
3527            self.doSnapy(nx,ny);
3528          }
3529        };
3530
3531        onscroll();
3532
3533      } else {
3534        self.doSnapy(self.nc.getScrollLeft(),self.nc.getScrollTop());
3535      }
3536
3537    }
3538
3539  };
3540
3541
3542// override jQuery scrollTop
3543
3544  var _scrollTop = jQuery.fn.scrollTop; // preserve original function
3545
3546  jQuery.cssHooks["pageYOffset"] = {
3547    get: function(elem,computed,extra) {
3548      var nice = $.data(elem,'__nicescroll')||false;
3549      return (nice&&nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(elem);
3550    },
3551    set: function(elem,value) {
3552      var nice = $.data(elem,'__nicescroll')||false;
3553      (nice&&nice.ishwscroll) ? nice.setScrollTop(parseInt(value)) : _scrollTop.call(elem,value);
3554      return this;
3555    }
3556  };
3557
3558/*
3559  $.fx.step["scrollTop"] = function(fx){
3560    $.cssHooks["scrollTop"].set( fx.elem, fx.now + fx.unit );
3561  };
3562*/
3563
3564  jQuery.fn.scrollTop = function(value) {
3565    if (typeof value == "undefined") {
3566      var nice = (this[0]) ? $.data(this[0],'__nicescroll')||false : false;
3567      return (nice&&nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(this);
3568    } else {
3569      return this.each(function() {
3570        var nice = $.data(this,'__nicescroll')||false;
3571        (nice&&nice.ishwscroll) ? nice.setScrollTop(parseInt(value)) : _scrollTop.call($(this),value);
3572      });
3573    }
3574  }
3575
3576// override jQuery scrollLeft
3577
3578  var _scrollLeft = jQuery.fn.scrollLeft; // preserve original function
3579
3580  $.cssHooks.pageXOffset = {
3581    get: function(elem,computed,extra) {
3582      var nice = $.data(elem,'__nicescroll')||false;
3583      return (nice&&nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(elem);
3584    },
3585    set: function(elem,value) {
3586      var nice = $.data(elem,'__nicescroll')||false;
3587      (nice&&nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)) : _scrollLeft.call(elem,value);
3588      return this;
3589    }
3590  };
3591
3592/*
3593  $.fx.step["scrollLeft"] = function(fx){
3594    $.cssHooks["scrollLeft"].set( fx.elem, fx.now + fx.unit );
3595  };
3596*/
3597
3598  jQuery.fn.scrollLeft = function(value) {
3599    if (typeof value == "undefined") {
3600      var nice = (this[0]) ? $.data(this[0],'__nicescroll')||false : false;
3601      return (nice&&nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(this);
3602    } else {
3603      return this.each(function() {
3604        var nice = $.data(this,'__nicescroll')||false;
3605        (nice&&nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)) : _scrollLeft.call($(this),value);
3606      });
3607    }
3608  }
3609
3610  var NiceScrollArray = function(doms) {
3611    var self = this;
3612    this.length = 0;
3613    this.name = "nicescrollarray";
3614
3615    this.each = function(fn) {
3616      for(var a=0,i=0;a<self.length;a++) fn.call(self[a],i++);
3617      return self;
3618    };
3619
3620    this.push = function(nice) {
3621      self[self.length]=nice;
3622      self.length++;
3623    };
3624
3625    this.eq = function(idx) {
3626      return self[idx];
3627    };
3628
3629    if (doms) {
3630      for(a=0;a<doms.length;a++) {
3631        var nice = $.data(doms[a],'__nicescroll')||false;
3632        if (nice) {
3633          this[this.length]=nice;
3634          this.length++;
3635        }
3636      };
3637    }
3638
3639    return this;
3640  };
3641
3642  function mplex(el,lst,fn) {
3643    for(var a=0;a<lst.length;a++) fn(el,lst[a]);
3644  };
3645  mplex(
3646    NiceScrollArray.prototype,
3647    ['show','hide','toggle','onResize','resize','remove','stop','doScrollPos'],
3648    function(e,n) {
3649      e[n] = function(){
3650        var args = arguments;
3651        return this.each(function(){
3652          this[n].apply(this,args);
3653        });
3654      };
3655    }
3656  );
3657
3658  jQuery.fn.getNiceScroll = function(index) {
3659    if (typeof index == "undefined") {
3660      return new NiceScrollArray(this);
3661    } else {
3662      var nice = this[index]&&$.data(this[index],'__nicescroll')||false;
3663      return nice;
3664    }
3665  };
3666
3667  jQuery.extend(jQuery.expr[':'], {
3668    nicescroll: function(a) {
3669      return ($.data(a,'__nicescroll'))?true:false;
3670    }
3671  });
3672
3673  $.fn.niceScroll = function(wrapper,opt) {
3674    if (typeof opt=="undefined") {
3675      if ((typeof wrapper=="object")&&!("jquery" in wrapper)) {
3676        opt = wrapper;
3677        wrapper = false;
3678      }
3679    }
3680    var ret = new NiceScrollArray();
3681    if (typeof opt=="undefined") opt = {};
3682
3683    if (wrapper||false) {
3684      opt.doc = $(wrapper);
3685      opt.win = $(this);
3686    }
3687    var docundef = !("doc" in opt);
3688    if (!docundef&&!("win" in opt)) opt.win = $(this);
3689
3690    this.each(function() {
3691      var nice = $(this).data('__nicescroll')||false;
3692      if (!nice) {
3693        opt.doc = (docundef) ? $(this) : opt.doc;
3694        nice = new NiceScrollClass(opt,$(this));
3695        $(this).data('__nicescroll',nice);
3696      }
3697      ret.push(nice);
3698    });
3699    return (ret.length==1) ? ret[0] : ret;
3700  };
3701
3702  window.NiceScroll = {
3703    getjQuery:function(){return jQuery}
3704  };
3705
3706  if (!$.nicescroll) {
3707   $.nicescroll = new NiceScrollArray();
3708   $.nicescroll.options = _globaloptions;
3709  }
3710
3711})( jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.