PageSourceSearch

https://3x3hustle.com/wp-content/themes/the-league/js/scripts.js?ver=1790347248

js 3x3hustle.com collected 2026-09-25 14:56:44 UTC 122,138 bytes, 3,504 lines download raw bytes

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

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.