PageSourceSearch

https://aast.edu/template/50yrs-slider/js/jquery.mCustomScrollbar.js

js aast.edu collected 2026-10-01 11:28:53 UTC 67,171 bytes, 1,765 lines download raw bytes

vendor: 4,498 bytes, lines 1-166
1(function(factory){
2	if(typeof define==="function" && define.amd){
3		define(["jquery"],factory);
4	}else if(typeof module!=="undefined" && module.exports){
5		module.exports=factory;
6	}else{
7		factory(jQuery,window,document);
8	}
9}(function($){
10(function(init){
11	var _rjs=typeof define==="function" && define.amd, /* RequireJS */
12		_njs=typeof module !== "undefined" && module.exports, /* NodeJS */
13		_dlp=("https:"==document.location.protocol) ? "https:" : "http:", /* location protocol */
14		_url="cdn.bootcss.com/jquery-mousewheel/3.1.13/jquery.mousewheel.js";
15	if(!_rjs){
16		if(_njs){
17			require("jquery-mousewheel")($);
18		}else{
19			/* load jquery-mousewheel plugin (via CDN) if it's not present or not loaded via RequireJS 
20			(works when mCustomScrollbar fn is called on window load) */
21			$.event.special.mousewheel || $("head").append(decodeURI("%3Cscript src="+_dlp+"//"+_url+"%3E%3C/script%3E"));
22		}
23	}
24	init();
25}(function(){
26	
27	/* 
28	----------------------------------------
29	PLUGIN NAMESPACE, PREFIX, DEFAULT SELECTOR(S) 
30	----------------------------------------
31	*/
32	
33	var pluginNS="mCustomScrollbar",
34		pluginPfx="mCS",
35		defaultSelector=".mCustomScrollbar",
36	
37	
38		
39	
40	
41	/* 
42	----------------------------------------
43	DEFAULT OPTIONS 
44	----------------------------------------
45	*/
46	
47		defaults={
48			/*
49			set element/content width/height programmatically 
50			values: boolean, pixels, percentage 
51				option						default
52				-------------------------------------
53				setWidth					false
54				setHeight					false
55			*/
56			/*
57			set the initial css top property of content  
58			values: string (e.g. "-100px", "10%" etc.)
59			*/
60			setTop:0,
61			/*
62			set the initial css left property of content  
63			values: string (e.g. "-100px", "10%" etc.)
64			*/
65			setLeft:0,
66			/* 
67			scrollbar axis (vertical and/or horizontal scrollbars) 
68			values (string): "y", "x", "yx"
69			*/
70			axis:"y",
71			/*
72			position of scrollbar relative to content  
73			values (string): "inside", "outside" ("outside" requires elements with position:relative)
74			*/
75			scrollbarPosition:"inside",
76			/*
77			scrolling inertia
78			values: integer (milliseconds)
79			*/
80			scrollInertia:280,
81			/* 
82			auto-adjust scrollbar dragger length
83			values: boolean
84			*/
85			autoDraggerLength:true,
86			/*
87			auto-hide scrollbar when idle 
88			values: boolean
89				option						default
90				-------------------------------------
91				autoHideScrollbar			false
92			*/
93			/*
94			auto-expands scrollbar on mouse-over and dragging
95			values: boolean
96				option						default
97				-------------------------------------
98				autoExpandScrollbar			false
99			*/
100			/*
101			always show scrollbar, even when there's nothing to scroll 
102			values: integer (0=disable, 1=always show dragger rail and buttons, 2=always show dragger rail, dragger and buttons), boolean
103			*/
104			alwaysShowScrollbar:0,
105			/*
106			scrolling always snaps to a multiple of this number in pixels
107			values: integer, array ([y,x])
108				option						default
109				-------------------------------------
110				snapAmount					null
111			*/
112			/*
113			when snapping, snap with this number in pixels as an offset 
114			values: integer
115			*/
116			snapOffset:0,
117			/* 
118			mouse-wheel scrolling
119			*/
120			mouseWheel:{
121				/* 
122				enable mouse-wheel scrolling
123				values: boolean
124				*/
125				enable:true,
126				/* 
127				scrolling amount in pixels
128				values: "auto", integer 
129				*/
130				scrollAmount:"auto",
131				/* 
132				mouse-wheel scrolling axis 
133				the default scrolling direction when both vertical and horizontal scrollbars are present 
134				values (string): "y", "x" 
135				*/
136				axis:"y",
137				/* 
138				prevent the default behaviour which automatically scrolls the parent element(s) when end of scrolling is reached 
139				values: boolean
140					option						default
141					-------------------------------------
142					preventDefault				null
143				*/
144				/*
145				the reported mouse-wheel delta value. The number of lines (translated to pixels) one wheel notch scrolls.  
146				values: "auto", integer 
147				"auto" uses the default OS/browser value 
148				*/
149				deltaFactor:"auto",
150				/*
151				normalize mouse-wheel delta to -1 or 1 (disables mouse-wheel acceleration) 
152				values: boolean
153					option						default
154					-------------------------------------
155					normalizeDelta				null
156				*/
157				/*
158				invert mouse-wheel scrolling direction 
159				values: boolean
160					option						default
161					-------------------------------------
162					invert						null
163				*/
164				/*
165				the tags that disable mouse-wheel when cursor is over them
166				*/
167				disableOver:["select","option","keygen","datalist","textarea"]
168			},
169			/* 
170			scrollbar buttons
171			*/
172			scrollButtons:{ 
173				/*
174				enable scrollbar buttons
175				values: boolean
176					option						default
177					-------------------------------------
178					enable						null
179				*/
180				/*
181				scrollbar buttons scrolling type 
182				values (string): "stepless", "stepped"
183				*/
184				scrollType:"stepless",
185				/*
186				scrolling amount in pixels
187				values: "auto", integer 
188				*/
189				scrollAmount:"auto"
190				/*
191				tabindex of the scrollbar buttons
192				values: false, integer
193					option						default
194					-------------------------------------
195					tabindex					null
196				*/
197			},
198			/* 
199			keyboard scrolling
200			*/
201			keyboard:{ 
202				/*
203				enable scrolling via keyboard
204				values: boolean
205				*/
206				enable:true,
207				/*
208				keyboard scrolling type 
209				values (string): "stepless", "stepped"
210				*/
211				scrollType:"stepless",
212				/*
213				scrolling amount in pixels
214				values: "auto", integer 
215				*/
216				scrollAmount:"auto"
217			},
218			/*
219			enable content touch-swipe scrolling 
220			values: boolean, integer, string (number)
221			integer values define the axis-specific minimum amount required for scrolling momentum
222			*/
223			contentTouchScroll:25,
224			/*
225			enable/disable document (default) touch-swipe scrolling 
226			*/
227			documentTouchScroll:true,
228			/*
229			advanced option parameters
230			*/
231			advanced:{
232				/*
233				auto-expand content horizontally (for "x" or "yx" axis) 
234				values: boolean, integer (the value 2 forces the non scrollHeight/scrollWidth method, the value 3 forces the scrollHeight/scrollWidth method)
235					option						default
236					-------------------------------------
237					autoExpandHorizontalScroll	null
238				*/
239				/*
240				auto-scroll to elements with focus
241				*/
242				autoScrollOnFocus:"input,textarea,select,button,datalist,keygen,a[tabindex],area,object,[contenteditable='true']",
243				/*
244				auto-update scrollbars on content, element or viewport resize 
245				should be true for fluid layouts/elements, adding/removing content dynamically, hiding/showing elements, content with images etc. 
246				values: boolean
247				*/
248				updateOnContentResize:true,
249				/*
250				auto-update scrollbars each time each image inside the element is fully loaded 
251				values: "auto", boolean
252				*/
253				updateOnImageLoad:"auto",
254			
255				autoUpdateTimeout:120
256			},
257			/* 
258			scrollbar theme 
259			values: string 
260			*/
261			theme:"light",
262			/*
263			user defined callback functions
264			*/
265			callbacks:{
266				/*
267				Available callbacks: 
268					callback					default
269					-------------------------------------
270					onCreate					null
271					onInit						null
272					onScrollStart				null
273					onScroll					null
274					onTotalScroll				null
275					onTotalScrollBack			null
276					whileScrolling				null
277					onOverflowY					null
278					onOverflowX					null
279					onOverflowYNone				null
280					onOverflowXNone				null
281					onImageLoad					null
282					onSelectorChange			null
283					onBeforeUpdate				null
284					onUpdate					null
285				*/
286				onTotalScrollOffset:0,
287				onTotalScrollBackOffset:0,
288				alwaysTriggerOffsets:true
289			}
290			/*
291			add scrollbar(s) on all elements matching the current selector, now and in the future 
292			values: boolean, string 
293			string values: "on" (enable), "once" (disable after first invocation), "off" (disable)
294			liveSelector values: string (selector)
295				option						default
296				-------------------------------------
297				live						false
298				liveSelector				null
299			*/
300		},
301	
302	/* 
303	----------------------------------------
304	VARS, CONSTANTS 
305	----------------------------------------
306	*/
307	
308		totalInstances=0, /* plugin instances amount */
309		liveTimers={}, /* live option timers */
310		oldIE=(window.attachEvent && !window.addEventListener) ? 1 : 0, /* detect IE < 9 */
311		touchActive=false,touchable, /* global touch vars (for touch and pointer events) */
312		/* general plugin classes */
313		classes=[
314			"mCSB_dragger_onDrag","mCSB_scrollTools_onDrag","mCS_img_loaded","mCS_disabled","mCS_destroyed","mCS_no_scrollbar",
315			"mCS-autoHide","mCS-dir-rtl","mCS_no_scrollbar_y","mCS_no_scrollbar_x","mCS_y_hidden","mCS_x_hidden","mCSB_draggerContainer",
316			"mCSB_buttonUp","mCSB_buttonDown","mCSB_buttonLeft","mCSB_buttonRight"
317		],
318	
319	/* 
320	----------------------------------------
321	FUNCTIONS
322	----------------------------------------
323	*/
324	
vendor: 27,012 bytes, lines 325-943
325		/* validates selector (if selector is invalid or undefined uses the default one) */
326		_selector=function(){
327			return (typeof $(this)!=="object" || $(this).length<1) ? defaultSelector : this;
328		},
329		/* -------------------- */
330		
331		/* live option timers removal */
332		removeLiveTimers=function(selector){
333			if(liveTimers[selector]){
334				clearTimeout(liveTimers[selector]);
335				_delete(liveTimers,selector);
336			}
337		},
338		/* -------------------- */
339		
340		
341		/* normalizes axis option to valid values: "y", "x", "yx" */
342		_findAxis=function(val){
343			return (val==="yx" || val==="xy" || val==="auto") ? "yx" : (val==="x" || val==="horizontal") ? "x" : "y";
344		},
345		/* -------------------- */
346		
347		
348		/* normalizes scrollButtons.scrollType option to valid values: "stepless", "stepped" */
349		_findScrollButtonsType=function(val){
350			return (val==="stepped" || val==="pixels" || val==="step" || val==="click") ? "stepped" : "stepless";
351		},
352		/* -------------------- */
353		
354		
355		/* generates plugin markup */
356		_pluginMarkup=function(){
357			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
358				expandClass=o.autoExpandScrollbar ? " "+classes[1]+"_expand" : "",
359				scrollbar=["<div id='mCSB_"+d.idx+"_scrollbar_vertical' class='mCSB_scrollTools mCSB_"+d.idx+"_scrollbar mCS-"+o.theme+" mCSB_scrollTools_vertical"+expandClass+"'><div class='"+classes[12]+"'><div id='mCSB_"+d.idx+"_dragger_vertical' class='mCSB_dragger' style='position:absolute;'><div class='mCSB_dragger_bar' /></div><div class='mCSB_draggerRail' /></div></div>","<div id='mCSB_"+d.idx+"_scrollbar_horizontal' class='mCSB_scrollTools mCSB_"+d.idx+"_scrollbar mCS-"+o.theme+" mCSB_scrollTools_horizontal"+expandClass+"'><div class='"+classes[12]+"'><div id='mCSB_"+d.idx+"_dragger_horizontal' class='mCSB_dragger' style='position:absolute;'><div class='mCSB_dragger_bar' /></div><div class='mCSB_draggerRail' /></div></div>"],
360				wrapperClass=o.axis==="yx" ? "mCSB_vertical_horizontal" : o.axis==="x" ? "mCSB_horizontal" : "mCSB_vertical",
361				scrollbars=o.axis==="yx" ? scrollbar[0]+scrollbar[1] : o.axis==="x" ? scrollbar[1] : scrollbar[0],
362				contentWrapper=o.axis==="yx" ? "<div id='mCSB_"+d.idx+"_container_wrapper' class='mCSB_container_wrapper' />" : "",
363				autoHideClass=o.autoHideScrollbar ? " "+classes[6] : "",
364				scrollbarDirClass=(o.axis!=="x" && d.langDir==="rtl") ? " "+classes[7] : "";
365			if(o.setWidth){$this.css("width",o.setWidth);} /* set element width */
366			if(o.setHeight){$this.css("height",o.setHeight);} /* set element height */
367			o.setLeft=(o.axis!=="y" && d.langDir==="rtl") ? "989999px" : o.setLeft; /* adjust left position for rtl direction */
368			$this.addClass(pluginNS+" _"+pluginPfx+"_"+d.idx+autoHideClass+scrollbarDirClass).wrapInner("<div id='mCSB_"+d.idx+"' class='mCustomScrollBox mCS-"+o.theme+" "+wrapperClass+"'><div id='mCSB_"+d.idx+"_container' class='mCSB_container' style='position:relative; top:"+o.setTop+"; left:"+o.setLeft+";' dir='"+d.langDir+"' /></div>");
369			var mCustomScrollBox=$("#mCSB_"+d.idx),
370				mCSB_container=$("#mCSB_"+d.idx+"_container");
371			if(o.axis!=="y" && !o.advanced.autoExpandHorizontalScroll){
372				mCSB_container.css("width",_contentWidth(mCSB_container));
373			}
374			if(o.scrollbarPosition==="outside"){
375				if($this.css("position")==="static"){ /* requires elements with non-static position */
376					$this.css("position","relative");
377				}
378				$this.css("overflow","visible");
379				mCustomScrollBox.addClass("mCSB_outside").after(scrollbars);
380			}else{
381				mCustomScrollBox.addClass("mCSB_inside").append(scrollbars);
382				mCSB_container.wrap(contentWrapper);
383			}
384			_scrollButtons.call(this); /* add scrollbar buttons */
385			/* minimum dragger length */
386			var mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")];
387			mCSB_dragger[0].css("min-height",mCSB_dragger[0].height());
388			mCSB_dragger[1].css("min-width",mCSB_dragger[1].width());
389		},
390		/* -------------------- */
391		
392		
393		/* calculates content width */
394		_contentWidth=function(el){
395			var val=[el[0].scrollWidth,Math.max.apply(Math,el.children().map(function(){return $(this).outerWidth(true);}).get())],w=el.parent().width();
396			return val[0]>w ? val[0] : val[1]>w ? val[1] : "100%";
397		},
398		/* -------------------- */
399		
400		
401		/* expands content horizontally */
402		_expandContentHorizontally=function(){
403			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
404				mCSB_container=$("#mCSB_"+d.idx+"_container");
405			if(o.advanced.autoExpandHorizontalScroll && o.axis!=="y"){
406				/* calculate scrollWidth */
407				mCSB_container.css({"width":"auto","min-width":0,"overflow-x":"scroll"});
408				var w=Math.ceil(mCSB_container[0].scrollWidth);
409				if(o.advanced.autoExpandHorizontalScroll===3 || (o.advanced.autoExpandHorizontalScroll!==2 && w>mCSB_container.parent().width())){
410					mCSB_container.css({"width":w,"min-width":"100%","overflow-x":"inherit"});
411				}else{
412					/* 
413					wrap content with an infinite width div and set its position to absolute and width to auto. 
414					Setting width to auto before calculating the actual width is important! 
415					We must let the browser set the width as browser zoom values are impossible to calculate.
416					*/
417					mCSB_container.css({"overflow-x":"inherit","position":"absolute"})
418						.wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />")
419						.css({ /* set actual width, original position and un-wrap */
420							/* 
421							get the exact width (with decimals) and then round-up. 
422							Using jquery outerWidth() will round the width value which will mess up with inner elements that have non-integer width
423							*/
424							"width":(Math.ceil(mCSB_container[0].getBoundingClientRect().right+0.4)-Math.floor(mCSB_container[0].getBoundingClientRect().left)),
425							"min-width":"100%",
426							"position":"relative"
427						}).unwrap();
428				}
429			}
430		},
431		/* -------------------- */
432		
433		
434		/* adds scrollbar buttons */
435		_scrollButtons=function(){
436			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
437				mCSB_scrollTools=$(".mCSB_"+d.idx+"_scrollbar:first"),
438				tabindex=!_isNumeric(o.scrollButtons.tabindex) ? "" : "tabindex='"+o.scrollButtons.tabindex+"'",
439				btnHTML=[
440					"<a href='#' class='"+classes[13]+"' "+tabindex+" />",
441					"<a href='#' class='"+classes[14]+"' "+tabindex+" />",
442					"<a href='#' class='"+classes[15]+"' "+tabindex+" />",
443					"<a href='#' class='"+classes[16]+"' "+tabindex+" />"
444				],
445				btn=[(o.axis==="x" ? btnHTML[2] : btnHTML[0]),(o.axis==="x" ? btnHTML[3] : btnHTML[1]),btnHTML[2],btnHTML[3]];
446			if(o.scrollButtons.enable){
447				mCSB_scrollTools.prepend(btn[0]).append(btn[1]).next(".mCSB_scrollTools").prepend(btn[2]).append(btn[3]);
448			}
449		},
450		/* -------------------- */
451		
452		
453		/* auto-adjusts scrollbar dragger length */
454		_setDraggerLength=function(){
455			var $this=$(this),d=$this.data(pluginPfx),
456				mCustomScrollBox=$("#mCSB_"+d.idx),
457				mCSB_container=$("#mCSB_"+d.idx+"_container"),
458				mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
459				ratio=[mCustomScrollBox.height()/mCSB_container.outerHeight(false),mCustomScrollBox.width()/mCSB_container.outerWidth(false)],
460				l=[
461					parseInt(mCSB_dragger[0].css("min-height")),Math.round(ratio[0]*mCSB_dragger[0].parent().height()),
462					parseInt(mCSB_dragger[1].css("min-width")),Math.round(ratio[1]*mCSB_dragger[1].parent().width())
463				],
464				h=oldIE && (l[1]<l[0]) ? l[0] : l[1],w=oldIE && (l[3]<l[2]) ? l[2] : l[3];
465			mCSB_dragger[0].css({
466				"height":h,"max-height":(mCSB_dragger[0].parent().height()-10)
467			}).find(".mCSB_dragger_bar").css({"line-height":l[0]+"px"});
468			mCSB_dragger[1].css({
469				"width":w,"max-width":(mCSB_dragger[1].parent().width()-10)
470			});
471		},
472		/* -------------------- */
473		
474		
475		/* calculates scrollbar to content ratio */
476		_scrollRatio=function(){
477			var $this=$(this),d=$this.data(pluginPfx),
478				mCustomScrollBox=$("#mCSB_"+d.idx),
479				mCSB_container=$("#mCSB_"+d.idx+"_container"),
480				mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
481				scrollAmount=[mCSB_container.outerHeight(false)-mCustomScrollBox.height(),mCSB_container.outerWidth(false)-mCustomScrollBox.width()],
482				ratio=[
483					scrollAmount[0]/(mCSB_dragger[0].parent().height()-mCSB_dragger[0].height()),
484					scrollAmount[1]/(mCSB_dragger[1].parent().width()-mCSB_dragger[1].width())
485				];
486			d.scrollRatio={y:ratio[0],x:ratio[1]};
487		},
488		/* -------------------- */
489		
490		
491		/* toggles scrolling classes */
492		_onDragClasses=function(el,action,xpnd){
493			var expandClass=xpnd ? classes[0]+"_expanded" : "",
494				scrollbar=el.closest(".mCSB_scrollTools");
495			if(action==="active"){
496				el.toggleClass(classes[0]+" "+expandClass); scrollbar.toggleClass(classes[1]); 
497				el[0]._draggable=el[0]._draggable ? 0 : 1;
498			}else{
499				if(!el[0]._draggable){
500					if(action==="hide"){
501						el.removeClass(classes[0]); scrollbar.removeClass(classes[1]);
502					}else{
503						el.addClass(classes[0]); scrollbar.addClass(classes[1]);
504					}
505				}
506			}
507		},
508		/* -------------------- */
509		
510		
511		/* checks if content overflows its container to determine if scrolling is required */
512		_overflowed=function(){
513			var $this=$(this),d=$this.data(pluginPfx),
514				mCustomScrollBox=$("#mCSB_"+d.idx),
515				mCSB_container=$("#mCSB_"+d.idx+"_container"),
516				contentHeight=d.overflowed==null ? mCSB_container.height() : mCSB_container.outerHeight(false),
517				contentWidth=d.overflowed==null ? mCSB_container.width() : mCSB_container.outerWidth(false),
518				h=mCSB_container[0].scrollHeight,w=mCSB_container[0].scrollWidth;
519			if(h>contentHeight){contentHeight=h;}
520			if(w>contentWidth){contentWidth=w;}
521			return [contentHeight>mCustomScrollBox.height(),contentWidth>mCustomScrollBox.width()];
522		},
523		/* -------------------- */
524		
525		
526		/* resets content position to 0 */
527		_resetContentPosition=function(){
528			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
529				mCustomScrollBox=$("#mCSB_"+d.idx),
530				mCSB_container=$("#mCSB_"+d.idx+"_container"),
531				mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")];
532			_stop($this); /* stop any current scrolling before resetting */
533			if((o.axis!=="x" && !d.overflowed[0]) || (o.axis==="y" && d.overflowed[0])){ /* reset y */
534				mCSB_dragger[0].add(mCSB_container).css("top",0);
535				_scrollTo($this,"_resetY");
536			}
537			if((o.axis!=="y" && !d.overflowed[1]) || (o.axis==="x" && d.overflowed[1])){ /* reset x */
538				var cx=dx=0;
539				if(d.langDir==="rtl"){ /* adjust left position for rtl direction */
540					cx=mCustomScrollBox.width()-mCSB_container.outerWidth(false);
541					dx=Math.abs(cx/d.scrollRatio.x);
542				}
543				mCSB_container.css("left",cx);
544				mCSB_dragger[1].css("left",dx);
545				_scrollTo($this,"_resetX");
546			}
547		},
548		/* -------------------- */
549		
550		
551		/* binds scrollbar events */
552		_bindEvents=function(){
553			var $this=$(this),d=$this.data(pluginPfx),o=d.opt;
554			if(!d.bindEvents){ /* check if events are already bound */
555				_draggable.call(this);
556				if(o.contentTouchScroll){_contentDraggable.call(this);}
557				_selectable.call(this);
558				if(o.mouseWheel.enable){ /* bind mousewheel fn when plugin is available */
559					function _mwt(){
560						mousewheelTimeout=setTimeout(function(){
561							if(!$.event.special.mousewheel){
562								_mwt();
563							}else{
564								clearTimeout(mousewheelTimeout);
565								_mousewheel.call($this[0]);
566							}
567						},100);
568					}
569					var mousewheelTimeout;
570					_mwt();
571				}
572				_draggerRail.call(this);
573				_wrapperScroll.call(this);
574				if(o.advanced.autoScrollOnFocus){_focus.call(this);}
575				if(o.scrollButtons.enable){_buttons.call(this);}
576				if(o.keyboard.enable){_keyboard.call(this);}
577				d.bindEvents=true;
578			}
579		},
580		/* -------------------- */
581		
582		
583		/* unbinds scrollbar events */
584		_unbindEvents=function(){
585			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
586				namespace=pluginPfx+"_"+d.idx,
587				sb=".mCSB_"+d.idx+"_scrollbar",
588				sel=$("#mCSB_"+d.idx+",#mCSB_"+d.idx+"_container,#mCSB_"+d.idx+"_container_wrapper,"+sb+" ."+classes[12]+",#mCSB_"+d.idx+"_dragger_vertical,#mCSB_"+d.idx+"_dragger_horizontal,"+sb+">a"),
589				mCSB_container=$("#mCSB_"+d.idx+"_container");
590			if(o.advanced.releaseDraggableSelectors){sel.add($(o.advanced.releaseDraggableSelectors));}
591			if(o.advanced.extraDraggableSelectors){sel.add($(o.advanced.extraDraggableSelectors));}
592			if(d.bindEvents){ /* check if events are bound */
593				/* unbind namespaced events from document/selectors */
594				$(document).add($(!_canAccessIFrame() || top.document)).unbind("."+namespace);
595				sel.each(function(){
596					$(this).unbind("."+namespace);
597				});
598				/* clear and delete timeouts/objects */
599				clearTimeout($this[0]._focusTimeout); _delete($this[0],"_focusTimeout");
600				clearTimeout(d.sequential.step); _delete(d.sequential,"step");
601				clearTimeout(mCSB_container[0].onCompleteTimeout); _delete(mCSB_container[0],"onCompleteTimeout");
602				d.bindEvents=false;
603			}
604		},
605		/* -------------------- */
606		
607		
608		/* toggles scrollbar visibility */
609		_scrollbarVisibility=function(disabled){
610			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
611				contentWrapper=$("#mCSB_"+d.idx+"_container_wrapper"),
612				content=contentWrapper.length ? contentWrapper : $("#mCSB_"+d.idx+"_container"),
613				scrollbar=[$("#mCSB_"+d.idx+"_scrollbar_vertical"),$("#mCSB_"+d.idx+"_scrollbar_horizontal")],
614				mCSB_dragger=[scrollbar[0].find(".mCSB_dragger"),scrollbar[1].find(".mCSB_dragger")];
615			if(o.axis!=="x"){
616				if(d.overflowed[0] && !disabled){
617					scrollbar[0].add(mCSB_dragger[0]).add(scrollbar[0].children("a")).css("display","block");
618					content.removeClass(classes[8]+" "+classes[10]);
619				}else{
620					if(o.alwaysShowScrollbar){
621						if(o.alwaysShowScrollbar!==2){mCSB_dragger[0].css("display","none");}
622						content.removeClass(classes[10]);
623					}else{
624						scrollbar[0].css("display","none");
625						content.addClass(classes[10]);
626					}
627					content.addClass(classes[8]);
628				}
629			}
630			if(o.axis!=="y"){
631				if(d.overflowed[1] && !disabled){
632					scrollbar[1].add(mCSB_dragger[1]).add(scrollbar[1].children("a")).css("display","block");
633					content.removeClass(classes[9]+" "+classes[11]);
634				}else{
635					if(o.alwaysShowScrollbar){
636						if(o.alwaysShowScrollbar!==2){mCSB_dragger[1].css("display","none");}
637						content.removeClass(classes[11]);
638					}else{
639						scrollbar[1].css("display","none");
640						content.addClass(classes[11]);
641					}
642					content.addClass(classes[9]);
643				}
644			}
645			if(!d.overflowed[0] && !d.overflowed[1]){
646				$this.addClass(classes[5]);
647			}else{
648				$this.removeClass(classes[5]);
649			}
650		},
651		/* -------------------- */
652		
653		
654		/* returns input coordinates of pointer, touch and mouse events (relative to document) */
655		_coordinates=function(e){
656			var t=e.type,o=e.target.ownerDocument!==document && frameElement!==null ? [$(frameElement).offset().top,$(frameElement).offset().left] : null,
657				io=_canAccessIFrame() && e.target.ownerDocument!==top.document && frameElement!==null ? [$(e.view.frameElement).offset().top,$(e.view.frameElement).offset().left] : [0,0];
658			switch(t){
659				case "pointerdown": case "MSPointerDown": case "pointermove": case "MSPointerMove": case "pointerup": case "MSPointerUp":
660					return o ? [e.originalEvent.pageY-o[0]+io[0],e.originalEvent.pageX-o[1]+io[1],false] : [e.originalEvent.pageY,e.originalEvent.pageX,false];
661					break;
662				case "touchstart": case "touchmove": case "touchend":
663					var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0],
664						touches=e.originalEvent.touches.length || e.originalEvent.changedTouches.length;
665					return e.target.ownerDocument!==document ? [touch.screenY,touch.screenX,touches>1] : [touch.pageY,touch.pageX,touches>1];
666					break;
667				default:
668					return o ? [e.pageY-o[0]+io[0],e.pageX-o[1]+io[1],false] : [e.pageY,e.pageX,false];
669			}
670		},
671		/* -------------------- */
672		
673		
674		/* 
675		SCROLLBAR DRAG EVENTS
676		scrolls content via scrollbar dragging 
677		*/
678		_draggable=function(){
679			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
680				namespace=pluginPfx+"_"+d.idx,
681				draggerId=["mCSB_"+d.idx+"_dragger_vertical","mCSB_"+d.idx+"_dragger_horizontal"],
682				mCSB_container=$("#mCSB_"+d.idx+"_container"),
683				mCSB_dragger=$("#"+draggerId[0]+",#"+draggerId[1]),
684				draggable,dragY,dragX,
685				rds=o.advanced.releaseDraggableSelectors ? mCSB_dragger.add($(o.advanced.releaseDraggableSelectors)) : mCSB_dragger,
686				eds=o.advanced.extraDraggableSelectors ? $(!_canAccessIFrame() || top.document).add($(o.advanced.extraDraggableSelectors)) : $(!_canAccessIFrame() || top.document);
687			mCSB_dragger.bind("contextmenu."+namespace,function(e){
688				e.preventDefault(); //prevent right click
689			}).bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){
690				e.stopImmediatePropagation();
691				e.preventDefault();
692				if(!_mouseBtnLeft(e)){return;} /* left mouse button only */
693				touchActive=true;
694				if(oldIE){document.onselectstart=function(){return false;}} /* disable text selection for IE < 9 */
695				_iframe.call(mCSB_container,false); /* enable scrollbar dragging over iframes by disabling their events */
696				_stop($this);
697				draggable=$(this);
698				var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left,
699					h=draggable.height()+offset.top,w=draggable.width()+offset.left;
700				if(y<h && y>0 && x<w && x>0){
701					dragY=y; 
702					dragX=x;
703				}
704				_onDragClasses(draggable,"active",o.autoExpandScrollbar); 
705			}).bind("touchmove."+namespace,function(e){
706				e.stopImmediatePropagation();
707				e.preventDefault();
708				var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left;
709				_drag(dragY,dragX,y,x);
710			});
711			$(document).add(eds).bind("mousemove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace,function(e){
712				if(draggable){
713					var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left;
714					if(dragY===y && dragX===x){return;} /* has it really moved? */
715					_drag(dragY,dragX,y,x);
716				}
717			}).add(rds).bind("mouseup."+namespace+" touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){
718				if(draggable){
719					_onDragClasses(draggable,"active",o.autoExpandScrollbar); 
720					draggable=null;
721				}
722				touchActive=false;
723				if(oldIE){document.onselectstart=null;} /* enable text selection for IE < 9 */
724				_iframe.call(mCSB_container,true); /* enable iframes events */
725			});
726			function _drag(dragY,dragX,y,x){
727				mCSB_container[0].idleTimer=o.scrollInertia<233 ? 250 : 0;
728				if(draggable.attr("id")===draggerId[1]){
729					var dir="x",to=((draggable[0].offsetLeft-dragX)+x)*d.scrollRatio.x;
730				}else{
731					var dir="y",to=((draggable[0].offsetTop-dragY)+y)*d.scrollRatio.y;
732				}
733				_scrollTo($this,to.toString(),{dir:dir,drag:true});
734			}
735		},
736		/* -------------------- */
737		
738		
739		/* 
740		TOUCH SWIPE EVENTS
741		scrolls content via touch swipe 
742		Emulates the native touch-swipe scrolling with momentum found in iOS, Android and WP devices 
743		*/
744		_contentDraggable=function(){
745			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
746				namespace=pluginPfx+"_"+d.idx,
747				mCustomScrollBox=$("#mCSB_"+d.idx),
748				mCSB_container=$("#mCSB_"+d.idx+"_container"),
749				mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
750				draggable,dragY,dragX,touchStartY,touchStartX,touchMoveY=[],touchMoveX=[],startTime,runningTime,endTime,distance,speed,amount,
751				durA=0,durB,overwrite=o.axis==="yx" ? "none" : "all",touchIntent=[],touchDrag,docDrag,
752				iframe=mCSB_container.find("iframe"),
753				events=[
754					"touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace, //start
755					"touchmove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace, //move
756					"touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace //end
757				],
758				touchAction=document.body.style.touchAction!==undefined && document.body.style.touchAction!=="";
759			mCSB_container.bind(events[0],function(e){
760				_onTouchstart(e);
761			}).bind(events[1],function(e){
762				_onTouchmove(e);
763			});
764			mCustomScrollBox.bind(events[0],function(e){
765				_onTouchstart2(e);
766			}).bind(events[2],function(e){
767				_onTouchend(e);
768			});
769			if(iframe.length){
770				iframe.each(function(){
771					$(this).bind("load",function(){
772						/* bind events on accessible iframes */
773						if(_canAccessIFrame(this)){
774							$(this.contentDocument || this.contentWindow.document).bind(events[0],function(e){
775								_onTouchstart(e);
776								_onTouchstart2(e);
777							}).bind(events[1],function(e){
778								_onTouchmove(e);
779							}).bind(events[2],function(e){
780								_onTouchend(e);
781							});
782						}
783					});
784				});
785			}
786			function _onTouchstart(e){
787				if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){touchable=0; return;}
788				touchable=1; touchDrag=0; docDrag=0; draggable=1;
789				$this.removeClass("mCS_touch_action");
790				var offset=mCSB_container.offset();
791				dragY=_coordinates(e)[0]-offset.top;
792				dragX=_coordinates(e)[1]-offset.left;
793				touchIntent=[_coordinates(e)[0],_coordinates(e)[1]];
794			}
795			function _onTouchmove(e){
796				if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){return;}
797				if(!o.documentTouchScroll){e.preventDefault();} 
798				e.stopImmediatePropagation();
799				if(docDrag && !touchDrag){return;}
800				if(draggable){
801					runningTime=_getTime();
802					var offset=mCustomScrollBox.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left,
803						easing="mcsLinearOut";
804					touchMoveY.push(y);
805					touchMoveX.push(x);
806					touchIntent[2]=Math.abs(_coordinates(e)[0]-touchIntent[0]); touchIntent[3]=Math.abs(_coordinates(e)[1]-touchIntent[1]);
807					if(d.overflowed[0]){
808						var limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(),
809							prevent=((dragY-y)>0 && (y-dragY)>-(limit*d.scrollRatio.y) && (touchIntent[3]*2<touchIntent[2] || o.axis==="yx"));
810					}
811					if(d.overflowed[1]){
812						var limitX=mCSB_dragger[1].parent().width()-mCSB_dragger[1].width(),
813							preventX=((dragX-x)>0 && (x-dragX)>-(limitX*d.scrollRatio.x) && (touchIntent[2]*2<touchIntent[3] || o.axis==="yx"));
814					}
815					if(prevent || preventX){ /* prevent native document scrolling */
816						if(!touchAction){e.preventDefault();} 
817						touchDrag=1;
818					}else{
819						docDrag=1;
820						$this.addClass("mCS_touch_action");
821					}
822					if(touchAction){e.preventDefault();} 
823					amount=o.axis==="yx" ? [(dragY-y),(dragX-x)] : o.axis==="x" ? [null,(dragX-x)] : [(dragY-y),null];
824					mCSB_container[0].idleTimer=250;
825					if(d.overflowed[0]){_drag(amount[0],durA,easing,"y","all",true);}
826					if(d.overflowed[1]){_drag(amount[1],durA,easing,"x",overwrite,true);}
827				}
828			}
829			function _onTouchstart2(e){
830				if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){touchable=0; return;}
831				touchable=1;
832				e.stopImmediatePropagation();
833				_stop($this);
834				startTime=_getTime();
835				var offset=mCustomScrollBox.offset();
836				touchStartY=_coordinates(e)[0]-offset.top;
837				touchStartX=_coordinates(e)[1]-offset.left;
838				touchMoveY=[]; touchMoveX=[];
839			}
840			function _onTouchend(e){
841				if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){return;}
842				draggable=0;
843				e.stopImmediatePropagation();
844				touchDrag=0; docDrag=0;
845				endTime=_getTime();
846				var offset=mCustomScrollBox.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left;
847				if((endTime-runningTime)>30){return;}
848				speed=1000/(endTime-startTime);
849				var easing="mcsEaseOut",slow=speed<2.5,
850					diff=slow ? [touchMoveY[touchMoveY.length-2],touchMoveX[touchMoveX.length-2]] : [0,0];
851				distance=slow ? [(y-diff[0]),(x-diff[1])] : [y-touchStartY,x-touchStartX];
852				var absDistance=[Math.abs(distance[0]),Math.abs(distance[1])];
853				speed=slow ? [Math.abs(distance[0]/4),Math.abs(distance[1]/4)] : [speed,speed];
854				var a=[
855					Math.abs(mCSB_container[0].offsetTop)-(distance[0]*_m((absDistance[0]/speed[0]),speed[0])),
856					Math.abs(mCSB_container[0].offsetLeft)-(distance[1]*_m((absDistance[1]/speed[1]),speed[1]))
857				];
858				amount=o.axis==="yx" ? [a[0],a[1]] : o.axis==="x" ? [null,a[1]] : [a[0],null];
859				durB=[(absDistance[0]*4)+o.scrollInertia,(absDistance[1]*4)+o.scrollInertia];
860				var md=parseInt(o.contentTouchScroll) || 0; /* absolute minimum distance required */
861				amount[0]=absDistance[0]>md ? amount[0] : 0;
862				amount[1]=absDistance[1]>md ? amount[1] : 0;
863				if(d.overflowed[0]){_drag(amount[0],durB[0],easing,"y",overwrite,false);}
864				if(d.overflowed[1]){_drag(amount[1],durB[1],easing,"x",overwrite,false);}
865			}
866			function _m(ds,s){
867				var r=[s*1.5,s*2,s/1.5,s/2];
868				if(ds>90){
869					return s>4 ? r[0] : r[3];
870				}else if(ds>60){
871					return s>3 ? r[3] : r[2];
872				}else if(ds>30){
873					return s>8 ? r[1] : s>6 ? r[0] : s>4 ? s : r[2];
874				}else{
875					return s>8 ? s : r[3];
876				}
877			}
878			function _drag(amount,dur,easing,dir,overwrite,drag){
879				if(!amount){return;}
880				_scrollTo($this,amount.toString(),{dur:dur,scrollEasing:easing,dir:dir,overwrite:overwrite,drag:drag});
881			}
882		},
883		/* -------------------- */
884		
885		
886		/* 
887		SELECT TEXT EVENTS 
888		scrolls content when text is selected 
889		*/
890		_selectable=function(){
891			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential,
892				namespace=pluginPfx+"_"+d.idx,
893				mCSB_container=$("#mCSB_"+d.idx+"_container"),
894				wrapper=mCSB_container.parent(),
895				action;
896			mCSB_container.bind("mousedown."+namespace,function(e){
897				if(touchable){return;}
898				if(!action){action=1; touchActive=true;}
899			}).add(document).bind("mousemove."+namespace,function(e){
900				if(!touchable && action && _sel()){
901					var offset=mCSB_container.offset(),
902						y=_coordinates(e)[0]-offset.top+mCSB_container[0].offsetTop,x=_coordinates(e)[1]-offset.left+mCSB_container[0].offsetLeft;
903					if(y>0 && y<wrapper.height() && x>0 && x<wrapper.width()){
904						if(seq.step){_seq("off",null,"stepped");}
905					}else{
906						if(o.axis!=="x" && d.overflowed[0]){
907							if(y<0){
908								_seq("on",38);
909							}else if(y>wrapper.height()){
910								_seq("on",40);
911							}
912						}
913						if(o.axis!=="y" && d.overflowed[1]){
914							if(x<0){
915								_seq("on",37);
916							}else if(x>wrapper.width()){
917								_seq("on",39);
918							}
919						}
920					}
921				}
922			}).bind("mouseup."+namespace+" dragend."+namespace,function(e){
923				if(touchable){return;}
924				if(action){action=0; _seq("off",null);}
925				touchActive=false;
926			});
927			function _sel(){
928				return 	window.getSelection ? window.getSelection().toString() : 
929						document.selection && document.selection.type!="Control" ? document.selection.createRange().text : 0;
930			}
931			function _seq(a,c,s){
932				seq.type=s && action ? "stepped" : "stepless";
933				seq.scrollAmount=10;
934				_sequentialScroll($this,a,c,"mcsLinearOut",s ? 60 : null);
935			}
936		},
937		/* -------------------- */
938		
939		
940		/* 
941		MOUSE WHEEL EVENT
942		scrolls content via mouse-wheel 
943		via mouse-wheel plugin
vendor: 29,444 bytes, lines 943-1694
943
944		*/
945		_mousewheel=function(){
946			if(!$(this).data(pluginPfx)){return;} /* Check if the scrollbar is ready to use mousewheel events (issue: #185) */
947			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
948				namespace=pluginPfx+"_"+d.idx,
949				mCustomScrollBox=$("#mCSB_"+d.idx),
950				mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
951				iframe=$("#mCSB_"+d.idx+"_container").find("iframe");
952			if(iframe.length){
953				iframe.each(function(){
954					$(this).bind("load",function(){
955						/* bind events on accessible iframes */
956						if(_canAccessIFrame(this)){
957							$(this.contentDocument || this.contentWindow.document).bind("mousewheel."+namespace,function(e,delta){
958								_onMousewheel(e,delta);
959							});
960						}
961					});
962				});
963			}
964			mCustomScrollBox.bind("mousewheel."+namespace,function(e,delta){
965				_onMousewheel(e,delta);
966			});
967			function _onMousewheel(e,delta){
968				_stop($this);
969				if(_disableMousewheel($this,e.target)){return;} /* disables mouse-wheel when hovering specific elements */
970				var deltaFactor=o.mouseWheel.deltaFactor!=="auto" ? parseInt(o.mouseWheel.deltaFactor) : (oldIE && e.deltaFactor<100) ? 100 : e.deltaFactor || 100,
971					dur=o.scrollInertia;
972				if(o.axis==="x" || o.mouseWheel.axis==="x"){
973					var dir="x",
974						px=[Math.round(deltaFactor*d.scrollRatio.x),parseInt(o.mouseWheel.scrollAmount)],
975						amount=o.mouseWheel.scrollAmount!=="auto" ? px[1] : px[0]>=mCustomScrollBox.width() ? mCustomScrollBox.width()*0.9 : px[0],
976						contentPos=Math.abs($("#mCSB_"+d.idx+"_container")[0].offsetLeft),
977						draggerPos=mCSB_dragger[1][0].offsetLeft,
978						limit=mCSB_dragger[1].parent().width()-mCSB_dragger[1].width(),
979						dlt=o.mouseWheel.axis==="y" ? (e.deltaY || delta) : e.deltaX;
980				}else{
981					var dir="y",
982						px=[Math.round(deltaFactor*d.scrollRatio.y),parseInt(o.mouseWheel.scrollAmount)],
983						amount=o.mouseWheel.scrollAmount!=="auto" ? px[1] : px[0]>=mCustomScrollBox.height() ? mCustomScrollBox.height()*0.9 : px[0],
984						contentPos=Math.abs($("#mCSB_"+d.idx+"_container")[0].offsetTop),
985						draggerPos=mCSB_dragger[0][0].offsetTop,
986						limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(),
987						dlt=e.deltaY || delta;
988				}
989				if((dir==="y" && !d.overflowed[0]) || (dir==="x" && !d.overflowed[1])){return;}
990				if(o.mouseWheel.invert || e.webkitDirectionInvertedFromDevice){dlt=-dlt;}
991				if(o.mouseWheel.normalizeDelta){dlt=dlt<0 ? -1 : 1;}
992				if((dlt>0 && draggerPos!==0) || (dlt<0 && draggerPos!==limit) || o.mouseWheel.preventDefault){
993					e.stopImmediatePropagation();
994					e.preventDefault();
995				}
996				if(e.deltaFactor<5 && !o.mouseWheel.normalizeDelta){
997					//very low deltaFactor values mean some kind of delta acceleration (e.g. osx trackpad), so adjusting scrolling accordingly
998					amount=e.deltaFactor; dur=17;
999				}
1000				_scrollTo($this,(contentPos-(dlt*amount)).toString(),{dir:dir,dur:dur});
1001			}
1002		},
1003		/* -------------------- */
1004		
1005		
1006		/* checks if iframe can be accessed */
1007		_canAccessIFrameCache=new Object(),
1008		_canAccessIFrame=function(iframe){
1009		    var result=false,cacheKey=false,html=null;
1010		    if(iframe===undefined){
1011				cacheKey="#empty";
1012		    }else if($(iframe).attr("id")!==undefined){
1013				cacheKey=$(iframe).attr("id");
1014		    }
1015			if(cacheKey!==false && _canAccessIFrameCache[cacheKey]!==undefined){
1016				return _canAccessIFrameCache[cacheKey];
1017			}
1018			if(!iframe){
1019				try{
1020					var doc=top.document;
1021					html=doc.body.innerHTML;
1022				}catch(err){/* do nothing */}
1023				result=(html!==null);
1024			}else{
1025				try{
1026					var doc=iframe.contentDocument || iframe.contentWindow.document;
1027					html=doc.body.innerHTML;
1028				}catch(err){/* do nothing */}
1029				result=(html!==null);
1030			}
1031			if(cacheKey!==false){_canAccessIFrameCache[cacheKey]=result;}
1032			return result;
1033		},
1034		/* -------------------- */
1035		
1036		
1037		/* switches iframe's pointer-events property (drag, mousewheel etc. over cross-domain iframes) */
1038		_iframe=function(evt){
1039			var el=this.find("iframe");
1040			if(!el.length){return;} /* check if content contains iframes */
1041			var val=!evt ? "none" : "auto";
1042			el.css("pointer-events",val); /* for IE11, iframe's display property should not be "block" */
1043		},
1044		/* -------------------- */
1045		
1046		
1047		/* disables mouse-wheel when hovering specific elements like select, datalist etc. */
1048		_disableMousewheel=function(el,target){
1049			var tag=target.nodeName.toLowerCase(),
1050				tags=el.data(pluginPfx).opt.mouseWheel.disableOver,
1051				/* elements that require focus */
1052				focusTags=["select","textarea"];
1053			return $.inArray(tag,tags) > -1 && !($.inArray(tag,focusTags) > -1 && !$(target).is(":focus"));
1054		},
1055		/* -------------------- */
1056		
1057		
1058		/* 
1059		DRAGGER RAIL CLICK EVENT
1060		scrolls content via dragger rail 
1061		*/
1062		_draggerRail=function(){
1063			var $this=$(this),d=$this.data(pluginPfx),
1064				namespace=pluginPfx+"_"+d.idx,
1065				mCSB_container=$("#mCSB_"+d.idx+"_container"),
1066				wrapper=mCSB_container.parent(),
1067				mCSB_draggerContainer=$(".mCSB_"+d.idx+"_scrollbar ."+classes[12]),
1068				clickable;
1069			mCSB_draggerContainer.bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){
1070				touchActive=true;
1071				if(!$(e.target).hasClass("mCSB_dragger")){clickable=1;}
1072			}).bind("touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){
1073				touchActive=false;
1074			}).bind("click."+namespace,function(e){
1075				if(!clickable){return;}
1076				clickable=0;
1077				if($(e.target).hasClass(classes[12]) || $(e.target).hasClass("mCSB_draggerRail")){
1078					_stop($this);
1079					var el=$(this),mCSB_dragger=el.find(".mCSB_dragger");
1080					if(el.parent(".mCSB_scrollTools_horizontal").length>0){
1081						if(!d.overflowed[1]){return;}
1082						var dir="x",
1083							clickDir=e.pageX>mCSB_dragger.offset().left ? -1 : 1,
1084							to=Math.abs(mCSB_container[0].offsetLeft)-(clickDir*(wrapper.width()*0.9));
1085					}else{
1086						if(!d.overflowed[0]){return;}
1087						var dir="y",
1088							clickDir=e.pageY>mCSB_dragger.offset().top ? -1 : 1,
1089							to=Math.abs(mCSB_container[0].offsetTop)-(clickDir*(wrapper.height()*0.9));
1090					}
1091					_scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"});
1092				}
1093			});
1094		},
1095		/* -------------------- */
1096		
1097		
1098		/* 
1099		FOCUS EVENT
1100		scrolls content via element focus (e.g. clicking an input, pressing TAB key etc.)
1101		*/
1102		_focus=function(){
1103			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
1104				namespace=pluginPfx+"_"+d.idx,
1105				mCSB_container=$("#mCSB_"+d.idx+"_container"),
1106				wrapper=mCSB_container.parent();
1107			mCSB_container.bind("focusin."+namespace,function(e){
1108				var el=$(document.activeElement),
1109					nested=mCSB_container.find(".mCustomScrollBox").length,
1110					dur=0;
1111				if(!el.is(o.advanced.autoScrollOnFocus)){return;}
1112				_stop($this);
1113				clearTimeout($this[0]._focusTimeout);
1114				$this[0]._focusTimer=nested ? (dur+17)*nested : 0;
1115				$this[0]._focusTimeout=setTimeout(function(){
1116					var	to=[_childPos(el)[0],_childPos(el)[1]],
1117						contentPos=[mCSB_container[0].offsetTop,mCSB_container[0].offsetLeft],
1118						isVisible=[
1119							(contentPos[0]+to[0]>=0 && contentPos[0]+to[0]<wrapper.height()-el.outerHeight(false)),
1120							(contentPos[1]+to[1]>=0 && contentPos[0]+to[1]<wrapper.width()-el.outerWidth(false))
1121						],
1122						overwrite=(o.axis==="yx" && !isVisible[0] && !isVisible[1]) ? "none" : "all";
1123					if(o.axis!=="x" && !isVisible[0]){
1124						_scrollTo($this,to[0].toString(),{dir:"y",scrollEasing:"mcsEaseInOut",overwrite:overwrite,dur:dur});
1125					}
1126					if(o.axis!=="y" && !isVisible[1]){
1127						_scrollTo($this,to[1].toString(),{dir:"x",scrollEasing:"mcsEaseInOut",overwrite:overwrite,dur:dur});
1128					}
1129				},$this[0]._focusTimer);
1130			});
1131		},
1132		/* -------------------- */
1133		
1134		
1135		/* sets content wrapper scrollTop/scrollLeft always to 0 */
1136		_wrapperScroll=function(){
1137			var $this=$(this),d=$this.data(pluginPfx),
1138				namespace=pluginPfx+"_"+d.idx,
1139				wrapper=$("#mCSB_"+d.idx+"_container").parent();
1140			wrapper.bind("scroll."+namespace,function(e){
1141				if(wrapper.scrollTop()!==0 || wrapper.scrollLeft()!==0){
1142					$(".mCSB_"+d.idx+"_scrollbar").css("visibility","hidden"); /* hide scrollbar(s) */
1143				}
1144			});
1145		},
1146		/* -------------------- */
1147		
1148		
1149		/* 
1150		BUTTONS EVENTS
1151		scrolls content via up, down, left and right buttons 
1152		*/
1153		_buttons=function(){
1154			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential,
1155				namespace=pluginPfx+"_"+d.idx,
1156				sel=".mCSB_"+d.idx+"_scrollbar",
1157				btn=$(sel+">a");
1158			btn.bind("contextmenu."+namespace,function(e){
1159				e.preventDefault(); //prevent right click
1160			}).bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace+" mouseup."+namespace+" touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace+" mouseout."+namespace+" pointerout."+namespace+" MSPointerOut."+namespace+" click."+namespace,function(e){
1161				e.preventDefault();
1162				if(!_mouseBtnLeft(e)){return;} /* left mouse button only */
1163				var btnClass=$(this).attr("class");
1164				seq.type=o.scrollButtons.scrollType;
1165				switch(e.type){
1166					case "mousedown": case "touchstart": case "pointerdown": case "MSPointerDown":
1167						if(seq.type==="stepped"){return;}
1168						touchActive=true;
1169						d.tweenRunning=false;
1170						_seq("on",btnClass);
1171						break;
1172					case "mouseup": case "touchend": case "pointerup": case "MSPointerUp":
1173					case "mouseout": case "pointerout": case "MSPointerOut":
1174						if(seq.type==="stepped"){return;}
1175						touchActive=false;
1176						if(seq.dir){_seq("off",btnClass);}
1177						break;
1178					case "click":
1179						if(seq.type!=="stepped" || d.tweenRunning){return;}
1180						_seq("on",btnClass);
1181						break;
1182				}
1183				function _seq(a,c){
1184					seq.scrollAmount=o.scrollButtons.scrollAmount;
1185					_sequentialScroll($this,a,c);
1186				}
1187			});
1188		},
1189		/* -------------------- */
1190		
1191		
1192		/* 
1193		KEYBOARD EVENTS
1194		scrolls content via keyboard 
1195		Keys: up arrow, down arrow, left arrow, right arrow, PgUp, PgDn, Home, End
1196		*/
1197		_keyboard=function(){
1198			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential,
1199				namespace=pluginPfx+"_"+d.idx,
1200				mCustomScrollBox=$("#mCSB_"+d.idx),
1201				mCSB_container=$("#mCSB_"+d.idx+"_container"),
1202				wrapper=mCSB_container.parent(),
1203				editables="input,textarea,select,datalist,keygen,[contenteditable='true']",
1204				iframe=mCSB_container.find("iframe"),
1205				events=["blur."+namespace+" keydown."+namespace+" keyup."+namespace];
1206			if(iframe.length){
1207				iframe.each(function(){
1208					$(this).bind("load",function(){
1209						/* bind events on accessible iframes */
1210						if(_canAccessIFrame(this)){
1211							$(this.contentDocument || this.contentWindow.document).bind(events[0],function(e){
1212								_onKeyboard(e);
1213							});
1214						}
1215					});
1216				});
1217			}
1218			mCustomScrollBox.attr("tabindex","0").bind(events[0],function(e){
1219				_onKeyboard(e);
1220			});
1221			function _onKeyboard(e){
1222				switch(e.type){
1223					case "blur":
1224						if(d.tweenRunning && seq.dir){_seq("off",null);}
1225						break;
1226					case "keydown": case "keyup":
1227						var code=e.keyCode ? e.keyCode : e.which,action="on";
1228						if((o.axis!=="x" && (code===38 || code===40)) || (o.axis!=="y" && (code===37 || code===39))){
1229							/* up (38), down (40), left (37), right (39) arrows */
1230							if(((code===38 || code===40) && !d.overflowed[0]) || ((code===37 || code===39) && !d.overflowed[1])){return;}
1231							if(e.type==="keyup"){action="off";}
1232							if(!$(document.activeElement).is(editables)){
1233								e.preventDefault();
1234								e.stopImmediatePropagation();
1235								_seq(action,code);
1236							}
1237						}else if(code===33 || code===34){
1238							/* PgUp (33), PgDn (34) */
1239							if(d.overflowed[0] || d.overflowed[1]){
1240								e.preventDefault();
1241								e.stopImmediatePropagation();
1242							}
1243							if(e.type==="keyup"){
1244								_stop($this);
1245								var keyboardDir=code===34 ? -1 : 1;
1246								if(o.axis==="x" || (o.axis==="yx" && d.overflowed[1] && !d.overflowed[0])){
1247									var dir="x",to=Math.abs(mCSB_container[0].offsetLeft)-(keyboardDir*(wrapper.width()*0.9));
1248								}else{
1249									var dir="y",to=Math.abs(mCSB_container[0].offsetTop)-(keyboardDir*(wrapper.height()*0.9));
1250								}
1251								_scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"});
1252							}
1253						}else if(code===35 || code===36){
1254							/* End (35), Home (36) */
1255							if(!$(document.activeElement).is(editables)){
1256								if(d.overflowed[0] || d.overflowed[1]){
1257									e.preventDefault();
1258									e.stopImmediatePropagation();
1259								}
1260								if(e.type==="keyup"){
1261									if(o.axis==="x" || (o.axis==="yx" && d.overflowed[1] && !d.overflowed[0])){
1262										var dir="x",to=code===35 ? Math.abs(wrapper.width()-mCSB_container.outerWidth(false)) : 0;
1263									}else{
1264										var dir="y",to=code===35 ? Math.abs(wrapper.height()-mCSB_container.outerHeight(false)) : 0;
1265									}
1266									_scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"});
1267								}
1268							}
1269						}
1270						break;
1271				}
1272				function _seq(a,c){
1273					seq.type=o.keyboard.scrollType;
1274					seq.scrollAmount=o.keyboard.scrollAmount;
1275					if(seq.type==="stepped" && d.tweenRunning){return;}
1276					_sequentialScroll($this,a,c);
1277				}
1278			}
1279		},
1280		/* -------------------- */
1281		
1282		
1283		/* scrolls content sequentially (used when scrolling via buttons, keyboard arrows etc.) */
1284		_sequentialScroll=function(el,action,trigger,e,s){
1285			var d=el.data(pluginPfx),o=d.opt,seq=d.sequential,
1286				mCSB_container=$("#mCSB_"+d.idx+"_container"),
1287				once=seq.type==="stepped" ? true : false,
1288				steplessSpeed=o.scrollInertia < 26 ? 26 : o.scrollInertia, /* 26/1.5=17 */
1289				steppedSpeed=o.scrollInertia < 1 ? 17 : o.scrollInertia;
1290			switch(action){
1291				case "on":
1292					seq.dir=[
1293						(trigger===classes[16] || trigger===classes[15] || trigger===39 || trigger===37 ? "x" : "y"),
1294						(trigger===classes[13] || trigger===classes[15] || trigger===38 || trigger===37 ? -1 : 1)
1295					];
1296					_stop(el);
1297					if(_isNumeric(trigger) && seq.type==="stepped"){return;}
1298					_on(once);
1299					break;
1300				case "off":
1301					_off();
1302					if(once || (d.tweenRunning && seq.dir)){
1303						_on(true);
1304					}
1305					break;
1306			}
1307			
1308			/* starts sequence */
1309			function _on(once){
1310				if(o.snapAmount){seq.scrollAmount=!(o.snapAmount instanceof Array) ? o.snapAmount : seq.dir[0]==="x" ? o.snapAmount[1] : o.snapAmount[0];} /* scrolling snapping */
1311				var c=seq.type!=="stepped", /* continuous scrolling */
1312					t=s ? s : !once ? 1000/60 : c ? steplessSpeed/1.5 : steppedSpeed, /* timer */
1313					m=!once ? 2.5 : c ? 7.5 : 40, /* multiplier */
1314					contentPos=[Math.abs(mCSB_container[0].offsetTop),Math.abs(mCSB_container[0].offsetLeft)],
1315					ratio=[d.scrollRatio.y>10 ? 10 : d.scrollRatio.y,d.scrollRatio.x>10 ? 10 : d.scrollRatio.x],
1316					amount=seq.dir[0]==="x" ? contentPos[1]+(seq.dir[1]*(ratio[1]*m)) : contentPos[0]+(seq.dir[1]*(ratio[0]*m)),
1317					px=seq.dir[0]==="x" ? contentPos[1]+(seq.dir[1]*parseInt(seq.scrollAmount)) : contentPos[0]+(seq.dir[1]*parseInt(seq.scrollAmount)),
1318					to=seq.scrollAmount!=="auto" ? px : amount,
1319					easing=e ? e : !once ? "mcsLinear" : c ? "mcsLinearOut" : "mcsEaseInOut",
1320					onComplete=!once ? false : true;
1321				if(once && t<17){
1322					to=seq.dir[0]==="x" ? contentPos[1] : contentPos[0];
1323				}
1324				_scrollTo(el,to.toString(),{dir:seq.dir[0],scrollEasing:easing,dur:t,onComplete:onComplete});
1325				if(once){
1326					seq.dir=false;
1327					return;
1328				}
1329				clearTimeout(seq.step);
1330				seq.step=setTimeout(function(){
1331					_on();
1332				},t);
1333			}
1334			/* stops sequence */
1335			function _off(){
1336				clearTimeout(seq.step);
1337				_delete(seq,"step");
1338				_stop(el);
1339			}
1340		},
1341		/* -------------------- */
1342		
1343		
1344		/* returns a yx array from value */
1345		_arr=function(val){
1346			var o=$(this).data(pluginPfx).opt,vals=[];
1347			if(typeof val==="function"){val=val();} /* check if the value is a single anonymous function */
1348			/* check if value is object or array, its length and create an array with yx values */
1349			if(!(val instanceof Array)){ /* object value (e.g. {y:"100",x:"100"}, 100 etc.) */
1350				vals[0]=val.y ? val.y : val.x || o.axis==="x" ? null : val;
1351				vals[1]=val.x ? val.x : val.y || o.axis==="y" ? null : val;
1352			}else{ /* array value (e.g. [100,100]) */
1353				vals=val.length>1 ? [val[0],val[1]] : o.axis==="x" ? [null,val[0]] : [val[0],null];
1354			}
1355			/* check if array values are anonymous functions */
1356			if(typeof vals[0]==="function"){vals[0]=vals[0]();}
1357			if(typeof vals[1]==="function"){vals[1]=vals[1]();}
1358			return vals;
1359		},
1360		/* -------------------- */
1361		
1362		
1363		/* translates values (e.g. "top", 100, "100px", "#id") to actual scroll-to positions */
1364		_to=function(val,dir){
1365			if(val==null || typeof val=="undefined"){return;}
1366			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
1367				mCSB_container=$("#mCSB_"+d.idx+"_container"),
1368				wrapper=mCSB_container.parent(),
1369				t=typeof val;
1370			if(!dir){dir=o.axis==="x" ? "x" : "y";}
1371			var contentLength=dir==="x" ? mCSB_container.outerWidth(false)-wrapper.width() : mCSB_container.outerHeight(false)-wrapper.height(),
1372				contentPos=dir==="x" ? mCSB_container[0].offsetLeft : mCSB_container[0].offsetTop,
1373				cssProp=dir==="x" ? "left" : "top";
1374			switch(t){
1375				case "function": /* this currently is not used. Consider removing it */
1376					return val();
1377					break;
1378				case "object": /* js/jquery object */
1379					var obj=val.jquery ? val : $(val);
1380					if(!obj.length){return;}
1381					return dir==="x" ? _childPos(obj)[1] : _childPos(obj)[0];
1382					break;
1383				case "string": case "number":
1384					if(_isNumeric(val)){ /* numeric value */
1385						return Math.abs(val);
1386					}else if(val.indexOf("%")!==-1){ /* percentage value */
1387						return Math.abs(contentLength*parseInt(val)/100);
1388					}else if(val.indexOf("-=")!==-1){ /* decrease value */
1389						return Math.abs(contentPos-parseInt(val.split("-=")[1]));
1390					}else if(val.indexOf("+=")!==-1){ /* inrease value */
1391						var p=(contentPos+parseInt(val.split("+=")[1]));
1392						return p>=0 ? 0 : Math.abs(p);
1393					}else if(val.indexOf("px")!==-1 && _isNumeric(val.split("px")[0])){ /* pixels string value (e.g. "100px") */
1394						return Math.abs(val.split("px")[0]);
1395					}else{
1396						if(val==="top" || val==="left"){ /* special strings */
1397							return 0;
1398						}else if(val==="bottom"){
1399							return Math.abs(wrapper.height()-mCSB_container.outerHeight(false));
1400						}else if(val==="right"){
1401							return Math.abs(wrapper.width()-mCSB_container.outerWidth(false));
1402						}else if(val==="first" || val==="last"){
1403							var obj=mCSB_container.find(":"+val);
1404							return dir==="x" ? _childPos(obj)[1] : _childPos(obj)[0];
1405						}else{
1406							if($(val).length){ /* jquery selector */
1407								return dir==="x" ? _childPos($(val))[1] : _childPos($(val))[0];
1408							}else{ /* other values (e.g. "100em") */
1409								mCSB_container.css(cssProp,val);
1410								methods.update.call(null,$this[0]);
1411								return;
1412							}
1413						}
1414					}
1415					break;
1416			}
1417		},
1418		/* -------------------- */
1419		
1420		
1421		/* calls the update method automatically */
1422		_autoUpdate=function(rem){
1423			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
1424				mCSB_container=$("#mCSB_"+d.idx+"_container");
1425			if(rem){
1426				/* 
1427				removes autoUpdate timer 
1428				usage: _autoUpdate.call(this,"remove");
1429				*/
1430				clearTimeout(mCSB_container[0].autoUpdate);
1431				_delete(mCSB_container[0],"autoUpdate");
1432				return;
1433			}
1434			upd();
1435			function upd(){
1436				clearTimeout(mCSB_container[0].autoUpdate);
1437				if($this.parents("html").length===0){
1438					/* check element in dom tree */
1439					$this=null;
1440					return;
1441				}
1442				mCSB_container[0].autoUpdate=setTimeout(function(){
1443					/* update on specific selector(s) length and size change */
1444					if(o.advanced.updateOnSelectorChange){
1445						d.poll.change.n=sizesSum();
1446						if(d.poll.change.n!==d.poll.change.o){
1447							d.poll.change.o=d.poll.change.n;
1448							doUpd(3);
1449							return;
1450						}
1451					}
1452					/* update on main element and scrollbar size changes */
1453					if(o.advanced.updateOnContentResize){
1454						d.poll.size.n=$this[0].scrollHeight+$this[0].scrollWidth+mCSB_container[0].offsetHeight+$this[0].offsetHeight+$this[0].offsetWidth;
1455						if(d.poll.size.n!==d.poll.size.o){
1456							d.poll.size.o=d.poll.size.n;
1457							doUpd(1);
1458							return;
1459						}
1460					}
1461					/* update on image load */
1462					if(o.advanced.updateOnImageLoad){
1463						if(!(o.advanced.updateOnImageLoad==="auto" && o.axis==="y")){ //by default, it doesn't run on vertical content
1464							d.poll.img.n=mCSB_container.find("img").length;
1465							if(d.poll.img.n!==d.poll.img.o){
1466								d.poll.img.o=d.poll.img.n;
1467								mCSB_container.find("img").each(function(){
1468									imgLoader(this);
1469								});
1470								return;
1471							}
1472
1473						}
1474					}
1475					if(o.advanced.updateOnSelectorChange || o.advanced.updateOnContentResize || o.advanced.updateOnImageLoad){upd();}
1476				},o.advanced.autoUpdateTimeout);
1477			}
1478			/* a tiny image loader */
1479			function imgLoader(el){
1480				if($(el).hasClass(classes[2])){doUpd(); return;}
1481				var img=new Image();
1482				function createDelegate(contextObject,delegateMethod){
1483					return function(){return delegateMethod.apply(contextObject,arguments);}
1484				}
1485				function imgOnLoad(){
1486					this.onload=null;
1487					$(el).addClass(classes[2]);
1488					doUpd(2);
1489				}
1490				img.onload=createDelegate(img,imgOnLoad);
1491				img.src=el.src;
1492			}
1493			/* returns the total height and width sum of all elements matching the selector */
1494			function sizesSum(){
1495				if(o.advanced.updateOnSelectorChange===true){o.advanced.updateOnSelectorChange="*";}
1496				var total=0,sel=mCSB_container.find(o.advanced.updateOnSelectorChange);
1497				if(o.advanced.updateOnSelectorChange && sel.length>0){sel.each(function(){total+=this.offsetHeight+this.offsetWidth;});}
1498				return total;
1499			}
1500			/* calls the update method */
1501			function doUpd(cb){
1502				clearTimeout(mCSB_container[0].autoUpdate);
1503				methods.update.call(null,$this[0],cb);
1504			}
1505		},
1506		/* -------------------- */
1507		
1508		
1509		/* snaps scrolling to a multiple of a pixels number */
1510		_snapAmount=function(to,amount,offset){
1511			return (Math.round(to/amount)*amount-offset); 
1512		},
1513		/* -------------------- */
1514		
1515		
1516		/* stops content and scrollbar animations */
1517		_stop=function(el){
1518			var d=el.data(pluginPfx),
1519				sel=$("#mCSB_"+d.idx+"_container,#mCSB_"+d.idx+"_container_wrapper,#mCSB_"+d.idx+"_dragger_vertical,#mCSB_"+d.idx+"_dragger_horizontal");
1520			sel.each(function(){
1521				_stopTween.call(this);
1522			});
1523		},
1524		/* -------------------- */
1525		
1526		
1527		/* 
1528		ANIMATES CONTENT 
1529		This is where the actual scrolling happens
1530		*/
1531		_scrollTo=function(el,to,options){
1532			var d=el.data(pluginPfx),o=d.opt,
1533				defaults={
1534					trigger:"internal",
1535					dir:"y",
1536					scrollEasing:"mcsEaseOut",
1537					drag:false,
1538					dur:o.scrollInertia,
1539					overwrite:"all",
1540					callbacks:true,
1541					onStart:true,
1542					onUpdate:true,
1543					onComplete:true
1544				},
1545				options=$.extend(defaults,options),
1546				dur=[options.dur,(options.drag ? 0 : options.dur)],
1547				mCustomScrollBox=$("#mCSB_"+d.idx),
1548				mCSB_container=$("#mCSB_"+d.idx+"_container"),
1549				wrapper=mCSB_container.parent(),
1550				totalScrollOffsets=o.callbacks.onTotalScrollOffset ? _arr.call(el,o.callbacks.onTotalScrollOffset) : [0,0],
1551				totalScrollBackOffsets=o.callbacks.onTotalScrollBackOffset ? _arr.call(el,o.callbacks.onTotalScrollBackOffset) : [0,0];
1552			d.trigger=options.trigger;
1553			if(wrapper.scrollTop()!==0 || wrapper.scrollLeft()!==0){ /* always reset scrollTop/Left */
1554				$(".mCSB_"+d.idx+"_scrollbar").css("visibility","visible");
1555				wrapper.scrollTop(0).scrollLeft(0);
1556			}
1557			if(to==="_resetY" && !d.contentReset.y){
1558				/* callbacks: onOverflowYNone */
1559				if(_cb("onOverflowYNone")){o.callbacks.onOverflowYNone.call(el[0]);}
1560				d.contentReset.y=1;
1561			}
1562			if(to==="_resetX" && !d.contentReset.x){
1563				/* callbacks: onOverflowXNone */
1564				if(_cb("onOverflowXNone")){o.callbacks.onOverflowXNone.call(el[0]);}
1565				d.contentReset.x=1;
1566			}
1567			if(to==="_resetY" || to==="_resetX"){return;}
1568			if((d.contentReset.y || !el[0].mcs) && d.overflowed[0]){
1569				/* callbacks: onOverflowY */
1570				if(_cb("onOverflowY")){o.callbacks.onOverflowY.call(el[0]);}
1571				d.contentReset.x=null;
1572			}
1573			if((d.contentReset.x || !el[0].mcs) && d.overflowed[1]){
1574				/* callbacks: onOverflowX */
1575				if(_cb("onOverflowX")){o.callbacks.onOverflowX.call(el[0]);}
1576				d.contentReset.x=null;
1577			}
1578			if(o.snapAmount){ /* scrolling snapping */
1579				var snapAmount=!(o.snapAmount instanceof Array) ? o.snapAmount : options.dir==="x" ? o.snapAmount[1] : o.snapAmount[0];
1580				to=_snapAmount(to,snapAmount,o.snapOffset);
1581			}
1582			switch(options.dir){
1583				case "x":
1584					var mCSB_dragger=$("#mCSB_"+d.idx+"_dragger_horizontal"),
1585						property="left",
1586						contentPos=mCSB_container[0].offsetLeft,
1587						limit=[
1588							mCustomScrollBox.width()-mCSB_container.outerWidth(false),
1589							mCSB_dragger.parent().width()-mCSB_dragger.width()
1590						],
1591						scrollTo=[to,to===0 ? 0 : (to/d.scrollRatio.x)],
1592						tso=totalScrollOffsets[1],
1593						tsbo=totalScrollBackOffsets[1],
1594						totalScrollOffset=tso>0 ? tso/d.scrollRatio.x : 0,
1595						totalScrollBackOffset=tsbo>0 ? tsbo/d.scrollRatio.x : 0;
1596					break;
1597				case "y":
1598					var mCSB_dragger=$("#mCSB_"+d.idx+"_dragger_vertical"),
1599						property="top",
1600						contentPos=mCSB_container[0].offsetTop,
1601						limit=[
1602							mCustomScrollBox.height()-mCSB_container.outerHeight(false),
1603							mCSB_dragger.parent().height()-mCSB_dragger.height()
1604						],
1605						scrollTo=[to,to===0 ? 0 : (to/d.scrollRatio.y)],
1606						tso=totalScrollOffsets[0],
1607						tsbo=totalScrollBackOffsets[0],
1608						totalScrollOffset=tso>0 ? tso/d.scrollRatio.y : 0,
1609						totalScrollBackOffset=tsbo>0 ? tsbo/d.scrollRatio.y : 0;
1610					break;
1611			}
1612			if(scrollTo[1]<0 || (scrollTo[0]===0 && scrollTo[1]===0)){
1613				scrollTo=[0,0];
1614			}else if(scrollTo[1]>=limit[1]){
1615				scrollTo=[limit[0],limit[1]];
1616			}else{
1617				scrollTo[0]=-scrollTo[0];
1618			}
1619			if(!el[0].mcs){
1620				_mcs();  /* init mcs object (once) to make it available before callbacks */
1621				if(_cb("onInit")){o.callbacks.onInit.call(el[0]);} /* callbacks: onInit */
1622			}
1623			clearTimeout(mCSB_container[0].onCompleteTimeout);
1624			_tweenTo(mCSB_dragger[0],property,Math.round(scrollTo[1]),dur[1],options.scrollEasing);
1625			if(!d.tweenRunning && ((contentPos===0 && scrollTo[0]>=0) || (contentPos===limit[0] && scrollTo[0]<=limit[0]))){return;}
1626			_tweenTo(mCSB_container[0],property,Math.round(scrollTo[0]),dur[0],options.scrollEasing,options.overwrite,{
1627				onStart:function(){
1628					if(options.callbacks && options.onStart && !d.tweenRunning){
1629						/* callbacks: onScrollStart */
1630						if(_cb("onScrollStart")){_mcs(); o.callbacks.onScrollStart.call(el[0]);}
1631						d.tweenRunning=true;
1632						_onDragClasses(mCSB_dragger);
1633						d.cbOffsets=_cbOffsets();
1634					}
1635				},onUpdate:function(){
1636					if(options.callbacks && options.onUpdate){
1637						/* callbacks: whileScrolling */
1638						if(_cb("whileScrolling")){_mcs(); o.callbacks.whileScrolling.call(el[0]);}
1639					}
1640				},onComplete:function(){
1641					if(options.callbacks && options.onComplete){
1642						if(o.axis==="yx"){clearTimeout(mCSB_container[0].onCompleteTimeout);}
1643						var t=mCSB_container[0].idleTimer || 0;
1644						mCSB_container[0].onCompleteTimeout=setTimeout(function(){
1645							/* callbacks: onScroll, onTotalScroll, onTotalScrollBack */
1646							if(_cb("onScroll")){_mcs(); o.callbacks.onScroll.call(el[0]);}
1647							if(_cb("onTotalScroll") && scrollTo[1]>=limit[1]-totalScrollOffset && d.cbOffsets[0]){_mcs(); o.callbacks.onTotalScroll.call(el[0]);}
1648							if(_cb("onTotalScrollBack") && scrollTo[1]<=totalScrollBackOffset && d.cbOffsets[1]){_mcs(); o.callbacks.onTotalScrollBack.call(el[0]);}
1649							d.tweenRunning=false;
1650							mCSB_container[0].idleTimer=0;
1651							_onDragClasses(mCSB_dragger,"hide");
1652						},t);
1653					}
1654				}
1655			});
1656			/* checks if callback function exists */
1657			function _cb(cb){
1658				return d && o.callbacks[cb] && typeof o.callbacks[cb]==="function";
1659			}
1660			/* checks whether callback offsets always trigger */
1661			function _cbOffsets(){
1662				return [o.callbacks.alwaysTriggerOffsets || contentPos>=limit[0]+tso,o.callbacks.alwaysTriggerOffsets || contentPos<=-tsbo];
1663			}
1664			/* 
1665			populates object with useful values for the user 
1666			values: 
1667				content: this.mcs.content
1668				content top position: this.mcs.top 
1669				content left position: this.mcs.left 
1670				dragger top position: this.mcs.draggerTop 
1671				dragger left position: this.mcs.draggerLeft 
1672				scrolling y percentage: this.mcs.topPct 
1673				scrolling x percentage: this.mcs.leftPct 
1674				scrolling direction: this.mcs.direction
1675			*/
1676			function _mcs(){
1677				var cp=[mCSB_container[0].offsetTop,mCSB_container[0].offsetLeft], /* content position */
1678					dp=[mCSB_dragger[0].offsetTop,mCSB_dragger[0].offsetLeft], /* dragger position */
1679					cl=[mCSB_container.outerHeight(false),mCSB_container.outerWidth(false)], /* content length */
1680					pl=[mCustomScrollBox.height(),mCustomScrollBox.width()]; /* content parent length */
1681				el[0].mcs={
1682					content:mCSB_container, /* original content wrapper as jquery object */
1683					top:cp[0],left:cp[1],draggerTop:dp[0],draggerLeft:dp[1],
1684					topPct:Math.round((100*Math.abs(cp[0]))/(Math.abs(cl[0])-pl[0])),leftPct:Math.round((100*Math.abs(cp[1]))/(Math.abs(cl[1])-pl[1])),
1685					direction:options.dir
1686				};
1687				/* 
1688				this refers to the original element containing the scrollbar(s)
1689				usage: this.mcs.top, this.mcs.leftPct etc. 
1690				*/
1691			}
1692		},
1693		/* -------------------- */
1694		
vendor: 1,892 bytes, lines 1694-1765
1694/* CUSTOM JAVASCRIPT ANIMATION TWEEN 
1695		Lighter and faster than jquery animate() and css transitions 
1696		Animates top/left properties and includes easings */
1697		/* returns current time */
1698		_getTime=function(){
1699			if(window.performance && window.performance.now){
1700				return window.performance.now();
1701			}else{
1702				if(window.performance && window.performance.webkitNow){
1703					return window.performance.webkitNow();
1704				}else{
1705					if(Date.now){return Date.now();}else{return new Date().getTime();}
1706				}
1707			}
1708		},
1709		/* -------------------- */
1710		
1711		
1712		/* stops a tween */
1713		_stopTween=function(){
1714			var el=this;
1715			if(!el._mTween){el._mTween={top:{},left:{}};}
1716			var props=["top","left"];
1717			for(var i=0; i<props.length; i++){
1718				var prop=props[i];
1719				if(el._mTween[prop].id){
1720					if(!window.requestAnimationFrame){clearTimeout(el._mTween[prop].id);
1721					}else{window.cancelAnimationFrame(el._mTween[prop].id);}
1722					el._mTween[prop].id=null;
1723					el._mTween[prop].stop=1;
1724				}
1725			}
1726		},
1727		/* -------------------- */
1728		
1729		
1730		/* deletes a property (avoiding the exception thrown by IE) */
1731		_delete=function(c,m){
1732			try{delete c[m];}catch(e){c[m]=null;}
1733		},
1734		/* -------------------- */
1735		
1736		
1737		/* detects left mouse button */
1738		_mouseBtnLeft=function(e){
1739			return !(e.which && e.which!==1);
1740		},
1741		/* -------------------- */
1742		
1743		
1744		/* detects if pointer type event is touch */
1745		_pointerTouch=function(e){
1746			var t=e.originalEvent.pointerType;
1747			return !(t && t!=="touch" && t!==2);
1748		},
1749		/* -------------------- */
1750		
1751		
1752		/* checks if value is numeric */
1753		_isNumeric=function(val){
1754			return !isNaN(parseFloat(val)) && isFinite(val);
1755		},
1756		/* -------------------- */
1757		
1758		
1759		/* returns element position according to content */
1760		_childPos=function(el){
1761			var p=el.parents(".mCSB_container");
1762			return [el.offset().top-p.offset().top,el.offset().left-p.offset().left];
1763		}
1764
1765}))}
vendor: 3 bytes, line 1765
1765));

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.