diff --git a/dist/vue-scroller.min.js b/dist/vue-scroller.min.js index c88ec83..7cff23a 100644 --- a/dist/vue-scroller.min.js +++ b/dist/vue-scroller.min.js @@ -2,7 +2,7 @@ * Vue Scroller * version: 2.2.4 * repo: https://github.com/wangdahoo/vue-scroller - * build: 2017-09-21 16:25:35 + * build: 2020-02-17 16:04:07 */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("VueScroller",[],e):"object"==typeof exports?exports.VueScroller=e():t.VueScroller=e()}(this,function(){return function(t){function e(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return t[o].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,o){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:o})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=4)}([function(t,e){t.exports=function(t,e,n,o){var i,r=t=t||{},a=typeof t.default;"object"!==a&&"function"!==a||(i=t,r=t.default);var l="function"==typeof r?r.options:r;if(e&&(l.render=e.render,l.staticRenderFns=e.staticRenderFns),n&&(l._scopeId=n),o){var s=Object.create(l.computed||null);Object.keys(o).forEach(function(t){var e=o[t];s[t]=function(){return e}}),l.computed=s}return{esModule:i,exports:r,options:l}}},function(t,e,n){n(14);var o=n(0)(n(3),n(13),"data-v-ecaca2b0",null);t.exports=o.exports},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={props:{fillColor:{type:String,default:"#AAA"}}}},function(t,e,n){"use strict";function o(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0});var i=n(5),r=o(i),a=n(6),l=o(a),s=n(10),c=o(s),_=n(9),u=o(_),f=/^[\d]+(\%)?$/,p=function(t){return"%"!=t[t.length-1]?t+"px":t},h=function(t){return f.test(t)};e.default={components:{Spinner:c.default,Arrow:u.default},props:{onRefresh:Function,onInfinite:Function,refreshText:{type:String,default:"下拉刷新"},noDataText:{type:String,default:"没有更多数据"},width:{type:String,default:"100%",validator:h},height:{type:String,default:"100%",validator:h},snapping:{type:Boolean,default:!1},snapWidth:{type:Number,default:100},snapHeight:{type:Number,default:100},animating:{type:Boolean,default:!0},animationDuration:{type:Number,default:250},bouncing:{type:Boolean,default:!0},refreshLayerColor:{type:String,default:"#AAA"},loadingLayerColor:{type:String,default:"#AAA"},cssClass:String,minContentHeight:{type:Number,default:0}},computed:{w:function(){return p(this.width)},h:function(){return p(this.height)},showInfiniteLayer:function(){var t=0;return this.content&&(t=this.content.offsetHeight),!!this.onInfinite&&t>this.minContentHeight}},data:function(){return{containerId:"outer-"+Math.random().toString(36).substring(3,8),contentId:"inner-"+Math.random().toString(36).substring(3,8),state:0,loadingState:0,showLoading:!1,container:void 0,content:void 0,scroller:void 0,pullToRefreshLayer:void 0,mousedown:!1,infiniteTimer:void 0,resizeTimer:void 0}},mounted:function(){var t=this;this.container=document.getElementById(this.containerId),this.container.style.width=this.w,this.container.style.height=this.h,this.content=document.getElementById(this.contentId),this.cssClass&&this.content.classList.add(this.cssClass),this.pullToRefreshLayer=this.content.getElementsByTagName("div")[0];var e=(0,l.default)(this.content);this.scroller=new r.default(e,{scrollingX:!1,snapping:this.snapping,animating:this.animating,animationDuration:this.animationDuration,bouncing:this.bouncing}),this.onRefresh&&this.scroller.activatePullToRefresh(60,function(){t.state=1},function(){t.state=0},function(){t.state=2,t.$on("$finishPullToRefresh",function(){setTimeout(function(){t.state=0,t.finishPullToRefresh()})}),t.onRefresh(t.finishPullToRefresh)}),this.onInfinite&&(this.infiniteTimer=setInterval(function(){var e=t.scroller.getValues(),n=(e.left,e.top);e.zoom;if(t.content.offsetHeight>0&&n+60>t.content.offsetHeight-t.container.clientHeight){if(t.loadingState)return;t.loadingState=1,t.showLoading=!0,t.onInfinite(t.finishInfinite)}},10));var n=this.container.getBoundingClientRect();this.scroller.setPosition(n.left+this.container.clientLeft,n.top+this.container.clientTop),this.snapping&&this.scroller.setSnapSize(this.snapWidth,this.snapHeight);var o=function(){return{width:t.content.offsetWidth,height:t.content.offsetHeight}},i=o(),a=i.content_width,s=i.content_height;this.resizeTimer=setInterval(function(){var e=o(),n=e.width,i=e.height;n===a&&i===s||(a=n,s=i,t.resize())},10)},destroyed:function(){clearInterval(this.resizeTimer),this.infiniteTimer&&clearInterval(this.infiniteTimer)},methods:{resize:function(){var t=this.container,e=this.content;this.scroller.setDimensions(t.clientWidth,t.clientHeight,e.offsetWidth,e.offsetHeight)},finishPullToRefresh:function(){this.scroller.finishPullToRefresh()},finishInfinite:function(t){this.loadingState=t?2:0,this.showLoading=!1,2==this.loadingState&&this.resetLoadingState()},triggerPullToRefresh:function(){this.scroller.triggerPullToRefresh()},scrollTo:function(t,e,n){this.scroller.scrollTo(t,e,n)},scrollBy:function(t,e,n){this.scroller.scrollBy(t,e,n)},touchStart:function(t){t.target.tagName.match(/input|textarea|select/i)||this.scroller.doTouchStart(t.touches,t.timeStamp)},touchMove:function(t){t.preventDefault(),this.scroller.doTouchMove(t.touches,t.timeStamp)},touchEnd:function(t){this.scroller.doTouchEnd(t.timeStamp)},mouseDown:function(t){t.target.tagName.match(/input|textarea|select/i)||(this.scroller.doTouchStart([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),this.mousedown=!0)},mouseMove:function(t){this.mousedown&&(this.scroller.doTouchMove([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),this.mousedown=!0)},mouseUp:function(t){this.mousedown&&(this.scroller.doTouchEnd(t.timeStamp),this.mousedown=!1)},getPosition:function(){var t=this.scroller.getValues();return{left:parseInt(t.left),top:parseInt(t.top)}},resetLoadingState:function(){var t=this,e=this.scroller.getValues(),n=(e.left,e.top);e.zoom,this.container,this.content;n+60>this.content.offsetHeight-this.container.clientHeight?setTimeout(function(){t.resetLoadingState()},1e3):this.loadingState=0}}}},function(t,e,n){"use strict";function o(t){o.installed||(o.installed=!0,t.component("scroller",a.default))}Object.defineProperty(e,"__esModule",{value:!0});var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r=n(1),a=function(t){return t&&t.__esModule?t:{default:t}}(r),l={install:o,Scroller:a.default};void 0!==("undefined"==typeof window?"undefined":i(window))&&window.Vue&&window.Vue.use(l),e.default=l},function(t,e,n){"use strict";var o;!function(i){var r=function(){},a=function(t){var e=Date.now||function(){return+new Date},n={},o=1,i={effect:{}};return i.effect.Animate={requestAnimationFrame:function(){var e=t.requestAnimationFrame||t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||t.oRequestAnimationFrame,n=!!e;if(e&&!/requestAnimationFrame\(\)\s*\{\s*\[native code\]\s*\}/i.test(e.toString())&&(n=!1),n)return function(t,n){e(t,n)};var o={},i=0,r=1,a=null,l=+new Date;return function(t,e){var n=r++;return o[n]=t,i++,null===a&&(a=setInterval(function(){var t=+new Date,e=o;o={},i=0;for(var n in e)e.hasOwnProperty(n)&&(e[n](t),l=t);t-l>2500&&(clearInterval(a),a=null)},1e3/60)),n}}(),stop:function(t){var e=null!=n[t];return e&&(n[t]=null),e},isRunning:function(t){return null!=n[t]},start:function(t,r,a,l,s,c){var _=e(),u=_,f=0,p=0,h=o++;if(c||(c=document.body),h%20==0){var d={};for(var m in n)d[m]=!0;n=d}var g=function o(d){var m=!0!==d,g=e();if(!n[h]||r&&!r(h))return n[h]=null,void(a&&a(60-p/((g-_)/1e3),h,!1));if(m)for(var v=Math.round((g-u)/(1e3/60))-1,y=0;y1&&(f=1);var T=s?s(f):f;!1!==t(T,g,m)&&1!==f||!m?m&&(u=g,i.effect.Animate.requestAnimationFrame(o,c)):(n[h]=null,a&&a(60-p/((g-_)/1e3),h,1===f||null==l))};return n[h]=!0,i.effect.Animate.requestAnimationFrame(g,c),h}},i}(i),l=function(t,e){this.__callback=t,this.options={scrollingX:!0,scrollingY:!0,animating:!0,animationDuration:250,bouncing:!0,locking:!0,paging:!1,snapping:!1,zooming:!1,minZoom:.5,maxZoom:3,speedMultiplier:1,scrollingComplete:r,penetrationDeceleration:.03,penetrationAcceleration:.08};for(var n in e)this.options[n]=e[n]},s=function(t){return Math.pow(t-1,3)+1},c=function(t){return(t/=.5)<1?.5*Math.pow(t,3):.5*(Math.pow(t-2,3)+2)},_={__isSingleTouch:!1,__isTracking:!1,__didDecelerationComplete:!1,__isGesturing:!1,__isDragging:!1,__isDecelerating:!1,__isAnimating:!1,__clientLeft:0,__clientTop:0,__clientWidth:0,__clientHeight:0,__contentWidth:0,__contentHeight:0,__snapWidth:100,__snapHeight:100,__refreshHeight:null,__refreshActive:!1,__refreshActivate:null,__refreshDeactivate:null,__refreshStart:null,__zoomLevel:1,__scrollLeft:0,__scrollTop:0,__maxScrollLeft:0,__maxScrollTop:0,__scheduledLeft:0,__scheduledTop:0,__scheduledZoom:0,__lastTouchLeft:null,__lastTouchTop:null,__lastTouchMove:null,__positions:null,__minDecelerationScrollLeft:null,__minDecelerationScrollTop:null,__maxDecelerationScrollLeft:null,__maxDecelerationScrollTop:null,__decelerationVelocityX:null,__decelerationVelocityY:null,setDimensions:function(t,e,n,o){var i=this;t===+t&&(i.__clientWidth=t),e===+e&&(i.__clientHeight=e),n===+n&&(i.__contentWidth=n),o===+o&&(i.__contentHeight=o),i.__computeScrollMax(),i.scrollTo(i.__scrollLeft,i.__scrollTop,!0)},setPosition:function(t,e){var n=this;n.__clientLeft=t||0,n.__clientTop=e||0},setSnapSize:function(t,e){var n=this;n.__snapWidth=t,n.__snapHeight=e},activatePullToRefresh:function(t,e,n,o){var i=this;i.__refreshHeight=t,i.__refreshActivate=e,i.__refreshDeactivate=n,i.__refreshStart=o},triggerPullToRefresh:function(){this.__publish(this.__scrollLeft,-this.__refreshHeight,this.__zoomLevel,!0),this.__refreshStart&&this.__refreshStart()},finishPullToRefresh:function(){var t=this;t.__refreshActive=!1,t.__refreshDeactivate&&t.__refreshDeactivate(),t.scrollTo(t.__scrollLeft,t.__scrollTop,!0)},getValues:function(){var t=this;return{left:t.__scrollLeft,top:t.__scrollTop,zoom:t.__zoomLevel}},getScrollMax:function(){var t=this;return{left:t.__maxScrollLeft,top:t.__maxScrollTop}},zoomTo:function(t,e,n,o,i){var r=this;if(!r.options.zooming)throw new Error("Zooming is not enabled!");i&&(r.__zoomComplete=i),r.__isDecelerating&&(a.effect.Animate.stop(r.__isDecelerating),r.__isDecelerating=!1);var l=r.__zoomLevel;null==n&&(n=r.__clientWidth/2),null==o&&(o=r.__clientHeight/2),t=Math.max(Math.min(t,r.options.maxZoom),r.options.minZoom),r.__computeScrollMax(t);var s=(n+r.__scrollLeft)*t/l-n,c=(o+r.__scrollTop)*t/l-o;s>r.__maxScrollLeft?s=r.__maxScrollLeft:s<0&&(s=0),c>r.__maxScrollTop?c=r.__maxScrollTop:c<0&&(c=0),r.__publish(s,c,t,e)},zoomBy:function(t,e,n,o,i){var r=this;r.zoomTo(r.__zoomLevel*t,e,n,o,i)},scrollTo:function(t,e,n,o){var i=this;if(i.__isDecelerating&&(a.effect.Animate.stop(i.__isDecelerating),i.__isDecelerating=!1),null!=o&&o!==i.__zoomLevel){if(!i.options.zooming)throw new Error("Zooming is not enabled!");t*=o,e*=o,i.__computeScrollMax(o)}else o=i.__zoomLevel;i.options.scrollingX?i.options.paging?t=Math.round(t/i.__clientWidth)*i.__clientWidth:i.options.snapping&&(t=Math.round(t/i.__snapWidth)*i.__snapWidth):t=i.__scrollLeft,i.options.scrollingY?i.options.paging?e=Math.round(e/i.__clientHeight)*i.__clientHeight:i.options.snapping&&(e=Math.round(e/i.__snapHeight)*i.__snapHeight):e=i.__scrollTop,t=Math.max(Math.min(i.__maxScrollLeft,t),0),e=Math.max(Math.min(i.__maxScrollTop,e),0),t===i.__scrollLeft&&e===i.__scrollTop&&(n=!1),i.__isTracking||i.__publish(t,e,o,n)},scrollBy:function(t,e,n){var o=this,i=o.__isAnimating?o.__scheduledLeft:o.__scrollLeft,r=o.__isAnimating?o.__scheduledTop:o.__scrollTop;o.scrollTo(i+(t||0),r+(e||0),n)},doMouseZoom:function(t,e,n,o){var i=this,r=t>0?.97:1.03;return i.zoomTo(i.__zoomLevel*r,!1,n-i.__clientLeft,o-i.__clientTop)},doTouchStart:function(t,e){if(null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var n=this;n.__interruptedAnimation=!0,n.__isDecelerating&&(a.effect.Animate.stop(n.__isDecelerating),n.__isDecelerating=!1,n.__interruptedAnimation=!0),n.__isAnimating&&(a.effect.Animate.stop(n.__isAnimating),n.__isAnimating=!1,n.__interruptedAnimation=!0);var o,i,r=1===t.length;r?(o=t[0].pageX,i=t[0].pageY):(o=Math.abs(t[0].pageX+t[1].pageX)/2,i=Math.abs(t[0].pageY+t[1].pageY)/2),n.__initialTouchLeft=o,n.__initialTouchTop=i,n.__zoomLevelStart=n.__zoomLevel,n.__lastTouchLeft=o,n.__lastTouchTop=i,n.__lastTouchMove=e,n.__lastScale=1,n.__enableScrollX=!r&&n.options.scrollingX,n.__enableScrollY=!r&&n.options.scrollingY,n.__isTracking=!0,n.__didDecelerationComplete=!1,n.__isDragging=!r,n.__isSingleTouch=r,n.__positions=[]},doTouchMove:function(t,e,n){if(null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var o=this;if(o.__isTracking){var i,r;2===t.length?(i=Math.abs(t[0].pageX+t[1].pageX)/2,r=Math.abs(t[0].pageY+t[1].pageY)/2):(i=t[0].pageX,r=t[0].pageY);var a=o.__positions;if(o.__isDragging){var l=i-o.__lastTouchLeft,s=r-o.__lastTouchTop,c=o.__scrollLeft,_=o.__scrollTop,u=o.__zoomLevel;if(null!=n&&o.options.zooming){var f=u;if(u=u/o.__lastScale*n,u=Math.max(Math.min(u,o.options.maxZoom),o.options.minZoom),f!==u){var p=i-o.__clientLeft,h=r-o.__clientTop;c=(p+c)*u/f-p,_=(h+_)*u/f-h,o.__computeScrollMax(u)}}if(o.__enableScrollX){c-=l*this.options.speedMultiplier;var d=o.__maxScrollLeft;(c>d||c<0)&&(o.options.bouncing?c+=l/2*this.options.speedMultiplier:c=c>d?d:0)}if(o.__enableScrollY){_-=s*this.options.speedMultiplier;var m=o.__maxScrollTop;(_>m||_<0)&&(o.options.bouncing?(_+=s/2*this.options.speedMultiplier,o.__enableScrollX||null==o.__refreshHeight||(!o.__refreshActive&&_<=-o.__refreshHeight?(o.__refreshActive=!0,o.__refreshActivate&&o.__refreshActivate()):o.__refreshActive&&_>-o.__refreshHeight&&(o.__refreshActive=!1,o.__refreshDeactivate&&o.__refreshDeactivate()))):_=_>m?m:0)}a.length>60&&a.splice(0,30),a.push(c,_,e),o.__publish(c,_,u)}else{var g=o.options.locking?3:0,v=Math.abs(i-o.__initialTouchLeft),y=Math.abs(r-o.__initialTouchTop);o.__enableScrollX=o.options.scrollingX&&v>=g,o.__enableScrollY=o.options.scrollingY&&y>=g,a.push(o.__scrollLeft,o.__scrollTop,e),o.__isDragging=(o.__enableScrollX||o.__enableScrollY)&&(v>=5||y>=5),o.__isDragging&&(o.__interruptedAnimation=!1)}o.__lastTouchLeft=i,o.__lastTouchTop=r,o.__lastTouchMove=e,o.__lastScale=n}},doTouchEnd:function(t){if(t instanceof Date&&(t=t.valueOf()),"number"!=typeof t)throw new Error("Invalid timestamp value: "+t);var e=this;if(e.__isTracking){if(e.__isTracking=!1,e.__isDragging)if(e.__isDragging=!1,e.__isSingleTouch&&e.options.animating&&t-e.__lastTouchMove<=100){for(var n=e.__positions,o=n.length-1,i=o,r=o;r>0&&n[r]>e.__lastTouchMove-100;r-=3)i=r;if(i!==o){var a=n[o]-n[i],l=e.__scrollLeft-n[i-2],s=e.__scrollTop-n[i-1];e.__decelerationVelocityX=l/a*(1e3/60),e.__decelerationVelocityY=s/a*(1e3/60);var c=e.options.paging||e.options.snapping?4:1;Math.abs(e.__decelerationVelocityX)>c||Math.abs(e.__decelerationVelocityY)>c?e.__refreshActive||e.__startDeceleration(t):e.options.scrollingComplete()}else e.options.scrollingComplete()}else t-e.__lastTouchMove>100&&e.options.scrollingComplete();e.__isDecelerating||(e.__refreshActive&&e.__refreshStart?(e.__publish(e.__scrollLeft,-e.__refreshHeight,e.__zoomLevel,!0),e.__refreshStart&&e.__refreshStart()):((e.__interruptedAnimation||e.__isDragging)&&e.options.scrollingComplete(),e.scrollTo(e.__scrollLeft,e.__scrollTop,!0,e.__zoomLevel),e.__refreshActive&&(e.__refreshActive=!1,e.__refreshDeactivate&&e.__refreshDeactivate()))),e.__positions.length=0}},__publish:function(t,e,n,o){var i=this,r=i.__isAnimating;if(r&&(a.effect.Animate.stop(r),i.__isAnimating=!1),o&&i.options.animating){i.__scheduledLeft=t,i.__scheduledTop=e,i.__scheduledZoom=n;var l=i.__scrollLeft,_=i.__scrollTop,u=i.__zoomLevel,f=t-l,p=e-_,h=n-u,d=function(t,e,n){n&&(i.__scrollLeft=l+f*t,i.__scrollTop=_+p*t,i.__zoomLevel=u+h*t,i.__callback&&i.__callback(i.__scrollLeft,i.__scrollTop,i.__zoomLevel))},m=function(t){return i.__isAnimating===t},g=function(t,e,n){e===i.__isAnimating&&(i.__isAnimating=!1),(i.__didDecelerationComplete||n)&&i.options.scrollingComplete(),i.options.zooming&&(i.__computeScrollMax(),i.__zoomComplete&&(i.__zoomComplete(),i.__zoomComplete=null))};i.__isAnimating=a.effect.Animate.start(d,m,g,i.options.animationDuration,r?s:c)}else i.__scheduledLeft=i.__scrollLeft=t,i.__scheduledTop=i.__scrollTop=e,i.__scheduledZoom=i.__zoomLevel=n,i.__callback&&i.__callback(t,e,n),i.options.zooming&&(i.__computeScrollMax(),i.__zoomComplete&&(i.__zoomComplete(),i.__zoomComplete=null))},__computeScrollMax:function(t){var e=this;null==t&&(t=e.__zoomLevel),e.__maxScrollLeft=Math.max(e.__contentWidth*t-e.__clientWidth,0),e.__maxScrollTop=Math.max(e.__contentHeight*t-e.__clientHeight,0)},__startDeceleration:function(t){var e=this;if(e.options.paging){var n=Math.max(Math.min(e.__scrollLeft,e.__maxScrollLeft),0),o=Math.max(Math.min(e.__scrollTop,e.__maxScrollTop),0),i=e.__clientWidth,r=e.__clientHeight;e.__minDecelerationScrollLeft=Math.floor(n/i)*i,e.__minDecelerationScrollTop=Math.floor(o/r)*r,e.__maxDecelerationScrollLeft=Math.ceil(n/i)*i,e.__maxDecelerationScrollTop=Math.ceil(o/r)*r}else e.__minDecelerationScrollLeft=0,e.__minDecelerationScrollTop=0,e.__maxDecelerationScrollLeft=e.__maxScrollLeft,e.__maxDecelerationScrollTop=e.__maxScrollTop;var l=function(t,n,o){e.__stepThroughDeceleration(o)},s=e.options.snapping?4:.001,c=function(){var t=Math.abs(e.__decelerationVelocityX)>=s||Math.abs(e.__decelerationVelocityY)>=s;return t||(e.__didDecelerationComplete=!0),t},_=function(t,n,o){e.__isDecelerating=!1,e.__didDecelerationComplete&&e.options.scrollingComplete(),e.scrollTo(e.__scrollLeft,e.__scrollTop,e.options.snapping)};e.__isDecelerating=a.effect.Animate.start(l,c,_)},__stepThroughDeceleration:function(t){var e=this,n=e.__scrollLeft+e.__decelerationVelocityX,o=e.__scrollTop+e.__decelerationVelocityY;if(!e.options.bouncing){var i=Math.max(Math.min(e.__maxDecelerationScrollLeft,n),e.__minDecelerationScrollLeft);i!==n&&(n=i,e.__decelerationVelocityX=0);var r=Math.max(Math.min(e.__maxDecelerationScrollTop,o),e.__minDecelerationScrollTop);r!==o&&(o=r,e.__decelerationVelocityY=0)}if(t?e.__publish(n,o,e.__zoomLevel):(e.__scrollLeft=n,e.__scrollTop=o),!e.options.paging){e.__decelerationVelocityX*=.95,e.__decelerationVelocityY*=.95}if(e.options.bouncing){var a=0,l=0,s=e.options.penetrationDeceleration,c=e.options.penetrationAcceleration;ne.__maxDecelerationScrollLeft&&(a=e.__maxDecelerationScrollLeft-n),oe.__maxDecelerationScrollTop&&(l=e.__maxDecelerationScrollTop-o),0!==a&&(a*e.__decelerationVelocityX<=0?e.__decelerationVelocityX+=a*s:e.__decelerationVelocityX=a*c),0!==l&&(l*e.__decelerationVelocityY<=0?e.__decelerationVelocityY+=l*s:e.__decelerationVelocityY=l*c)}}};for(var u in _)l.prototype[u]=_[u];void 0!==t&&t.exports?t.exports=l:void 0!==(o=function(){return l}.call(e,n,e,t))&&(t.exports=o)}(window)},function(t,e,n){"use strict";function o(t){var e,n=window,o=document.documentElement.style;n.opera&&"[object Opera]"===Object.prototype.toString.call(opera)?e="presto":"MozAppearance"in o?e="gecko":"WebkitAppearance"in o?e="webkit":"string"==typeof navigator.cpuClass&&(e="trident");var i={trident:"ms",gecko:"Moz",webkit:"Webkit",presto:"O"}[e],r=document.createElement("div"),a=i+"Perspective",l=i+"Transform";return void 0!==r.style[a]?function(e,n,o){t.style[l]="translate3d("+-e+"px,"+-n+"px,0) scale("+o+")"}:void 0!==r.style[l]?function(e,n,o){t.style[l]="translate("+-e+"px,"+-n+"px) scale("+o+")"}:function(e,n,o){t.style.marginLeft=e?-e/o+"px":"",t.style.marginTop=n?-n/o+"px":"",t.style.zoom=o||""}}t.exports=o},function(t,e,n){e=t.exports=n(8)(),e.push([t.i,"._v-container[data-v-ecaca2b0]{-webkit-tap-highlight-color:rgba(0,0,0,0);width:100%;height:100%;position:absolute;top:0;left:0;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}._v-container>._v-content[data-v-ecaca2b0]{width:100%;-webkit-transform-origin:left top;-webkit-transform:translateZ(0);-moz-transform-origin:left top;-moz-transform:translateZ(0);-ms-transform-origin:left top;-ms-transform:translateZ(0);-o-transform-origin:left top;-o-transform:translateZ(0);transform-origin:left top;transform:translateZ(0)}._v-container>._v-content>.pull-to-refresh-layer[data-v-ecaca2b0]{width:100%;height:60px;margin-top:-60px;text-align:center;font-size:16px;color:#aaa}._v-container>._v-content>.loading-layer[data-v-ecaca2b0]{width:100%;height:60px;text-align:center;font-size:16px;line-height:60px;color:#aaa;position:relative}._v-container>._v-content>.loading-layer>.no-data-text[data-v-ecaca2b0]{position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}._v-container>._v-content>.loading-layer>.no-data-text[data-v-ecaca2b0],._v-container>._v-content>.loading-layer>.spinner-holder[data-v-ecaca2b0]{opacity:0;transition:opacity .15s linear;-webkit-transition:opacity .15s linear}._v-container>._v-content>.loading-layer>.no-data-text.active[data-v-ecaca2b0],._v-container>._v-content>.loading-layer>.spinner-holder.active[data-v-ecaca2b0]{opacity:1}._v-container>._v-content>.loading-layer .spinner-holder[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder[data-v-ecaca2b0]{text-align:center;-webkit-font-smoothing:antialiased}._v-container>._v-content>.loading-layer .spinner-holder .arrow[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .arrow[data-v-ecaca2b0]{width:20px;height:20px;margin:8px auto 0;-webkit-transform:translateZ(0) rotate(0deg);transform:translateZ(0) rotate(0deg);transition:transform .2s linear}._v-container>._v-content>.loading-layer .spinner-holder .text[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .text[data-v-ecaca2b0]{display:block;margin:0 auto;font-size:14px;line-height:20px;color:#aaa}._v-container>._v-content>.loading-layer .spinner-holder .spinner[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .spinner[data-v-ecaca2b0]{margin-top:14px;width:32px;height:32px;fill:#444;stroke:#69717d}._v-container>._v-content>.pull-to-refresh-layer.active .spinner-holder .arrow[data-v-ecaca2b0]{-webkit-transform:translateZ(0) rotate(180deg);transform:translateZ(0) rotate(180deg)}",""])},function(t,e){t.exports=function(){var t=[];return t.toString=function(){for(var t=[],e=0;en.parts.length&&(o.parts.length=n.parts.length)}else{for(var a=[],i=0;ithis.minContentHeight}}},i(r,"data",function(){return{containerId:"outer-"+Math.random().toString(36).substring(3,8),contentId:"inner-"+Math.random().toString(36).substring(3,8),state:0,loadingState:0,showLoading:!1,container:void 0,content:void 0,scroller:void 0,pullToRefreshLayer:void 0,mousedown:!1,infiniteTimer:void 0,resizeTimer:void 0,mutationObserver:void 0}}),i(r,"mounted",function(){var t=this;this.container=document.getElementById(this.containerId),this.container.style.width=this.w,this.container.style.height=this.h,this.content=document.getElementById(this.contentId),this.cssClass&&this.content.classList.add(this.cssClass),this.pullToRefreshLayer=this.content.getElementsByTagName("div")[0];var e=(0,c.default)(this.content);this.scroller=new l.default(e,{scrollingX:!1,snapping:this.snapping,animating:this.animating,animationDuration:this.animationDuration,bouncing:this.bouncing}),this.contentWidth=this.content.offsetWidth,this.contentHeight=this.content.offsetHeight,this.onRefresh&&this.scroller.activatePullToRefresh(60,function(){t.state=1},function(){t.state=0},function(){t.state=2,t.$on("$finishPullToRefresh",function(){setTimeout(function(){t.state=0,t.finishPullToRefresh()})}),t.onRefresh(t.finishPullToRefresh)}),d?(this.onInfinite&&this.scroller.addEventListener("scrollTopChanged",function(e){t.scrollTop!==e&&(t.scrollTop=e,t.checkAndInfinite())}),this.mutationObserver=new d(function(){t.checkAndResize(),t.onInfinite&&t.checkAndInfinite()}),this.mutationObserver.observe(this.container,{attributes:!0,childList:!0,subtree:!0,attributeFilter:["style","class"]})):(this.resizeTimer=setInterval(this.checkAndResize,10),this.onInfinite&&(this.infiniteTimer=setInterval(this.checkAndInfinite,10)));var n=this.container.getBoundingClientRect();this.scroller.setPosition(n.left+this.container.clientLeft,n.top+this.container.clientTop),this.snapping&&this.scroller.setSnapSize(this.snapWidth,this.snapHeight)}),i(r,"destroyed",function(){this.resizeTimer&&clearInterval(this.resizeTimer),this.infiniteTimer&&clearInterval(this.infiniteTimer),this.mutationObserver&&this.mutationObserver.disconnect()}),i(r,"methods",{resize:function(){var t=this.container,e=this.content;this.scroller.setDimensions(t.clientWidth,t.clientHeight,e.offsetWidth,e.offsetHeight)},checkAndResize:function(){var t=this.content.offsetWidth,e=this.content.offsetHeight;t===this.contentWidth&&e===this.contentHeight||(this.contentWidth=t,this.contentHeight=e,this.resize())},checkAndInfinite:function(){this.loadingState||this.contentHeight<=0||this.scrollTop+60<=this.contentHeight-this.container.clientHeight||(this.loadingState=1,this.showLoading=!0,this.onInfinite(this.finishInfinite))},finishPullToRefresh:function(){this.scroller.finishPullToRefresh()},finishInfinite:function(t){this.loadingState=t?2:0,this.showLoading=!1,2==this.loadingState&&this.resetLoadingState()},triggerPullToRefresh:function(){this.scroller.triggerPullToRefresh()},scrollTo:function(t,e,n){this.scroller.scrollTo(t,e,n)},scrollBy:function(t,e,n){this.scroller.scrollBy(t,e,n)},touchStart:function(t){t.target.tagName.match(/input|textarea|select/i)||this.scroller.doTouchStart(t.touches,t.timeStamp)},touchMove:function(t){t.preventDefault(),this.scroller.doTouchMove(t.touches,t.timeStamp)},touchEnd:function(t){this.scroller.doTouchEnd(t.timeStamp)},mouseDown:function(t){t.target.tagName.match(/input|textarea|select/i)||(this.scroller.doTouchStart([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),this.mousedown=!0)},mouseMove:function(t){this.mousedown&&(this.scroller.doTouchMove([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),this.mousedown=!0)},mouseUp:function(t){this.mousedown&&(this.scroller.doTouchEnd(t.timeStamp),this.mousedown=!1)},getPosition:function(){var t=this.scroller.getValues();return{left:parseInt(t.left),top:parseInt(t.top)}},resetLoadingState:function(){var t=this,e=this.scroller.getValues(),n=(e.left,e.top);e.zoom,this.container,this.content;n+60>this.content.offsetHeight-this.container.clientHeight?setTimeout(function(){t.resetLoadingState()},1e3):this.loadingState=0}}),r)},function(t,e,n){"use strict";function o(t){o.installed||(o.installed=!0,t.component("scroller",a.default))}Object.defineProperty(e,"__esModule",{value:!0});var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r=n(1),a=function(t){return t&&t.__esModule?t:{default:t}}(r),l={install:o,Scroller:a.default};void 0!==("undefined"==typeof window?"undefined":i(window))&&window.Vue&&window.Vue.use(l),e.default=l},function(t,e,n){"use strict";var o;!function(i){var r=function(){},a=function(t){var e=Date.now||function(){return+new Date},n={},o=1,i={effect:{}};return i.effect.Animate={requestAnimationFrame:function(){var e=t.requestAnimationFrame||t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||t.oRequestAnimationFrame,n=!!e;if(e&&!/requestAnimationFrame\(\)\s*\{\s*\[native code\]\s*\}/i.test(e.toString())&&(n=!1),n)return function(t,n){e(t,n)};var o={},i=0,r=1,a=null,l=+new Date;return function(t,e){var n=r++;return o[n]=t,i++,null===a&&(a=setInterval(function(){var t=+new Date,e=o;o={},i=0;for(var n in e)e.hasOwnProperty(n)&&(e[n](t),l=t);t-l>2500&&(clearInterval(a),a=null)},1e3/60)),n}}(),stop:function(t){var e=null!=n[t];return e&&(n[t]=null),e},isRunning:function(t){return null!=n[t]},start:function(t,r,a,l,s,c){var _=e(),u=_,f=0,h=0,p=o++;if(c||(c=document.body),p%20==0){var d={};for(var m in n)d[m]=!0;n=d}var g=function o(d){var m=!0!==d,g=e();if(!n[p]||r&&!r(p))return n[p]=null,void(a&&a(60-h/((g-_)/1e3),p,!1));if(m)for(var v=Math.round((g-u)/(1e3/60))-1,y=0;y1&&(f=1);var b=s?s(f):f;!1!==t(b,g,m)&&1!==f||!m?m&&(u=g,i.effect.Animate.requestAnimationFrame(o,c)):(n[p]=null,a&&a(60-h/((g-_)/1e3),p,1===f||null==l))};return n[p]=!0,i.effect.Animate.requestAnimationFrame(g,c),p}},i}(i),l=function(t,e){this.__callback=t,this.options={scrollingX:!0,scrollingY:!0,animating:!0,animationDuration:250,bouncing:!0,locking:!0,paging:!1,snapping:!1,zooming:!1,minZoom:.5,maxZoom:3,speedMultiplier:1,scrollingComplete:r,penetrationDeceleration:.03,penetrationAcceleration:.08};for(var n in e)this.options[n]=e[n]},s=function(t){return Math.pow(t-1,3)+1},c=function(t){return(t/=.5)<1?.5*Math.pow(t,3):.5*(Math.pow(t-2,3)+2)},_={__isSingleTouch:!1,__isTracking:!1,__didDecelerationComplete:!1,__isGesturing:!1,__isDragging:!1,__isDecelerating:!1,__isAnimating:!1,__clientLeft:0,__clientTop:0,__clientWidth:0,__clientHeight:0,__contentWidth:0,__contentHeight:0,__snapWidth:100,__snapHeight:100,__refreshHeight:null,__refreshActive:!1,__refreshActivate:null,__refreshDeactivate:null,__refreshStart:null,__zoomLevel:1,__scrollLeft:0,__scrollTop:0,__maxScrollLeft:0,__maxScrollTop:0,__scheduledLeft:0,__scheduledTop:0,__scheduledZoom:0,__lastTouchLeft:null,__lastTouchTop:null,__lastTouchMove:null,__positions:null,__minDecelerationScrollLeft:null,__minDecelerationScrollTop:null,__maxDecelerationScrollLeft:null,__maxDecelerationScrollTop:null,__decelerationVelocityX:null,__decelerationVelocityY:null,setDimensions:function(t,e,n,o){var i=this;t===+t&&(i.__clientWidth=t),e===+e&&(i.__clientHeight=e),n===+n&&(i.__contentWidth=n),o===+o&&(i.__contentHeight=o),i.__computeScrollMax(),i.scrollTo(i.__scrollLeft,i.__scrollTop,!0)},setPosition:function(t,e){var n=this;n.__clientLeft=t||0,n.__clientTop=e||0},setSnapSize:function(t,e){var n=this;n.__snapWidth=t,n.__snapHeight=e},activatePullToRefresh:function(t,e,n,o){var i=this;i.__refreshHeight=t,i.__refreshActivate=e,i.__refreshDeactivate=n,i.__refreshStart=o},triggerPullToRefresh:function(){this.__publish(this.__scrollLeft,-this.__refreshHeight,this.__zoomLevel,!0),this.__refreshStart&&this.__refreshStart()},finishPullToRefresh:function(){var t=this;t.__refreshActive=!1,t.__refreshDeactivate&&t.__refreshDeactivate(),t.scrollTo(t.__scrollLeft,t.__scrollTop,!0)},getValues:function(){var t=this;return{left:t.__scrollLeft,top:t.__scrollTop,zoom:t.__zoomLevel}},getScrollMax:function(){var t=this;return{left:t.__maxScrollLeft,top:t.__maxScrollTop}},zoomTo:function(t,e,n,o,i){var r=this;if(!r.options.zooming)throw new Error("Zooming is not enabled!");i&&(r.__zoomComplete=i),r.__isDecelerating&&(a.effect.Animate.stop(r.__isDecelerating),r.__isDecelerating=!1);var l=r.__zoomLevel;null==n&&(n=r.__clientWidth/2),null==o&&(o=r.__clientHeight/2),t=Math.max(Math.min(t,r.options.maxZoom),r.options.minZoom),r.__computeScrollMax(t);var s=(n+r.__scrollLeft)*t/l-n,c=(o+r.__scrollTop)*t/l-o;s>r.__maxScrollLeft?s=r.__maxScrollLeft:s<0&&(s=0),c>r.__maxScrollTop?c=r.__maxScrollTop:c<0&&(c=0),r.__publish(s,c,t,e)},zoomBy:function(t,e,n,o,i){var r=this;r.zoomTo(r.__zoomLevel*t,e,n,o,i)},scrollTo:function(t,e,n,o){var i=this;if(i.__isDecelerating&&(a.effect.Animate.stop(i.__isDecelerating),i.__isDecelerating=!1),null!=o&&o!==i.__zoomLevel){if(!i.options.zooming)throw new Error("Zooming is not enabled!");t*=o,e*=o,i.__computeScrollMax(o)}else o=i.__zoomLevel;i.options.scrollingX?i.options.paging?t=Math.round(t/i.__clientWidth)*i.__clientWidth:i.options.snapping&&(t=Math.round(t/i.__snapWidth)*i.__snapWidth):t=i.__scrollLeft,i.options.scrollingY?i.options.paging?e=Math.round(e/i.__clientHeight)*i.__clientHeight:i.options.snapping&&(e=Math.round(e/i.__snapHeight)*i.__snapHeight):e=i.__scrollTop,t=Math.max(Math.min(i.__maxScrollLeft,t),0),e=Math.max(Math.min(i.__maxScrollTop,e),0),t===i.__scrollLeft&&e===i.__scrollTop&&(n=!1),i.__isTracking||i.__publish(t,e,o,n)},scrollBy:function(t,e,n){var o=this,i=o.__isAnimating?o.__scheduledLeft:o.__scrollLeft,r=o.__isAnimating?o.__scheduledTop:o.__scrollTop;o.scrollTo(i+(t||0),r+(e||0),n)},doMouseZoom:function(t,e,n,o){var i=this,r=t>0?.97:1.03;return i.zoomTo(i.__zoomLevel*r,!1,n-i.__clientLeft,o-i.__clientTop)},doTouchStart:function(t,e){if(null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var n=this;n.__interruptedAnimation=!0,n.__isDecelerating&&(a.effect.Animate.stop(n.__isDecelerating),n.__isDecelerating=!1,n.__interruptedAnimation=!0),n.__isAnimating&&(a.effect.Animate.stop(n.__isAnimating),n.__isAnimating=!1,n.__interruptedAnimation=!0);var o,i,r=1===t.length;r?(o=t[0].pageX,i=t[0].pageY):(o=Math.abs(t[0].pageX+t[1].pageX)/2,i=Math.abs(t[0].pageY+t[1].pageY)/2),n.__initialTouchLeft=o,n.__initialTouchTop=i,n.__zoomLevelStart=n.__zoomLevel,n.__lastTouchLeft=o,n.__lastTouchTop=i,n.__lastTouchMove=e,n.__lastScale=1,n.__enableScrollX=!r&&n.options.scrollingX,n.__enableScrollY=!r&&n.options.scrollingY,n.__isTracking=!0,n.__didDecelerationComplete=!1,n.__isDragging=!r,n.__isSingleTouch=r,n.__positions=[]},doTouchMove:function(t,e,n){if(null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var o=this;if(o.__isTracking){var i,r;2===t.length?(i=Math.abs(t[0].pageX+t[1].pageX)/2,r=Math.abs(t[0].pageY+t[1].pageY)/2):(i=t[0].pageX,r=t[0].pageY);var a=o.__positions;if(o.__isDragging){var l=i-o.__lastTouchLeft,s=r-o.__lastTouchTop,c=o.__scrollLeft,_=o.__scrollTop,u=o.__zoomLevel;if(null!=n&&o.options.zooming){var f=u;if(u=u/o.__lastScale*n,u=Math.max(Math.min(u,o.options.maxZoom),o.options.minZoom),f!==u){var h=i-o.__clientLeft,p=r-o.__clientTop;c=(h+c)*u/f-h,_=(p+_)*u/f-p,o.__computeScrollMax(u)}}if(o.__enableScrollX){c-=l*this.options.speedMultiplier;var d=o.__maxScrollLeft;(c>d||c<0)&&(o.options.bouncing?c+=l/2*this.options.speedMultiplier:c=c>d?d:0)}if(o.__enableScrollY){_-=s*this.options.speedMultiplier;var m=o.__maxScrollTop;(_>m||_<0)&&(o.options.bouncing?(_+=s/2*this.options.speedMultiplier,o.__enableScrollX||null==o.__refreshHeight||(!o.__refreshActive&&_<=-o.__refreshHeight?(o.__refreshActive=!0,o.__refreshActivate&&o.__refreshActivate()):o.__refreshActive&&_>-o.__refreshHeight&&(o.__refreshActive=!1,o.__refreshDeactivate&&o.__refreshDeactivate()))):_=_>m?m:0)}a.length>60&&a.splice(0,30),a.push(c,_,e),o.__publish(c,_,u)}else{var g=o.options.locking?3:0,v=Math.abs(i-o.__initialTouchLeft),y=Math.abs(r-o.__initialTouchTop);o.__enableScrollX=o.options.scrollingX&&v>=g,o.__enableScrollY=o.options.scrollingY&&y>=g,a.push(o.__scrollLeft,o.__scrollTop,e),o.__isDragging=(o.__enableScrollX||o.__enableScrollY)&&(v>=5||y>=5),o.__isDragging&&(o.__interruptedAnimation=!1)}o.__lastTouchLeft=i,o.__lastTouchTop=r,o.__lastTouchMove=e,o.__lastScale=n}},doTouchEnd:function(t){if(t instanceof Date&&(t=t.valueOf()),"number"!=typeof t)throw new Error("Invalid timestamp value: "+t);var e=this;if(e.__isTracking){if(e.__isTracking=!1,e.__isDragging)if(e.__isDragging=!1,e.__isSingleTouch&&e.options.animating&&t-e.__lastTouchMove<=100){for(var n=e.__positions,o=n.length-1,i=o,r=o;r>0&&n[r]>e.__lastTouchMove-100;r-=3)i=r;if(i!==o){var a=n[o]-n[i],l=e.__scrollLeft-n[i-2],s=e.__scrollTop-n[i-1];e.__decelerationVelocityX=l/a*(1e3/60),e.__decelerationVelocityY=s/a*(1e3/60);var c=e.options.paging||e.options.snapping?4:1;Math.abs(e.__decelerationVelocityX)>c||Math.abs(e.__decelerationVelocityY)>c?e.__refreshActive||e.__startDeceleration(t):e.options.scrollingComplete()}else e.options.scrollingComplete()}else t-e.__lastTouchMove>100&&e.options.scrollingComplete();e.__isDecelerating||(e.__refreshActive&&e.__refreshStart?(e.__publish(e.__scrollLeft,-e.__refreshHeight,e.__zoomLevel,!0),e.__refreshStart&&e.__refreshStart()):((e.__interruptedAnimation||e.__isDragging)&&e.options.scrollingComplete(),e.scrollTo(e.__scrollLeft,e.__scrollTop,!0,e.__zoomLevel),e.__refreshActive&&(e.__refreshActive=!1,e.__refreshDeactivate&&e.__refreshDeactivate()))),e.__positions.length=0}},__publish:function(t,e,n,o){var i=this,r=i.__isAnimating;if(r&&(a.effect.Animate.stop(r),i.__isAnimating=!1),o&&i.options.animating){i.__scheduledLeft=t,i.__scheduledTop=e,i.__scheduledZoom=n;var l=i.__scrollLeft,_=i.__scrollTop,u=i.__zoomLevel,f=t-l,h=e-_,p=n-u,d=function(t,e,n){n&&(i.__scrollLeft=l+f*t,i.__scrollTop=_+h*t,i.fireEvent("scrollTopChanged",i.__scrollTop),i.__zoomLevel=u+p*t,i.__callback&&i.__callback(i.__scrollLeft,i.__scrollTop,i.__zoomLevel))},m=function(t){return i.__isAnimating===t},g=function(t,e,n){e===i.__isAnimating&&(i.__isAnimating=!1),(i.__didDecelerationComplete||n)&&i.options.scrollingComplete(),i.options.zooming&&(i.__computeScrollMax(),i.__zoomComplete&&(i.__zoomComplete(),i.__zoomComplete=null))};i.__isAnimating=a.effect.Animate.start(d,m,g,i.options.animationDuration,r?s:c)}else i.__scheduledLeft=i.__scrollLeft=t,i.__scheduledTop=i.__scrollTop=e,i.fireEvent("scrollTopChanged",i.__scrollTop),i.__scheduledZoom=i.__zoomLevel=n,i.__callback&&i.__callback(t,e,n),i.options.zooming&&(i.__computeScrollMax(),i.__zoomComplete&&(i.__zoomComplete(),i.__zoomComplete=null))},__computeScrollMax:function(t){var e=this;null==t&&(t=e.__zoomLevel),e.__maxScrollLeft=Math.max(e.__contentWidth*t-e.__clientWidth,0),e.__maxScrollTop=Math.max(e.__contentHeight*t-e.__clientHeight,0)},__startDeceleration:function(t){var e=this;if(e.options.paging){var n=Math.max(Math.min(e.__scrollLeft,e.__maxScrollLeft),0),o=Math.max(Math.min(e.__scrollTop,e.__maxScrollTop),0),i=e.__clientWidth,r=e.__clientHeight;e.__minDecelerationScrollLeft=Math.floor(n/i)*i,e.__minDecelerationScrollTop=Math.floor(o/r)*r,e.__maxDecelerationScrollLeft=Math.ceil(n/i)*i,e.__maxDecelerationScrollTop=Math.ceil(o/r)*r}else e.__minDecelerationScrollLeft=0,e.__minDecelerationScrollTop=0,e.__maxDecelerationScrollLeft=e.__maxScrollLeft,e.__maxDecelerationScrollTop=e.__maxScrollTop;var l=function(t,n,o){e.__stepThroughDeceleration(o)},s=e.options.snapping?4:.001,c=function(){var t=Math.abs(e.__decelerationVelocityX)>=s||Math.abs(e.__decelerationVelocityY)>=s;return t||(e.__didDecelerationComplete=!0),t},_=function(t,n,o){e.__isDecelerating=!1,e.__didDecelerationComplete&&e.options.scrollingComplete(),e.scrollTo(e.__scrollLeft,e.__scrollTop,e.options.snapping)};e.__isDecelerating=a.effect.Animate.start(l,c,_)},__stepThroughDeceleration:function(t){var e=this,n=e.__scrollLeft+e.__decelerationVelocityX,o=e.__scrollTop+e.__decelerationVelocityY;if(!e.options.bouncing){var i=Math.max(Math.min(e.__maxDecelerationScrollLeft,n),e.__minDecelerationScrollLeft);i!==n&&(n=i,e.__decelerationVelocityX=0);var r=Math.max(Math.min(e.__maxDecelerationScrollTop,o),e.__minDecelerationScrollTop);r!==o&&(o=r,e.__decelerationVelocityY=0)}if(t?e.__publish(n,o,e.__zoomLevel):(e.__scrollLeft=n,e.__scrollTop=o,e.fireEvent("scrollTopChanged",e.__scrollTop)),!e.options.paging){e.__decelerationVelocityX*=.95,e.__decelerationVelocityY*=.95}if(e.options.bouncing){var a=0,l=0,s=e.options.penetrationDeceleration,c=e.options.penetrationAcceleration;ne.__maxDecelerationScrollLeft&&(a=e.__maxDecelerationScrollLeft-n),oe.__maxDecelerationScrollTop&&(l=e.__maxDecelerationScrollTop-o),0!==a&&(a*e.__decelerationVelocityX<=0?e.__decelerationVelocityX+=a*s:e.__decelerationVelocityX=a*c),0!==l&&(l*e.__decelerationVelocityY<=0?e.__decelerationVelocityY+=l*s:e.__decelerationVelocityY=l*c)}},eventMap:new Map,addEventListener:function(t,e){var n=this.eventMap.get(t);n||(n=[],this.eventMap.set(t,n)),n.push(e)},fireEvent:function(t,e){var n=this.eventMap.get(t);n&&n.forEach(function(t){t(e)})}};for(var u in _)l.prototype[u]=_[u];void 0!==t&&t.exports?t.exports=l:void 0!==(o=function(){return l}.call(e,n,e,t))&&(t.exports=o)}(window)},function(t,e,n){"use strict";function o(t){var e,n=window,o=document.documentElement.style;n.opera&&"[object Opera]"===Object.prototype.toString.call(opera)?e="presto":"MozAppearance"in o?e="gecko":"WebkitAppearance"in o?e="webkit":"string"==typeof navigator.cpuClass&&(e="trident");var i={trident:"ms",gecko:"Moz",webkit:"Webkit",presto:"O"}[e],r=document.createElement("div"),a=i+"Perspective",l=i+"Transform";return void 0!==r.style[a]?function(e,n,o){t.style[l]="translate3d("+-e+"px,"+-n+"px,0) scale("+o+")"}:void 0!==r.style[l]?function(e,n,o){t.style[l]="translate("+-e+"px,"+-n+"px) scale("+o+")"}:function(e,n,o){t.style.marginLeft=e?-e/o+"px":"",t.style.marginTop=n?-n/o+"px":"",t.style.zoom=o||""}}t.exports=o},function(t,e,n){e=t.exports=n(8)(),e.push([t.i,"._v-container[data-v-ecaca2b0]{-webkit-tap-highlight-color:rgba(0,0,0,0);width:100%;height:100%;position:absolute;top:0;left:0;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}._v-container>._v-content[data-v-ecaca2b0]{width:100%;-webkit-transform-origin:left top;-webkit-transform:translateZ(0);-moz-transform-origin:left top;-moz-transform:translateZ(0);-ms-transform-origin:left top;-ms-transform:translateZ(0);-o-transform-origin:left top;-o-transform:translateZ(0);transform-origin:left top;transform:translateZ(0)}._v-container>._v-content>.pull-to-refresh-layer[data-v-ecaca2b0]{width:100%;height:60px;margin-top:-60px;text-align:center;font-size:16px;color:#aaa}._v-container>._v-content>.loading-layer[data-v-ecaca2b0]{width:100%;height:60px;text-align:center;font-size:16px;line-height:60px;color:#aaa;position:relative}._v-container>._v-content>.loading-layer>.no-data-text[data-v-ecaca2b0]{position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}._v-container>._v-content>.loading-layer>.no-data-text[data-v-ecaca2b0],._v-container>._v-content>.loading-layer>.spinner-holder[data-v-ecaca2b0]{opacity:0;transition:opacity .15s linear;-webkit-transition:opacity .15s linear}._v-container>._v-content>.loading-layer>.no-data-text.active[data-v-ecaca2b0],._v-container>._v-content>.loading-layer>.spinner-holder.active[data-v-ecaca2b0]{opacity:1}._v-container>._v-content>.loading-layer .spinner-holder[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder[data-v-ecaca2b0]{text-align:center;-webkit-font-smoothing:antialiased}._v-container>._v-content>.loading-layer .spinner-holder .arrow[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .arrow[data-v-ecaca2b0]{width:20px;height:20px;margin:8px auto 0;-webkit-transform:translateZ(0) rotate(0deg);transform:translateZ(0) rotate(0deg);transition:transform .2s linear}._v-container>._v-content>.loading-layer .spinner-holder .text[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .text[data-v-ecaca2b0]{display:block;margin:0 auto;font-size:14px;line-height:20px;color:#aaa}._v-container>._v-content>.loading-layer .spinner-holder .spinner[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .spinner[data-v-ecaca2b0]{margin-top:14px;width:32px;height:32px;fill:#444;stroke:#69717d}._v-container>._v-content>.pull-to-refresh-layer.active .spinner-holder .arrow[data-v-ecaca2b0]{-webkit-transform:translateZ(0) rotate(180deg);transform:translateZ(0) rotate(180deg)}",""])},function(t,e){t.exports=function(){var t=[];return t.toString=function(){for(var t=[],e=0;en.parts.length&&(o.parts.length=n.parts.length)}else{for(var a=[],i=0;i this.minContentHeight : false;\n }\n },\n\n data: function data() {\n return {\n containerId: 'outer-' + Math.random().toString(36).substring(3, 8),\n contentId: 'inner-' + Math.random().toString(36).substring(3, 8),\n state: 0, // 0: pull to refresh, 1: release to refresh, 2: refreshing\n loadingState: 0, // 0: stop, 1: loading, 2: stopping loading\n\n showLoading: false,\n\n container: undefined,\n content: undefined,\n scroller: undefined,\n pullToRefreshLayer: undefined,\n mousedown: false,\n infiniteTimer: undefined,\n resizeTimer: undefined\n };\n },\n mounted: function mounted() {\n var _this = this;\n\n this.container = document.getElementById(this.containerId);\n this.container.style.width = this.w;\n this.container.style.height = this.h;\n\n this.content = document.getElementById(this.contentId);\n if (this.cssClass) this.content.classList.add(this.cssClass);\n this.pullToRefreshLayer = this.content.getElementsByTagName(\"div\")[0];\n\n var render = (0, _render2.default)(this.content);\n\n var scrollerOptions = {\n scrollingX: false\n };\n\n this.scroller = new _core2.default(render, {\n scrollingX: false,\n snapping: this.snapping,\n animating: this.animating,\n animationDuration: this.animationDuration,\n bouncing: this.bouncing\n });\n\n // enable PullToRefresh\n if (this.onRefresh) {\n this.scroller.activatePullToRefresh(60, function () {\n _this.state = 1;\n }, function () {\n _this.state = 0;\n }, function () {\n _this.state = 2;\n\n _this.$on('$finishPullToRefresh', function () {\n setTimeout(function () {\n _this.state = 0;\n _this.finishPullToRefresh();\n });\n });\n\n _this.onRefresh(_this.finishPullToRefresh);\n });\n }\n\n // enable infinite loading\n if (this.onInfinite) {\n this.infiniteTimer = setInterval(function () {\n var _scroller$getValues = _this.scroller.getValues(),\n left = _scroller$getValues.left,\n top = _scroller$getValues.top,\n zoom = _scroller$getValues.zoom;\n\n // 在 keep alive 中 deactivated 的组件长宽变为 0 \n\n\n if (_this.content.offsetHeight > 0 && top + 60 > _this.content.offsetHeight - _this.container.clientHeight) {\n if (_this.loadingState) return;\n _this.loadingState = 1;\n _this.showLoading = true;\n _this.onInfinite(_this.finishInfinite);\n }\n }, 10);\n }\n\n // setup scroller\n var rect = this.container.getBoundingClientRect();\n this.scroller.setPosition(rect.left + this.container.clientLeft, rect.top + this.container.clientTop);\n\n // snapping\n if (this.snapping) {\n // console.log(this.snapWidth, this.snapHeight)\n this.scroller.setSnapSize(this.snapWidth, this.snapHeight);\n }\n\n // onContentResize\n var contentSize = function contentSize() {\n return {\n width: _this.content.offsetWidth,\n height: _this.content.offsetHeight\n };\n };\n\n var _contentSize = contentSize(),\n content_width = _contentSize.content_width,\n content_height = _contentSize.content_height;\n\n this.resizeTimer = setInterval(function () {\n var _contentSize2 = contentSize(),\n width = _contentSize2.width,\n height = _contentSize2.height;\n\n if (width !== content_width || height !== content_height) {\n content_width = width;\n content_height = height;\n _this.resize();\n }\n }, 10);\n },\n destroyed: function destroyed() {\n clearInterval(this.resizeTimer);\n if (this.infiniteTimer) clearInterval(this.infiniteTimer);\n },\n\n\n methods: {\n resize: function resize() {\n var container = this.container;\n var content = this.content;\n this.scroller.setDimensions(container.clientWidth, container.clientHeight, content.offsetWidth, content.offsetHeight);\n },\n finishPullToRefresh: function finishPullToRefresh() {\n this.scroller.finishPullToRefresh();\n },\n finishInfinite: function finishInfinite(hideSpinner) {\n this.loadingState = hideSpinner ? 2 : 0;\n this.showLoading = false;\n\n if (this.loadingState == 2) {\n this.resetLoadingState();\n }\n },\n triggerPullToRefresh: function triggerPullToRefresh() {\n this.scroller.triggerPullToRefresh();\n },\n scrollTo: function scrollTo(x, y, animate) {\n this.scroller.scrollTo(x, y, animate);\n },\n scrollBy: function scrollBy(x, y, animate) {\n this.scroller.scrollBy(x, y, animate);\n },\n touchStart: function touchStart(e) {\n // Don't react if initial down happens on a form element\n if (e.target.tagName.match(/input|textarea|select/i)) {\n return;\n }\n this.scroller.doTouchStart(e.touches, e.timeStamp);\n },\n touchMove: function touchMove(e) {\n e.preventDefault();\n this.scroller.doTouchMove(e.touches, e.timeStamp);\n },\n touchEnd: function touchEnd(e) {\n this.scroller.doTouchEnd(e.timeStamp);\n },\n mouseDown: function mouseDown(e) {\n // Don't react if initial down happens on a form element\n if (e.target.tagName.match(/input|textarea|select/i)) {\n return;\n }\n this.scroller.doTouchStart([{\n pageX: e.pageX,\n pageY: e.pageY\n }], e.timeStamp);\n this.mousedown = true;\n },\n mouseMove: function mouseMove(e) {\n if (!this.mousedown) {\n return;\n }\n this.scroller.doTouchMove([{\n pageX: e.pageX,\n pageY: e.pageY\n }], e.timeStamp);\n this.mousedown = true;\n },\n mouseUp: function mouseUp(e) {\n if (!this.mousedown) {\n return;\n }\n this.scroller.doTouchEnd(e.timeStamp);\n this.mousedown = false;\n },\n\n\n // 获取位置\n getPosition: function getPosition() {\n var v = this.scroller.getValues();\n\n return {\n left: parseInt(v.left),\n top: parseInt(v.top)\n };\n },\n resetLoadingState: function resetLoadingState() {\n var _this2 = this;\n\n var _scroller$getValues2 = this.scroller.getValues(),\n left = _scroller$getValues2.left,\n top = _scroller$getValues2.top,\n zoom = _scroller$getValues2.zoom;\n\n var container = this.container;\n var content = this.content;\n\n if (top + 60 > this.content.offsetHeight - this.container.clientHeight) {\n setTimeout(function () {\n _this2.resetLoadingState();\n }, 1000);\n } else {\n this.loadingState = 0;\n }\n }\n }\n};\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _Scroller = __webpack_require__(1);\n\nvar _Scroller2 = _interopRequireDefault(_Scroller);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction install(Vue) {\n if (install.installed) return;\n install.installed = true;\n Vue.component('scroller', _Scroller2.default);\n}\n\nvar VueScroller = {\n install: install,\n Scroller: _Scroller2.default\n};\n\nif ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) !== undefined && window.Vue) {\n window.Vue.use(VueScroller);\n}\n\nexports.default = VueScroller;\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\nvar __WEBPACK_AMD_DEFINE_RESULT__;\n\n(function (window) {\n\tvar NOOP = function NOOP() {};\n\n\tvar core = function Animate(global) {\n\n\t\tvar time = Date.now || function () {\n\t\t\treturn +new Date();\n\t\t};\n\n\t\tvar desiredFrames = 60;\n\t\tvar millisecondsPerSecond = 1000;\n\t\tvar running = {};\n\t\tvar counter = 1;\n\n\t\tvar core = { effect: {} };\n\n\t\tcore.effect.Animate = {\n\n\t\t\t/**\n * A requestAnimationFrame wrapper / polyfill.\n *\n * @param callback {Function} The callback to be invoked before the next repaint.\n * @param root {HTMLElement} The root element for the repaint\n */\n\t\t\trequestAnimationFrame: function () {\n\n\t\t\t\t// Check for request animation Frame support\n\t\t\t\tvar requestFrame = global.requestAnimationFrame || global.webkitRequestAnimationFrame || global.mozRequestAnimationFrame || global.oRequestAnimationFrame;\n\t\t\t\tvar isNative = !!requestFrame;\n\n\t\t\t\tif (requestFrame && !/requestAnimationFrame\\(\\)\\s*\\{\\s*\\[native code\\]\\s*\\}/i.test(requestFrame.toString())) {\n\t\t\t\t\tisNative = false;\n\t\t\t\t}\n\n\t\t\t\tif (isNative) {\n\t\t\t\t\treturn function (callback, root) {\n\t\t\t\t\t\trequestFrame(callback, root);\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tvar TARGET_FPS = 60;\n\t\t\t\tvar requests = {};\n\t\t\t\tvar requestCount = 0;\n\t\t\t\tvar rafHandle = 1;\n\t\t\t\tvar intervalHandle = null;\n\t\t\t\tvar lastActive = +new Date();\n\n\t\t\t\treturn function (callback, root) {\n\t\t\t\t\tvar callbackHandle = rafHandle++;\n\n\t\t\t\t\t// Store callback\n\t\t\t\t\trequests[callbackHandle] = callback;\n\t\t\t\t\trequestCount++;\n\n\t\t\t\t\t// Create timeout at first request\n\t\t\t\t\tif (intervalHandle === null) {\n\n\t\t\t\t\t\tintervalHandle = setInterval(function () {\n\n\t\t\t\t\t\t\tvar time = +new Date();\n\t\t\t\t\t\t\tvar currentRequests = requests;\n\n\t\t\t\t\t\t\t// Reset data structure before executing callbacks\n\t\t\t\t\t\t\trequests = {};\n\t\t\t\t\t\t\trequestCount = 0;\n\n\t\t\t\t\t\t\tfor (var key in currentRequests) {\n\t\t\t\t\t\t\t\tif (currentRequests.hasOwnProperty(key)) {\n\t\t\t\t\t\t\t\t\tcurrentRequests[key](time);\n\t\t\t\t\t\t\t\t\tlastActive = time;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Disable the timeout when nothing happens for a certain\n\t\t\t\t\t\t\t// period of time\n\t\t\t\t\t\t\tif (time - lastActive > 2500) {\n\t\t\t\t\t\t\t\tclearInterval(intervalHandle);\n\t\t\t\t\t\t\t\tintervalHandle = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 1000 / TARGET_FPS);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn callbackHandle;\n\t\t\t\t};\n\t\t\t}(),\n\n\t\t\t/**\n * Stops the given animation.\n *\n * @param id {Integer} Unique animation ID\n * @return {Boolean} Whether the animation was stopped (aka, was running before)\n */\n\t\t\tstop: function stop(id) {\n\t\t\t\tvar cleared = running[id] != null;\n\t\t\t\tif (cleared) {\n\t\t\t\t\trunning[id] = null;\n\t\t\t\t}\n\n\t\t\t\treturn cleared;\n\t\t\t},\n\n\t\t\t/**\n * Whether the given animation is still running.\n *\n * @param id {Integer} Unique animation ID\n * @return {Boolean} Whether the animation is still running\n */\n\t\t\tisRunning: function isRunning(id) {\n\t\t\t\treturn running[id] != null;\n\t\t\t},\n\n\t\t\t/**\n * Start the animation.\n *\n * @param stepCallback {Function} Pointer to function which is executed on every step.\n * Signature of the method should be `function(percent, now, virtual) { return continueWithAnimation; }`\n * @param verifyCallback {Function} Executed before every animation step.\n * Signature of the method should be `function() { return continueWithAnimation; }`\n * @param completedCallback {Function}\n * Signature of the method should be `function(droppedFrames, finishedAnimation) {}`\n * @param duration {Integer} Milliseconds to run the animation\n * @param easingMethod {Function} Pointer to easing function\n * Signature of the method should be `function(percent) { return modifiedValue; }`\n * @param root {Element ? document.body} Render root, when available. Used for internal\n * usage of requestAnimationFrame.\n * @return {Integer} Identifier of animation. Can be used to stop it any time.\n */\n\t\t\tstart: function start(stepCallback, verifyCallback, completedCallback, duration, easingMethod, root) {\n\n\t\t\t\tvar start = time();\n\t\t\t\tvar lastFrame = start;\n\t\t\t\tvar percent = 0;\n\t\t\t\tvar dropCounter = 0;\n\t\t\t\tvar id = counter++;\n\n\t\t\t\tif (!root) {\n\t\t\t\t\troot = document.body;\n\t\t\t\t}\n\n\t\t\t\t// Compacting running db automatically every few new animations\n\t\t\t\tif (id % 20 === 0) {\n\t\t\t\t\tvar newRunning = {};\n\t\t\t\t\tfor (var usedId in running) {\n\t\t\t\t\t\tnewRunning[usedId] = true;\n\t\t\t\t\t}\n\t\t\t\t\trunning = newRunning;\n\t\t\t\t}\n\n\t\t\t\t// This is the internal step method which is called every few milliseconds\n\t\t\t\tvar step = function step(virtual) {\n\n\t\t\t\t\t// Normalize virtual value\n\t\t\t\t\tvar render = virtual !== true;\n\n\t\t\t\t\t// Get current time\n\t\t\t\t\tvar now = time();\n\n\t\t\t\t\t// Verification is executed before next animation step\n\t\t\t\t\tif (!running[id] || verifyCallback && !verifyCallback(id)) {\n\n\t\t\t\t\t\trunning[id] = null;\n\t\t\t\t\t\tcompletedCallback && completedCallback(desiredFrames - dropCounter / ((now - start) / millisecondsPerSecond), id, false);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// For the current rendering to apply let's update omitted steps in memory.\n\t\t\t\t\t// This is important to bring internal state variables up-to-date with progress in time.\n\t\t\t\t\tif (render) {\n\n\t\t\t\t\t\tvar droppedFrames = Math.round((now - lastFrame) / (millisecondsPerSecond / desiredFrames)) - 1;\n\t\t\t\t\t\tfor (var j = 0; j < Math.min(droppedFrames, 4); j++) {\n\t\t\t\t\t\t\tstep(true);\n\t\t\t\t\t\t\tdropCounter++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Compute percent value\n\t\t\t\t\tif (duration) {\n\t\t\t\t\t\tpercent = (now - start) / duration;\n\t\t\t\t\t\tif (percent > 1) {\n\t\t\t\t\t\t\tpercent = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Execute step callback, then...\n\t\t\t\t\tvar value = easingMethod ? easingMethod(percent) : percent;\n\t\t\t\t\tif ((stepCallback(value, now, render) === false || percent === 1) && render) {\n\t\t\t\t\t\trunning[id] = null;\n\t\t\t\t\t\tcompletedCallback && completedCallback(desiredFrames - dropCounter / ((now - start) / millisecondsPerSecond), id, percent === 1 || duration == null);\n\t\t\t\t\t} else if (render) {\n\t\t\t\t\t\tlastFrame = now;\n\t\t\t\t\t\tcore.effect.Animate.requestAnimationFrame(step, root);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Mark as running\n\t\t\t\trunning[id] = true;\n\n\t\t\t\t// Init first step\n\t\t\t\tcore.effect.Animate.requestAnimationFrame(step, root);\n\n\t\t\t\t// Return unique animation ID\n\t\t\t\treturn id;\n\t\t\t}\n\t\t};\n\n\t\treturn core;\n\t}(window);\n\n\t/**\n * A pure logic 'component' for 'virtual' scrolling/zooming.\n */\n\tvar Scroller = function Scroller(callback, options) {\n\n\t\tthis.__callback = callback;\n\t\t// core = animate;\n\n\t\tthis.options = {\n\n\t\t\t/** Enable scrolling on x-axis */\n\t\t\tscrollingX: true,\n\n\t\t\t/** Enable scrolling on y-axis */\n\t\t\tscrollingY: true,\n\n\t\t\t/** Enable animations for deceleration, snap back, zooming and scrolling */\n\t\t\tanimating: true,\n\n\t\t\t/** duration for animations triggered by scrollTo/zoomTo */\n\t\t\tanimationDuration: 250,\n\n\t\t\t/** Enable bouncing (content can be slowly moved outside and jumps back after releasing) */\n\t\t\tbouncing: true,\n\n\t\t\t/** Enable locking to the main axis if user moves only slightly on one of them at start */\n\t\t\tlocking: true,\n\n\t\t\t/** Enable pagination mode (switching between full page content panes) */\n\t\t\tpaging: false,\n\n\t\t\t/** Enable snapping of content to a configured pixel grid */\n\t\t\tsnapping: false,\n\n\t\t\t/** Enable zooming of content via API, fingers and mouse wheel */\n\t\t\tzooming: false,\n\n\t\t\t/** Minimum zoom level */\n\t\t\tminZoom: 0.5,\n\n\t\t\t/** Maximum zoom level */\n\t\t\tmaxZoom: 3,\n\n\t\t\t/** Multiply or decrease scrolling speed **/\n\t\t\tspeedMultiplier: 1,\n\n\t\t\t/** Callback that is fired on the later of touch end or deceleration end,\n \tprovided that another scrolling action has not begun. Used to know\n \twhen to fade out a scrollbar. */\n\t\t\tscrollingComplete: NOOP,\n\n\t\t\t/** This configures the amount of change applied to deceleration when reaching boundaries **/\n\t\t\tpenetrationDeceleration: 0.03,\n\n\t\t\t/** This configures the amount of change applied to acceleration when reaching boundaries **/\n\t\t\tpenetrationAcceleration: 0.08\n\n\t\t};\n\n\t\tfor (var key in options) {\n\t\t\tthis.options[key] = options[key];\n\t\t}\n\t};\n\n\t// Easing Equations (c) 2003 Robert Penner, all rights reserved.\n\t// Open source under the BSD License.\n\n\t/**\n * @param pos {Number} position between 0 (start of effect) and 1 (end of effect)\n **/\n\tvar easeOutCubic = function easeOutCubic(pos) {\n\t\treturn Math.pow(pos - 1, 3) + 1;\n\t};\n\n\t/**\n * @param pos {Number} position between 0 (start of effect) and 1 (end of effect)\n **/\n\tvar easeInOutCubic = function easeInOutCubic(pos) {\n\t\tif ((pos /= 0.5) < 1) {\n\t\t\treturn 0.5 * Math.pow(pos, 3);\n\t\t}\n\n\t\treturn 0.5 * (Math.pow(pos - 2, 3) + 2);\n\t};\n\n\tvar members = {\n\n\t\t/*\n ---------------------------------------------------------------------------\n \tINTERNAL FIELDS :: STATUS\n ---------------------------------------------------------------------------\n */\n\n\t\t/** {Boolean} Whether only a single finger is used in touch handling */\n\t\t__isSingleTouch: false,\n\n\t\t/** {Boolean} Whether a touch event sequence is in progress */\n\t\t__isTracking: false,\n\n\t\t/** {Boolean} Whether a deceleration animation went to completion. */\n\t\t__didDecelerationComplete: false,\n\n\t\t/**\n * {Boolean} Whether a gesture zoom/rotate event is in progress. Activates when\n * a gesturestart event happens. This has higher priority than dragging.\n */\n\t\t__isGesturing: false,\n\n\t\t/**\n * {Boolean} Whether the user has moved by such a distance that we have enabled\n * dragging mode. Hint: It's only enabled after some pixels of movement to\n * not interrupt with clicks etc.\n */\n\t\t__isDragging: false,\n\n\t\t/**\n * {Boolean} Not touching and dragging anymore, and smoothly animating the\n * touch sequence using deceleration.\n */\n\t\t__isDecelerating: false,\n\n\t\t/**\n * {Boolean} Smoothly animating the currently configured change\n */\n\t\t__isAnimating: false,\n\n\t\t/*\n ---------------------------------------------------------------------------\n \tINTERNAL FIELDS :: DIMENSIONS\n ---------------------------------------------------------------------------\n */\n\n\t\t/** {Integer} Available outer left position (from document perspective) */\n\t\t__clientLeft: 0,\n\n\t\t/** {Integer} Available outer top position (from document perspective) */\n\t\t__clientTop: 0,\n\n\t\t/** {Integer} Available outer width */\n\t\t__clientWidth: 0,\n\n\t\t/** {Integer} Available outer height */\n\t\t__clientHeight: 0,\n\n\t\t/** {Integer} Outer width of content */\n\t\t__contentWidth: 0,\n\n\t\t/** {Integer} Outer height of content */\n\t\t__contentHeight: 0,\n\n\t\t/** {Integer} Snapping width for content */\n\t\t__snapWidth: 100,\n\n\t\t/** {Integer} Snapping height for content */\n\t\t__snapHeight: 100,\n\n\t\t/** {Integer} Height to assign to refresh area */\n\t\t__refreshHeight: null,\n\n\t\t/** {Boolean} Whether the refresh process is enabled when the event is released now */\n\t\t__refreshActive: false,\n\n\t\t/** {Function} Callback to execute on activation. This is for signalling the user about a refresh is about to happen when he release */\n\t\t__refreshActivate: null,\n\n\t\t/** {Function} Callback to execute on deactivation. This is for signalling the user about the refresh being cancelled */\n\t\t__refreshDeactivate: null,\n\n\t\t/** {Function} Callback to execute to start the actual refresh. Call {@link #refreshFinish} when done */\n\t\t__refreshStart: null,\n\n\t\t/** {Number} Zoom level */\n\t\t__zoomLevel: 1,\n\n\t\t/** {Number} Scroll position on x-axis */\n\t\t__scrollLeft: 0,\n\n\t\t/** {Number} Scroll position on y-axis */\n\t\t__scrollTop: 0,\n\n\t\t/** {Integer} Maximum allowed scroll position on x-axis */\n\t\t__maxScrollLeft: 0,\n\n\t\t/** {Integer} Maximum allowed scroll position on y-axis */\n\t\t__maxScrollTop: 0,\n\n\t\t/* {Number} Scheduled left position (final position when animating) */\n\t\t__scheduledLeft: 0,\n\n\t\t/* {Number} Scheduled top position (final position when animating) */\n\t\t__scheduledTop: 0,\n\n\t\t/* {Number} Scheduled zoom level (final scale when animating) */\n\t\t__scheduledZoom: 0,\n\n\t\t/*\n ---------------------------------------------------------------------------\n \tINTERNAL FIELDS :: LAST POSITIONS\n ---------------------------------------------------------------------------\n */\n\n\t\t/** {Number} Left position of finger at start */\n\t\t__lastTouchLeft: null,\n\n\t\t/** {Number} Top position of finger at start */\n\t\t__lastTouchTop: null,\n\n\t\t/** {Date} Timestamp of last move of finger. Used to limit tracking range for deceleration speed. */\n\t\t__lastTouchMove: null,\n\n\t\t/** {Array} List of positions, uses three indexes for each state: left, top, timestamp */\n\t\t__positions: null,\n\n\t\t/*\n ---------------------------------------------------------------------------\n \tINTERNAL FIELDS :: DECELERATION SUPPORT\n ---------------------------------------------------------------------------\n */\n\n\t\t/** {Integer} Minimum left scroll position during deceleration */\n\t\t__minDecelerationScrollLeft: null,\n\n\t\t/** {Integer} Minimum top scroll position during deceleration */\n\t\t__minDecelerationScrollTop: null,\n\n\t\t/** {Integer} Maximum left scroll position during deceleration */\n\t\t__maxDecelerationScrollLeft: null,\n\n\t\t/** {Integer} Maximum top scroll position during deceleration */\n\t\t__maxDecelerationScrollTop: null,\n\n\t\t/** {Number} Current factor to modify horizontal scroll position with on every step */\n\t\t__decelerationVelocityX: null,\n\n\t\t/** {Number} Current factor to modify vertical scroll position with on every step */\n\t\t__decelerationVelocityY: null,\n\n\t\t/*\n ---------------------------------------------------------------------------\n \tPUBLIC API\n ---------------------------------------------------------------------------\n */\n\n\t\t/**\n * Configures the dimensions of the client (outer) and content (inner) elements.\n * Requires the available space for the outer element and the outer size of the inner element.\n * All values which are falsy (null or zero etc.) are ignored and the old value is kept.\n *\n * @param clientWidth {Integer ? null} Inner width of outer element\n * @param clientHeight {Integer ? null} Inner height of outer element\n * @param contentWidth {Integer ? null} Outer width of inner element\n * @param contentHeight {Integer ? null} Outer height of inner element\n */\n\t\tsetDimensions: function setDimensions(clientWidth, clientHeight, contentWidth, contentHeight) {\n\n\t\t\tvar self = this;\n\n\t\t\t// Only update values which are defined\n\t\t\tif (clientWidth === +clientWidth) {\n\t\t\t\tself.__clientWidth = clientWidth;\n\t\t\t}\n\n\t\t\tif (clientHeight === +clientHeight) {\n\t\t\t\tself.__clientHeight = clientHeight;\n\t\t\t}\n\n\t\t\tif (contentWidth === +contentWidth) {\n\t\t\t\tself.__contentWidth = contentWidth;\n\t\t\t}\n\n\t\t\tif (contentHeight === +contentHeight) {\n\t\t\t\tself.__contentHeight = contentHeight;\n\t\t\t}\n\n\t\t\t// Refresh maximums\n\t\t\tself.__computeScrollMax();\n\n\t\t\t// Refresh scroll position\n\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, true);\n\t\t},\n\n\t\t/**\n * Sets the client coordinates in relation to the document.\n *\n * @param left {Integer ? 0} Left position of outer element\n * @param top {Integer ? 0} Top position of outer element\n */\n\t\tsetPosition: function setPosition(left, top) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__clientLeft = left || 0;\n\t\t\tself.__clientTop = top || 0;\n\t\t},\n\n\t\t/**\n * Configures the snapping (when snapping is active)\n *\n * @param width {Integer} Snapping width\n * @param height {Integer} Snapping height\n */\n\t\tsetSnapSize: function setSnapSize(width, height) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__snapWidth = width;\n\t\t\tself.__snapHeight = height;\n\t\t},\n\n\t\t/**\n * Activates pull-to-refresh. A special zone on the top of the list to start a list refresh whenever\n * the user event is released during visibility of this zone. This was introduced by some apps on iOS like\n * the official Twitter client.\n *\n * @param height {Integer} Height of pull-to-refresh zone on top of rendered list\n * @param activateCallback {Function} Callback to execute on activation. This is for signalling the user about a refresh is about to happen when he release.\n * @param deactivateCallback {Function} Callback to execute on deactivation. This is for signalling the user about the refresh being cancelled.\n * @param startCallback {Function} Callback to execute to start the real async refresh action. Call {@link #finishPullToRefresh} after finish of refresh.\n */\n\t\tactivatePullToRefresh: function activatePullToRefresh(height, activateCallback, deactivateCallback, startCallback) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__refreshHeight = height;\n\t\t\tself.__refreshActivate = activateCallback;\n\t\t\tself.__refreshDeactivate = deactivateCallback;\n\t\t\tself.__refreshStart = startCallback;\n\t\t},\n\n\t\t/**\n * Starts pull-to-refresh manually.\n */\n\t\ttriggerPullToRefresh: function triggerPullToRefresh() {\n\t\t\t// Use publish instead of scrollTo to allow scrolling to out of boundary position\n\t\t\t// We don't need to normalize scrollLeft, zoomLevel, etc. here because we only y-scrolling when pull-to-refresh is enabled\n\t\t\tthis.__publish(this.__scrollLeft, -this.__refreshHeight, this.__zoomLevel, true);\n\n\t\t\tif (this.__refreshStart) {\n\t\t\t\tthis.__refreshStart();\n\t\t\t}\n\t\t},\n\n\t\t/**\n * Signalizes that pull-to-refresh is finished.\n */\n\t\tfinishPullToRefresh: function finishPullToRefresh() {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__refreshActive = false;\n\t\t\tif (self.__refreshDeactivate) {\n\t\t\t\tself.__refreshDeactivate();\n\t\t\t}\n\n\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, true);\n\t\t},\n\n\t\t/**\n * Returns the scroll position and zooming values\n *\n * @return {Map} `left` and `top` scroll position and `zoom` level\n */\n\t\tgetValues: function getValues() {\n\n\t\t\tvar self = this;\n\n\t\t\treturn {\n\t\t\t\tleft: self.__scrollLeft,\n\t\t\t\ttop: self.__scrollTop,\n\t\t\t\tzoom: self.__zoomLevel\n\t\t\t};\n\t\t},\n\n\t\t/**\n * Returns the maximum scroll values\n *\n * @return {Map} `left` and `top` maximum scroll values\n */\n\t\tgetScrollMax: function getScrollMax() {\n\n\t\t\tvar self = this;\n\n\t\t\treturn {\n\t\t\t\tleft: self.__maxScrollLeft,\n\t\t\t\ttop: self.__maxScrollTop\n\t\t\t};\n\t\t},\n\n\t\t/**\n * Zooms to the given level. Supports optional animation. Zooms\n * the center when no coordinates are given.\n *\n * @param level {Number} Level to zoom to\n * @param animate {Boolean ? false} Whether to use animation\n * @param originLeft {Number ? null} Zoom in at given left coordinate\n * @param originTop {Number ? null} Zoom in at given top coordinate\n * @param callback {Function ? null} A callback that gets fired when the zoom is complete.\n */\n\t\tzoomTo: function zoomTo(level, animate, originLeft, originTop, callback) {\n\n\t\t\tvar self = this;\n\n\t\t\tif (!self.options.zooming) {\n\t\t\t\tthrow new Error(\"Zooming is not enabled!\");\n\t\t\t}\n\n\t\t\t// Add callback if exists\n\t\t\tif (callback) {\n\t\t\t\tself.__zoomComplete = callback;\n\t\t\t}\n\n\t\t\t// Stop deceleration\n\t\t\tif (self.__isDecelerating) {\n\t\t\t\tcore.effect.Animate.stop(self.__isDecelerating);\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t}\n\n\t\t\tvar oldLevel = self.__zoomLevel;\n\n\t\t\t// Normalize input origin to center of viewport if not defined\n\t\t\tif (originLeft == null) {\n\t\t\t\toriginLeft = self.__clientWidth / 2;\n\t\t\t}\n\n\t\t\tif (originTop == null) {\n\t\t\t\toriginTop = self.__clientHeight / 2;\n\t\t\t}\n\n\t\t\t// Limit level according to configuration\n\t\t\tlevel = Math.max(Math.min(level, self.options.maxZoom), self.options.minZoom);\n\n\t\t\t// Recompute maximum values while temporary tweaking maximum scroll ranges\n\t\t\tself.__computeScrollMax(level);\n\n\t\t\t// Recompute left and top coordinates based on new zoom level\n\t\t\tvar left = (originLeft + self.__scrollLeft) * level / oldLevel - originLeft;\n\t\t\tvar top = (originTop + self.__scrollTop) * level / oldLevel - originTop;\n\n\t\t\t// Limit x-axis\n\t\t\tif (left > self.__maxScrollLeft) {\n\t\t\t\tleft = self.__maxScrollLeft;\n\t\t\t} else if (left < 0) {\n\t\t\t\tleft = 0;\n\t\t\t}\n\n\t\t\t// Limit y-axis\n\t\t\tif (top > self.__maxScrollTop) {\n\t\t\t\ttop = self.__maxScrollTop;\n\t\t\t} else if (top < 0) {\n\t\t\t\ttop = 0;\n\t\t\t}\n\n\t\t\t// Push values out\n\t\t\tself.__publish(left, top, level, animate);\n\t\t},\n\n\t\t/**\n * Zooms the content by the given factor.\n *\n * @param factor {Number} Zoom by given factor\n * @param animate {Boolean ? false} Whether to use animation\n * @param originLeft {Number ? 0} Zoom in at given left coordinate\n * @param originTop {Number ? 0} Zoom in at given top coordinate\n * @param callback {Function ? null} A callback that gets fired when the zoom is complete.\n */\n\t\tzoomBy: function zoomBy(factor, animate, originLeft, originTop, callback) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.zoomTo(self.__zoomLevel * factor, animate, originLeft, originTop, callback);\n\t\t},\n\n\t\t/**\n * Scrolls to the given position. Respect limitations and snapping automatically.\n *\n * @param left {Number?null} Horizontal scroll position, keeps current if value is null\n * @param top {Number?null} Vertical scroll position, keeps current if value is null\n * @param animate {Boolean?false} Whether the scrolling should happen using an animation\n * @param zoom {Number?null} Zoom level to go to\n */\n\t\tscrollTo: function scrollTo(left, top, animate, zoom) {\n\n\t\t\tvar self = this;\n\n\t\t\t// Stop deceleration\n\t\t\tif (self.__isDecelerating) {\n\t\t\t\tcore.effect.Animate.stop(self.__isDecelerating);\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t}\n\n\t\t\t// Correct coordinates based on new zoom level\n\t\t\tif (zoom != null && zoom !== self.__zoomLevel) {\n\n\t\t\t\tif (!self.options.zooming) {\n\t\t\t\t\tthrow new Error(\"Zooming is not enabled!\");\n\t\t\t\t}\n\n\t\t\t\tleft *= zoom;\n\t\t\t\ttop *= zoom;\n\n\t\t\t\t// Recompute maximum values while temporary tweaking maximum scroll ranges\n\t\t\t\tself.__computeScrollMax(zoom);\n\t\t\t} else {\n\n\t\t\t\t// Keep zoom when not defined\n\t\t\t\tzoom = self.__zoomLevel;\n\t\t\t}\n\n\t\t\tif (!self.options.scrollingX) {\n\n\t\t\t\tleft = self.__scrollLeft;\n\t\t\t} else {\n\n\t\t\t\tif (self.options.paging) {\n\t\t\t\t\tleft = Math.round(left / self.__clientWidth) * self.__clientWidth;\n\t\t\t\t} else if (self.options.snapping) {\n\t\t\t\t\tleft = Math.round(left / self.__snapWidth) * self.__snapWidth;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!self.options.scrollingY) {\n\n\t\t\t\ttop = self.__scrollTop;\n\t\t\t} else {\n\n\t\t\t\tif (self.options.paging) {\n\t\t\t\t\ttop = Math.round(top / self.__clientHeight) * self.__clientHeight;\n\t\t\t\t} else if (self.options.snapping) {\n\t\t\t\t\ttop = Math.round(top / self.__snapHeight) * self.__snapHeight;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Limit for allowed ranges\n\t\t\tleft = Math.max(Math.min(self.__maxScrollLeft, left), 0);\n\t\t\ttop = Math.max(Math.min(self.__maxScrollTop, top), 0);\n\n\t\t\t// Don't animate when no change detected, still call publish to make sure\n\t\t\t// that rendered position is really in-sync with internal data\n\t\t\tif (left === self.__scrollLeft && top === self.__scrollTop) {\n\t\t\t\tanimate = false;\n\t\t\t}\n\n\t\t\t// Publish new values\n\t\t\tif (!self.__isTracking) {\n\t\t\t\tself.__publish(left, top, zoom, animate);\n\t\t\t}\n\t\t},\n\n\t\t/**\n * Scroll by the given offset\n *\n * @param left {Number ? 0} Scroll x-axis by given offset\n * @param top {Number ? 0} Scroll x-axis by given offset\n * @param animate {Boolean ? false} Whether to animate the given change\n */\n\t\tscrollBy: function scrollBy(left, top, animate) {\n\n\t\t\tvar self = this;\n\n\t\t\tvar startLeft = self.__isAnimating ? self.__scheduledLeft : self.__scrollLeft;\n\t\t\tvar startTop = self.__isAnimating ? self.__scheduledTop : self.__scrollTop;\n\n\t\t\tself.scrollTo(startLeft + (left || 0), startTop + (top || 0), animate);\n\t\t},\n\n\t\t/*\n ---------------------------------------------------------------------------\n \tEVENT CALLBACKS\n ---------------------------------------------------------------------------\n */\n\n\t\t/**\n * Mouse wheel handler for zooming support\n */\n\t\tdoMouseZoom: function doMouseZoom(wheelDelta, timeStamp, pageX, pageY) {\n\n\t\t\tvar self = this;\n\t\t\tvar change = wheelDelta > 0 ? 0.97 : 1.03;\n\n\t\t\treturn self.zoomTo(self.__zoomLevel * change, false, pageX - self.__clientLeft, pageY - self.__clientTop);\n\t\t},\n\n\t\t/**\n * Touch start handler for scrolling support\n */\n\t\tdoTouchStart: function doTouchStart(touches, timeStamp) {\n\t\t\t// Array-like check is enough here\n\t\t\tif (touches.length == null) {\n\t\t\t\tthrow new Error(\"Invalid touch list: \" + touches);\n\t\t\t}\n\n\t\t\tif (timeStamp instanceof Date) {\n\t\t\t\ttimeStamp = timeStamp.valueOf();\n\t\t\t}\n\t\t\tif (typeof timeStamp !== \"number\") {\n\t\t\t\tthrow new Error(\"Invalid timestamp value: \" + timeStamp);\n\t\t\t}\n\n\t\t\tvar self = this;\n\n\t\t\t// Reset interruptedAnimation flag\n\t\t\tself.__interruptedAnimation = true;\n\n\t\t\t// Stop deceleration\n\t\t\tif (self.__isDecelerating) {\n\t\t\t\tcore.effect.Animate.stop(self.__isDecelerating);\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t\tself.__interruptedAnimation = true;\n\t\t\t}\n\n\t\t\t// Stop animation\n\t\t\tif (self.__isAnimating) {\n\t\t\t\tcore.effect.Animate.stop(self.__isAnimating);\n\t\t\t\tself.__isAnimating = false;\n\t\t\t\tself.__interruptedAnimation = true;\n\t\t\t}\n\n\t\t\t// Use center point when dealing with two fingers\n\t\t\tvar currentTouchLeft, currentTouchTop;\n\t\t\tvar isSingleTouch = touches.length === 1;\n\t\t\tif (isSingleTouch) {\n\t\t\t\tcurrentTouchLeft = touches[0].pageX;\n\t\t\t\tcurrentTouchTop = touches[0].pageY;\n\t\t\t} else {\n\t\t\t\tcurrentTouchLeft = Math.abs(touches[0].pageX + touches[1].pageX) / 2;\n\t\t\t\tcurrentTouchTop = Math.abs(touches[0].pageY + touches[1].pageY) / 2;\n\t\t\t}\n\n\t\t\t// Store initial positions\n\t\t\tself.__initialTouchLeft = currentTouchLeft;\n\t\t\tself.__initialTouchTop = currentTouchTop;\n\n\t\t\t// Store current zoom level\n\t\t\tself.__zoomLevelStart = self.__zoomLevel;\n\n\t\t\t// Store initial touch positions\n\t\t\tself.__lastTouchLeft = currentTouchLeft;\n\t\t\tself.__lastTouchTop = currentTouchTop;\n\n\t\t\t// Store initial move time stamp\n\t\t\tself.__lastTouchMove = timeStamp;\n\n\t\t\t// Reset initial scale\n\t\t\tself.__lastScale = 1;\n\n\t\t\t// Reset locking flags\n\t\t\tself.__enableScrollX = !isSingleTouch && self.options.scrollingX;\n\t\t\tself.__enableScrollY = !isSingleTouch && self.options.scrollingY;\n\n\t\t\t// Reset tracking flag\n\t\t\tself.__isTracking = true;\n\n\t\t\t// Reset deceleration complete flag\n\t\t\tself.__didDecelerationComplete = false;\n\n\t\t\t// Dragging starts directly with two fingers, otherwise lazy with an offset\n\t\t\tself.__isDragging = !isSingleTouch;\n\n\t\t\t// Some features are disabled in multi touch scenarios\n\t\t\tself.__isSingleTouch = isSingleTouch;\n\n\t\t\t// Clearing data structure\n\t\t\tself.__positions = [];\n\t\t},\n\n\t\t/**\n * Touch move handler for scrolling support\n */\n\t\tdoTouchMove: function doTouchMove(touches, timeStamp, scale) {\n\n\t\t\t// Array-like check is enough here\n\t\t\tif (touches.length == null) {\n\t\t\t\tthrow new Error(\"Invalid touch list: \" + touches);\n\t\t\t}\n\n\t\t\tif (timeStamp instanceof Date) {\n\t\t\t\ttimeStamp = timeStamp.valueOf();\n\t\t\t}\n\t\t\tif (typeof timeStamp !== \"number\") {\n\t\t\t\tthrow new Error(\"Invalid timestamp value: \" + timeStamp);\n\t\t\t}\n\n\t\t\tvar self = this;\n\n\t\t\t// Ignore event when tracking is not enabled (event might be outside of element)\n\t\t\tif (!self.__isTracking) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar currentTouchLeft, currentTouchTop;\n\n\t\t\t// Compute move based around of center of fingers\n\t\t\tif (touches.length === 2) {\n\t\t\t\tcurrentTouchLeft = Math.abs(touches[0].pageX + touches[1].pageX) / 2;\n\t\t\t\tcurrentTouchTop = Math.abs(touches[0].pageY + touches[1].pageY) / 2;\n\t\t\t} else {\n\t\t\t\tcurrentTouchLeft = touches[0].pageX;\n\t\t\t\tcurrentTouchTop = touches[0].pageY;\n\t\t\t}\n\n\t\t\tvar positions = self.__positions;\n\n\t\t\t// Are we already is dragging mode?\n\t\t\tif (self.__isDragging) {\n\n\t\t\t\t// Compute move distance\n\t\t\t\tvar moveX = currentTouchLeft - self.__lastTouchLeft;\n\t\t\t\tvar moveY = currentTouchTop - self.__lastTouchTop;\n\n\t\t\t\t// Read previous scroll position and zooming\n\t\t\t\tvar scrollLeft = self.__scrollLeft;\n\t\t\t\tvar scrollTop = self.__scrollTop;\n\t\t\t\tvar level = self.__zoomLevel;\n\n\t\t\t\t// Work with scaling\n\t\t\t\tif (scale != null && self.options.zooming) {\n\n\t\t\t\t\tvar oldLevel = level;\n\n\t\t\t\t\t// Recompute level based on previous scale and new scale\n\t\t\t\t\tlevel = level / self.__lastScale * scale;\n\n\t\t\t\t\t// Limit level according to configuration\n\t\t\t\t\tlevel = Math.max(Math.min(level, self.options.maxZoom), self.options.minZoom);\n\n\t\t\t\t\t// Only do further compution when change happened\n\t\t\t\t\tif (oldLevel !== level) {\n\n\t\t\t\t\t\t// Compute relative event position to container\n\t\t\t\t\t\tvar currentTouchLeftRel = currentTouchLeft - self.__clientLeft;\n\t\t\t\t\t\tvar currentTouchTopRel = currentTouchTop - self.__clientTop;\n\n\t\t\t\t\t\t// Recompute left and top coordinates based on new zoom level\n\t\t\t\t\t\tscrollLeft = (currentTouchLeftRel + scrollLeft) * level / oldLevel - currentTouchLeftRel;\n\t\t\t\t\t\tscrollTop = (currentTouchTopRel + scrollTop) * level / oldLevel - currentTouchTopRel;\n\n\t\t\t\t\t\t// Recompute max scroll values\n\t\t\t\t\t\tself.__computeScrollMax(level);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (self.__enableScrollX) {\n\n\t\t\t\t\tscrollLeft -= moveX * this.options.speedMultiplier;\n\t\t\t\t\tvar maxScrollLeft = self.__maxScrollLeft;\n\n\t\t\t\t\tif (scrollLeft > maxScrollLeft || scrollLeft < 0) {\n\n\t\t\t\t\t\t// Slow down on the edges\n\t\t\t\t\t\tif (self.options.bouncing) {\n\n\t\t\t\t\t\t\tscrollLeft += moveX / 2 * this.options.speedMultiplier;\n\t\t\t\t\t\t} else if (scrollLeft > maxScrollLeft) {\n\n\t\t\t\t\t\t\tscrollLeft = maxScrollLeft;\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tscrollLeft = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Compute new vertical scroll position\n\t\t\t\tif (self.__enableScrollY) {\n\n\t\t\t\t\tscrollTop -= moveY * this.options.speedMultiplier;\n\t\t\t\t\tvar maxScrollTop = self.__maxScrollTop;\n\n\t\t\t\t\tif (scrollTop > maxScrollTop || scrollTop < 0) {\n\n\t\t\t\t\t\t// Slow down on the edges\n\t\t\t\t\t\tif (self.options.bouncing) {\n\n\t\t\t\t\t\t\tscrollTop += moveY / 2 * this.options.speedMultiplier;\n\n\t\t\t\t\t\t\t// Support pull-to-refresh (only when only y is scrollable)\n\t\t\t\t\t\t\tif (!self.__enableScrollX && self.__refreshHeight != null) {\n\n\t\t\t\t\t\t\t\tif (!self.__refreshActive && scrollTop <= -self.__refreshHeight) {\n\n\t\t\t\t\t\t\t\t\tself.__refreshActive = true;\n\t\t\t\t\t\t\t\t\tif (self.__refreshActivate) {\n\t\t\t\t\t\t\t\t\t\tself.__refreshActivate();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else if (self.__refreshActive && scrollTop > -self.__refreshHeight) {\n\n\t\t\t\t\t\t\t\t\tself.__refreshActive = false;\n\t\t\t\t\t\t\t\t\tif (self.__refreshDeactivate) {\n\t\t\t\t\t\t\t\t\t\tself.__refreshDeactivate();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (scrollTop > maxScrollTop) {\n\n\t\t\t\t\t\t\tscrollTop = maxScrollTop;\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tscrollTop = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Keep list from growing infinitely (holding min 10, max 20 measure points)\n\t\t\t\tif (positions.length > 60) {\n\t\t\t\t\tpositions.splice(0, 30);\n\t\t\t\t}\n\n\t\t\t\t// Track scroll movement for decleration\n\t\t\t\tpositions.push(scrollLeft, scrollTop, timeStamp);\n\n\t\t\t\t// Sync scroll position\n\t\t\t\tself.__publish(scrollLeft, scrollTop, level);\n\n\t\t\t\t// Otherwise figure out whether we are switching into dragging mode now.\n\t\t\t} else {\n\n\t\t\t\tvar minimumTrackingForScroll = self.options.locking ? 3 : 0;\n\t\t\t\tvar minimumTrackingForDrag = 5;\n\n\t\t\t\tvar distanceX = Math.abs(currentTouchLeft - self.__initialTouchLeft);\n\t\t\t\tvar distanceY = Math.abs(currentTouchTop - self.__initialTouchTop);\n\n\t\t\t\tself.__enableScrollX = self.options.scrollingX && distanceX >= minimumTrackingForScroll;\n\t\t\t\tself.__enableScrollY = self.options.scrollingY && distanceY >= minimumTrackingForScroll;\n\n\t\t\t\tpositions.push(self.__scrollLeft, self.__scrollTop, timeStamp);\n\n\t\t\t\tself.__isDragging = (self.__enableScrollX || self.__enableScrollY) && (distanceX >= minimumTrackingForDrag || distanceY >= minimumTrackingForDrag);\n\t\t\t\tif (self.__isDragging) {\n\t\t\t\t\tself.__interruptedAnimation = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update last touch positions and time stamp for next event\n\t\t\tself.__lastTouchLeft = currentTouchLeft;\n\t\t\tself.__lastTouchTop = currentTouchTop;\n\t\t\tself.__lastTouchMove = timeStamp;\n\t\t\tself.__lastScale = scale;\n\t\t},\n\n\t\t/**\n * Touch end handler for scrolling support\n */\n\t\tdoTouchEnd: function doTouchEnd(timeStamp) {\n\n\t\t\tif (timeStamp instanceof Date) {\n\t\t\t\ttimeStamp = timeStamp.valueOf();\n\t\t\t}\n\t\t\tif (typeof timeStamp !== \"number\") {\n\t\t\t\tthrow new Error(\"Invalid timestamp value: \" + timeStamp);\n\t\t\t}\n\n\t\t\tvar self = this;\n\n\t\t\t// Ignore event when tracking is not enabled (no touchstart event on element)\n\t\t\t// This is required as this listener ('touchmove') sits on the document and not on the element itself.\n\t\t\tif (!self.__isTracking) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Not touching anymore (when two finger hit the screen there are two touch end events)\n\t\t\tself.__isTracking = false;\n\n\t\t\t// Be sure to reset the dragging flag now. Here we also detect whether\n\t\t\t// the finger has moved fast enough to switch into a deceleration animation.\n\t\t\tif (self.__isDragging) {\n\n\t\t\t\t// Reset dragging flag\n\t\t\t\tself.__isDragging = false;\n\n\t\t\t\t// Start deceleration\n\t\t\t\t// Verify that the last move detected was in some relevant time frame\n\t\t\t\tif (self.__isSingleTouch && self.options.animating && timeStamp - self.__lastTouchMove <= 100) {\n\n\t\t\t\t\t// Then figure out what the scroll position was about 100ms ago\n\t\t\t\t\tvar positions = self.__positions;\n\t\t\t\t\tvar endPos = positions.length - 1;\n\t\t\t\t\tvar startPos = endPos;\n\n\t\t\t\t\t// Move pointer to position measured 100ms ago\n\t\t\t\t\tfor (var i = endPos; i > 0 && positions[i] > self.__lastTouchMove - 100; i -= 3) {\n\t\t\t\t\t\tstartPos = i;\n\t\t\t\t\t}\n\n\t\t\t\t\t// If start and stop position is identical in a 100ms timeframe,\n\t\t\t\t\t// we cannot compute any useful deceleration.\n\t\t\t\t\tif (startPos !== endPos) {\n\n\t\t\t\t\t\t// Compute relative movement between these two points\n\t\t\t\t\t\tvar timeOffset = positions[endPos] - positions[startPos];\n\t\t\t\t\t\tvar movedLeft = self.__scrollLeft - positions[startPos - 2];\n\t\t\t\t\t\tvar movedTop = self.__scrollTop - positions[startPos - 1];\n\n\t\t\t\t\t\t// Based on 50ms compute the movement to apply for each render step\n\t\t\t\t\t\tself.__decelerationVelocityX = movedLeft / timeOffset * (1000 / 60);\n\t\t\t\t\t\tself.__decelerationVelocityY = movedTop / timeOffset * (1000 / 60);\n\n\t\t\t\t\t\t// How much velocity is required to start the deceleration\n\t\t\t\t\t\tvar minVelocityToStartDeceleration = self.options.paging || self.options.snapping ? 4 : 1;\n\n\t\t\t\t\t\t// Verify that we have enough velocity to start deceleration\n\t\t\t\t\t\tif (Math.abs(self.__decelerationVelocityX) > minVelocityToStartDeceleration || Math.abs(self.__decelerationVelocityY) > minVelocityToStartDeceleration) {\n\n\t\t\t\t\t\t\t// Deactivate pull-to-refresh when decelerating\n\t\t\t\t\t\t\tif (!self.__refreshActive) {\n\t\t\t\t\t\t\t\tself.__startDeceleration(timeStamp);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t}\n\t\t\t\t} else if (timeStamp - self.__lastTouchMove > 100) {\n\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If this was a slower move it is per default non decelerated, but this\n\t\t\t// still means that we want snap back to the bounds which is done here.\n\t\t\t// This is placed outside the condition above to improve edge case stability\n\t\t\t// e.g. touchend fired without enabled dragging. This should normally do not\n\t\t\t// have modified the scroll positions or even showed the scrollbars though.\n\t\t\tif (!self.__isDecelerating) {\n\n\t\t\t\tif (self.__refreshActive && self.__refreshStart) {\n\n\t\t\t\t\t// Use publish instead of scrollTo to allow scrolling to out of boundary position\n\t\t\t\t\t// We don't need to normalize scrollLeft, zoomLevel, etc. here because we only y-scrolling when pull-to-refresh is enabled\n\t\t\t\t\tself.__publish(self.__scrollLeft, -self.__refreshHeight, self.__zoomLevel, true);\n\n\t\t\t\t\tif (self.__refreshStart) {\n\t\t\t\t\t\tself.__refreshStart();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\n\t\t\t\t\tif (self.__interruptedAnimation || self.__isDragging) {\n\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t}\n\t\t\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, true, self.__zoomLevel);\n\n\t\t\t\t\t// Directly signalize deactivation (nothing todo on refresh?)\n\t\t\t\t\tif (self.__refreshActive) {\n\n\t\t\t\t\t\tself.__refreshActive = false;\n\t\t\t\t\t\tif (self.__refreshDeactivate) {\n\t\t\t\t\t\t\tself.__refreshDeactivate();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fully cleanup list\n\t\t\tself.__positions.length = 0;\n\t\t},\n\n\t\t/*\n ---------------------------------------------------------------------------\n \tPRIVATE API\n ---------------------------------------------------------------------------\n */\n\n\t\t/**\n * Applies the scroll position to the content element\n *\n * @param left {Number} Left scroll position\n * @param top {Number} Top scroll position\n * @param animate {Boolean?false} Whether animation should be used to move to the new coordinates\n */\n\t\t__publish: function __publish(left, top, zoom, animate) {\n\n\t\t\tvar self = this;\n\n\t\t\t// Remember whether we had an animation, then we try to continue based on the current \"drive\" of the animation\n\t\t\tvar wasAnimating = self.__isAnimating;\n\t\t\tif (wasAnimating) {\n\t\t\t\tcore.effect.Animate.stop(wasAnimating);\n\t\t\t\tself.__isAnimating = false;\n\t\t\t}\n\n\t\t\tif (animate && self.options.animating) {\n\n\t\t\t\t// Keep scheduled positions for scrollBy/zoomBy functionality\n\t\t\t\tself.__scheduledLeft = left;\n\t\t\t\tself.__scheduledTop = top;\n\t\t\t\tself.__scheduledZoom = zoom;\n\n\t\t\t\tvar oldLeft = self.__scrollLeft;\n\t\t\t\tvar oldTop = self.__scrollTop;\n\t\t\t\tvar oldZoom = self.__zoomLevel;\n\n\t\t\t\tvar diffLeft = left - oldLeft;\n\t\t\t\tvar diffTop = top - oldTop;\n\t\t\t\tvar diffZoom = zoom - oldZoom;\n\n\t\t\t\tvar step = function step(percent, now, render) {\n\n\t\t\t\t\tif (render) {\n\n\t\t\t\t\t\tself.__scrollLeft = oldLeft + diffLeft * percent;\n\t\t\t\t\t\tself.__scrollTop = oldTop + diffTop * percent;\n\t\t\t\t\t\tself.__zoomLevel = oldZoom + diffZoom * percent;\n\n\t\t\t\t\t\t// Push values out\n\t\t\t\t\t\tif (self.__callback) {\n\t\t\t\t\t\t\tself.__callback(self.__scrollLeft, self.__scrollTop, self.__zoomLevel);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tvar verify = function verify(id) {\n\t\t\t\t\treturn self.__isAnimating === id;\n\t\t\t\t};\n\n\t\t\t\tvar completed = function completed(renderedFramesPerSecond, animationId, wasFinished) {\n\t\t\t\t\tif (animationId === self.__isAnimating) {\n\t\t\t\t\t\tself.__isAnimating = false;\n\t\t\t\t\t}\n\t\t\t\t\tif (self.__didDecelerationComplete || wasFinished) {\n\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (self.options.zooming) {\n\t\t\t\t\t\tself.__computeScrollMax();\n\t\t\t\t\t\tif (self.__zoomComplete) {\n\t\t\t\t\t\t\tself.__zoomComplete();\n\t\t\t\t\t\t\tself.__zoomComplete = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// When continuing based on previous animation we choose an ease-out animation instead of ease-in-out\n\t\t\t\tself.__isAnimating = core.effect.Animate.start(step, verify, completed, self.options.animationDuration, wasAnimating ? easeOutCubic : easeInOutCubic);\n\t\t\t} else {\n\n\t\t\t\tself.__scheduledLeft = self.__scrollLeft = left;\n\t\t\t\tself.__scheduledTop = self.__scrollTop = top;\n\t\t\t\tself.__scheduledZoom = self.__zoomLevel = zoom;\n\n\t\t\t\t// Push values out\n\t\t\t\tif (self.__callback) {\n\t\t\t\t\tself.__callback(left, top, zoom);\n\t\t\t\t}\n\n\t\t\t\t// Fix max scroll ranges\n\t\t\t\tif (self.options.zooming) {\n\t\t\t\t\tself.__computeScrollMax();\n\t\t\t\t\tif (self.__zoomComplete) {\n\t\t\t\t\t\tself.__zoomComplete();\n\t\t\t\t\t\tself.__zoomComplete = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n * Recomputes scroll minimum values based on client dimensions and content dimensions.\n */\n\t\t__computeScrollMax: function __computeScrollMax(zoomLevel) {\n\n\t\t\tvar self = this;\n\n\t\t\tif (zoomLevel == null) {\n\t\t\t\tzoomLevel = self.__zoomLevel;\n\t\t\t}\n\n\t\t\tself.__maxScrollLeft = Math.max(self.__contentWidth * zoomLevel - self.__clientWidth, 0);\n\t\t\tself.__maxScrollTop = Math.max(self.__contentHeight * zoomLevel - self.__clientHeight, 0);\n\t\t},\n\n\t\t/*\n ---------------------------------------------------------------------------\n \tANIMATION (DECELERATION) SUPPORT\n ---------------------------------------------------------------------------\n */\n\n\t\t/**\n * Called when a touch sequence end and the speed of the finger was high enough\n * to switch into deceleration mode.\n */\n\t\t__startDeceleration: function __startDeceleration(timeStamp) {\n\n\t\t\tvar self = this;\n\n\t\t\tif (self.options.paging) {\n\n\t\t\t\tvar scrollLeft = Math.max(Math.min(self.__scrollLeft, self.__maxScrollLeft), 0);\n\t\t\t\tvar scrollTop = Math.max(Math.min(self.__scrollTop, self.__maxScrollTop), 0);\n\t\t\t\tvar clientWidth = self.__clientWidth;\n\t\t\t\tvar clientHeight = self.__clientHeight;\n\n\t\t\t\t// We limit deceleration not to the min/max values of the allowed range, but to the size of the visible client area.\n\t\t\t\t// Each page should have exactly the size of the client area.\n\t\t\t\tself.__minDecelerationScrollLeft = Math.floor(scrollLeft / clientWidth) * clientWidth;\n\t\t\t\tself.__minDecelerationScrollTop = Math.floor(scrollTop / clientHeight) * clientHeight;\n\t\t\t\tself.__maxDecelerationScrollLeft = Math.ceil(scrollLeft / clientWidth) * clientWidth;\n\t\t\t\tself.__maxDecelerationScrollTop = Math.ceil(scrollTop / clientHeight) * clientHeight;\n\t\t\t} else {\n\n\t\t\t\tself.__minDecelerationScrollLeft = 0;\n\t\t\t\tself.__minDecelerationScrollTop = 0;\n\t\t\t\tself.__maxDecelerationScrollLeft = self.__maxScrollLeft;\n\t\t\t\tself.__maxDecelerationScrollTop = self.__maxScrollTop;\n\t\t\t}\n\n\t\t\t// Wrap class method\n\t\t\tvar step = function step(percent, now, render) {\n\t\t\t\tself.__stepThroughDeceleration(render);\n\t\t\t};\n\n\t\t\t// How much velocity is required to keep the deceleration running\n\t\t\tvar minVelocityToKeepDecelerating = self.options.snapping ? 4 : 0.001;\n\n\t\t\t// Detect whether it's still worth to continue animating steps\n\t\t\t// If we are already slow enough to not being user perceivable anymore, we stop the whole process here.\n\t\t\tvar verify = function verify() {\n\t\t\t\tvar shouldContinue = Math.abs(self.__decelerationVelocityX) >= minVelocityToKeepDecelerating || Math.abs(self.__decelerationVelocityY) >= minVelocityToKeepDecelerating;\n\t\t\t\tif (!shouldContinue) {\n\t\t\t\t\tself.__didDecelerationComplete = true;\n\t\t\t\t}\n\t\t\t\treturn shouldContinue;\n\t\t\t};\n\n\t\t\tvar completed = function completed(renderedFramesPerSecond, animationId, wasFinished) {\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t\tif (self.__didDecelerationComplete) {\n\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t}\n\n\t\t\t\t// Animate to grid when snapping is active, otherwise just fix out-of-boundary positions\n\t\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, self.options.snapping);\n\t\t\t};\n\n\t\t\t// Start animation and switch on flag\n\t\t\tself.__isDecelerating = core.effect.Animate.start(step, verify, completed);\n\t\t},\n\n\t\t/**\n * Called on every step of the animation\n *\n * @param inMemory {Boolean?false} Whether to not render the current step, but keep it in memory only. Used internally only!\n */\n\t\t__stepThroughDeceleration: function __stepThroughDeceleration(render) {\n\n\t\t\tvar self = this;\n\n\t\t\t//\n\t\t\t// COMPUTE NEXT SCROLL POSITION\n\t\t\t//\n\n\t\t\t// Add deceleration to scroll position\n\t\t\tvar scrollLeft = self.__scrollLeft + self.__decelerationVelocityX;\n\t\t\tvar scrollTop = self.__scrollTop + self.__decelerationVelocityY;\n\n\t\t\t//\n\t\t\t// HARD LIMIT SCROLL POSITION FOR NON BOUNCING MODE\n\t\t\t//\n\n\t\t\tif (!self.options.bouncing) {\n\n\t\t\t\tvar scrollLeftFixed = Math.max(Math.min(self.__maxDecelerationScrollLeft, scrollLeft), self.__minDecelerationScrollLeft);\n\t\t\t\tif (scrollLeftFixed !== scrollLeft) {\n\t\t\t\t\tscrollLeft = scrollLeftFixed;\n\t\t\t\t\tself.__decelerationVelocityX = 0;\n\t\t\t\t}\n\n\t\t\t\tvar scrollTopFixed = Math.max(Math.min(self.__maxDecelerationScrollTop, scrollTop), self.__minDecelerationScrollTop);\n\t\t\t\tif (scrollTopFixed !== scrollTop) {\n\t\t\t\t\tscrollTop = scrollTopFixed;\n\t\t\t\t\tself.__decelerationVelocityY = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//\n\t\t\t// UPDATE SCROLL POSITION\n\t\t\t//\n\n\t\t\tif (render) {\n\n\t\t\t\tself.__publish(scrollLeft, scrollTop, self.__zoomLevel);\n\t\t\t} else {\n\n\t\t\t\tself.__scrollLeft = scrollLeft;\n\t\t\t\tself.__scrollTop = scrollTop;\n\t\t\t}\n\n\t\t\t//\n\t\t\t// SLOW DOWN\n\t\t\t//\n\n\t\t\t// Slow down velocity on every iteration\n\t\t\tif (!self.options.paging) {\n\n\t\t\t\t// This is the factor applied to every iteration of the animation\n\t\t\t\t// to slow down the process. This should emulate natural behavior where\n\t\t\t\t// objects slow down when the initiator of the movement is removed\n\t\t\t\tvar frictionFactor = 0.95;\n\n\t\t\t\tself.__decelerationVelocityX *= frictionFactor;\n\t\t\t\tself.__decelerationVelocityY *= frictionFactor;\n\t\t\t}\n\n\t\t\t//\n\t\t\t// BOUNCING SUPPORT\n\t\t\t//\n\n\t\t\tif (self.options.bouncing) {\n\n\t\t\t\tvar scrollOutsideX = 0;\n\t\t\t\tvar scrollOutsideY = 0;\n\n\t\t\t\t// This configures the amount of change applied to deceleration/acceleration when reaching boundaries\n\t\t\t\tvar penetrationDeceleration = self.options.penetrationDeceleration;\n\t\t\t\tvar penetrationAcceleration = self.options.penetrationAcceleration;\n\n\t\t\t\t// Check limits\n\t\t\t\tif (scrollLeft < self.__minDecelerationScrollLeft) {\n\t\t\t\t\tscrollOutsideX = self.__minDecelerationScrollLeft - scrollLeft;\n\t\t\t\t} else if (scrollLeft > self.__maxDecelerationScrollLeft) {\n\t\t\t\t\tscrollOutsideX = self.__maxDecelerationScrollLeft - scrollLeft;\n\t\t\t\t}\n\n\t\t\t\tif (scrollTop < self.__minDecelerationScrollTop) {\n\t\t\t\t\tscrollOutsideY = self.__minDecelerationScrollTop - scrollTop;\n\t\t\t\t} else if (scrollTop > self.__maxDecelerationScrollTop) {\n\t\t\t\t\tscrollOutsideY = self.__maxDecelerationScrollTop - scrollTop;\n\t\t\t\t}\n\n\t\t\t\t// Slow down until slow enough, then flip back to snap position\n\t\t\t\tif (scrollOutsideX !== 0) {\n\t\t\t\t\tif (scrollOutsideX * self.__decelerationVelocityX <= 0) {\n\t\t\t\t\t\tself.__decelerationVelocityX += scrollOutsideX * penetrationDeceleration;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.__decelerationVelocityX = scrollOutsideX * penetrationAcceleration;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (scrollOutsideY !== 0) {\n\t\t\t\t\tif (scrollOutsideY * self.__decelerationVelocityY <= 0) {\n\t\t\t\t\t\tself.__decelerationVelocityY += scrollOutsideY * penetrationDeceleration;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.__decelerationVelocityY = scrollOutsideY * penetrationAcceleration;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Copy over members to prototype\n\tfor (var key in members) {\n\t\tScroller.prototype[key] = members[key];\n\t}\n\n\tif (typeof module != 'undefined' && module.exports) {\n\t\tmodule.exports = Scroller;\n\t} else if (true) {\n\t\t!(__WEBPACK_AMD_DEFINE_RESULT__ = function () {\n\t\t\treturn Scroller;\n\t\t}.call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else {\n\t\twindow.Scroller = Scroller;\n\t}\n})(window);\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction getContentRender(content) {\n var global = window;\n\n var docStyle = document.documentElement.style;\n\n var engine;\n if (global.opera && Object.prototype.toString.call(opera) === '[object Opera]') {\n engine = 'presto';\n } else if ('MozAppearance' in docStyle) {\n engine = 'gecko';\n } else if ('WebkitAppearance' in docStyle) {\n engine = 'webkit';\n } else if (typeof navigator.cpuClass === 'string') {\n engine = 'trident';\n }\n\n var vendorPrefix = {\n trident: 'ms',\n gecko: 'Moz',\n webkit: 'Webkit',\n presto: 'O'\n }[engine];\n\n var helperElem = document.createElement(\"div\");\n var undef;\n\n var perspectiveProperty = vendorPrefix + \"Perspective\";\n var transformProperty = vendorPrefix + \"Transform\";\n\n if (helperElem.style[perspectiveProperty] !== undef) {\n\n return function (left, top, zoom) {\n content.style[transformProperty] = 'translate3d(' + -left + 'px,' + -top + 'px,0) scale(' + zoom + ')';\n };\n } else if (helperElem.style[transformProperty] !== undef) {\n\n return function (left, top, zoom) {\n content.style[transformProperty] = 'translate(' + -left + 'px,' + -top + 'px) scale(' + zoom + ')';\n };\n } else {\n\n return function (left, top, zoom) {\n content.style.marginLeft = left ? -left / zoom + 'px' : '';\n content.style.marginTop = top ? -top / zoom + 'px' : '';\n content.style.zoom = zoom || '';\n };\n }\n}\n\nmodule.exports = getContentRender;\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\nexports = module.exports = __webpack_require__(8)();\n// imports\n\n\n// module\nexports.push([module.i, \"._v-container[data-v-ecaca2b0]{-webkit-tap-highlight-color:rgba(0,0,0,0);width:100%;height:100%;position:absolute;top:0;left:0;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}._v-container>._v-content[data-v-ecaca2b0]{width:100%;-webkit-transform-origin:left top;-webkit-transform:translateZ(0);-moz-transform-origin:left top;-moz-transform:translateZ(0);-ms-transform-origin:left top;-ms-transform:translateZ(0);-o-transform-origin:left top;-o-transform:translateZ(0);transform-origin:left top;transform:translateZ(0)}._v-container>._v-content>.pull-to-refresh-layer[data-v-ecaca2b0]{width:100%;height:60px;margin-top:-60px;text-align:center;font-size:16px;color:#aaa}._v-container>._v-content>.loading-layer[data-v-ecaca2b0]{width:100%;height:60px;text-align:center;font-size:16px;line-height:60px;color:#aaa;position:relative}._v-container>._v-content>.loading-layer>.no-data-text[data-v-ecaca2b0]{position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}._v-container>._v-content>.loading-layer>.no-data-text[data-v-ecaca2b0],._v-container>._v-content>.loading-layer>.spinner-holder[data-v-ecaca2b0]{opacity:0;transition:opacity .15s linear;-webkit-transition:opacity .15s linear}._v-container>._v-content>.loading-layer>.no-data-text.active[data-v-ecaca2b0],._v-container>._v-content>.loading-layer>.spinner-holder.active[data-v-ecaca2b0]{opacity:1}._v-container>._v-content>.loading-layer .spinner-holder[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder[data-v-ecaca2b0]{text-align:center;-webkit-font-smoothing:antialiased}._v-container>._v-content>.loading-layer .spinner-holder .arrow[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .arrow[data-v-ecaca2b0]{width:20px;height:20px;margin:8px auto 0;-webkit-transform:translateZ(0) rotate(0deg);transform:translateZ(0) rotate(0deg);transition:transform .2s linear}._v-container>._v-content>.loading-layer .spinner-holder .text[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .text[data-v-ecaca2b0]{display:block;margin:0 auto;font-size:14px;line-height:20px;color:#aaa}._v-container>._v-content>.loading-layer .spinner-holder .spinner[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .spinner[data-v-ecaca2b0]{margin-top:14px;width:32px;height:32px;fill:#444;stroke:#69717d}._v-container>._v-content>.pull-to-refresh-layer.active .spinner-holder .arrow[data-v-ecaca2b0]{-webkit-transform:translateZ(0) rotate(180deg);transform:translateZ(0) rotate(180deg)}\", \"\"]);\n\n// exports\n\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports) {\n\n/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Component = __webpack_require__(0)(\n /* script */\n __webpack_require__(2),\n /* template */\n __webpack_require__(11),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Component = __webpack_require__(0)(\n /* script */\n null,\n /* template */\n __webpack_require__(12),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('svg', {\n staticStyle: {\n \"enable-background\": \"new 0 0 63.657 63.657\"\n },\n attrs: {\n \"viewBox\": \"0 0 63.657 63.657\",\n \"xml:space\": \"preserve\",\n \"width\": \"512px\",\n \"height\": \"512px\"\n }\n }, [_c('g', [_c('g', [_c('g', [_c('g', [_c('polygon', {\n attrs: {\n \"points\": \"31.891,63.657 0.012,35.835 2.642,32.821 31.886,58.343 61.009,32.824 63.645,35.832\",\n \"fill\": _vm.fillColor\n }\n })])]), _vm._v(\" \"), _c('g', [_c('g', [_c('rect', {\n attrs: {\n \"x\": \"29.827\",\n \"width\": \"4\",\n \"height\": \"60\",\n \"fill\": _vm.fillColor\n }\n })])])]), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g')]), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g')])\n},staticRenderFns: []}\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('svg', {\n staticClass: \"spinner\",\n attrs: {\n \"viewBox\": \"0 0 64 64\"\n }\n }, [_c('g', {\n attrs: {\n \"stroke-width\": \"4\",\n \"stroke-linecap\": \"round\"\n }\n }, [_c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(180)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \"1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0;1\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(210)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \"0;1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(240)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".1;0;1;.85;.7;.65;.55;.45;.35;.25;.15;.1\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(270)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".15;.1;0;1;.85;.7;.65;.55;.45;.35;.25;.15\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(300)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".25;.15;.1;0;1;.85;.7;.65;.55;.45;.35;.25\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(330)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".35;.25;.15;.1;0;1;.85;.7;.65;.55;.45;.35\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(0)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".45;.35;.25;.15;.1;0;1;.85;.7;.65;.55;.45\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(30)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".55;.45;.35;.25;.15;.1;0;1;.85;.7;.65;.55\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(60)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".65;.55;.45;.35;.25;.15;.1;0;1;.85;.7;.65\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(90)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".7;.65;.55;.45;.35;.25;.15;.1;0;1;.85;.7\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(120)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".85;.7;.65;.55;.45;.35;.25;.15;.1;0;1;.85\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(150)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \"1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0;1\",\n \"repeatCount\": \"indefinite\"\n }\n })])])])\n},staticRenderFns: []}\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n staticClass: \"_v-container\",\n attrs: {\n \"id\": _vm.containerId\n },\n on: {\n \"touchstart\": function($event) {\n _vm.touchStart($event)\n },\n \"touchmove\": function($event) {\n _vm.touchMove($event)\n },\n \"touchend\": function($event) {\n _vm.touchEnd($event)\n },\n \"mousedown\": function($event) {\n _vm.mouseDown($event)\n },\n \"mousemove\": function($event) {\n _vm.mouseMove($event)\n },\n \"mouseup\": function($event) {\n _vm.mouseUp($event)\n }\n }\n }, [_c('div', {\n staticClass: \"_v-content\",\n attrs: {\n \"id\": _vm.contentId\n }\n }, [(_vm.onRefresh) ? _c('div', {\n staticClass: \"pull-to-refresh-layer\",\n class: {\n 'active': _vm.state == 1, 'active refreshing': _vm.state == 2\n }\n }, [_c('span', {\n staticClass: \"spinner-holder\"\n }, [(_vm.state != 2) ? _c('arrow', {\n staticClass: \"arrow\",\n attrs: {\n \"fillColor\": _vm.refreshLayerColor\n }\n }) : _vm._e(), _vm._v(\" \"), (_vm.state != 2) ? _c('span', {\n staticClass: \"text\",\n style: ({\n color: _vm.refreshLayerColor\n }),\n domProps: {\n \"textContent\": _vm._s(_vm.refreshText)\n }\n }) : _vm._e(), _vm._v(\" \"), (_vm.state == 2) ? _c('span', [_vm._t(\"refresh-spinner\", [_c('spinner', {\n style: ({\n fill: _vm.refreshLayerColor,\n stroke: _vm.refreshLayerColor\n })\n })])], 2) : _vm._e()], 1)]) : _vm._e(), _vm._v(\" \"), _vm._t(\"default\"), _vm._v(\" \"), (_vm.showInfiniteLayer) ? _c('div', {\n staticClass: \"loading-layer\"\n }, [_c('span', {\n staticClass: \"spinner-holder\",\n class: {\n 'active': _vm.showLoading\n }\n }, [_vm._t(\"infinite-spinner\", [_c('spinner', {\n style: ({\n fill: _vm.loadingLayerColor,\n stroke: _vm.loadingLayerColor\n })\n })])], 2), _vm._v(\" \"), _c('div', {\n staticClass: \"no-data-text\",\n class: {\n 'active': !_vm.showLoading && _vm.loadingState == 2\n },\n style: ({\n color: _vm.loadingLayerColor\n }),\n domProps: {\n \"textContent\": _vm._s(_vm.noDataText)\n }\n })]) : _vm._e()], 2)])\n},staticRenderFns: []}\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n// style-loader: Adds some css to the DOM by adding a \n\n\n\n\n// WEBPACK FOOTER //\n// Scroller.vue?7deee931","import Scroller from './components/Scroller.vue'\n\nfunction install (Vue) {\n if (install.installed) return\n install.installed = true\n Vue.component('scroller', Scroller)\n}\n\nconst VueScroller = {\n install: install,\n Scroller\n}\n\nif (typeof window !== undefined && window.Vue) {\n window.Vue.use(VueScroller)\n}\n\nexport default VueScroller\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","(function(window) {\n\tvar NOOP = function () {};\n\n\tvar core = (function Animate (global) {\n\t\t\n\t\tvar time = Date.now || function() {\n\t\t\treturn +new Date();\n\t\t};\n\n\t\tvar desiredFrames = 60;\n\t\tvar millisecondsPerSecond = 1000;\n\t\tvar running = {};\n\t\tvar counter = 1;\n\n\t\tvar core = { effect: {} };\n\n\t\tcore.effect.Animate = {\n\n\t\t\t/**\n\t\t\t * A requestAnimationFrame wrapper / polyfill.\n\t\t\t *\n\t\t\t * @param callback {Function} The callback to be invoked before the next repaint.\n\t\t\t * @param root {HTMLElement} The root element for the repaint\n\t\t\t */\n\t\t\trequestAnimationFrame: (function() {\n\n\t\t\t\t// Check for request animation Frame support\n\t\t\t\tvar requestFrame = global.requestAnimationFrame || global.webkitRequestAnimationFrame || global.mozRequestAnimationFrame || global.oRequestAnimationFrame;\n\t\t\t\tvar isNative = !!requestFrame;\n\n\t\t\t\tif (requestFrame && !/requestAnimationFrame\\(\\)\\s*\\{\\s*\\[native code\\]\\s*\\}/i.test(requestFrame.toString())) {\n\t\t\t\t\tisNative = false;\n\t\t\t\t}\n\n\t\t\t\tif (isNative) {\n\t\t\t\t\treturn function(callback, root) {\n\t\t\t\t\t\trequestFrame(callback, root)\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tvar TARGET_FPS = 60;\n\t\t\t\tvar requests = {};\n\t\t\t\tvar requestCount = 0;\n\t\t\t\tvar rafHandle = 1;\n\t\t\t\tvar intervalHandle = null;\n\t\t\t\tvar lastActive = +new Date();\n\n\t\t\t\treturn function(callback, root) {\n\t\t\t\t\tvar callbackHandle = rafHandle++;\n\n\t\t\t\t\t// Store callback\n\t\t\t\t\trequests[callbackHandle] = callback;\n\t\t\t\t\trequestCount++;\n\n\t\t\t\t\t// Create timeout at first request\n\t\t\t\t\tif (intervalHandle === null) {\n\n\t\t\t\t\t\tintervalHandle = setInterval(function() {\n\n\t\t\t\t\t\t\tvar time = +new Date();\n\t\t\t\t\t\t\tvar currentRequests = requests;\n\n\t\t\t\t\t\t\t// Reset data structure before executing callbacks\n\t\t\t\t\t\t\trequests = {};\n\t\t\t\t\t\t\trequestCount = 0;\n\n\t\t\t\t\t\t\tfor(var key in currentRequests) {\n\t\t\t\t\t\t\t\tif (currentRequests.hasOwnProperty(key)) {\n\t\t\t\t\t\t\t\t\tcurrentRequests[key](time);\n\t\t\t\t\t\t\t\t\tlastActive = time;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Disable the timeout when nothing happens for a certain\n\t\t\t\t\t\t\t// period of time\n\t\t\t\t\t\t\tif (time - lastActive > 2500) {\n\t\t\t\t\t\t\t\tclearInterval(intervalHandle);\n\t\t\t\t\t\t\t\tintervalHandle = null;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}, 1000 / TARGET_FPS);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn callbackHandle;\n\t\t\t\t};\n\n\t\t\t})(),\n\n\n\t\t\t/**\n\t\t\t * Stops the given animation.\n\t\t\t *\n\t\t\t * @param id {Integer} Unique animation ID\n\t\t\t * @return {Boolean} Whether the animation was stopped (aka, was running before)\n\t\t\t */\n\t\t\tstop: function(id) {\n\t\t\t\tvar cleared = running[id] != null;\n\t\t\t\tif (cleared) {\n\t\t\t\t\trunning[id] = null;\n\t\t\t\t}\n\n\t\t\t\treturn cleared;\n\t\t\t},\n\n\n\t\t\t/**\n\t\t\t * Whether the given animation is still running.\n\t\t\t *\n\t\t\t * @param id {Integer} Unique animation ID\n\t\t\t * @return {Boolean} Whether the animation is still running\n\t\t\t */\n\t\t\tisRunning: function(id) {\n\t\t\t\treturn running[id] != null;\n\t\t\t},\n\n\n\t\t\t/**\n\t\t\t * Start the animation.\n\t\t\t *\n\t\t\t * @param stepCallback {Function} Pointer to function which is executed on every step.\n\t\t\t * Signature of the method should be `function(percent, now, virtual) { return continueWithAnimation; }`\n\t\t\t * @param verifyCallback {Function} Executed before every animation step.\n\t\t\t * Signature of the method should be `function() { return continueWithAnimation; }`\n\t\t\t * @param completedCallback {Function}\n\t\t\t * Signature of the method should be `function(droppedFrames, finishedAnimation) {}`\n\t\t\t * @param duration {Integer} Milliseconds to run the animation\n\t\t\t * @param easingMethod {Function} Pointer to easing function\n\t\t\t * Signature of the method should be `function(percent) { return modifiedValue; }`\n\t\t\t * @param root {Element ? document.body} Render root, when available. Used for internal\n\t\t\t * usage of requestAnimationFrame.\n\t\t\t * @return {Integer} Identifier of animation. Can be used to stop it any time.\n\t\t\t */\n\t\t\tstart: function(stepCallback, verifyCallback, completedCallback, duration, easingMethod, root) {\n\n\t\t\t\tvar start = time();\n\t\t\t\tvar lastFrame = start;\n\t\t\t\tvar percent = 0;\n\t\t\t\tvar dropCounter = 0;\n\t\t\t\tvar id = counter++;\n\n\t\t\t\tif (!root) {\n\t\t\t\t\troot = document.body;\n\t\t\t\t}\n\n\t\t\t\t// Compacting running db automatically every few new animations\n\t\t\t\tif (id % 20 === 0) {\n\t\t\t\t\tvar newRunning = {};\n\t\t\t\t\tfor (var usedId in running) {\n\t\t\t\t\t\tnewRunning[usedId] = true;\n\t\t\t\t\t}\n\t\t\t\t\trunning = newRunning;\n\t\t\t\t}\n\n\t\t\t\t// This is the internal step method which is called every few milliseconds\n\t\t\t\tvar step = function(virtual) {\n\n\t\t\t\t\t// Normalize virtual value\n\t\t\t\t\tvar render = virtual !== true;\n\n\t\t\t\t\t// Get current time\n\t\t\t\t\tvar now = time();\n\n\t\t\t\t\t// Verification is executed before next animation step\n\t\t\t\t\tif (!running[id] || (verifyCallback && !verifyCallback(id))) {\n\n\t\t\t\t\t\trunning[id] = null;\n\t\t\t\t\t\tcompletedCallback && completedCallback(desiredFrames - (dropCounter / ((now - start) / millisecondsPerSecond)), id, false);\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// For the current rendering to apply let's update omitted steps in memory.\n\t\t\t\t\t// This is important to bring internal state variables up-to-date with progress in time.\n\t\t\t\t\tif (render) {\n\n\t\t\t\t\t\tvar droppedFrames = Math.round((now - lastFrame) / (millisecondsPerSecond / desiredFrames)) - 1;\n\t\t\t\t\t\tfor (var j = 0; j < Math.min(droppedFrames, 4); j++) {\n\t\t\t\t\t\t\tstep(true);\n\t\t\t\t\t\t\tdropCounter++;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Compute percent value\n\t\t\t\t\tif (duration) {\n\t\t\t\t\t\tpercent = (now - start) / duration;\n\t\t\t\t\t\tif (percent > 1) {\n\t\t\t\t\t\t\tpercent = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Execute step callback, then...\n\t\t\t\t\tvar value = easingMethod ? easingMethod(percent) : percent;\n\t\t\t\t\tif ((stepCallback(value, now, render) === false || percent === 1) && render) {\n\t\t\t\t\t\trunning[id] = null;\n\t\t\t\t\t\tcompletedCallback && completedCallback(desiredFrames - (dropCounter / ((now - start) / millisecondsPerSecond)), id, percent === 1 || duration == null);\n\t\t\t\t\t} else if (render) {\n\t\t\t\t\t\tlastFrame = now;\n\t\t\t\t\t\tcore.effect.Animate.requestAnimationFrame(step, root);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Mark as running\n\t\t\t\trunning[id] = true;\n\n\t\t\t\t// Init first step\n\t\t\t\tcore.effect.Animate.requestAnimationFrame(step, root);\n\n\t\t\t\t// Return unique animation ID\n\t\t\t\treturn id;\n\t\t\t}\n\t\t};\n\n\t\treturn core;\n\n\t})(window);\n\n\t/**\n\t * A pure logic 'component' for 'virtual' scrolling/zooming.\n\t */\n\tvar Scroller = function(callback, options) {\n\n\t\tthis.__callback = callback;\n // core = animate;\n\n\t\tthis.options = {\n\n\t\t\t/** Enable scrolling on x-axis */\n\t\t\tscrollingX: true,\n\n\t\t\t/** Enable scrolling on y-axis */\n\t\t\tscrollingY: true,\n\n\t\t\t/** Enable animations for deceleration, snap back, zooming and scrolling */\n\t\t\tanimating: true,\n\n\t\t\t/** duration for animations triggered by scrollTo/zoomTo */\n\t\t\tanimationDuration: 250,\n\n\t\t\t/** Enable bouncing (content can be slowly moved outside and jumps back after releasing) */\n\t\t\tbouncing: true,\n\n\t\t\t/** Enable locking to the main axis if user moves only slightly on one of them at start */\n\t\t\tlocking: true,\n\n\t\t\t/** Enable pagination mode (switching between full page content panes) */\n\t\t\tpaging: false,\n\n\t\t\t/** Enable snapping of content to a configured pixel grid */\n\t\t\tsnapping: false,\n\n\t\t\t/** Enable zooming of content via API, fingers and mouse wheel */\n\t\t\tzooming: false,\n\n\t\t\t/** Minimum zoom level */\n\t\t\tminZoom: 0.5,\n\n\t\t\t/** Maximum zoom level */\n\t\t\tmaxZoom: 3,\n\n\t\t\t/** Multiply or decrease scrolling speed **/\n\t\t\tspeedMultiplier: 1,\n\n\t\t\t/** Callback that is fired on the later of touch end or deceleration end,\n\t\t\t\tprovided that another scrolling action has not begun. Used to know\n\t\t\t\twhen to fade out a scrollbar. */\n\t\t\tscrollingComplete: NOOP,\n\n\t\t\t/** This configures the amount of change applied to deceleration when reaching boundaries **/\n penetrationDeceleration : 0.03,\n\n /** This configures the amount of change applied to acceleration when reaching boundaries **/\n penetrationAcceleration : 0.08\n\n\t\t};\n\n\t\tfor (var key in options) {\n\t\t\tthis.options[key] = options[key];\n\t\t}\n\n\t};\n\n\n\t// Easing Equations (c) 2003 Robert Penner, all rights reserved.\n\t// Open source under the BSD License.\n\n\t/**\n\t * @param pos {Number} position between 0 (start of effect) and 1 (end of effect)\n\t**/\n\tvar easeOutCubic = function(pos) {\n\t\treturn (Math.pow((pos - 1), 3) + 1);\n\t};\n\n\t/**\n\t * @param pos {Number} position between 0 (start of effect) and 1 (end of effect)\n\t**/\n\tvar easeInOutCubic = function(pos) {\n\t\tif ((pos /= 0.5) < 1) {\n\t\t\treturn 0.5 * Math.pow(pos, 3);\n\t\t}\n\n\t\treturn 0.5 * (Math.pow((pos - 2), 3) + 2);\n\t};\n\n\n\tvar members = {\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tINTERNAL FIELDS :: STATUS\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/** {Boolean} Whether only a single finger is used in touch handling */\n\t\t__isSingleTouch: false,\n\n\t\t/** {Boolean} Whether a touch event sequence is in progress */\n\t\t__isTracking: false,\n\n\t\t/** {Boolean} Whether a deceleration animation went to completion. */\n\t\t__didDecelerationComplete: false,\n\n\t\t/**\n\t\t * {Boolean} Whether a gesture zoom/rotate event is in progress. Activates when\n\t\t * a gesturestart event happens. This has higher priority than dragging.\n\t\t */\n\t\t__isGesturing: false,\n\n\t\t/**\n\t\t * {Boolean} Whether the user has moved by such a distance that we have enabled\n\t\t * dragging mode. Hint: It's only enabled after some pixels of movement to\n\t\t * not interrupt with clicks etc.\n\t\t */\n\t\t__isDragging: false,\n\n\t\t/**\n\t\t * {Boolean} Not touching and dragging anymore, and smoothly animating the\n\t\t * touch sequence using deceleration.\n\t\t */\n\t\t__isDecelerating: false,\n\n\t\t/**\n\t\t * {Boolean} Smoothly animating the currently configured change\n\t\t */\n\t\t__isAnimating: false,\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tINTERNAL FIELDS :: DIMENSIONS\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/** {Integer} Available outer left position (from document perspective) */\n\t\t__clientLeft: 0,\n\n\t\t/** {Integer} Available outer top position (from document perspective) */\n\t\t__clientTop: 0,\n\n\t\t/** {Integer} Available outer width */\n\t\t__clientWidth: 0,\n\n\t\t/** {Integer} Available outer height */\n\t\t__clientHeight: 0,\n\n\t\t/** {Integer} Outer width of content */\n\t\t__contentWidth: 0,\n\n\t\t/** {Integer} Outer height of content */\n\t\t__contentHeight: 0,\n\n\t\t/** {Integer} Snapping width for content */\n\t\t__snapWidth: 100,\n\n\t\t/** {Integer} Snapping height for content */\n\t\t__snapHeight: 100,\n\n\t\t/** {Integer} Height to assign to refresh area */\n\t\t__refreshHeight: null,\n\n\t\t/** {Boolean} Whether the refresh process is enabled when the event is released now */\n\t\t__refreshActive: false,\n\n\t\t/** {Function} Callback to execute on activation. This is for signalling the user about a refresh is about to happen when he release */\n\t\t__refreshActivate: null,\n\n\t\t/** {Function} Callback to execute on deactivation. This is for signalling the user about the refresh being cancelled */\n\t\t__refreshDeactivate: null,\n\n\t\t/** {Function} Callback to execute to start the actual refresh. Call {@link #refreshFinish} when done */\n\t\t__refreshStart: null,\n\n\t\t/** {Number} Zoom level */\n\t\t__zoomLevel: 1,\n\n\t\t/** {Number} Scroll position on x-axis */\n\t\t__scrollLeft: 0,\n\n\t\t/** {Number} Scroll position on y-axis */\n\t\t__scrollTop: 0,\n\n\t\t/** {Integer} Maximum allowed scroll position on x-axis */\n\t\t__maxScrollLeft: 0,\n\n\t\t/** {Integer} Maximum allowed scroll position on y-axis */\n\t\t__maxScrollTop: 0,\n\n\t\t/* {Number} Scheduled left position (final position when animating) */\n\t\t__scheduledLeft: 0,\n\n\t\t/* {Number} Scheduled top position (final position when animating) */\n\t\t__scheduledTop: 0,\n\n\t\t/* {Number} Scheduled zoom level (final scale when animating) */\n\t\t__scheduledZoom: 0,\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tINTERNAL FIELDS :: LAST POSITIONS\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/** {Number} Left position of finger at start */\n\t\t__lastTouchLeft: null,\n\n\t\t/** {Number} Top position of finger at start */\n\t\t__lastTouchTop: null,\n\n\t\t/** {Date} Timestamp of last move of finger. Used to limit tracking range for deceleration speed. */\n\t\t__lastTouchMove: null,\n\n\t\t/** {Array} List of positions, uses three indexes for each state: left, top, timestamp */\n\t\t__positions: null,\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tINTERNAL FIELDS :: DECELERATION SUPPORT\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/** {Integer} Minimum left scroll position during deceleration */\n\t\t__minDecelerationScrollLeft: null,\n\n\t\t/** {Integer} Minimum top scroll position during deceleration */\n\t\t__minDecelerationScrollTop: null,\n\n\t\t/** {Integer} Maximum left scroll position during deceleration */\n\t\t__maxDecelerationScrollLeft: null,\n\n\t\t/** {Integer} Maximum top scroll position during deceleration */\n\t\t__maxDecelerationScrollTop: null,\n\n\t\t/** {Number} Current factor to modify horizontal scroll position with on every step */\n\t\t__decelerationVelocityX: null,\n\n\t\t/** {Number} Current factor to modify vertical scroll position with on every step */\n\t\t__decelerationVelocityY: null,\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tPUBLIC API\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/**\n\t\t * Configures the dimensions of the client (outer) and content (inner) elements.\n\t\t * Requires the available space for the outer element and the outer size of the inner element.\n\t\t * All values which are falsy (null or zero etc.) are ignored and the old value is kept.\n\t\t *\n\t\t * @param clientWidth {Integer ? null} Inner width of outer element\n\t\t * @param clientHeight {Integer ? null} Inner height of outer element\n\t\t * @param contentWidth {Integer ? null} Outer width of inner element\n\t\t * @param contentHeight {Integer ? null} Outer height of inner element\n\t\t */\n\t\tsetDimensions: function(clientWidth, clientHeight, contentWidth, contentHeight) {\n\n\t\t\tvar self = this;\n\n\t\t\t// Only update values which are defined\n\t\t\tif (clientWidth === +clientWidth) {\n\t\t\t\tself.__clientWidth = clientWidth;\n\t\t\t}\n\n\t\t\tif (clientHeight === +clientHeight) {\n\t\t\t\tself.__clientHeight = clientHeight;\n\t\t\t}\n\n\t\t\tif (contentWidth === +contentWidth) {\n\t\t\t\tself.__contentWidth = contentWidth;\n\t\t\t}\n\n\t\t\tif (contentHeight === +contentHeight) {\n\t\t\t\tself.__contentHeight = contentHeight;\n\t\t\t}\n\n\t\t\t// Refresh maximums\n\t\t\tself.__computeScrollMax();\n\n\t\t\t// Refresh scroll position\n\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, true);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Sets the client coordinates in relation to the document.\n\t\t *\n\t\t * @param left {Integer ? 0} Left position of outer element\n\t\t * @param top {Integer ? 0} Top position of outer element\n\t\t */\n\t\tsetPosition: function(left, top) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__clientLeft = left || 0;\n\t\t\tself.__clientTop = top || 0;\n\n\t\t},\n\n\n\t\t/**\n\t\t * Configures the snapping (when snapping is active)\n\t\t *\n\t\t * @param width {Integer} Snapping width\n\t\t * @param height {Integer} Snapping height\n\t\t */\n\t\tsetSnapSize: function(width, height) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__snapWidth = width;\n\t\t\tself.__snapHeight = height;\n\n\t\t},\n\n\n\t\t/**\n\t\t * Activates pull-to-refresh. A special zone on the top of the list to start a list refresh whenever\n\t\t * the user event is released during visibility of this zone. This was introduced by some apps on iOS like\n\t\t * the official Twitter client.\n\t\t *\n\t\t * @param height {Integer} Height of pull-to-refresh zone on top of rendered list\n\t\t * @param activateCallback {Function} Callback to execute on activation. This is for signalling the user about a refresh is about to happen when he release.\n\t\t * @param deactivateCallback {Function} Callback to execute on deactivation. This is for signalling the user about the refresh being cancelled.\n\t\t * @param startCallback {Function} Callback to execute to start the real async refresh action. Call {@link #finishPullToRefresh} after finish of refresh.\n\t\t */\n\t\tactivatePullToRefresh: function(height, activateCallback, deactivateCallback, startCallback) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__refreshHeight = height;\n\t\t\tself.__refreshActivate = activateCallback;\n\t\t\tself.__refreshDeactivate = deactivateCallback;\n\t\t\tself.__refreshStart = startCallback;\n\n\t\t},\n\n\n\t\t/**\n\t\t * Starts pull-to-refresh manually.\n\t\t */\n\t\ttriggerPullToRefresh: function() {\n\t\t\t// Use publish instead of scrollTo to allow scrolling to out of boundary position\n\t\t\t// We don't need to normalize scrollLeft, zoomLevel, etc. here because we only y-scrolling when pull-to-refresh is enabled\n\t\t\tthis.__publish(this.__scrollLeft, -this.__refreshHeight, this.__zoomLevel, true);\n\n\t\t\tif (this.__refreshStart) {\n\t\t\t\tthis.__refreshStart();\n\t\t\t}\n\t\t},\n\n\n\t\t/**\n\t\t * Signalizes that pull-to-refresh is finished.\n\t\t */\n\t\tfinishPullToRefresh: function() {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__refreshActive = false;\n\t\t\tif (self.__refreshDeactivate) {\n\t\t\t\tself.__refreshDeactivate();\n\t\t\t}\n\n\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, true);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Returns the scroll position and zooming values\n\t\t *\n\t\t * @return {Map} `left` and `top` scroll position and `zoom` level\n\t\t */\n\t\tgetValues: function() {\n\n\t\t\tvar self = this;\n\n\t\t\treturn {\n\t\t\t\tleft: self.__scrollLeft,\n\t\t\t\ttop: self.__scrollTop,\n\t\t\t\tzoom: self.__zoomLevel\n\t\t\t};\n\n\t\t},\n\n\n\t\t/**\n\t\t * Returns the maximum scroll values\n\t\t *\n\t\t * @return {Map} `left` and `top` maximum scroll values\n\t\t */\n\t\tgetScrollMax: function() {\n\n\t\t\tvar self = this;\n\n\t\t\treturn {\n\t\t\t\tleft: self.__maxScrollLeft,\n\t\t\t\ttop: self.__maxScrollTop\n\t\t\t};\n\n\t\t},\n\n\n\t\t/**\n\t\t * Zooms to the given level. Supports optional animation. Zooms\n\t\t * the center when no coordinates are given.\n\t\t *\n\t\t * @param level {Number} Level to zoom to\n\t\t * @param animate {Boolean ? false} Whether to use animation\n\t\t * @param originLeft {Number ? null} Zoom in at given left coordinate\n\t\t * @param originTop {Number ? null} Zoom in at given top coordinate\n\t\t * @param callback {Function ? null} A callback that gets fired when the zoom is complete.\n\t\t */\n\t\tzoomTo: function(level, animate, originLeft, originTop, callback) {\n\n\t\t\tvar self = this;\n\n\t\t\tif (!self.options.zooming) {\n\t\t\t\tthrow new Error(\"Zooming is not enabled!\");\n\t\t\t}\n\n\t\t\t// Add callback if exists\n\t\t\tif(callback) {\n\t\t\t\tself.__zoomComplete = callback;\n\t\t\t}\n\n\t\t\t// Stop deceleration\n\t\t\tif (self.__isDecelerating) {\n\t\t\t\tcore.effect.Animate.stop(self.__isDecelerating);\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t}\n\n\t\t\tvar oldLevel = self.__zoomLevel;\n\n\t\t\t// Normalize input origin to center of viewport if not defined\n\t\t\tif (originLeft == null) {\n\t\t\t\toriginLeft = self.__clientWidth / 2;\n\t\t\t}\n\n\t\t\tif (originTop == null) {\n\t\t\t\toriginTop = self.__clientHeight / 2;\n\t\t\t}\n\n\t\t\t// Limit level according to configuration\n\t\t\tlevel = Math.max(Math.min(level, self.options.maxZoom), self.options.minZoom);\n\n\t\t\t// Recompute maximum values while temporary tweaking maximum scroll ranges\n\t\t\tself.__computeScrollMax(level);\n\n\t\t\t// Recompute left and top coordinates based on new zoom level\n\t\t\tvar left = ((originLeft + self.__scrollLeft) * level / oldLevel) - originLeft;\n\t\t\tvar top = ((originTop + self.__scrollTop) * level / oldLevel) - originTop;\n\n\t\t\t// Limit x-axis\n\t\t\tif (left > self.__maxScrollLeft) {\n\t\t\t\tleft = self.__maxScrollLeft;\n\t\t\t} else if (left < 0) {\n\t\t\t\tleft = 0;\n\t\t\t}\n\n\t\t\t// Limit y-axis\n\t\t\tif (top > self.__maxScrollTop) {\n\t\t\t\ttop = self.__maxScrollTop;\n\t\t\t} else if (top < 0) {\n\t\t\t\ttop = 0;\n\t\t\t}\n\n\t\t\t// Push values out\n\t\t\tself.__publish(left, top, level, animate);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Zooms the content by the given factor.\n\t\t *\n\t\t * @param factor {Number} Zoom by given factor\n\t\t * @param animate {Boolean ? false} Whether to use animation\n\t\t * @param originLeft {Number ? 0} Zoom in at given left coordinate\n\t\t * @param originTop {Number ? 0} Zoom in at given top coordinate\n\t\t * @param callback {Function ? null} A callback that gets fired when the zoom is complete.\n\t\t */\n\t\tzoomBy: function(factor, animate, originLeft, originTop, callback) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.zoomTo(self.__zoomLevel * factor, animate, originLeft, originTop, callback);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Scrolls to the given position. Respect limitations and snapping automatically.\n\t\t *\n\t\t * @param left {Number?null} Horizontal scroll position, keeps current if value is null\n\t\t * @param top {Number?null} Vertical scroll position, keeps current if value is null\n\t\t * @param animate {Boolean?false} Whether the scrolling should happen using an animation\n\t\t * @param zoom {Number?null} Zoom level to go to\n\t\t */\n\t\tscrollTo: function(left, top, animate, zoom) {\n\n\t\t\tvar self = this;\n\n\t\t\t// Stop deceleration\n\t\t\tif (self.__isDecelerating) {\n\t\t\t\tcore.effect.Animate.stop(self.__isDecelerating);\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t}\n\n\t\t\t// Correct coordinates based on new zoom level\n\t\t\tif (zoom != null && zoom !== self.__zoomLevel) {\n\n\t\t\t\tif (!self.options.zooming) {\n\t\t\t\t\tthrow new Error(\"Zooming is not enabled!\");\n\t\t\t\t}\n\n\t\t\t\tleft *= zoom;\n\t\t\t\ttop *= zoom;\n\n\t\t\t\t// Recompute maximum values while temporary tweaking maximum scroll ranges\n\t\t\t\tself.__computeScrollMax(zoom);\n\n\t\t\t} else {\n\n\t\t\t\t// Keep zoom when not defined\n\t\t\t\tzoom = self.__zoomLevel;\n\n\t\t\t}\n\n\t\t\tif (!self.options.scrollingX) {\n\n\t\t\t\tleft = self.__scrollLeft;\n\n\t\t\t} else {\n\n\t\t\t\tif (self.options.paging) {\n\t\t\t\t\tleft = Math.round(left / self.__clientWidth) * self.__clientWidth;\n\t\t\t\t} else if (self.options.snapping) {\n\t\t\t\t\tleft = Math.round(left / self.__snapWidth) * self.__snapWidth;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif (!self.options.scrollingY) {\n\n\t\t\t\ttop = self.__scrollTop;\n\n\t\t\t} else {\n\n\t\t\t\tif (self.options.paging) {\n\t\t\t\t\ttop = Math.round(top / self.__clientHeight) * self.__clientHeight;\n\t\t\t\t} else if (self.options.snapping) {\n\t\t\t\t\ttop = Math.round(top / self.__snapHeight) * self.__snapHeight;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Limit for allowed ranges\n\t\t\tleft = Math.max(Math.min(self.__maxScrollLeft, left), 0);\n\t\t\ttop = Math.max(Math.min(self.__maxScrollTop, top), 0);\n\n\t\t\t// Don't animate when no change detected, still call publish to make sure\n\t\t\t// that rendered position is really in-sync with internal data\n\t\t\tif (left === self.__scrollLeft && top === self.__scrollTop) {\n\t\t\t\tanimate = false;\n\t\t\t}\n\n\t\t\t// Publish new values\n\t\t\tif (!self.__isTracking) {\n self.__publish(left, top, zoom, animate);\n }\n\n\t\t},\n\n\n\t\t/**\n\t\t * Scroll by the given offset\n\t\t *\n\t\t * @param left {Number ? 0} Scroll x-axis by given offset\n\t\t * @param top {Number ? 0} Scroll x-axis by given offset\n\t\t * @param animate {Boolean ? false} Whether to animate the given change\n\t\t */\n\t\tscrollBy: function(left, top, animate) {\n\n\t\t\tvar self = this;\n\n\t\t\tvar startLeft = self.__isAnimating ? self.__scheduledLeft : self.__scrollLeft;\n\t\t\tvar startTop = self.__isAnimating ? self.__scheduledTop : self.__scrollTop;\n\n\t\t\tself.scrollTo(startLeft + (left || 0), startTop + (top || 0), animate);\n\n\t\t},\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tEVENT CALLBACKS\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/**\n\t\t * Mouse wheel handler for zooming support\n\t\t */\n\t\tdoMouseZoom: function(wheelDelta, timeStamp, pageX, pageY) {\n\n\t\t\tvar self = this;\n\t\t\tvar change = wheelDelta > 0 ? 0.97 : 1.03;\n\n\t\t\treturn self.zoomTo(self.__zoomLevel * change, false, pageX - self.__clientLeft, pageY - self.__clientTop);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Touch start handler for scrolling support\n\t\t */\n\t\tdoTouchStart: function(touches, timeStamp) {\n\t\t\t// Array-like check is enough here\n\t\t\tif (touches.length == null) {\n\t\t\t\tthrow new Error(\"Invalid touch list: \" + touches);\n\t\t\t}\n\n\t\t\tif (timeStamp instanceof Date) {\n\t\t\t\ttimeStamp = timeStamp.valueOf();\n\t\t\t}\n\t\t\tif (typeof timeStamp !== \"number\") {\n\t\t\t\tthrow new Error(\"Invalid timestamp value: \" + timeStamp);\n\t\t\t}\n\n\t\t\tvar self = this;\n\n\t\t\t// Reset interruptedAnimation flag\n\t\t\tself.__interruptedAnimation = true;\n\n\t\t\t// Stop deceleration\n\t\t\tif (self.__isDecelerating) {\n\t\t\t\tcore.effect.Animate.stop(self.__isDecelerating);\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t\tself.__interruptedAnimation = true;\n\t\t\t}\n\n\t\t\t// Stop animation\n\t\t\tif (self.__isAnimating) {\n core.effect.Animate.stop(self.__isAnimating);\n\t\t\t\tself.__isAnimating = false;\n\t\t\t\tself.__interruptedAnimation = true;\n\t\t\t}\n\n\t\t\t// Use center point when dealing with two fingers\n\t\t\tvar currentTouchLeft, currentTouchTop;\n\t\t\tvar isSingleTouch = touches.length === 1;\n\t\t\tif (isSingleTouch) {\n\t\t\t\tcurrentTouchLeft = touches[0].pageX;\n\t\t\t\tcurrentTouchTop = touches[0].pageY;\n\t\t\t} else {\n\t\t\t\tcurrentTouchLeft = Math.abs(touches[0].pageX + touches[1].pageX) / 2;\n\t\t\t\tcurrentTouchTop = Math.abs(touches[0].pageY + touches[1].pageY) / 2;\n\t\t\t}\n\n\t\t\t// Store initial positions\n\t\t\tself.__initialTouchLeft = currentTouchLeft;\n\t\t\tself.__initialTouchTop = currentTouchTop;\n\n\t\t\t// Store current zoom level\n\t\t\tself.__zoomLevelStart = self.__zoomLevel;\n\n\t\t\t// Store initial touch positions\n\t\t\tself.__lastTouchLeft = currentTouchLeft;\n\t\t\tself.__lastTouchTop = currentTouchTop;\n\n\t\t\t// Store initial move time stamp\n\t\t\tself.__lastTouchMove = timeStamp;\n\n\t\t\t// Reset initial scale\n\t\t\tself.__lastScale = 1;\n\n\t\t\t// Reset locking flags\n\t\t\tself.__enableScrollX = !isSingleTouch && self.options.scrollingX;\n\t\t\tself.__enableScrollY = !isSingleTouch && self.options.scrollingY;\n\n\t\t\t// Reset tracking flag\n\t\t\tself.__isTracking = true;\n\n\t\t\t// Reset deceleration complete flag\n\t\t\tself.__didDecelerationComplete = false;\n\n\t\t\t// Dragging starts directly with two fingers, otherwise lazy with an offset\n\t\t\tself.__isDragging = !isSingleTouch;\n\n\t\t\t// Some features are disabled in multi touch scenarios\n\t\t\tself.__isSingleTouch = isSingleTouch;\n\n\t\t\t// Clearing data structure\n\t\t\tself.__positions = [];\n\n\t\t},\n\n\n\t\t/**\n\t\t * Touch move handler for scrolling support\n\t\t */\n\t\tdoTouchMove: function(touches, timeStamp, scale) {\n\n\t\t\t// Array-like check is enough here\n\t\t\tif (touches.length == null) {\n\t\t\t\tthrow new Error(\"Invalid touch list: \" + touches);\n\t\t\t}\n\n\t\t\tif (timeStamp instanceof Date) {\n\t\t\t\ttimeStamp = timeStamp.valueOf();\n\t\t\t}\n\t\t\tif (typeof timeStamp !== \"number\") {\n\t\t\t\tthrow new Error(\"Invalid timestamp value: \" + timeStamp);\n\t\t\t}\n\n\t\t\tvar self = this;\n\n\t\t\t// Ignore event when tracking is not enabled (event might be outside of element)\n\t\t\tif (!self.__isTracking) {\n\t\t\t\treturn;\n\t\t\t}\n\n\n\t\t\tvar currentTouchLeft, currentTouchTop;\n\n\t\t\t// Compute move based around of center of fingers\n\t\t\tif (touches.length === 2) {\n\t\t\t\tcurrentTouchLeft = Math.abs(touches[0].pageX + touches[1].pageX) / 2;\n\t\t\t\tcurrentTouchTop = Math.abs(touches[0].pageY + touches[1].pageY) / 2;\n\t\t\t} else {\n\t\t\t\tcurrentTouchLeft = touches[0].pageX;\n\t\t\t\tcurrentTouchTop = touches[0].pageY;\n\t\t\t}\n\n\t\t\tvar positions = self.__positions;\n\n\t\t\t// Are we already is dragging mode?\n\t\t\tif (self.__isDragging) {\n\n\t\t\t\t// Compute move distance\n\t\t\t\tvar moveX = currentTouchLeft - self.__lastTouchLeft;\n\t\t\t\tvar moveY = currentTouchTop - self.__lastTouchTop;\n\n\t\t\t\t// Read previous scroll position and zooming\n\t\t\t\tvar scrollLeft = self.__scrollLeft;\n\t\t\t\tvar scrollTop = self.__scrollTop;\n\t\t\t\tvar level = self.__zoomLevel;\n\n\t\t\t\t// Work with scaling\n\t\t\t\tif (scale != null && self.options.zooming) {\n\n\t\t\t\t\tvar oldLevel = level;\n\n\t\t\t\t\t// Recompute level based on previous scale and new scale\n\t\t\t\t\tlevel = level / self.__lastScale * scale;\n\n\t\t\t\t\t// Limit level according to configuration\n\t\t\t\t\tlevel = Math.max(Math.min(level, self.options.maxZoom), self.options.minZoom);\n\n\t\t\t\t\t// Only do further compution when change happened\n\t\t\t\t\tif (oldLevel !== level) {\n\n\t\t\t\t\t\t// Compute relative event position to container\n\t\t\t\t\t\tvar currentTouchLeftRel = currentTouchLeft - self.__clientLeft;\n\t\t\t\t\t\tvar currentTouchTopRel = currentTouchTop - self.__clientTop;\n\n\t\t\t\t\t\t// Recompute left and top coordinates based on new zoom level\n\t\t\t\t\t\tscrollLeft = ((currentTouchLeftRel + scrollLeft) * level / oldLevel) - currentTouchLeftRel;\n\t\t\t\t\t\tscrollTop = ((currentTouchTopRel + scrollTop) * level / oldLevel) - currentTouchTopRel;\n\n\t\t\t\t\t\t// Recompute max scroll values\n\t\t\t\t\t\tself.__computeScrollMax(level);\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (self.__enableScrollX) {\n\n\t\t\t\t\tscrollLeft -= moveX * this.options.speedMultiplier;\n\t\t\t\t\tvar maxScrollLeft = self.__maxScrollLeft;\n\n\t\t\t\t\tif (scrollLeft > maxScrollLeft || scrollLeft < 0) {\n\n\t\t\t\t\t\t// Slow down on the edges\n\t\t\t\t\t\tif (self.options.bouncing) {\n\n\t\t\t\t\t\t\tscrollLeft += (moveX / 2 * this.options.speedMultiplier);\n\n\t\t\t\t\t\t} else if (scrollLeft > maxScrollLeft) {\n\n\t\t\t\t\t\t\tscrollLeft = maxScrollLeft;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tscrollLeft = 0;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Compute new vertical scroll position\n\t\t\t\tif (self.__enableScrollY) {\n\n\t\t\t\t\tscrollTop -= moveY * this.options.speedMultiplier;\n\t\t\t\t\tvar maxScrollTop = self.__maxScrollTop;\n\n\t\t\t\t\tif (scrollTop > maxScrollTop || scrollTop < 0) {\n\n\t\t\t\t\t\t// Slow down on the edges\n\t\t\t\t\t\tif (self.options.bouncing) {\n\n\t\t\t\t\t\t\tscrollTop += (moveY / 2 * this.options.speedMultiplier);\n\n\t\t\t\t\t\t\t// Support pull-to-refresh (only when only y is scrollable)\n\t\t\t\t\t\t\tif (!self.__enableScrollX && self.__refreshHeight != null) {\n\n\t\t\t\t\t\t\t\tif (!self.__refreshActive && scrollTop <= -self.__refreshHeight) {\n\n\t\t\t\t\t\t\t\t\tself.__refreshActive = true;\n\t\t\t\t\t\t\t\t\tif (self.__refreshActivate) {\n\t\t\t\t\t\t\t\t\t\tself.__refreshActivate();\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else if (self.__refreshActive && scrollTop > -self.__refreshHeight) {\n\n\t\t\t\t\t\t\t\t\tself.__refreshActive = false;\n\t\t\t\t\t\t\t\t\tif (self.__refreshDeactivate) {\n\t\t\t\t\t\t\t\t\t\tself.__refreshDeactivate();\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if (scrollTop > maxScrollTop) {\n\n\t\t\t\t\t\t\tscrollTop = maxScrollTop;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tscrollTop = 0;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Keep list from growing infinitely (holding min 10, max 20 measure points)\n\t\t\t\tif (positions.length > 60) {\n\t\t\t\t\tpositions.splice(0, 30);\n\t\t\t\t}\n\n\t\t\t\t// Track scroll movement for decleration\n\t\t\t\tpositions.push(scrollLeft, scrollTop, timeStamp);\n\n\t\t\t\t// Sync scroll position\n\t\t\t\tself.__publish(scrollLeft, scrollTop, level);\n\n\t\t\t// Otherwise figure out whether we are switching into dragging mode now.\n\t\t\t} else {\n\n\t\t\t\tvar minimumTrackingForScroll = self.options.locking ? 3 : 0;\n\t\t\t\tvar minimumTrackingForDrag = 5;\n\n\t\t\t\tvar distanceX = Math.abs(currentTouchLeft - self.__initialTouchLeft);\n\t\t\t\tvar distanceY = Math.abs(currentTouchTop - self.__initialTouchTop);\n\n\t\t\t\tself.__enableScrollX = self.options.scrollingX && distanceX >= minimumTrackingForScroll;\n\t\t\t\tself.__enableScrollY = self.options.scrollingY && distanceY >= minimumTrackingForScroll;\n\n\t\t\t\tpositions.push(self.__scrollLeft, self.__scrollTop, timeStamp);\n\n\t\t\t\tself.__isDragging = (self.__enableScrollX || self.__enableScrollY) && (distanceX >= minimumTrackingForDrag || distanceY >= minimumTrackingForDrag);\n\t\t\t\tif (self.__isDragging) {\n\t\t\t\t\tself.__interruptedAnimation = false;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Update last touch positions and time stamp for next event\n\t\t\tself.__lastTouchLeft = currentTouchLeft;\n\t\t\tself.__lastTouchTop = currentTouchTop;\n\t\t\tself.__lastTouchMove = timeStamp;\n\t\t\tself.__lastScale = scale;\n\n\t\t},\n\n\n\t\t/**\n\t\t * Touch end handler for scrolling support\n\t\t */\n\t\tdoTouchEnd: function(timeStamp) {\n\n\t\t\tif (timeStamp instanceof Date) {\n\t\t\t\ttimeStamp = timeStamp.valueOf();\n\t\t\t}\n\t\t\tif (typeof timeStamp !== \"number\") {\n\t\t\t\tthrow new Error(\"Invalid timestamp value: \" + timeStamp);\n\t\t\t}\n\n\t\t\tvar self = this;\n\n\t\t\t// Ignore event when tracking is not enabled (no touchstart event on element)\n\t\t\t// This is required as this listener ('touchmove') sits on the document and not on the element itself.\n\t\t\tif (!self.__isTracking) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Not touching anymore (when two finger hit the screen there are two touch end events)\n\t\t\tself.__isTracking = false;\n\n\t\t\t// Be sure to reset the dragging flag now. Here we also detect whether\n\t\t\t// the finger has moved fast enough to switch into a deceleration animation.\n\t\t\tif (self.__isDragging) {\n\n\t\t\t\t// Reset dragging flag\n\t\t\t\tself.__isDragging = false;\n\n\t\t\t\t// Start deceleration\n\t\t\t\t// Verify that the last move detected was in some relevant time frame\n\t\t\t\tif (self.__isSingleTouch && self.options.animating && (timeStamp - self.__lastTouchMove) <= 100) {\n\n\t\t\t\t\t// Then figure out what the scroll position was about 100ms ago\n\t\t\t\t\tvar positions = self.__positions;\n\t\t\t\t\tvar endPos = positions.length - 1;\n\t\t\t\t\tvar startPos = endPos;\n\n\t\t\t\t\t// Move pointer to position measured 100ms ago\n\t\t\t\t\tfor (var i = endPos; i > 0 && positions[i] > (self.__lastTouchMove - 100); i -= 3) {\n\t\t\t\t\t\tstartPos = i;\n\t\t\t\t\t}\n\n\t\t\t\t\t// If start and stop position is identical in a 100ms timeframe,\n\t\t\t\t\t// we cannot compute any useful deceleration.\n\t\t\t\t\tif (startPos !== endPos) {\n\n\t\t\t\t\t\t// Compute relative movement between these two points\n\t\t\t\t\t\tvar timeOffset = positions[endPos] - positions[startPos];\n\t\t\t\t\t\tvar movedLeft = self.__scrollLeft - positions[startPos - 2];\n\t\t\t\t\t\tvar movedTop = self.__scrollTop - positions[startPos - 1];\n\n\t\t\t\t\t\t// Based on 50ms compute the movement to apply for each render step\n\t\t\t\t\t\tself.__decelerationVelocityX = movedLeft / timeOffset * (1000 / 60);\n\t\t\t\t\t\tself.__decelerationVelocityY = movedTop / timeOffset * (1000 / 60);\n\n\t\t\t\t\t\t// How much velocity is required to start the deceleration\n\t\t\t\t\t\tvar minVelocityToStartDeceleration = self.options.paging || self.options.snapping ? 4 : 1;\n\n\t\t\t\t\t\t// Verify that we have enough velocity to start deceleration\n\t\t\t\t\t\tif (Math.abs(self.__decelerationVelocityX) > minVelocityToStartDeceleration || Math.abs(self.__decelerationVelocityY) > minVelocityToStartDeceleration) {\n\n\t\t\t\t\t\t\t// Deactivate pull-to-refresh when decelerating\n\t\t\t\t\t\t\tif (!self.__refreshActive) {\n\t\t\t\t\t\t\t\tself.__startDeceleration(timeStamp);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t}\n\t\t\t\t} else if ((timeStamp - self.__lastTouchMove) > 100) {\n\t\t\t\t\tself.options.scrollingComplete();\n\t \t\t\t}\n\t\t\t}\n\n\t\t\t// If this was a slower move it is per default non decelerated, but this\n\t\t\t// still means that we want snap back to the bounds which is done here.\n\t\t\t// This is placed outside the condition above to improve edge case stability\n\t\t\t// e.g. touchend fired without enabled dragging. This should normally do not\n\t\t\t// have modified the scroll positions or even showed the scrollbars though.\n\t\t\tif (!self.__isDecelerating) {\n\n\t\t\t\tif (self.__refreshActive && self.__refreshStart) {\n\n\t\t\t\t\t// Use publish instead of scrollTo to allow scrolling to out of boundary position\n\t\t\t\t\t// We don't need to normalize scrollLeft, zoomLevel, etc. here because we only y-scrolling when pull-to-refresh is enabled\n\t\t\t\t\tself.__publish(self.__scrollLeft, -self.__refreshHeight, self.__zoomLevel, true);\n\n\t\t\t\t\tif (self.__refreshStart) {\n\t\t\t\t\t\tself.__refreshStart();\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif (self.__interruptedAnimation || self.__isDragging) {\n\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t}\n\t\t\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, true, self.__zoomLevel);\n\n\t\t\t\t\t// Directly signalize deactivation (nothing todo on refresh?)\n\t\t\t\t\tif (self.__refreshActive) {\n\n\t\t\t\t\t\tself.__refreshActive = false;\n\t\t\t\t\t\tif (self.__refreshDeactivate) {\n\t\t\t\t\t\t\tself.__refreshDeactivate();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fully cleanup list\n\t\t\tself.__positions.length = 0;\n\n\t\t},\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tPRIVATE API\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/**\n\t\t * Applies the scroll position to the content element\n\t\t *\n\t\t * @param left {Number} Left scroll position\n\t\t * @param top {Number} Top scroll position\n\t\t * @param animate {Boolean?false} Whether animation should be used to move to the new coordinates\n\t\t */\n\t\t__publish: function(left, top, zoom, animate) {\n\n\t\t\tvar self = this;\n\n\t\t\t// Remember whether we had an animation, then we try to continue based on the current \"drive\" of the animation\n\t\t\tvar wasAnimating = self.__isAnimating;\n\t\t\tif (wasAnimating) {\n core.effect.Animate.stop(wasAnimating);\n\t\t\t\tself.__isAnimating = false;\n\t\t\t}\n\n\t\t\tif (animate && self.options.animating) {\n\n\t\t\t\t// Keep scheduled positions for scrollBy/zoomBy functionality\n\t\t\t\tself.__scheduledLeft = left;\n\t\t\t\tself.__scheduledTop = top;\n\t\t\t\tself.__scheduledZoom = zoom;\n\n\t\t\t\tvar oldLeft = self.__scrollLeft;\n\t\t\t\tvar oldTop = self.__scrollTop;\n\t\t\t\tvar oldZoom = self.__zoomLevel;\n\n\t\t\t\tvar diffLeft = left - oldLeft;\n\t\t\t\tvar diffTop = top - oldTop;\n\t\t\t\tvar diffZoom = zoom - oldZoom;\n\n\t\t\t\tvar step = function(percent, now, render) {\n\n\t\t\t\t\tif (render) {\n\n\t\t\t\t\t\tself.__scrollLeft = oldLeft + (diffLeft * percent);\n\t\t\t\t\t\tself.__scrollTop = oldTop + (diffTop * percent);\n\t\t\t\t\t\tself.__zoomLevel = oldZoom + (diffZoom * percent);\n\n\t\t\t\t\t\t// Push values out\n\t\t\t\t\t\tif (self.__callback) {\n\t\t\t\t\t\t\tself.__callback(self.__scrollLeft, self.__scrollTop, self.__zoomLevel);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tvar verify = function(id) {\n\t\t\t\t\treturn self.__isAnimating === id;\n\t\t\t\t};\n\n\t\t\t\tvar completed = function(renderedFramesPerSecond, animationId, wasFinished) {\n\t\t\t\t\tif (animationId === self.__isAnimating) {\n\t\t\t\t\t\tself.__isAnimating = false;\n\t\t\t\t\t}\n\t\t\t\t\tif (self.__didDecelerationComplete || wasFinished) {\n\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (self.options.zooming) {\n\t\t\t\t\t\tself.__computeScrollMax();\n\t\t\t\t\t\tif(self.__zoomComplete) {\n\t\t\t\t\t\t\tself.__zoomComplete();\n\t\t\t\t\t\t\tself.__zoomComplete = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// When continuing based on previous animation we choose an ease-out animation instead of ease-in-out\n self.__isAnimating = core.effect.Animate.start(step, verify, completed, self.options.animationDuration, wasAnimating ? easeOutCubic : easeInOutCubic);\n\n\t\t\t} else {\n\n\t\t\t\tself.__scheduledLeft = self.__scrollLeft = left;\n\t\t\t\tself.__scheduledTop = self.__scrollTop = top;\n\t\t\t\tself.__scheduledZoom = self.__zoomLevel = zoom;\n\n\t\t\t\t// Push values out\n\t\t\t\tif (self.__callback) {\n\t\t\t\t\tself.__callback(left, top, zoom);\n\t\t\t\t}\n\n\t\t\t\t// Fix max scroll ranges\n\t\t\t\tif (self.options.zooming) {\n\t\t\t\t\tself.__computeScrollMax();\n\t\t\t\t\tif(self.__zoomComplete) {\n\t\t\t\t\t\tself.__zoomComplete();\n\t\t\t\t\t\tself.__zoomComplete = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\n\t\t/**\n\t\t * Recomputes scroll minimum values based on client dimensions and content dimensions.\n\t\t */\n\t\t__computeScrollMax: function(zoomLevel) {\n\n\t\t\tvar self = this;\n\n\t\t\tif (zoomLevel == null) {\n\t\t\t\tzoomLevel = self.__zoomLevel;\n\t\t\t}\n\n\t\t\tself.__maxScrollLeft = Math.max((self.__contentWidth * zoomLevel) - self.__clientWidth, 0);\n\t\t\tself.__maxScrollTop = Math.max((self.__contentHeight * zoomLevel) - self.__clientHeight, 0);\n\n\t\t},\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tANIMATION (DECELERATION) SUPPORT\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/**\n\t\t * Called when a touch sequence end and the speed of the finger was high enough\n\t\t * to switch into deceleration mode.\n\t\t */\n\t\t__startDeceleration: function(timeStamp) {\n\n\t\t\tvar self = this;\n\n\t\t\tif (self.options.paging) {\n\n\t\t\t\tvar scrollLeft = Math.max(Math.min(self.__scrollLeft, self.__maxScrollLeft), 0);\n\t\t\t\tvar scrollTop = Math.max(Math.min(self.__scrollTop, self.__maxScrollTop), 0);\n\t\t\t\tvar clientWidth = self.__clientWidth;\n\t\t\t\tvar clientHeight = self.__clientHeight;\n\n\t\t\t\t// We limit deceleration not to the min/max values of the allowed range, but to the size of the visible client area.\n\t\t\t\t// Each page should have exactly the size of the client area.\n\t\t\t\tself.__minDecelerationScrollLeft = Math.floor(scrollLeft / clientWidth) * clientWidth;\n\t\t\t\tself.__minDecelerationScrollTop = Math.floor(scrollTop / clientHeight) * clientHeight;\n\t\t\t\tself.__maxDecelerationScrollLeft = Math.ceil(scrollLeft / clientWidth) * clientWidth;\n\t\t\t\tself.__maxDecelerationScrollTop = Math.ceil(scrollTop / clientHeight) * clientHeight;\n\n\t\t\t} else {\n\n\t\t\t\tself.__minDecelerationScrollLeft = 0;\n\t\t\t\tself.__minDecelerationScrollTop = 0;\n\t\t\t\tself.__maxDecelerationScrollLeft = self.__maxScrollLeft;\n\t\t\t\tself.__maxDecelerationScrollTop = self.__maxScrollTop;\n\n\t\t\t}\n\n\t\t\t// Wrap class method\n\t\t\tvar step = function(percent, now, render) {\n\t\t\t\tself.__stepThroughDeceleration(render);\n\t\t\t};\n\n\t\t\t// How much velocity is required to keep the deceleration running\n\t\t\tvar minVelocityToKeepDecelerating = self.options.snapping ? 4 : 0.001;\n\n\t\t\t// Detect whether it's still worth to continue animating steps\n\t\t\t// If we are already slow enough to not being user perceivable anymore, we stop the whole process here.\n\t\t\tvar verify = function() {\n\t\t\t\tvar shouldContinue = Math.abs(self.__decelerationVelocityX) >= minVelocityToKeepDecelerating || Math.abs(self.__decelerationVelocityY) >= minVelocityToKeepDecelerating;\n\t\t\t\tif (!shouldContinue) {\n\t\t\t\t\tself.__didDecelerationComplete = true;\n\t\t\t\t}\n\t\t\t\treturn shouldContinue;\n\t\t\t};\n\n\t\t\tvar completed = function(renderedFramesPerSecond, animationId, wasFinished) {\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t\tif (self.__didDecelerationComplete) {\n\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t}\n\n\t\t\t\t// Animate to grid when snapping is active, otherwise just fix out-of-boundary positions\n\t\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, self.options.snapping);\n\t\t\t};\n\n\t\t\t// Start animation and switch on flag\n\t\t\tself.__isDecelerating = core.effect.Animate.start(step, verify, completed);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Called on every step of the animation\n\t\t *\n\t\t * @param inMemory {Boolean?false} Whether to not render the current step, but keep it in memory only. Used internally only!\n\t\t */\n\t\t__stepThroughDeceleration: function(render) {\n\n\t\t\tvar self = this;\n\n\n\t\t\t//\n\t\t\t// COMPUTE NEXT SCROLL POSITION\n\t\t\t//\n\n\t\t\t// Add deceleration to scroll position\n\t\t\tvar scrollLeft = self.__scrollLeft + self.__decelerationVelocityX;\n\t\t\tvar scrollTop = self.__scrollTop + self.__decelerationVelocityY;\n\n\n\t\t\t//\n\t\t\t// HARD LIMIT SCROLL POSITION FOR NON BOUNCING MODE\n\t\t\t//\n\n\t\t\tif (!self.options.bouncing) {\n\n\t\t\t\tvar scrollLeftFixed = Math.max(Math.min(self.__maxDecelerationScrollLeft, scrollLeft), self.__minDecelerationScrollLeft);\n\t\t\t\tif (scrollLeftFixed !== scrollLeft) {\n\t\t\t\t\tscrollLeft = scrollLeftFixed;\n\t\t\t\t\tself.__decelerationVelocityX = 0;\n\t\t\t\t}\n\n\t\t\t\tvar scrollTopFixed = Math.max(Math.min(self.__maxDecelerationScrollTop, scrollTop), self.__minDecelerationScrollTop);\n\t\t\t\tif (scrollTopFixed !== scrollTop) {\n\t\t\t\t\tscrollTop = scrollTopFixed;\n\t\t\t\t\tself.__decelerationVelocityY = 0;\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t//\n\t\t\t// UPDATE SCROLL POSITION\n\t\t\t//\n\n\t\t\tif (render) {\n\n\t\t\t\tself.__publish(scrollLeft, scrollTop, self.__zoomLevel);\n\n\t\t\t} else {\n\n\t\t\t\tself.__scrollLeft = scrollLeft;\n\t\t\t\tself.__scrollTop = scrollTop;\n\n\t\t\t}\n\n\n\t\t\t//\n\t\t\t// SLOW DOWN\n\t\t\t//\n\n\t\t\t// Slow down velocity on every iteration\n\t\t\tif (!self.options.paging) {\n\n\t\t\t\t// This is the factor applied to every iteration of the animation\n\t\t\t\t// to slow down the process. This should emulate natural behavior where\n\t\t\t\t// objects slow down when the initiator of the movement is removed\n\t\t\t\tvar frictionFactor = 0.95;\n\n\t\t\t\tself.__decelerationVelocityX *= frictionFactor;\n\t\t\t\tself.__decelerationVelocityY *= frictionFactor;\n\n\t\t\t}\n\n\n\t\t\t//\n\t\t\t// BOUNCING SUPPORT\n\t\t\t//\n\n\t\t\tif (self.options.bouncing) {\n\n\t\t\t\tvar scrollOutsideX = 0;\n\t\t\t\tvar scrollOutsideY = 0;\n\n\t\t\t\t// This configures the amount of change applied to deceleration/acceleration when reaching boundaries\n\t\t\t\tvar penetrationDeceleration = self.options.penetrationDeceleration;\n\t\t\t\tvar penetrationAcceleration = self.options.penetrationAcceleration;\n\n\t\t\t\t// Check limits\n\t\t\t\tif (scrollLeft < self.__minDecelerationScrollLeft) {\n\t\t\t\t\tscrollOutsideX = self.__minDecelerationScrollLeft - scrollLeft;\n\t\t\t\t} else if (scrollLeft > self.__maxDecelerationScrollLeft) {\n\t\t\t\t\tscrollOutsideX = self.__maxDecelerationScrollLeft - scrollLeft;\n\t\t\t\t}\n\n\t\t\t\tif (scrollTop < self.__minDecelerationScrollTop) {\n\t\t\t\t\tscrollOutsideY = self.__minDecelerationScrollTop - scrollTop;\n\t\t\t\t} else if (scrollTop > self.__maxDecelerationScrollTop) {\n\t\t\t\t\tscrollOutsideY = self.__maxDecelerationScrollTop - scrollTop;\n\t\t\t\t}\n\n\t\t\t\t// Slow down until slow enough, then flip back to snap position\n\t\t\t\tif (scrollOutsideX !== 0) {\n\t\t\t\t\tif (scrollOutsideX * self.__decelerationVelocityX <= 0) {\n\t\t\t\t\t\tself.__decelerationVelocityX += scrollOutsideX * penetrationDeceleration;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.__decelerationVelocityX = scrollOutsideX * penetrationAcceleration;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (scrollOutsideY !== 0) {\n\t\t\t\t\tif (scrollOutsideY * self.__decelerationVelocityY <= 0) {\n\t\t\t\t\t\tself.__decelerationVelocityY += scrollOutsideY * penetrationDeceleration;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.__decelerationVelocityY = scrollOutsideY * penetrationAcceleration;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Copy over members to prototype\n\tfor (var key in members) {\n\t\tScroller.prototype[key] = members[key];\n\t}\n\n if (typeof module != 'undefined' && module.exports) {\n module.exports = Scroller;\n } else if (typeof define == 'function' && define.amd) {\n define( function () { return Scroller; } );\n } else {\n window.Scroller = Scroller;\n }\n\n})(window);\n\n\n\n// WEBPACK FOOTER //\n// ./src/module/core.js","function getContentRender(content) {\n var global = window;\n\n var docStyle = document.documentElement.style;\n\n var engine;\n if (global.opera && Object.prototype.toString.call(opera) === '[object Opera]') {\n engine = 'presto';\n } else if ('MozAppearance' in docStyle) {\n engine = 'gecko';\n } else if ('WebkitAppearance' in docStyle) {\n engine = 'webkit';\n } else if (typeof navigator.cpuClass === 'string') {\n engine = 'trident';\n }\n\n var vendorPrefix = {\n trident: 'ms',\n gecko: 'Moz',\n webkit: 'Webkit',\n presto: 'O'\n }[engine];\n\n var helperElem = document.createElement(\"div\");\n var undef;\n\n var perspectiveProperty = vendorPrefix + \"Perspective\";\n var transformProperty = vendorPrefix + \"Transform\";\n\n if (helperElem.style[perspectiveProperty] !== undef) {\n\n return function(left, top, zoom) {\n content.style[transformProperty] = 'translate3d(' + (-left) + 'px,' + (-top) + 'px,0) scale(' + zoom + ')';\n };\n\n } else if (helperElem.style[transformProperty] !== undef) {\n\n return function(left, top, zoom) {\n content.style[transformProperty] = 'translate(' + (-left) + 'px,' + (-top) + 'px) scale(' + zoom + ')';\n };\n\n } else {\n\n return function(left, top, zoom) {\n content.style.marginLeft = left ? (-left/zoom) + 'px' : '';\n content.style.marginTop = top ? (-top/zoom) + 'px' : '';\n content.style.zoom = zoom || '';\n };\n\n }\n}\n\nmodule.exports = getContentRender;\n\n\n\n// WEBPACK FOOTER //\n// ./src/module/render.js","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"._v-container[data-v-ecaca2b0]{-webkit-tap-highlight-color:rgba(0,0,0,0);width:100%;height:100%;position:absolute;top:0;left:0;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}._v-container>._v-content[data-v-ecaca2b0]{width:100%;-webkit-transform-origin:left top;-webkit-transform:translateZ(0);-moz-transform-origin:left top;-moz-transform:translateZ(0);-ms-transform-origin:left top;-ms-transform:translateZ(0);-o-transform-origin:left top;-o-transform:translateZ(0);transform-origin:left top;transform:translateZ(0)}._v-container>._v-content>.pull-to-refresh-layer[data-v-ecaca2b0]{width:100%;height:60px;margin-top:-60px;text-align:center;font-size:16px;color:#aaa}._v-container>._v-content>.loading-layer[data-v-ecaca2b0]{width:100%;height:60px;text-align:center;font-size:16px;line-height:60px;color:#aaa;position:relative}._v-container>._v-content>.loading-layer>.no-data-text[data-v-ecaca2b0]{position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}._v-container>._v-content>.loading-layer>.no-data-text[data-v-ecaca2b0],._v-container>._v-content>.loading-layer>.spinner-holder[data-v-ecaca2b0]{opacity:0;transition:opacity .15s linear;-webkit-transition:opacity .15s linear}._v-container>._v-content>.loading-layer>.no-data-text.active[data-v-ecaca2b0],._v-container>._v-content>.loading-layer>.spinner-holder.active[data-v-ecaca2b0]{opacity:1}._v-container>._v-content>.loading-layer .spinner-holder[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder[data-v-ecaca2b0]{text-align:center;-webkit-font-smoothing:antialiased}._v-container>._v-content>.loading-layer .spinner-holder .arrow[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .arrow[data-v-ecaca2b0]{width:20px;height:20px;margin:8px auto 0;-webkit-transform:translateZ(0) rotate(0deg);transform:translateZ(0) rotate(0deg);transition:transform .2s linear}._v-container>._v-content>.loading-layer .spinner-holder .text[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .text[data-v-ecaca2b0]{display:block;margin:0 auto;font-size:14px;line-height:20px;color:#aaa}._v-container>._v-content>.loading-layer .spinner-holder .spinner[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .spinner[data-v-ecaca2b0]{margin-top:14px;width:32px;height:32px;fill:#444;stroke:#69717d}._v-container>._v-content>.pull-to-refresh-layer.active .spinner-holder .arrow[data-v-ecaca2b0]{-webkit-transform:translateZ(0) rotate(180deg);transform:translateZ(0) rotate(180deg)}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader?minimize!./~/vue-loader/lib/style-compiler?{\"id\":\"data-v-ecaca2b0\",\"scoped\":true,\"hasInlineConfig\":false}!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/components/Scroller.vue\n// module id = 7\n// module chunks = 0","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader/lib/css-base.js\n// module id = 8\n// module chunks = 0","var Component = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n require(\"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./Arrow.vue\"),\n /* template */\n require(\"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-338435ea\\\"}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./Arrow.vue\"),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/Arrow.vue\n// module id = 9\n// module chunks = 0","var Component = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n null,\n /* template */\n require(\"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-7e08eeca\\\"}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./Spinner.vue\"),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/Spinner.vue\n// module id = 10\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('svg', {\n staticStyle: {\n \"enable-background\": \"new 0 0 63.657 63.657\"\n },\n attrs: {\n \"viewBox\": \"0 0 63.657 63.657\",\n \"xml:space\": \"preserve\",\n \"width\": \"512px\",\n \"height\": \"512px\"\n }\n }, [_c('g', [_c('g', [_c('g', [_c('g', [_c('polygon', {\n attrs: {\n \"points\": \"31.891,63.657 0.012,35.835 2.642,32.821 31.886,58.343 61.009,32.824 63.645,35.832\",\n \"fill\": _vm.fillColor\n }\n })])]), _vm._v(\" \"), _c('g', [_c('g', [_c('rect', {\n attrs: {\n \"x\": \"29.827\",\n \"width\": \"4\",\n \"height\": \"60\",\n \"fill\": _vm.fillColor\n }\n })])])]), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g')]), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g')])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-338435ea\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/components/Arrow.vue\n// module id = 11\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('svg', {\n staticClass: \"spinner\",\n attrs: {\n \"viewBox\": \"0 0 64 64\"\n }\n }, [_c('g', {\n attrs: {\n \"stroke-width\": \"4\",\n \"stroke-linecap\": \"round\"\n }\n }, [_c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(180)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \"1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0;1\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(210)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \"0;1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(240)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".1;0;1;.85;.7;.65;.55;.45;.35;.25;.15;.1\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(270)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".15;.1;0;1;.85;.7;.65;.55;.45;.35;.25;.15\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(300)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".25;.15;.1;0;1;.85;.7;.65;.55;.45;.35;.25\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(330)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".35;.25;.15;.1;0;1;.85;.7;.65;.55;.45;.35\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(0)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".45;.35;.25;.15;.1;0;1;.85;.7;.65;.55;.45\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(30)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".55;.45;.35;.25;.15;.1;0;1;.85;.7;.65;.55\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(60)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".65;.55;.45;.35;.25;.15;.1;0;1;.85;.7;.65\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(90)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".7;.65;.55;.45;.35;.25;.15;.1;0;1;.85;.7\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(120)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".85;.7;.65;.55;.45;.35;.25;.15;.1;0;1;.85\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(150)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \"1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0;1\",\n \"repeatCount\": \"indefinite\"\n }\n })])])])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-7e08eeca\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/components/Spinner.vue\n// module id = 12\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n staticClass: \"_v-container\",\n attrs: {\n \"id\": _vm.containerId\n },\n on: {\n \"touchstart\": function($event) {\n _vm.touchStart($event)\n },\n \"touchmove\": function($event) {\n _vm.touchMove($event)\n },\n \"touchend\": function($event) {\n _vm.touchEnd($event)\n },\n \"mousedown\": function($event) {\n _vm.mouseDown($event)\n },\n \"mousemove\": function($event) {\n _vm.mouseMove($event)\n },\n \"mouseup\": function($event) {\n _vm.mouseUp($event)\n }\n }\n }, [_c('div', {\n staticClass: \"_v-content\",\n attrs: {\n \"id\": _vm.contentId\n }\n }, [(_vm.onRefresh) ? _c('div', {\n staticClass: \"pull-to-refresh-layer\",\n class: {\n 'active': _vm.state == 1, 'active refreshing': _vm.state == 2\n }\n }, [_c('span', {\n staticClass: \"spinner-holder\"\n }, [(_vm.state != 2) ? _c('arrow', {\n staticClass: \"arrow\",\n attrs: {\n \"fillColor\": _vm.refreshLayerColor\n }\n }) : _vm._e(), _vm._v(\" \"), (_vm.state != 2) ? _c('span', {\n staticClass: \"text\",\n style: ({\n color: _vm.refreshLayerColor\n }),\n domProps: {\n \"textContent\": _vm._s(_vm.refreshText)\n }\n }) : _vm._e(), _vm._v(\" \"), (_vm.state == 2) ? _c('span', [_vm._t(\"refresh-spinner\", [_c('spinner', {\n style: ({\n fill: _vm.refreshLayerColor,\n stroke: _vm.refreshLayerColor\n })\n })])], 2) : _vm._e()], 1)]) : _vm._e(), _vm._v(\" \"), _vm._t(\"default\"), _vm._v(\" \"), (_vm.showInfiniteLayer) ? _c('div', {\n staticClass: \"loading-layer\"\n }, [_c('span', {\n staticClass: \"spinner-holder\",\n class: {\n 'active': _vm.showLoading\n }\n }, [_vm._t(\"infinite-spinner\", [_c('spinner', {\n style: ({\n fill: _vm.loadingLayerColor,\n stroke: _vm.loadingLayerColor\n })\n })])], 2), _vm._v(\" \"), _c('div', {\n staticClass: \"no-data-text\",\n class: {\n 'active': !_vm.showLoading && _vm.loadingState == 2\n },\n style: ({\n color: _vm.loadingLayerColor\n }),\n domProps: {\n \"textContent\": _vm._s(_vm.noDataText)\n }\n })]) : _vm._e()], 2)])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-ecaca2b0\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/components/Scroller.vue\n// module id = 13\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a \n\n\n\n\n// WEBPACK FOOTER //\n// Scroller.vue?855fbad2","import Scroller from './components/Scroller.vue'\n\nfunction install (Vue) {\n if (install.installed) return\n install.installed = true\n Vue.component('scroller', Scroller)\n}\n\nconst VueScroller = {\n install: install,\n Scroller\n}\n\nif (typeof window !== undefined && window.Vue) {\n window.Vue.use(VueScroller)\n}\n\nexport default VueScroller\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","(function(window) {\n\tvar NOOP = function () {};\n\n\tvar core = (function Animate (global) {\n\t\t\n\t\tvar time = Date.now || function() {\n\t\t\treturn +new Date();\n\t\t};\n\n\t\tvar desiredFrames = 60;\n\t\tvar millisecondsPerSecond = 1000;\n\t\tvar running = {};\n\t\tvar counter = 1;\n\n\t\tvar core = { effect: {} };\n\n\t\tcore.effect.Animate = {\n\n\t\t\t/**\n\t\t\t * A requestAnimationFrame wrapper / polyfill.\n\t\t\t *\n\t\t\t * @param callback {Function} The callback to be invoked before the next repaint.\n\t\t\t * @param root {HTMLElement} The root element for the repaint\n\t\t\t */\n\t\t\trequestAnimationFrame: (function() {\n\n\t\t\t\t// Check for request animation Frame support\n\t\t\t\tvar requestFrame = global.requestAnimationFrame || global.webkitRequestAnimationFrame || global.mozRequestAnimationFrame || global.oRequestAnimationFrame;\n\t\t\t\tvar isNative = !!requestFrame;\n\n\t\t\t\tif (requestFrame && !/requestAnimationFrame\\(\\)\\s*\\{\\s*\\[native code\\]\\s*\\}/i.test(requestFrame.toString())) {\n\t\t\t\t\tisNative = false;\n\t\t\t\t}\n\n\t\t\t\tif (isNative) {\n\t\t\t\t\treturn function(callback, root) {\n\t\t\t\t\t\trequestFrame(callback, root)\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tvar TARGET_FPS = 60;\n\t\t\t\tvar requests = {};\n\t\t\t\tvar requestCount = 0;\n\t\t\t\tvar rafHandle = 1;\n\t\t\t\tvar intervalHandle = null;\n\t\t\t\tvar lastActive = +new Date();\n\n\t\t\t\treturn function(callback, root) {\n\t\t\t\t\tvar callbackHandle = rafHandle++;\n\n\t\t\t\t\t// Store callback\n\t\t\t\t\trequests[callbackHandle] = callback;\n\t\t\t\t\trequestCount++;\n\n\t\t\t\t\t// Create timeout at first request\n\t\t\t\t\tif (intervalHandle === null) {\n\n\t\t\t\t\t\tintervalHandle = setInterval(function() {\n\n\t\t\t\t\t\t\tvar time = +new Date();\n\t\t\t\t\t\t\tvar currentRequests = requests;\n\n\t\t\t\t\t\t\t// Reset data structure before executing callbacks\n\t\t\t\t\t\t\trequests = {};\n\t\t\t\t\t\t\trequestCount = 0;\n\n\t\t\t\t\t\t\tfor(var key in currentRequests) {\n\t\t\t\t\t\t\t\tif (currentRequests.hasOwnProperty(key)) {\n\t\t\t\t\t\t\t\t\tcurrentRequests[key](time);\n\t\t\t\t\t\t\t\t\tlastActive = time;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Disable the timeout when nothing happens for a certain\n\t\t\t\t\t\t\t// period of time\n\t\t\t\t\t\t\tif (time - lastActive > 2500) {\n\t\t\t\t\t\t\t\tclearInterval(intervalHandle);\n\t\t\t\t\t\t\t\tintervalHandle = null;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}, 1000 / TARGET_FPS);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn callbackHandle;\n\t\t\t\t};\n\n\t\t\t})(),\n\n\n\t\t\t/**\n\t\t\t * Stops the given animation.\n\t\t\t *\n\t\t\t * @param id {Integer} Unique animation ID\n\t\t\t * @return {Boolean} Whether the animation was stopped (aka, was running before)\n\t\t\t */\n\t\t\tstop: function(id) {\n\t\t\t\tvar cleared = running[id] != null;\n\t\t\t\tif (cleared) {\n\t\t\t\t\trunning[id] = null;\n\t\t\t\t}\n\n\t\t\t\treturn cleared;\n\t\t\t},\n\n\n\t\t\t/**\n\t\t\t * Whether the given animation is still running.\n\t\t\t *\n\t\t\t * @param id {Integer} Unique animation ID\n\t\t\t * @return {Boolean} Whether the animation is still running\n\t\t\t */\n\t\t\tisRunning: function(id) {\n\t\t\t\treturn running[id] != null;\n\t\t\t},\n\n\n\t\t\t/**\n\t\t\t * Start the animation.\n\t\t\t *\n\t\t\t * @param stepCallback {Function} Pointer to function which is executed on every step.\n\t\t\t * Signature of the method should be `function(percent, now, virtual) { return continueWithAnimation; }`\n\t\t\t * @param verifyCallback {Function} Executed before every animation step.\n\t\t\t * Signature of the method should be `function() { return continueWithAnimation; }`\n\t\t\t * @param completedCallback {Function}\n\t\t\t * Signature of the method should be `function(droppedFrames, finishedAnimation) {}`\n\t\t\t * @param duration {Integer} Milliseconds to run the animation\n\t\t\t * @param easingMethod {Function} Pointer to easing function\n\t\t\t * Signature of the method should be `function(percent) { return modifiedValue; }`\n\t\t\t * @param root {Element ? document.body} Render root, when available. Used for internal\n\t\t\t * usage of requestAnimationFrame.\n\t\t\t * @return {Integer} Identifier of animation. Can be used to stop it any time.\n\t\t\t */\n\t\t\tstart: function(stepCallback, verifyCallback, completedCallback, duration, easingMethod, root) {\n\n\t\t\t\tvar start = time();\n\t\t\t\tvar lastFrame = start;\n\t\t\t\tvar percent = 0;\n\t\t\t\tvar dropCounter = 0;\n\t\t\t\tvar id = counter++;\n\n\t\t\t\tif (!root) {\n\t\t\t\t\troot = document.body;\n\t\t\t\t}\n\n\t\t\t\t// Compacting running db automatically every few new animations\n\t\t\t\tif (id % 20 === 0) {\n\t\t\t\t\tvar newRunning = {};\n\t\t\t\t\tfor (var usedId in running) {\n\t\t\t\t\t\tnewRunning[usedId] = true;\n\t\t\t\t\t}\n\t\t\t\t\trunning = newRunning;\n\t\t\t\t}\n\n\t\t\t\t// This is the internal step method which is called every few milliseconds\n\t\t\t\tvar step = function(virtual) {\n\n\t\t\t\t\t// Normalize virtual value\n\t\t\t\t\tvar render = virtual !== true;\n\n\t\t\t\t\t// Get current time\n\t\t\t\t\tvar now = time();\n\n\t\t\t\t\t// Verification is executed before next animation step\n\t\t\t\t\tif (!running[id] || (verifyCallback && !verifyCallback(id))) {\n\n\t\t\t\t\t\trunning[id] = null;\n\t\t\t\t\t\tcompletedCallback && completedCallback(desiredFrames - (dropCounter / ((now - start) / millisecondsPerSecond)), id, false);\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// For the current rendering to apply let's update omitted steps in memory.\n\t\t\t\t\t// This is important to bring internal state variables up-to-date with progress in time.\n\t\t\t\t\tif (render) {\n\n\t\t\t\t\t\tvar droppedFrames = Math.round((now - lastFrame) / (millisecondsPerSecond / desiredFrames)) - 1;\n\t\t\t\t\t\tfor (var j = 0; j < Math.min(droppedFrames, 4); j++) {\n\t\t\t\t\t\t\tstep(true);\n\t\t\t\t\t\t\tdropCounter++;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Compute percent value\n\t\t\t\t\tif (duration) {\n\t\t\t\t\t\tpercent = (now - start) / duration;\n\t\t\t\t\t\tif (percent > 1) {\n\t\t\t\t\t\t\tpercent = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Execute step callback, then...\n\t\t\t\t\tvar value = easingMethod ? easingMethod(percent) : percent;\n\t\t\t\t\tif ((stepCallback(value, now, render) === false || percent === 1) && render) {\n\t\t\t\t\t\trunning[id] = null;\n\t\t\t\t\t\tcompletedCallback && completedCallback(desiredFrames - (dropCounter / ((now - start) / millisecondsPerSecond)), id, percent === 1 || duration == null);\n\t\t\t\t\t} else if (render) {\n\t\t\t\t\t\tlastFrame = now;\n\t\t\t\t\t\tcore.effect.Animate.requestAnimationFrame(step, root);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Mark as running\n\t\t\t\trunning[id] = true;\n\n\t\t\t\t// Init first step\n\t\t\t\tcore.effect.Animate.requestAnimationFrame(step, root);\n\n\t\t\t\t// Return unique animation ID\n\t\t\t\treturn id;\n\t\t\t}\n\t\t};\n\n\t\treturn core;\n\n\t})(window);\n\n\t/**\n\t * A pure logic 'component' for 'virtual' scrolling/zooming.\n\t */\n\tvar Scroller = function(callback, options) {\n\n\t\tthis.__callback = callback;\n // core = animate;\n\n\t\tthis.options = {\n\n\t\t\t/** Enable scrolling on x-axis */\n\t\t\tscrollingX: true,\n\n\t\t\t/** Enable scrolling on y-axis */\n\t\t\tscrollingY: true,\n\n\t\t\t/** Enable animations for deceleration, snap back, zooming and scrolling */\n\t\t\tanimating: true,\n\n\t\t\t/** duration for animations triggered by scrollTo/zoomTo */\n\t\t\tanimationDuration: 250,\n\n\t\t\t/** Enable bouncing (content can be slowly moved outside and jumps back after releasing) */\n\t\t\tbouncing: true,\n\n\t\t\t/** Enable locking to the main axis if user moves only slightly on one of them at start */\n\t\t\tlocking: true,\n\n\t\t\t/** Enable pagination mode (switching between full page content panes) */\n\t\t\tpaging: false,\n\n\t\t\t/** Enable snapping of content to a configured pixel grid */\n\t\t\tsnapping: false,\n\n\t\t\t/** Enable zooming of content via API, fingers and mouse wheel */\n\t\t\tzooming: false,\n\n\t\t\t/** Minimum zoom level */\n\t\t\tminZoom: 0.5,\n\n\t\t\t/** Maximum zoom level */\n\t\t\tmaxZoom: 3,\n\n\t\t\t/** Multiply or decrease scrolling speed **/\n\t\t\tspeedMultiplier: 1,\n\n\t\t\t/** Callback that is fired on the later of touch end or deceleration end,\n\t\t\t\tprovided that another scrolling action has not begun. Used to know\n\t\t\t\twhen to fade out a scrollbar. */\n\t\t\tscrollingComplete: NOOP,\n\n\t\t\t/** This configures the amount of change applied to deceleration when reaching boundaries **/\n penetrationDeceleration : 0.03,\n\n /** This configures the amount of change applied to acceleration when reaching boundaries **/\n penetrationAcceleration : 0.08\n\n\t\t};\n\n\t\tfor (var key in options) {\n\t\t\tthis.options[key] = options[key];\n\t\t}\n\n\t};\n\n\n\t// Easing Equations (c) 2003 Robert Penner, all rights reserved.\n\t// Open source under the BSD License.\n\n\t/**\n\t * @param pos {Number} position between 0 (start of effect) and 1 (end of effect)\n\t**/\n\tvar easeOutCubic = function(pos) {\n\t\treturn (Math.pow((pos - 1), 3) + 1);\n\t};\n\n\t/**\n\t * @param pos {Number} position between 0 (start of effect) and 1 (end of effect)\n\t**/\n\tvar easeInOutCubic = function(pos) {\n\t\tif ((pos /= 0.5) < 1) {\n\t\t\treturn 0.5 * Math.pow(pos, 3);\n\t\t}\n\n\t\treturn 0.5 * (Math.pow((pos - 2), 3) + 2);\n\t};\n\n\n\tvar members = {\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tINTERNAL FIELDS :: STATUS\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/** {Boolean} Whether only a single finger is used in touch handling */\n\t\t__isSingleTouch: false,\n\n\t\t/** {Boolean} Whether a touch event sequence is in progress */\n\t\t__isTracking: false,\n\n\t\t/** {Boolean} Whether a deceleration animation went to completion. */\n\t\t__didDecelerationComplete: false,\n\n\t\t/**\n\t\t * {Boolean} Whether a gesture zoom/rotate event is in progress. Activates when\n\t\t * a gesturestart event happens. This has higher priority than dragging.\n\t\t */\n\t\t__isGesturing: false,\n\n\t\t/**\n\t\t * {Boolean} Whether the user has moved by such a distance that we have enabled\n\t\t * dragging mode. Hint: It's only enabled after some pixels of movement to\n\t\t * not interrupt with clicks etc.\n\t\t */\n\t\t__isDragging: false,\n\n\t\t/**\n\t\t * {Boolean} Not touching and dragging anymore, and smoothly animating the\n\t\t * touch sequence using deceleration.\n\t\t */\n\t\t__isDecelerating: false,\n\n\t\t/**\n\t\t * {Boolean} Smoothly animating the currently configured change\n\t\t */\n\t\t__isAnimating: false,\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tINTERNAL FIELDS :: DIMENSIONS\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/** {Integer} Available outer left position (from document perspective) */\n\t\t__clientLeft: 0,\n\n\t\t/** {Integer} Available outer top position (from document perspective) */\n\t\t__clientTop: 0,\n\n\t\t/** {Integer} Available outer width */\n\t\t__clientWidth: 0,\n\n\t\t/** {Integer} Available outer height */\n\t\t__clientHeight: 0,\n\n\t\t/** {Integer} Outer width of content */\n\t\t__contentWidth: 0,\n\n\t\t/** {Integer} Outer height of content */\n\t\t__contentHeight: 0,\n\n\t\t/** {Integer} Snapping width for content */\n\t\t__snapWidth: 100,\n\n\t\t/** {Integer} Snapping height for content */\n\t\t__snapHeight: 100,\n\n\t\t/** {Integer} Height to assign to refresh area */\n\t\t__refreshHeight: null,\n\n\t\t/** {Boolean} Whether the refresh process is enabled when the event is released now */\n\t\t__refreshActive: false,\n\n\t\t/** {Function} Callback to execute on activation. This is for signalling the user about a refresh is about to happen when he release */\n\t\t__refreshActivate: null,\n\n\t\t/** {Function} Callback to execute on deactivation. This is for signalling the user about the refresh being cancelled */\n\t\t__refreshDeactivate: null,\n\n\t\t/** {Function} Callback to execute to start the actual refresh. Call {@link #refreshFinish} when done */\n\t\t__refreshStart: null,\n\n\t\t/** {Number} Zoom level */\n\t\t__zoomLevel: 1,\n\n\t\t/** {Number} Scroll position on x-axis */\n\t\t__scrollLeft: 0,\n\n\t\t/** {Number} Scroll position on y-axis */\n\t\t__scrollTop: 0,\n\n\t\t/** {Integer} Maximum allowed scroll position on x-axis */\n\t\t__maxScrollLeft: 0,\n\n\t\t/** {Integer} Maximum allowed scroll position on y-axis */\n\t\t__maxScrollTop: 0,\n\n\t\t/* {Number} Scheduled left position (final position when animating) */\n\t\t__scheduledLeft: 0,\n\n\t\t/* {Number} Scheduled top position (final position when animating) */\n\t\t__scheduledTop: 0,\n\n\t\t/* {Number} Scheduled zoom level (final scale when animating) */\n\t\t__scheduledZoom: 0,\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tINTERNAL FIELDS :: LAST POSITIONS\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/** {Number} Left position of finger at start */\n\t\t__lastTouchLeft: null,\n\n\t\t/** {Number} Top position of finger at start */\n\t\t__lastTouchTop: null,\n\n\t\t/** {Date} Timestamp of last move of finger. Used to limit tracking range for deceleration speed. */\n\t\t__lastTouchMove: null,\n\n\t\t/** {Array} List of positions, uses three indexes for each state: left, top, timestamp */\n\t\t__positions: null,\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tINTERNAL FIELDS :: DECELERATION SUPPORT\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/** {Integer} Minimum left scroll position during deceleration */\n\t\t__minDecelerationScrollLeft: null,\n\n\t\t/** {Integer} Minimum top scroll position during deceleration */\n\t\t__minDecelerationScrollTop: null,\n\n\t\t/** {Integer} Maximum left scroll position during deceleration */\n\t\t__maxDecelerationScrollLeft: null,\n\n\t\t/** {Integer} Maximum top scroll position during deceleration */\n\t\t__maxDecelerationScrollTop: null,\n\n\t\t/** {Number} Current factor to modify horizontal scroll position with on every step */\n\t\t__decelerationVelocityX: null,\n\n\t\t/** {Number} Current factor to modify vertical scroll position with on every step */\n\t\t__decelerationVelocityY: null,\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tPUBLIC API\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/**\n\t\t * Configures the dimensions of the client (outer) and content (inner) elements.\n\t\t * Requires the available space for the outer element and the outer size of the inner element.\n\t\t * All values which are falsy (null or zero etc.) are ignored and the old value is kept.\n\t\t *\n\t\t * @param clientWidth {Integer ? null} Inner width of outer element\n\t\t * @param clientHeight {Integer ? null} Inner height of outer element\n\t\t * @param contentWidth {Integer ? null} Outer width of inner element\n\t\t * @param contentHeight {Integer ? null} Outer height of inner element\n\t\t */\n\t\tsetDimensions: function(clientWidth, clientHeight, contentWidth, contentHeight) {\n\n\t\t\tvar self = this;\n\n\t\t\t// Only update values which are defined\n\t\t\tif (clientWidth === +clientWidth) {\n\t\t\t\tself.__clientWidth = clientWidth;\n\t\t\t}\n\n\t\t\tif (clientHeight === +clientHeight) {\n\t\t\t\tself.__clientHeight = clientHeight;\n\t\t\t}\n\n\t\t\tif (contentWidth === +contentWidth) {\n\t\t\t\tself.__contentWidth = contentWidth;\n\t\t\t}\n\n\t\t\tif (contentHeight === +contentHeight) {\n\t\t\t\tself.__contentHeight = contentHeight;\n\t\t\t}\n\n\t\t\t// Refresh maximums\n\t\t\tself.__computeScrollMax();\n\n\t\t\t// Refresh scroll position\n\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, true);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Sets the client coordinates in relation to the document.\n\t\t *\n\t\t * @param left {Integer ? 0} Left position of outer element\n\t\t * @param top {Integer ? 0} Top position of outer element\n\t\t */\n\t\tsetPosition: function(left, top) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__clientLeft = left || 0;\n\t\t\tself.__clientTop = top || 0;\n\n\t\t},\n\n\n\t\t/**\n\t\t * Configures the snapping (when snapping is active)\n\t\t *\n\t\t * @param width {Integer} Snapping width\n\t\t * @param height {Integer} Snapping height\n\t\t */\n\t\tsetSnapSize: function(width, height) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__snapWidth = width;\n\t\t\tself.__snapHeight = height;\n\n\t\t},\n\n\n\t\t/**\n\t\t * Activates pull-to-refresh. A special zone on the top of the list to start a list refresh whenever\n\t\t * the user event is released during visibility of this zone. This was introduced by some apps on iOS like\n\t\t * the official Twitter client.\n\t\t *\n\t\t * @param height {Integer} Height of pull-to-refresh zone on top of rendered list\n\t\t * @param activateCallback {Function} Callback to execute on activation. This is for signalling the user about a refresh is about to happen when he release.\n\t\t * @param deactivateCallback {Function} Callback to execute on deactivation. This is for signalling the user about the refresh being cancelled.\n\t\t * @param startCallback {Function} Callback to execute to start the real async refresh action. Call {@link #finishPullToRefresh} after finish of refresh.\n\t\t */\n\t\tactivatePullToRefresh: function(height, activateCallback, deactivateCallback, startCallback) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__refreshHeight = height;\n\t\t\tself.__refreshActivate = activateCallback;\n\t\t\tself.__refreshDeactivate = deactivateCallback;\n\t\t\tself.__refreshStart = startCallback;\n\n\t\t},\n\n\n\t\t/**\n\t\t * Starts pull-to-refresh manually.\n\t\t */\n\t\ttriggerPullToRefresh: function() {\n\t\t\t// Use publish instead of scrollTo to allow scrolling to out of boundary position\n\t\t\t// We don't need to normalize scrollLeft, zoomLevel, etc. here because we only y-scrolling when pull-to-refresh is enabled\n\t\t\tthis.__publish(this.__scrollLeft, -this.__refreshHeight, this.__zoomLevel, true);\n\n\t\t\tif (this.__refreshStart) {\n\t\t\t\tthis.__refreshStart();\n\t\t\t}\n\t\t},\n\n\n\t\t/**\n\t\t * Signalizes that pull-to-refresh is finished.\n\t\t */\n\t\tfinishPullToRefresh: function() {\n\n\t\t\tvar self = this;\n\n\t\t\tself.__refreshActive = false;\n\t\t\tif (self.__refreshDeactivate) {\n\t\t\t\tself.__refreshDeactivate();\n\t\t\t}\n\n\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, true);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Returns the scroll position and zooming values\n\t\t *\n\t\t * @return {Map} `left` and `top` scroll position and `zoom` level\n\t\t */\n\t\tgetValues: function() {\n\n\t\t\tvar self = this;\n\n\t\t\treturn {\n\t\t\t\tleft: self.__scrollLeft,\n\t\t\t\ttop: self.__scrollTop,\n\t\t\t\tzoom: self.__zoomLevel\n\t\t\t};\n\n\t\t},\n\n\n\t\t/**\n\t\t * Returns the maximum scroll values\n\t\t *\n\t\t * @return {Map} `left` and `top` maximum scroll values\n\t\t */\n\t\tgetScrollMax: function() {\n\n\t\t\tvar self = this;\n\n\t\t\treturn {\n\t\t\t\tleft: self.__maxScrollLeft,\n\t\t\t\ttop: self.__maxScrollTop\n\t\t\t};\n\n\t\t},\n\n\n\t\t/**\n\t\t * Zooms to the given level. Supports optional animation. Zooms\n\t\t * the center when no coordinates are given.\n\t\t *\n\t\t * @param level {Number} Level to zoom to\n\t\t * @param animate {Boolean ? false} Whether to use animation\n\t\t * @param originLeft {Number ? null} Zoom in at given left coordinate\n\t\t * @param originTop {Number ? null} Zoom in at given top coordinate\n\t\t * @param callback {Function ? null} A callback that gets fired when the zoom is complete.\n\t\t */\n\t\tzoomTo: function(level, animate, originLeft, originTop, callback) {\n\n\t\t\tvar self = this;\n\n\t\t\tif (!self.options.zooming) {\n\t\t\t\tthrow new Error(\"Zooming is not enabled!\");\n\t\t\t}\n\n\t\t\t// Add callback if exists\n\t\t\tif(callback) {\n\t\t\t\tself.__zoomComplete = callback;\n\t\t\t}\n\n\t\t\t// Stop deceleration\n\t\t\tif (self.__isDecelerating) {\n\t\t\t\tcore.effect.Animate.stop(self.__isDecelerating);\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t}\n\n\t\t\tvar oldLevel = self.__zoomLevel;\n\n\t\t\t// Normalize input origin to center of viewport if not defined\n\t\t\tif (originLeft == null) {\n\t\t\t\toriginLeft = self.__clientWidth / 2;\n\t\t\t}\n\n\t\t\tif (originTop == null) {\n\t\t\t\toriginTop = self.__clientHeight / 2;\n\t\t\t}\n\n\t\t\t// Limit level according to configuration\n\t\t\tlevel = Math.max(Math.min(level, self.options.maxZoom), self.options.minZoom);\n\n\t\t\t// Recompute maximum values while temporary tweaking maximum scroll ranges\n\t\t\tself.__computeScrollMax(level);\n\n\t\t\t// Recompute left and top coordinates based on new zoom level\n\t\t\tvar left = ((originLeft + self.__scrollLeft) * level / oldLevel) - originLeft;\n\t\t\tvar top = ((originTop + self.__scrollTop) * level / oldLevel) - originTop;\n\n\t\t\t// Limit x-axis\n\t\t\tif (left > self.__maxScrollLeft) {\n\t\t\t\tleft = self.__maxScrollLeft;\n\t\t\t} else if (left < 0) {\n\t\t\t\tleft = 0;\n\t\t\t}\n\n\t\t\t// Limit y-axis\n\t\t\tif (top > self.__maxScrollTop) {\n\t\t\t\ttop = self.__maxScrollTop;\n\t\t\t} else if (top < 0) {\n\t\t\t\ttop = 0;\n\t\t\t}\n\n\t\t\t// Push values out\n\t\t\tself.__publish(left, top, level, animate);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Zooms the content by the given factor.\n\t\t *\n\t\t * @param factor {Number} Zoom by given factor\n\t\t * @param animate {Boolean ? false} Whether to use animation\n\t\t * @param originLeft {Number ? 0} Zoom in at given left coordinate\n\t\t * @param originTop {Number ? 0} Zoom in at given top coordinate\n\t\t * @param callback {Function ? null} A callback that gets fired when the zoom is complete.\n\t\t */\n\t\tzoomBy: function(factor, animate, originLeft, originTop, callback) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.zoomTo(self.__zoomLevel * factor, animate, originLeft, originTop, callback);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Scrolls to the given position. Respect limitations and snapping automatically.\n\t\t *\n\t\t * @param left {Number?null} Horizontal scroll position, keeps current if value is null\n\t\t * @param top {Number?null} Vertical scroll position, keeps current if value is null\n\t\t * @param animate {Boolean?false} Whether the scrolling should happen using an animation\n\t\t * @param zoom {Number?null} Zoom level to go to\n\t\t */\n\t\tscrollTo: function(left, top, animate, zoom) {\n\n\t\t\tvar self = this;\n\n\t\t\t// Stop deceleration\n\t\t\tif (self.__isDecelerating) {\n\t\t\t\tcore.effect.Animate.stop(self.__isDecelerating);\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t}\n\n\t\t\t// Correct coordinates based on new zoom level\n\t\t\tif (zoom != null && zoom !== self.__zoomLevel) {\n\n\t\t\t\tif (!self.options.zooming) {\n\t\t\t\t\tthrow new Error(\"Zooming is not enabled!\");\n\t\t\t\t}\n\n\t\t\t\tleft *= zoom;\n\t\t\t\ttop *= zoom;\n\n\t\t\t\t// Recompute maximum values while temporary tweaking maximum scroll ranges\n\t\t\t\tself.__computeScrollMax(zoom);\n\n\t\t\t} else {\n\n\t\t\t\t// Keep zoom when not defined\n\t\t\t\tzoom = self.__zoomLevel;\n\n\t\t\t}\n\n\t\t\tif (!self.options.scrollingX) {\n\n\t\t\t\tleft = self.__scrollLeft;\n\n\t\t\t} else {\n\n\t\t\t\tif (self.options.paging) {\n\t\t\t\t\tleft = Math.round(left / self.__clientWidth) * self.__clientWidth;\n\t\t\t\t} else if (self.options.snapping) {\n\t\t\t\t\tleft = Math.round(left / self.__snapWidth) * self.__snapWidth;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif (!self.options.scrollingY) {\n\n\t\t\t\ttop = self.__scrollTop;\n\n\t\t\t} else {\n\n\t\t\t\tif (self.options.paging) {\n\t\t\t\t\ttop = Math.round(top / self.__clientHeight) * self.__clientHeight;\n\t\t\t\t} else if (self.options.snapping) {\n\t\t\t\t\ttop = Math.round(top / self.__snapHeight) * self.__snapHeight;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Limit for allowed ranges\n\t\t\tleft = Math.max(Math.min(self.__maxScrollLeft, left), 0);\n\t\t\ttop = Math.max(Math.min(self.__maxScrollTop, top), 0);\n\n\t\t\t// Don't animate when no change detected, still call publish to make sure\n\t\t\t// that rendered position is really in-sync with internal data\n\t\t\tif (left === self.__scrollLeft && top === self.__scrollTop) {\n\t\t\t\tanimate = false;\n\t\t\t}\n\n\t\t\t// Publish new values\n\t\t\tif (!self.__isTracking) {\n self.__publish(left, top, zoom, animate);\n }\n\n\t\t},\n\n\n\t\t/**\n\t\t * Scroll by the given offset\n\t\t *\n\t\t * @param left {Number ? 0} Scroll x-axis by given offset\n\t\t * @param top {Number ? 0} Scroll x-axis by given offset\n\t\t * @param animate {Boolean ? false} Whether to animate the given change\n\t\t */\n\t\tscrollBy: function(left, top, animate) {\n\n\t\t\tvar self = this;\n\n\t\t\tvar startLeft = self.__isAnimating ? self.__scheduledLeft : self.__scrollLeft;\n\t\t\tvar startTop = self.__isAnimating ? self.__scheduledTop : self.__scrollTop;\n\n\t\t\tself.scrollTo(startLeft + (left || 0), startTop + (top || 0), animate);\n\n\t\t},\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tEVENT CALLBACKS\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/**\n\t\t * Mouse wheel handler for zooming support\n\t\t */\n\t\tdoMouseZoom: function(wheelDelta, timeStamp, pageX, pageY) {\n\n\t\t\tvar self = this;\n\t\t\tvar change = wheelDelta > 0 ? 0.97 : 1.03;\n\n\t\t\treturn self.zoomTo(self.__zoomLevel * change, false, pageX - self.__clientLeft, pageY - self.__clientTop);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Touch start handler for scrolling support\n\t\t */\n\t\tdoTouchStart: function(touches, timeStamp) {\n\t\t\t// Array-like check is enough here\n\t\t\tif (touches.length == null) {\n\t\t\t\tthrow new Error(\"Invalid touch list: \" + touches);\n\t\t\t}\n\n\t\t\tif (timeStamp instanceof Date) {\n\t\t\t\ttimeStamp = timeStamp.valueOf();\n\t\t\t}\n\t\t\tif (typeof timeStamp !== \"number\") {\n\t\t\t\tthrow new Error(\"Invalid timestamp value: \" + timeStamp);\n\t\t\t}\n\n\t\t\tvar self = this;\n\n\t\t\t// Reset interruptedAnimation flag\n\t\t\tself.__interruptedAnimation = true;\n\n\t\t\t// Stop deceleration\n\t\t\tif (self.__isDecelerating) {\n\t\t\t\tcore.effect.Animate.stop(self.__isDecelerating);\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t\tself.__interruptedAnimation = true;\n\t\t\t}\n\n\t\t\t// Stop animation\n\t\t\tif (self.__isAnimating) {\n core.effect.Animate.stop(self.__isAnimating);\n\t\t\t\tself.__isAnimating = false;\n\t\t\t\tself.__interruptedAnimation = true;\n\t\t\t}\n\n\t\t\t// Use center point when dealing with two fingers\n\t\t\tvar currentTouchLeft, currentTouchTop;\n\t\t\tvar isSingleTouch = touches.length === 1;\n\t\t\tif (isSingleTouch) {\n\t\t\t\tcurrentTouchLeft = touches[0].pageX;\n\t\t\t\tcurrentTouchTop = touches[0].pageY;\n\t\t\t} else {\n\t\t\t\tcurrentTouchLeft = Math.abs(touches[0].pageX + touches[1].pageX) / 2;\n\t\t\t\tcurrentTouchTop = Math.abs(touches[0].pageY + touches[1].pageY) / 2;\n\t\t\t}\n\n\t\t\t// Store initial positions\n\t\t\tself.__initialTouchLeft = currentTouchLeft;\n\t\t\tself.__initialTouchTop = currentTouchTop;\n\n\t\t\t// Store current zoom level\n\t\t\tself.__zoomLevelStart = self.__zoomLevel;\n\n\t\t\t// Store initial touch positions\n\t\t\tself.__lastTouchLeft = currentTouchLeft;\n\t\t\tself.__lastTouchTop = currentTouchTop;\n\n\t\t\t// Store initial move time stamp\n\t\t\tself.__lastTouchMove = timeStamp;\n\n\t\t\t// Reset initial scale\n\t\t\tself.__lastScale = 1;\n\n\t\t\t// Reset locking flags\n\t\t\tself.__enableScrollX = !isSingleTouch && self.options.scrollingX;\n\t\t\tself.__enableScrollY = !isSingleTouch && self.options.scrollingY;\n\n\t\t\t// Reset tracking flag\n\t\t\tself.__isTracking = true;\n\n\t\t\t// Reset deceleration complete flag\n\t\t\tself.__didDecelerationComplete = false;\n\n\t\t\t// Dragging starts directly with two fingers, otherwise lazy with an offset\n\t\t\tself.__isDragging = !isSingleTouch;\n\n\t\t\t// Some features are disabled in multi touch scenarios\n\t\t\tself.__isSingleTouch = isSingleTouch;\n\n\t\t\t// Clearing data structure\n\t\t\tself.__positions = [];\n\n\t\t},\n\n\n\t\t/**\n\t\t * Touch move handler for scrolling support\n\t\t */\n\t\tdoTouchMove: function(touches, timeStamp, scale) {\n\n\t\t\t// Array-like check is enough here\n\t\t\tif (touches.length == null) {\n\t\t\t\tthrow new Error(\"Invalid touch list: \" + touches);\n\t\t\t}\n\n\t\t\tif (timeStamp instanceof Date) {\n\t\t\t\ttimeStamp = timeStamp.valueOf();\n\t\t\t}\n\t\t\tif (typeof timeStamp !== \"number\") {\n\t\t\t\tthrow new Error(\"Invalid timestamp value: \" + timeStamp);\n\t\t\t}\n\n\t\t\tvar self = this;\n\n\t\t\t// Ignore event when tracking is not enabled (event might be outside of element)\n\t\t\tif (!self.__isTracking) {\n\t\t\t\treturn;\n\t\t\t}\n\n\n\t\t\tvar currentTouchLeft, currentTouchTop;\n\n\t\t\t// Compute move based around of center of fingers\n\t\t\tif (touches.length === 2) {\n\t\t\t\tcurrentTouchLeft = Math.abs(touches[0].pageX + touches[1].pageX) / 2;\n\t\t\t\tcurrentTouchTop = Math.abs(touches[0].pageY + touches[1].pageY) / 2;\n\t\t\t} else {\n\t\t\t\tcurrentTouchLeft = touches[0].pageX;\n\t\t\t\tcurrentTouchTop = touches[0].pageY;\n\t\t\t}\n\n\t\t\tvar positions = self.__positions;\n\n\t\t\t// Are we already is dragging mode?\n\t\t\tif (self.__isDragging) {\n\n\t\t\t\t// Compute move distance\n\t\t\t\tvar moveX = currentTouchLeft - self.__lastTouchLeft;\n\t\t\t\tvar moveY = currentTouchTop - self.__lastTouchTop;\n\n\t\t\t\t// Read previous scroll position and zooming\n\t\t\t\tvar scrollLeft = self.__scrollLeft;\n\t\t\t\tvar scrollTop = self.__scrollTop;\n\t\t\t\tvar level = self.__zoomLevel;\n\n\t\t\t\t// Work with scaling\n\t\t\t\tif (scale != null && self.options.zooming) {\n\n\t\t\t\t\tvar oldLevel = level;\n\n\t\t\t\t\t// Recompute level based on previous scale and new scale\n\t\t\t\t\tlevel = level / self.__lastScale * scale;\n\n\t\t\t\t\t// Limit level according to configuration\n\t\t\t\t\tlevel = Math.max(Math.min(level, self.options.maxZoom), self.options.minZoom);\n\n\t\t\t\t\t// Only do further compution when change happened\n\t\t\t\t\tif (oldLevel !== level) {\n\n\t\t\t\t\t\t// Compute relative event position to container\n\t\t\t\t\t\tvar currentTouchLeftRel = currentTouchLeft - self.__clientLeft;\n\t\t\t\t\t\tvar currentTouchTopRel = currentTouchTop - self.__clientTop;\n\n\t\t\t\t\t\t// Recompute left and top coordinates based on new zoom level\n\t\t\t\t\t\tscrollLeft = ((currentTouchLeftRel + scrollLeft) * level / oldLevel) - currentTouchLeftRel;\n\t\t\t\t\t\tscrollTop = ((currentTouchTopRel + scrollTop) * level / oldLevel) - currentTouchTopRel;\n\n\t\t\t\t\t\t// Recompute max scroll values\n\t\t\t\t\t\tself.__computeScrollMax(level);\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (self.__enableScrollX) {\n\n\t\t\t\t\tscrollLeft -= moveX * this.options.speedMultiplier;\n\t\t\t\t\tvar maxScrollLeft = self.__maxScrollLeft;\n\n\t\t\t\t\tif (scrollLeft > maxScrollLeft || scrollLeft < 0) {\n\n\t\t\t\t\t\t// Slow down on the edges\n\t\t\t\t\t\tif (self.options.bouncing) {\n\n\t\t\t\t\t\t\tscrollLeft += (moveX / 2 * this.options.speedMultiplier);\n\n\t\t\t\t\t\t} else if (scrollLeft > maxScrollLeft) {\n\n\t\t\t\t\t\t\tscrollLeft = maxScrollLeft;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tscrollLeft = 0;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Compute new vertical scroll position\n\t\t\t\tif (self.__enableScrollY) {\n\n\t\t\t\t\tscrollTop -= moveY * this.options.speedMultiplier;\n\t\t\t\t\tvar maxScrollTop = self.__maxScrollTop;\n\n\t\t\t\t\tif (scrollTop > maxScrollTop || scrollTop < 0) {\n\n\t\t\t\t\t\t// Slow down on the edges\n\t\t\t\t\t\tif (self.options.bouncing) {\n\n\t\t\t\t\t\t\tscrollTop += (moveY / 2 * this.options.speedMultiplier);\n\n\t\t\t\t\t\t\t// Support pull-to-refresh (only when only y is scrollable)\n\t\t\t\t\t\t\tif (!self.__enableScrollX && self.__refreshHeight != null) {\n\n\t\t\t\t\t\t\t\tif (!self.__refreshActive && scrollTop <= -self.__refreshHeight) {\n\n\t\t\t\t\t\t\t\t\tself.__refreshActive = true;\n\t\t\t\t\t\t\t\t\tif (self.__refreshActivate) {\n\t\t\t\t\t\t\t\t\t\tself.__refreshActivate();\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else if (self.__refreshActive && scrollTop > -self.__refreshHeight) {\n\n\t\t\t\t\t\t\t\t\tself.__refreshActive = false;\n\t\t\t\t\t\t\t\t\tif (self.__refreshDeactivate) {\n\t\t\t\t\t\t\t\t\t\tself.__refreshDeactivate();\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if (scrollTop > maxScrollTop) {\n\n\t\t\t\t\t\t\tscrollTop = maxScrollTop;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tscrollTop = 0;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Keep list from growing infinitely (holding min 10, max 20 measure points)\n\t\t\t\tif (positions.length > 60) {\n\t\t\t\t\tpositions.splice(0, 30);\n\t\t\t\t}\n\n\t\t\t\t// Track scroll movement for decleration\n\t\t\t\tpositions.push(scrollLeft, scrollTop, timeStamp);\n\n\t\t\t\t// Sync scroll position\n\t\t\t\tself.__publish(scrollLeft, scrollTop, level);\n\n\t\t\t// Otherwise figure out whether we are switching into dragging mode now.\n\t\t\t} else {\n\n\t\t\t\tvar minimumTrackingForScroll = self.options.locking ? 3 : 0;\n\t\t\t\tvar minimumTrackingForDrag = 5;\n\n\t\t\t\tvar distanceX = Math.abs(currentTouchLeft - self.__initialTouchLeft);\n\t\t\t\tvar distanceY = Math.abs(currentTouchTop - self.__initialTouchTop);\n\n\t\t\t\tself.__enableScrollX = self.options.scrollingX && distanceX >= minimumTrackingForScroll;\n\t\t\t\tself.__enableScrollY = self.options.scrollingY && distanceY >= minimumTrackingForScroll;\n\n\t\t\t\tpositions.push(self.__scrollLeft, self.__scrollTop, timeStamp);\n\n\t\t\t\tself.__isDragging = (self.__enableScrollX || self.__enableScrollY) && (distanceX >= minimumTrackingForDrag || distanceY >= minimumTrackingForDrag);\n\t\t\t\tif (self.__isDragging) {\n\t\t\t\t\tself.__interruptedAnimation = false;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Update last touch positions and time stamp for next event\n\t\t\tself.__lastTouchLeft = currentTouchLeft;\n\t\t\tself.__lastTouchTop = currentTouchTop;\n\t\t\tself.__lastTouchMove = timeStamp;\n\t\t\tself.__lastScale = scale;\n\n\t\t},\n\n\n\t\t/**\n\t\t * Touch end handler for scrolling support\n\t\t */\n\t\tdoTouchEnd: function(timeStamp) {\n\n\t\t\tif (timeStamp instanceof Date) {\n\t\t\t\ttimeStamp = timeStamp.valueOf();\n\t\t\t}\n\t\t\tif (typeof timeStamp !== \"number\") {\n\t\t\t\tthrow new Error(\"Invalid timestamp value: \" + timeStamp);\n\t\t\t}\n\n\t\t\tvar self = this;\n\n\t\t\t// Ignore event when tracking is not enabled (no touchstart event on element)\n\t\t\t// This is required as this listener ('touchmove') sits on the document and not on the element itself.\n\t\t\tif (!self.__isTracking) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Not touching anymore (when two finger hit the screen there are two touch end events)\n\t\t\tself.__isTracking = false;\n\n\t\t\t// Be sure to reset the dragging flag now. Here we also detect whether\n\t\t\t// the finger has moved fast enough to switch into a deceleration animation.\n\t\t\tif (self.__isDragging) {\n\n\t\t\t\t// Reset dragging flag\n\t\t\t\tself.__isDragging = false;\n\n\t\t\t\t// Start deceleration\n\t\t\t\t// Verify that the last move detected was in some relevant time frame\n\t\t\t\tif (self.__isSingleTouch && self.options.animating && (timeStamp - self.__lastTouchMove) <= 100) {\n\n\t\t\t\t\t// Then figure out what the scroll position was about 100ms ago\n\t\t\t\t\tvar positions = self.__positions;\n\t\t\t\t\tvar endPos = positions.length - 1;\n\t\t\t\t\tvar startPos = endPos;\n\n\t\t\t\t\t// Move pointer to position measured 100ms ago\n\t\t\t\t\tfor (var i = endPos; i > 0 && positions[i] > (self.__lastTouchMove - 100); i -= 3) {\n\t\t\t\t\t\tstartPos = i;\n\t\t\t\t\t}\n\n\t\t\t\t\t// If start and stop position is identical in a 100ms timeframe,\n\t\t\t\t\t// we cannot compute any useful deceleration.\n\t\t\t\t\tif (startPos !== endPos) {\n\n\t\t\t\t\t\t// Compute relative movement between these two points\n\t\t\t\t\t\tvar timeOffset = positions[endPos] - positions[startPos];\n\t\t\t\t\t\tvar movedLeft = self.__scrollLeft - positions[startPos - 2];\n\t\t\t\t\t\tvar movedTop = self.__scrollTop - positions[startPos - 1];\n\n\t\t\t\t\t\t// Based on 50ms compute the movement to apply for each render step\n\t\t\t\t\t\tself.__decelerationVelocityX = movedLeft / timeOffset * (1000 / 60);\n\t\t\t\t\t\tself.__decelerationVelocityY = movedTop / timeOffset * (1000 / 60);\n\n\t\t\t\t\t\t// How much velocity is required to start the deceleration\n\t\t\t\t\t\tvar minVelocityToStartDeceleration = self.options.paging || self.options.snapping ? 4 : 1;\n\n\t\t\t\t\t\t// Verify that we have enough velocity to start deceleration\n\t\t\t\t\t\tif (Math.abs(self.__decelerationVelocityX) > minVelocityToStartDeceleration || Math.abs(self.__decelerationVelocityY) > minVelocityToStartDeceleration) {\n\n\t\t\t\t\t\t\t// Deactivate pull-to-refresh when decelerating\n\t\t\t\t\t\t\tif (!self.__refreshActive) {\n\t\t\t\t\t\t\t\tself.__startDeceleration(timeStamp);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t}\n\t\t\t\t} else if ((timeStamp - self.__lastTouchMove) > 100) {\n\t\t\t\t\tself.options.scrollingComplete();\n\t \t\t\t}\n\t\t\t}\n\n\t\t\t// If this was a slower move it is per default non decelerated, but this\n\t\t\t// still means that we want snap back to the bounds which is done here.\n\t\t\t// This is placed outside the condition above to improve edge case stability\n\t\t\t// e.g. touchend fired without enabled dragging. This should normally do not\n\t\t\t// have modified the scroll positions or even showed the scrollbars though.\n\t\t\tif (!self.__isDecelerating) {\n\n\t\t\t\tif (self.__refreshActive && self.__refreshStart) {\n\n\t\t\t\t\t// Use publish instead of scrollTo to allow scrolling to out of boundary position\n\t\t\t\t\t// We don't need to normalize scrollLeft, zoomLevel, etc. here because we only y-scrolling when pull-to-refresh is enabled\n\t\t\t\t\tself.__publish(self.__scrollLeft, -self.__refreshHeight, self.__zoomLevel, true);\n\n\t\t\t\t\tif (self.__refreshStart) {\n\t\t\t\t\t\tself.__refreshStart();\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif (self.__interruptedAnimation || self.__isDragging) {\n\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t}\n\t\t\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, true, self.__zoomLevel);\n\n\t\t\t\t\t// Directly signalize deactivation (nothing todo on refresh?)\n\t\t\t\t\tif (self.__refreshActive) {\n\n\t\t\t\t\t\tself.__refreshActive = false;\n\t\t\t\t\t\tif (self.__refreshDeactivate) {\n\t\t\t\t\t\t\tself.__refreshDeactivate();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fully cleanup list\n\t\t\tself.__positions.length = 0;\n\n\t\t},\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tPRIVATE API\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/**\n\t\t * Applies the scroll position to the content element\n\t\t *\n\t\t * @param left {Number} Left scroll position\n\t\t * @param top {Number} Top scroll position\n\t\t * @param animate {Boolean?false} Whether animation should be used to move to the new coordinates\n\t\t */\n\t\t__publish: function(left, top, zoom, animate) {\n\n\t\t\tvar self = this;\n\n\t\t\t// Remember whether we had an animation, then we try to continue based on the current \"drive\" of the animation\n\t\t\tvar wasAnimating = self.__isAnimating;\n\t\t\tif (wasAnimating) {\n core.effect.Animate.stop(wasAnimating);\n\t\t\t\tself.__isAnimating = false;\n\t\t\t}\n\n\t\t\tif (animate && self.options.animating) {\n\n\t\t\t\t// Keep scheduled positions for scrollBy/zoomBy functionality\n\t\t\t\tself.__scheduledLeft = left;\n\t\t\t\tself.__scheduledTop = top;\n\t\t\t\tself.__scheduledZoom = zoom;\n\n\t\t\t\tvar oldLeft = self.__scrollLeft;\n\t\t\t\tvar oldTop = self.__scrollTop;\n\t\t\t\tvar oldZoom = self.__zoomLevel;\n\n\t\t\t\tvar diffLeft = left - oldLeft;\n\t\t\t\tvar diffTop = top - oldTop;\n\t\t\t\tvar diffZoom = zoom - oldZoom;\n\n\t\t\t\tvar step = function(percent, now, render) {\n\n\t\t\t\t\tif (render) {\n\n\t\t\t\t\t\tself.__scrollLeft = oldLeft + (diffLeft * percent);\n\t\t\t\t\t\tself.__scrollTop = oldTop + (diffTop * percent);\n\t\t\t\t\t\tself.fireEvent('scrollTopChanged', self.__scrollTop);\n\t\t\t\t\t\tself.__zoomLevel = oldZoom + (diffZoom * percent);\n\n\t\t\t\t\t\t// Push values out\n\t\t\t\t\t\tif (self.__callback) {\n\t\t\t\t\t\t\tself.__callback(self.__scrollLeft, self.__scrollTop, self.__zoomLevel);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tvar verify = function(id) {\n\t\t\t\t\treturn self.__isAnimating === id;\n\t\t\t\t};\n\n\t\t\t\tvar completed = function(renderedFramesPerSecond, animationId, wasFinished) {\n\t\t\t\t\tif (animationId === self.__isAnimating) {\n\t\t\t\t\t\tself.__isAnimating = false;\n\t\t\t\t\t}\n\t\t\t\t\tif (self.__didDecelerationComplete || wasFinished) {\n\t\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (self.options.zooming) {\n\t\t\t\t\t\tself.__computeScrollMax();\n\t\t\t\t\t\tif(self.__zoomComplete) {\n\t\t\t\t\t\t\tself.__zoomComplete();\n\t\t\t\t\t\t\tself.__zoomComplete = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// When continuing based on previous animation we choose an ease-out animation instead of ease-in-out\n self.__isAnimating = core.effect.Animate.start(step, verify, completed, self.options.animationDuration, wasAnimating ? easeOutCubic : easeInOutCubic);\n\n\t\t\t} else {\n\n\t\t\t\tself.__scheduledLeft = self.__scrollLeft = left;\n\t\t\t\tself.__scheduledTop = self.__scrollTop = top;\n\t\t\t\tself.fireEvent('scrollTopChanged', self.__scrollTop);\n\t\t\t\tself.__scheduledZoom = self.__zoomLevel = zoom;\n\n\t\t\t\t// Push values out\n\t\t\t\tif (self.__callback) {\n\t\t\t\t\tself.__callback(left, top, zoom);\n\t\t\t\t}\n\n\t\t\t\t// Fix max scroll ranges\n\t\t\t\tif (self.options.zooming) {\n\t\t\t\t\tself.__computeScrollMax();\n\t\t\t\t\tif(self.__zoomComplete) {\n\t\t\t\t\t\tself.__zoomComplete();\n\t\t\t\t\t\tself.__zoomComplete = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\n\t\t/**\n\t\t * Recomputes scroll minimum values based on client dimensions and content dimensions.\n\t\t */\n\t\t__computeScrollMax: function(zoomLevel) {\n\n\t\t\tvar self = this;\n\n\t\t\tif (zoomLevel == null) {\n\t\t\t\tzoomLevel = self.__zoomLevel;\n\t\t\t}\n\n\t\t\tself.__maxScrollLeft = Math.max((self.__contentWidth * zoomLevel) - self.__clientWidth, 0);\n\t\t\tself.__maxScrollTop = Math.max((self.__contentHeight * zoomLevel) - self.__clientHeight, 0);\n\n\t\t},\n\n\n\n\t\t/*\n\t\t---------------------------------------------------------------------------\n\t\t\tANIMATION (DECELERATION) SUPPORT\n\t\t---------------------------------------------------------------------------\n\t\t*/\n\n\t\t/**\n\t\t * Called when a touch sequence end and the speed of the finger was high enough\n\t\t * to switch into deceleration mode.\n\t\t */\n\t\t__startDeceleration: function(timeStamp) {\n\n\t\t\tvar self = this;\n\n\t\t\tif (self.options.paging) {\n\n\t\t\t\tvar scrollLeft = Math.max(Math.min(self.__scrollLeft, self.__maxScrollLeft), 0);\n\t\t\t\tvar scrollTop = Math.max(Math.min(self.__scrollTop, self.__maxScrollTop), 0);\n\t\t\t\tvar clientWidth = self.__clientWidth;\n\t\t\t\tvar clientHeight = self.__clientHeight;\n\n\t\t\t\t// We limit deceleration not to the min/max values of the allowed range, but to the size of the visible client area.\n\t\t\t\t// Each page should have exactly the size of the client area.\n\t\t\t\tself.__minDecelerationScrollLeft = Math.floor(scrollLeft / clientWidth) * clientWidth;\n\t\t\t\tself.__minDecelerationScrollTop = Math.floor(scrollTop / clientHeight) * clientHeight;\n\t\t\t\tself.__maxDecelerationScrollLeft = Math.ceil(scrollLeft / clientWidth) * clientWidth;\n\t\t\t\tself.__maxDecelerationScrollTop = Math.ceil(scrollTop / clientHeight) * clientHeight;\n\n\t\t\t} else {\n\n\t\t\t\tself.__minDecelerationScrollLeft = 0;\n\t\t\t\tself.__minDecelerationScrollTop = 0;\n\t\t\t\tself.__maxDecelerationScrollLeft = self.__maxScrollLeft;\n\t\t\t\tself.__maxDecelerationScrollTop = self.__maxScrollTop;\n\n\t\t\t}\n\n\t\t\t// Wrap class method\n\t\t\tvar step = function(percent, now, render) {\n\t\t\t\tself.__stepThroughDeceleration(render);\n\t\t\t};\n\n\t\t\t// How much velocity is required to keep the deceleration running\n\t\t\tvar minVelocityToKeepDecelerating = self.options.snapping ? 4 : 0.001;\n\n\t\t\t// Detect whether it's still worth to continue animating steps\n\t\t\t// If we are already slow enough to not being user perceivable anymore, we stop the whole process here.\n\t\t\tvar verify = function() {\n\t\t\t\tvar shouldContinue = Math.abs(self.__decelerationVelocityX) >= minVelocityToKeepDecelerating || Math.abs(self.__decelerationVelocityY) >= minVelocityToKeepDecelerating;\n\t\t\t\tif (!shouldContinue) {\n\t\t\t\t\tself.__didDecelerationComplete = true;\n\t\t\t\t}\n\t\t\t\treturn shouldContinue;\n\t\t\t};\n\n\t\t\tvar completed = function(renderedFramesPerSecond, animationId, wasFinished) {\n\t\t\t\tself.__isDecelerating = false;\n\t\t\t\tif (self.__didDecelerationComplete) {\n\t\t\t\t\tself.options.scrollingComplete();\n\t\t\t\t}\n\n\t\t\t\t// Animate to grid when snapping is active, otherwise just fix out-of-boundary positions\n\t\t\t\tself.scrollTo(self.__scrollLeft, self.__scrollTop, self.options.snapping);\n\t\t\t};\n\n\t\t\t// Start animation and switch on flag\n\t\t\tself.__isDecelerating = core.effect.Animate.start(step, verify, completed);\n\n\t\t},\n\n\n\t\t/**\n\t\t * Called on every step of the animation\n\t\t *\n\t\t * @param inMemory {Boolean?false} Whether to not render the current step, but keep it in memory only. Used internally only!\n\t\t */\n\t\t__stepThroughDeceleration: function(render) {\n\n\t\t\tvar self = this;\n\n\n\t\t\t//\n\t\t\t// COMPUTE NEXT SCROLL POSITION\n\t\t\t//\n\n\t\t\t// Add deceleration to scroll position\n\t\t\tvar scrollLeft = self.__scrollLeft + self.__decelerationVelocityX;\n\t\t\tvar scrollTop = self.__scrollTop + self.__decelerationVelocityY;\n\n\n\t\t\t//\n\t\t\t// HARD LIMIT SCROLL POSITION FOR NON BOUNCING MODE\n\t\t\t//\n\n\t\t\tif (!self.options.bouncing) {\n\n\t\t\t\tvar scrollLeftFixed = Math.max(Math.min(self.__maxDecelerationScrollLeft, scrollLeft), self.__minDecelerationScrollLeft);\n\t\t\t\tif (scrollLeftFixed !== scrollLeft) {\n\t\t\t\t\tscrollLeft = scrollLeftFixed;\n\t\t\t\t\tself.__decelerationVelocityX = 0;\n\t\t\t\t}\n\n\t\t\t\tvar scrollTopFixed = Math.max(Math.min(self.__maxDecelerationScrollTop, scrollTop), self.__minDecelerationScrollTop);\n\t\t\t\tif (scrollTopFixed !== scrollTop) {\n\t\t\t\t\tscrollTop = scrollTopFixed;\n\t\t\t\t\tself.__decelerationVelocityY = 0;\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t//\n\t\t\t// UPDATE SCROLL POSITION\n\t\t\t//\n\n\t\t\tif (render) {\n\n\t\t\t\tself.__publish(scrollLeft, scrollTop, self.__zoomLevel);\n\n\t\t\t} else {\n\n\t\t\t\tself.__scrollLeft = scrollLeft;\n\t\t\t\tself.__scrollTop = scrollTop;\n\t\t\t\tself.fireEvent('scrollTopChanged', self.__scrollTop);\n\n\t\t\t}\n\n\n\t\t\t//\n\t\t\t// SLOW DOWN\n\t\t\t//\n\n\t\t\t// Slow down velocity on every iteration\n\t\t\tif (!self.options.paging) {\n\n\t\t\t\t// This is the factor applied to every iteration of the animation\n\t\t\t\t// to slow down the process. This should emulate natural behavior where\n\t\t\t\t// objects slow down when the initiator of the movement is removed\n\t\t\t\tvar frictionFactor = 0.95;\n\n\t\t\t\tself.__decelerationVelocityX *= frictionFactor;\n\t\t\t\tself.__decelerationVelocityY *= frictionFactor;\n\n\t\t\t}\n\n\n\t\t\t//\n\t\t\t// BOUNCING SUPPORT\n\t\t\t//\n\n\t\t\tif (self.options.bouncing) {\n\n\t\t\t\tvar scrollOutsideX = 0;\n\t\t\t\tvar scrollOutsideY = 0;\n\n\t\t\t\t// This configures the amount of change applied to deceleration/acceleration when reaching boundaries\n\t\t\t\tvar penetrationDeceleration = self.options.penetrationDeceleration;\n\t\t\t\tvar penetrationAcceleration = self.options.penetrationAcceleration;\n\n\t\t\t\t// Check limits\n\t\t\t\tif (scrollLeft < self.__minDecelerationScrollLeft) {\n\t\t\t\t\tscrollOutsideX = self.__minDecelerationScrollLeft - scrollLeft;\n\t\t\t\t} else if (scrollLeft > self.__maxDecelerationScrollLeft) {\n\t\t\t\t\tscrollOutsideX = self.__maxDecelerationScrollLeft - scrollLeft;\n\t\t\t\t}\n\n\t\t\t\tif (scrollTop < self.__minDecelerationScrollTop) {\n\t\t\t\t\tscrollOutsideY = self.__minDecelerationScrollTop - scrollTop;\n\t\t\t\t} else if (scrollTop > self.__maxDecelerationScrollTop) {\n\t\t\t\t\tscrollOutsideY = self.__maxDecelerationScrollTop - scrollTop;\n\t\t\t\t}\n\n\t\t\t\t// Slow down until slow enough, then flip back to snap position\n\t\t\t\tif (scrollOutsideX !== 0) {\n\t\t\t\t\tif (scrollOutsideX * self.__decelerationVelocityX <= 0) {\n\t\t\t\t\t\tself.__decelerationVelocityX += scrollOutsideX * penetrationDeceleration;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.__decelerationVelocityX = scrollOutsideX * penetrationAcceleration;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (scrollOutsideY !== 0) {\n\t\t\t\t\tif (scrollOutsideY * self.__decelerationVelocityY <= 0) {\n\t\t\t\t\t\tself.__decelerationVelocityY += scrollOutsideY * penetrationDeceleration;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.__decelerationVelocityY = scrollOutsideY * penetrationAcceleration;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\teventMap: new Map(),\n\n\t\taddEventListener: function(name, listener) {\n\t\t\tlet listeners = this.eventMap.get(name);\n\t\t\tif (!listeners) {\n\t\t\t\tlisteners = [];\n\t\t\t\tthis.eventMap.set(name, listeners);\n\t\t\t}\n\n\t\t\tlisteners.push(listener);\n\t\t},\n\n\t\tfireEvent: function(name, data) {\n\t\t\tlet listeners = this.eventMap.get(name);\n\t\t\tif (listeners) {\n\t\t\t\tlisteners.forEach(function(listener) {\n\t\t\t\t\tlistener(data);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t};\n\n\t// Copy over members to prototype\n\tfor (var key in members) {\n\t\tScroller.prototype[key] = members[key];\n\t}\n\n if (typeof module != 'undefined' && module.exports) {\n module.exports = Scroller;\n } else if (typeof define == 'function' && define.amd) {\n define( function () { return Scroller; } );\n } else {\n window.Scroller = Scroller;\n }\n\n})(window);\n\n\n\n// WEBPACK FOOTER //\n// ./src/module/core.js","function getContentRender(content) {\n var global = window;\n\n var docStyle = document.documentElement.style;\n\n var engine;\n if (global.opera && Object.prototype.toString.call(opera) === '[object Opera]') {\n engine = 'presto';\n } else if ('MozAppearance' in docStyle) {\n engine = 'gecko';\n } else if ('WebkitAppearance' in docStyle) {\n engine = 'webkit';\n } else if (typeof navigator.cpuClass === 'string') {\n engine = 'trident';\n }\n\n var vendorPrefix = {\n trident: 'ms',\n gecko: 'Moz',\n webkit: 'Webkit',\n presto: 'O'\n }[engine];\n\n var helperElem = document.createElement(\"div\");\n var undef;\n\n var perspectiveProperty = vendorPrefix + \"Perspective\";\n var transformProperty = vendorPrefix + \"Transform\";\n\n if (helperElem.style[perspectiveProperty] !== undef) {\n\n return function(left, top, zoom) {\n content.style[transformProperty] = 'translate3d(' + (-left) + 'px,' + (-top) + 'px,0) scale(' + zoom + ')';\n };\n\n } else if (helperElem.style[transformProperty] !== undef) {\n\n return function(left, top, zoom) {\n content.style[transformProperty] = 'translate(' + (-left) + 'px,' + (-top) + 'px) scale(' + zoom + ')';\n };\n\n } else {\n\n return function(left, top, zoom) {\n content.style.marginLeft = left ? (-left/zoom) + 'px' : '';\n content.style.marginTop = top ? (-top/zoom) + 'px' : '';\n content.style.zoom = zoom || '';\n };\n\n }\n}\n\nmodule.exports = getContentRender;\n\n\n\n// WEBPACK FOOTER //\n// ./src/module/render.js","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"._v-container[data-v-ecaca2b0]{-webkit-tap-highlight-color:rgba(0,0,0,0);width:100%;height:100%;position:absolute;top:0;left:0;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}._v-container>._v-content[data-v-ecaca2b0]{width:100%;-webkit-transform-origin:left top;-webkit-transform:translateZ(0);-moz-transform-origin:left top;-moz-transform:translateZ(0);-ms-transform-origin:left top;-ms-transform:translateZ(0);-o-transform-origin:left top;-o-transform:translateZ(0);transform-origin:left top;transform:translateZ(0)}._v-container>._v-content>.pull-to-refresh-layer[data-v-ecaca2b0]{width:100%;height:60px;margin-top:-60px;text-align:center;font-size:16px;color:#aaa}._v-container>._v-content>.loading-layer[data-v-ecaca2b0]{width:100%;height:60px;text-align:center;font-size:16px;line-height:60px;color:#aaa;position:relative}._v-container>._v-content>.loading-layer>.no-data-text[data-v-ecaca2b0]{position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}._v-container>._v-content>.loading-layer>.no-data-text[data-v-ecaca2b0],._v-container>._v-content>.loading-layer>.spinner-holder[data-v-ecaca2b0]{opacity:0;transition:opacity .15s linear;-webkit-transition:opacity .15s linear}._v-container>._v-content>.loading-layer>.no-data-text.active[data-v-ecaca2b0],._v-container>._v-content>.loading-layer>.spinner-holder.active[data-v-ecaca2b0]{opacity:1}._v-container>._v-content>.loading-layer .spinner-holder[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder[data-v-ecaca2b0]{text-align:center;-webkit-font-smoothing:antialiased}._v-container>._v-content>.loading-layer .spinner-holder .arrow[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .arrow[data-v-ecaca2b0]{width:20px;height:20px;margin:8px auto 0;-webkit-transform:translateZ(0) rotate(0deg);transform:translateZ(0) rotate(0deg);transition:transform .2s linear}._v-container>._v-content>.loading-layer .spinner-holder .text[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .text[data-v-ecaca2b0]{display:block;margin:0 auto;font-size:14px;line-height:20px;color:#aaa}._v-container>._v-content>.loading-layer .spinner-holder .spinner[data-v-ecaca2b0],._v-container>._v-content>.pull-to-refresh-layer .spinner-holder .spinner[data-v-ecaca2b0]{margin-top:14px;width:32px;height:32px;fill:#444;stroke:#69717d}._v-container>._v-content>.pull-to-refresh-layer.active .spinner-holder .arrow[data-v-ecaca2b0]{-webkit-transform:translateZ(0) rotate(180deg);transform:translateZ(0) rotate(180deg)}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader?minimize!./~/vue-loader/lib/style-compiler?{\"id\":\"data-v-ecaca2b0\",\"scoped\":true,\"hasInlineConfig\":false}!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/components/Scroller.vue\n// module id = 7\n// module chunks = 0","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader/lib/css-base.js\n// module id = 8\n// module chunks = 0","var Component = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n require(\"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./Arrow.vue\"),\n /* template */\n require(\"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-338435ea\\\"}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./Arrow.vue\"),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/Arrow.vue\n// module id = 9\n// module chunks = 0","var Component = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n null,\n /* template */\n require(\"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-7e08eeca\\\"}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./Spinner.vue\"),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/Spinner.vue\n// module id = 10\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('svg', {\n staticStyle: {\n \"enable-background\": \"new 0 0 63.657 63.657\"\n },\n attrs: {\n \"viewBox\": \"0 0 63.657 63.657\",\n \"xml:space\": \"preserve\",\n \"width\": \"512px\",\n \"height\": \"512px\"\n }\n }, [_c('g', [_c('g', [_c('g', [_c('g', [_c('polygon', {\n attrs: {\n \"points\": \"31.891,63.657 0.012,35.835 2.642,32.821 31.886,58.343 61.009,32.824 63.645,35.832\",\n \"fill\": _vm.fillColor\n }\n })])]), _vm._v(\" \"), _c('g', [_c('g', [_c('rect', {\n attrs: {\n \"x\": \"29.827\",\n \"width\": \"4\",\n \"height\": \"60\",\n \"fill\": _vm.fillColor\n }\n })])])]), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g')]), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g'), _vm._v(\" \"), _c('g')])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-338435ea\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/components/Arrow.vue\n// module id = 11\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('svg', {\n staticClass: \"spinner\",\n attrs: {\n \"viewBox\": \"0 0 64 64\"\n }\n }, [_c('g', {\n attrs: {\n \"stroke-width\": \"4\",\n \"stroke-linecap\": \"round\"\n }\n }, [_c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(180)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \"1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0;1\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(210)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \"0;1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(240)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".1;0;1;.85;.7;.65;.55;.45;.35;.25;.15;.1\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(270)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".15;.1;0;1;.85;.7;.65;.55;.45;.35;.25;.15\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(300)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".25;.15;.1;0;1;.85;.7;.65;.55;.45;.35;.25\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(330)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".35;.25;.15;.1;0;1;.85;.7;.65;.55;.45;.35\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(0)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".45;.35;.25;.15;.1;0;1;.85;.7;.65;.55;.45\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(30)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".55;.45;.35;.25;.15;.1;0;1;.85;.7;.65;.55\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(60)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".65;.55;.45;.35;.25;.15;.1;0;1;.85;.7;.65\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(90)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".7;.65;.55;.45;.35;.25;.15;.1;0;1;.85;.7\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(120)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \".85;.7;.65;.55;.45;.35;.25;.15;.1;0;1;.85\",\n \"repeatCount\": \"indefinite\"\n }\n })]), _c('line', {\n attrs: {\n \"y1\": \"17\",\n \"y2\": \"29\",\n \"transform\": \"translate(32,32) rotate(150)\"\n }\n }, [_c('animate', {\n attrs: {\n \"attributeName\": \"stroke-opacity\",\n \"dur\": \"750ms\",\n \"values\": \"1;.85;.7;.65;.55;.45;.35;.25;.15;.1;0;1\",\n \"repeatCount\": \"indefinite\"\n }\n })])])])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-7e08eeca\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/components/Spinner.vue\n// module id = 12\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n staticClass: \"_v-container\",\n attrs: {\n \"id\": _vm.containerId\n },\n on: {\n \"touchstart\": function($event) {\n _vm.touchStart($event)\n },\n \"touchmove\": function($event) {\n _vm.touchMove($event)\n },\n \"touchend\": function($event) {\n _vm.touchEnd($event)\n },\n \"mousedown\": function($event) {\n _vm.mouseDown($event)\n },\n \"mousemove\": function($event) {\n _vm.mouseMove($event)\n },\n \"mouseup\": function($event) {\n _vm.mouseUp($event)\n }\n }\n }, [_c('div', {\n staticClass: \"_v-content\",\n attrs: {\n \"id\": _vm.contentId\n }\n }, [(_vm.onRefresh) ? _c('div', {\n staticClass: \"pull-to-refresh-layer\",\n class: {\n 'active': _vm.state == 1, 'active refreshing': _vm.state == 2\n }\n }, [_c('span', {\n staticClass: \"spinner-holder\"\n }, [(_vm.state != 2) ? _c('arrow', {\n staticClass: \"arrow\",\n attrs: {\n \"fillColor\": _vm.refreshLayerColor\n }\n }) : _vm._e(), _vm._v(\" \"), (_vm.state != 2) ? _c('span', {\n staticClass: \"text\",\n style: ({\n color: _vm.refreshLayerColor\n }),\n domProps: {\n \"textContent\": _vm._s(_vm.refreshText)\n }\n }) : _vm._e(), _vm._v(\" \"), (_vm.state == 2) ? _c('span', [_vm._t(\"refresh-spinner\", [_c('spinner', {\n style: ({\n fill: _vm.refreshLayerColor,\n stroke: _vm.refreshLayerColor\n })\n })])], 2) : _vm._e()], 1)]) : _vm._e(), _vm._v(\" \"), _vm._t(\"default\"), _vm._v(\" \"), (_vm.showInfiniteLayer) ? _c('div', {\n staticClass: \"loading-layer\"\n }, [_c('span', {\n staticClass: \"spinner-holder\",\n class: {\n 'active': _vm.showLoading\n }\n }, [_vm._t(\"infinite-spinner\", [_c('spinner', {\n style: ({\n fill: _vm.loadingLayerColor,\n stroke: _vm.loadingLayerColor\n })\n })])], 2), _vm._v(\" \"), _c('div', {\n staticClass: \"no-data-text\",\n class: {\n 'active': !_vm.showLoading && _vm.loadingState == 2\n },\n style: ({\n color: _vm.loadingLayerColor\n }),\n domProps: {\n \"textContent\": _vm._s(_vm.noDataText)\n }\n })]) : _vm._e()], 2)])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-ecaca2b0\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/components/Scroller.vue\n// module id = 13\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a