{"version":3,"sources":["module.js","helpers.js","request-animation.js","spy-api.js","scroll-container-api.js","smooth-scroll.js","spy-context.js","scroll-container.js","scrollspy.js"],"names":[],"mappings":"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","file":"angular-scroll.min.js","sourcesContent":["/**\n  * x is a value between 0 and 1, indicating where in the animation you are.\n  */\nvar duScrollDefaultEasing = function (x) {\n  'use strict';\n\n  if(x < 0.5) {\n    return Math.pow(x*2, 2)/2;\n  }\n  return 1-Math.pow((1-x)*2, 2)/2;\n};\n\nangular.module('duScroll', [\n  'duScroll.scrollspy',\n  'duScroll.smoothScroll',\n  'duScroll.scrollContainer',\n  'duScroll.spyContext',\n  'duScroll.scrollHelpers'\n])\n  //Default animation duration for smoothScroll directive\n  .value('duScrollDuration', 350)\n  //Scrollspy debounce interval, set to 0 to disable\n  .value('duScrollSpyWait', 100)\n  //Wether or not multiple scrollspies can be active at once\n  .value('duScrollGreedy', false)\n  //Default offset for smoothScroll directive\n  .value('duScrollOffset', 0)\n  //Default easing function for scroll animation\n  .value('duScrollEasing', duScrollDefaultEasing);\n","angular.module('duScroll.scrollHelpers', ['duScroll.requestAnimation'])\n.run(function($window, $q, cancelAnimation, requestAnimation, duScrollEasing, duScrollDuration, duScrollOffset) {\n  'use strict';\n\n  var proto = {};\n\n  var isDocument = function(el) {\n    return (typeof HTMLDocument !== 'undefined' && el instanceof HTMLDocument) || (el.nodeType && el.nodeType === el.DOCUMENT_NODE);\n  };\n\n  var isElement = function(el) {\n    return (typeof HTMLElement !== 'undefined' && el instanceof HTMLElement) || (el.nodeType && el.nodeType === el.ELEMENT_NODE);\n  };\n\n  var unwrap = function(el) {\n    return isElement(el) || isDocument(el) ? el : el[0];\n  };\n\n  proto.duScrollTo = function(left, top, duration, easing) {\n    var aliasFn;\n    if(angular.isElement(left)) {\n      aliasFn = this.duScrollToElement;\n    } else if(angular.isDefined(duration)) {\n      aliasFn = this.duScrollToAnimated;\n    }\n    if(aliasFn) {\n      return aliasFn.apply(this, arguments);\n    }\n    var el = unwrap(this);\n    if(isDocument(el)) {\n      return $window.scrollTo(left, top);\n    }\n    el.scrollLeft = left;\n    el.scrollTop = top;\n  };\n\n  var scrollAnimation, deferred;\n  proto.duScrollToAnimated = function(left, top, duration, easing) {\n    if(duration && !easing) {\n      easing = duScrollEasing;\n    }\n    var startLeft = this.duScrollLeft(),\n        startTop = this.duScrollTop(),\n        deltaLeft = Math.round(left - startLeft),\n        deltaTop = Math.round(top - startTop);\n\n    var startTime = null;\n    var el = this;\n\n    var cancelOnEvents = 'scroll mousedown mousewheel touchmove keydown';\n    var cancelScrollAnimation = function($event) {\n      if (!$event || $event.which > 0) {\n        el.unbind(cancelOnEvents, cancelScrollAnimation);\n        cancelAnimation(scrollAnimation);\n        deferred.reject();\n        scrollAnimation = null;\n      }\n    };\n\n    if(scrollAnimation) {\n      cancelScrollAnimation();\n    }\n    deferred = $q.defer();\n\n    if(duration === 0 || (!deltaLeft && !deltaTop)) {\n      if(duration === 0) {\n        el.duScrollTo(left, top);\n      }\n      deferred.resolve();\n      return deferred.promise;\n    }\n\n    var animationStep = function(timestamp) {\n      if (startTime === null) {\n        startTime = timestamp;\n      }\n\n      var progress = timestamp - startTime;\n      var percent = (progress >= duration ? 1 : easing(progress/duration));\n\n      el.scrollTo(\n        startLeft + Math.ceil(deltaLeft * percent),\n        startTop + Math.ceil(deltaTop * percent)\n      );\n      if(percent < 1) {\n        scrollAnimation = requestAnimation(animationStep);\n      } else {\n        el.unbind(cancelOnEvents, cancelScrollAnimation);\n        scrollAnimation = null;\n        deferred.resolve();\n      }\n    };\n\n    //Fix random mobile safari bug when scrolling to top by hitting status bar\n    el.duScrollTo(startLeft, startTop);\n\n    el.bind(cancelOnEvents, cancelScrollAnimation);\n\n    scrollAnimation = requestAnimation(animationStep);\n    return deferred.promise;\n  };\n\n  proto.duScrollToElement = function(target, offset, duration, easing) {\n    var el = unwrap(this);\n    if(!angular.isNumber(offset) || isNaN(offset)) {\n      offset = duScrollOffset;\n    }\n    var top = this.duScrollTop() + unwrap(target).getBoundingClientRect().top - offset;\n    if(isElement(el)) {\n      top -= el.getBoundingClientRect().top;\n    }\n    return this.duScrollTo(0, top, duration, easing);\n  };\n\n  proto.duScrollLeft = function(value, duration, easing) {\n    if(angular.isNumber(value)) {\n      return this.duScrollTo(value, this.duScrollTop(), duration, easing);\n    }\n    var el = unwrap(this);\n    if(isDocument(el)) {\n      return $window.scrollX || document.documentElement.scrollLeft || document.body.scrollLeft;\n    }\n    return el.scrollLeft;\n  };\n  proto.duScrollTop = function(value, duration, easing) {\n    if(angular.isNumber(value)) {\n      return this.duScrollTo(this.duScrollLeft(), value, duration, easing);\n    }\n    var el = unwrap(this);\n    if(isDocument(el)) {\n      return $window.scrollY || document.documentElement.scrollTop || document.body.scrollTop;\n    }\n    return el.scrollTop;\n  };\n\n  proto.duScrollToElementAnimated = function(target, offset, duration, easing) {\n    return this.duScrollToElement(target, offset, duration || duScrollDuration, easing);\n  };\n\n  proto.duScrollTopAnimated = function(top, duration, easing) {\n    return this.duScrollTop(top, duration || duScrollDuration, easing);\n  };\n\n  proto.duScrollLeftAnimated = function(left, duration, easing) {\n    return this.duScrollLeft(left, duration || duScrollDuration, easing);\n  };\n\n  angular.forEach(proto, function(fn, key) {\n    angular.element.prototype[key] = fn;\n\n    //Remove prefix if not already claimed by jQuery / ui.utils\n    var unprefixed = key.replace(/^duScroll/, 'scroll');\n    if(angular.isUndefined(angular.element.prototype[unprefixed])) {\n      angular.element.prototype[unprefixed] = fn;\n    }\n  });\n\n});\n","//Adapted from https://gist.github.com/paulirish/1579671\nangular.module('duScroll.polyfill', [])\n.factory('polyfill', function($window) {\n  'use strict';\n\n  var vendors = ['webkit', 'moz', 'o', 'ms'];\n\n  return function(fnName, fallback) {\n    if($window[fnName]) {\n      return $window[fnName];\n    }\n    var suffix = fnName.substr(0, 1).toUpperCase() + fnName.substr(1);\n    for(var key, i = 0; i < vendors.length; i++) {\n      key = vendors[i]+suffix;\n      if($window[key]) {\n        return $window[key];\n      }\n    }\n    return fallback;\n  };\n});\n\nangular.module('duScroll.requestAnimation', ['duScroll.polyfill'])\n.factory('requestAnimation', function(polyfill, $timeout) {\n  'use strict';\n\n  var lastTime = 0;\n  var fallback = function(callback, element) {\n    var currTime = new Date().getTime();\n    var timeToCall = Math.max(0, 16 - (currTime - lastTime));\n    var id = $timeout(function() { callback(currTime + timeToCall); },\n      timeToCall);\n    lastTime = currTime + timeToCall;\n    return id;\n  };\n\n  return polyfill('requestAnimationFrame', fallback);\n})\n.factory('cancelAnimation', function(polyfill, $timeout) {\n  'use strict';\n\n  var fallback = function(promise) {\n    $timeout.cancel(promise);\n  };\n\n  return polyfill('cancelAnimationFrame', fallback);\n});\n","angular.module('duScroll.spyAPI', ['duScroll.scrollContainerAPI'])\n.factory('spyAPI', function($rootScope, $timeout, $window, $document, scrollContainerAPI, duScrollGreedy, duScrollSpyWait) {\n  'use strict';\n\n  var createScrollHandler = function(context) {\n    var timer = false, queued = false;\n    var handler = function() {\n      queued = false;\n      var container = context.container,\n          containerEl = container[0],\n          containerOffset = 0,\n          bottomReached;\n\n      if (typeof HTMLElement !== 'undefined' && containerEl instanceof HTMLElement || containerEl.nodeType && containerEl.nodeType === containerEl.ELEMENT_NODE) {\n        containerOffset = containerEl.getBoundingClientRect().top;\n        bottomReached = Math.round(containerEl.scrollTop + containerEl.clientHeight) >= containerEl.scrollHeight;\n      } else {\n        bottomReached = Math.round($window.pageYOffset + $window.innerHeight) >= $document[0].body.scrollHeight;\n      }\n      var compareProperty = (bottomReached ? 'bottom' : 'top');\n\n      var i, currentlyActive, toBeActive, spies, spy, pos;\n      spies = context.spies;\n      currentlyActive = context.currentlyActive;\n      toBeActive = undefined;\n\n      for(i = 0; i < spies.length; i++) {\n        spy = spies[i];\n        pos = spy.getTargetPosition();\n        if (!pos) continue;\n\n        if(bottomReached || (pos.top + spy.offset - containerOffset < 20 && (duScrollGreedy || pos.top*-1 + containerOffset) < pos.height)) {\n          //Find the one closest the viewport top or the page bottom if it's reached\n          if(!toBeActive || toBeActive[compareProperty] < pos[compareProperty]) {\n            toBeActive = {\n              spy: spy\n            };\n            toBeActive[compareProperty] = pos[compareProperty];\n          }\n        }\n      }\n\n      if(toBeActive) {\n        toBeActive = toBeActive.spy;\n      }\n      if(currentlyActive === toBeActive || (duScrollGreedy && !toBeActive)) return;\n      if(currentlyActive) {\n        currentlyActive.$element.removeClass('active');\n        $rootScope.$broadcast('duScrollspy:becameInactive', currentlyActive.$element);\n      }\n      if(toBeActive) {\n        toBeActive.$element.addClass('active');\n        $rootScope.$broadcast('duScrollspy:becameActive', toBeActive.$element);\n      }\n      context.currentlyActive = toBeActive;\n    };\n\n    if(!duScrollSpyWait) {\n      return handler;\n    }\n\n    //Debounce for potential performance savings\n    return function() {\n      if(!timer) {\n        handler();\n        timer = $timeout(function() {\n          timer = false;\n          if(queued) {\n            handler();\n          }\n        }, duScrollSpyWait, false);\n      } else {\n        queued = true;\n      }\n    };\n  };\n\n  var contexts = {};\n\n  var createContext = function($scope) {\n    var id = $scope.$id;\n    var context = {\n      spies: []\n    };\n\n    context.handler = createScrollHandler(context);\n    contexts[id] = context;\n\n    $scope.$on('$destroy', function() {\n      destroyContext($scope);\n    });\n\n    return id;\n  };\n\n  var destroyContext = function($scope) {\n    var id = $scope.$id;\n    var context = contexts[id], container = context.container;\n    if(container) {\n      container.off('scroll', context.handler);\n    }\n    delete contexts[id];\n  };\n\n  var defaultContextId = createContext($rootScope);\n\n  var getContextForScope = function(scope) {\n    if(contexts[scope.$id]) {\n      return contexts[scope.$id];\n    }\n    if(scope.$parent) {\n      return getContextForScope(scope.$parent);\n    }\n    return contexts[defaultContextId];\n  };\n\n  var getContextForSpy = function(spy) {\n    var context, contextId, scope = spy.$scope;\n    if(scope) {\n      return getContextForScope(scope);\n    }\n    //No scope, most likely destroyed\n    for(contextId in contexts) {\n      context = contexts[contextId];\n      if(context.spies.indexOf(spy) !== -1) {\n        return context;\n      }\n    }\n  };\n\n  var isElementInDocument = function(element) {\n    while (element.parentNode) {\n      element = element.parentNode;\n      if (element === document) {\n        return true;\n      }\n    }\n    return false;\n  };\n\n  var addSpy = function(spy) {\n    var context = getContextForSpy(spy);\n    if (!context) return;\n    context.spies.push(spy);\n    if (!context.container || !isElementInDocument(context.container)) {\n      if(context.container) {\n        context.container.off('scroll', context.handler);\n      }\n      context.container = scrollContainerAPI.getContainer(spy.$scope);\n      context.container.on('scroll', context.handler).triggerHandler('scroll');\n    }\n  };\n\n  var removeSpy = function(spy) {\n    var context = getContextForSpy(spy);\n    if(spy === context.currentlyActive) {\n      context.currentlyActive = null;\n    }\n    var i = context.spies.indexOf(spy);\n    if(i !== -1) {\n      context.spies.splice(i, 1);\n    }\n\t\tspy.$element = null;\n  };\n\n  return {\n    addSpy: addSpy,\n    removeSpy: removeSpy,\n    createContext: createContext,\n    destroyContext: destroyContext,\n    getContextForScope: getContextForScope\n  };\n});\n","angular.module('duScroll.scrollContainerAPI', [])\n.factory('scrollContainerAPI', function($document) {\n  'use strict';\n\n  var containers = {};\n\n  var setContainer = function(scope, element) {\n    var id = scope.$id;\n    containers[id] = element;\n    return id;\n  };\n\n  var getContainerId = function(scope) {\n    if(containers[scope.$id]) {\n      return scope.$id;\n    }\n    if(scope.$parent) {\n      return getContainerId(scope.$parent);\n    }\n    return;\n  };\n\n  var getContainer = function(scope) {\n    var id = getContainerId(scope);\n    return id ? containers[id] : $document;\n  };\n\n  var removeContainer = function(scope) {\n    var id = getContainerId(scope);\n    if(id) {\n      delete containers[id];\n    }\n  };\n\n  return {\n    getContainerId:   getContainerId,\n    getContainer:     getContainer,\n    setContainer:     setContainer,\n    removeContainer:  removeContainer\n  };\n});\n","angular.module('duScroll.smoothScroll', ['duScroll.scrollHelpers', 'duScroll.scrollContainerAPI'])\n.directive('duSmoothScroll', function(duScrollDuration, duScrollOffset, scrollContainerAPI) {\n  'use strict';\n\n  return {\n    link : function($scope, $element, $attr) {\n      $element.on('click', function(e) {\n        if(!$attr.href || $attr.href.indexOf('#') === -1) return;\n\n        var target = document.getElementById($attr.href.replace(/.*(?=#[^\\s]+$)/, '').substring(1));\n        if(!target || !target.getBoundingClientRect) return;\n\n        if (e.stopPropagation) e.stopPropagation();\n        if (e.preventDefault) e.preventDefault();\n\n        var offset    = $attr.offset ? parseInt($attr.offset, 10) : duScrollOffset;\n        var duration  = $attr.duration ? parseInt($attr.duration, 10) : duScrollDuration;\n        var container = scrollContainerAPI.getContainer($scope);\n\n        container.duScrollToElement(\n          angular.element(target),\n          isNaN(offset) ? 0 : offset,\n          isNaN(duration) ? 0 : duration\n        );\n      });\n    }\n  };\n});\n","angular.module('duScroll.spyContext', ['duScroll.spyAPI'])\n.directive('duSpyContext', function(spyAPI) {\n  'use strict';\n\n  return {\n    restrict: 'A',\n    scope: true,\n    compile: function compile(tElement, tAttrs, transclude) {\n      return {\n        pre: function preLink($scope, iElement, iAttrs, controller) {\n          spyAPI.createContext($scope);\n        }\n      };\n    }\n  };\n});\n","angular.module('duScroll.scrollContainer', ['duScroll.scrollContainerAPI'])\n.directive('duScrollContainer', function(scrollContainerAPI){\n  'use strict';\n\n  return {\n    restrict: 'A',\n    scope: true,\n    compile: function compile(tElement, tAttrs, transclude) {\n      return {\n        pre: function preLink($scope, iElement, iAttrs, controller) {\n          iAttrs.$observe('duScrollContainer', function(element) {\n            if(angular.isString(element)) {\n              element = document.getElementById(element);\n            }\n\n            element = (angular.isElement(element) ? angular.element(element) : iElement);\n            scrollContainerAPI.setContainer($scope, element);\n            $scope.$on('$destroy', function() {\n              scrollContainerAPI.removeContainer($scope);\n            });\n          });\n        }\n      };\n    }\n  };\n});\n","angular.module('duScroll.scrollspy', ['duScroll.spyAPI'])\n.directive('duScrollspy', function(spyAPI, duScrollOffset, $timeout, $rootScope) {\n  'use strict';\n\n  var Spy = function(targetElementOrId, $scope, $element, offset) {\n    if(angular.isElement(targetElementOrId)) {\n      this.target = targetElementOrId;\n    } else if(angular.isString(targetElementOrId)) {\n      this.targetId = targetElementOrId;\n    }\n    this.$scope = $scope;\n    this.$element = $element;\n    this.offset = offset;\n  };\n\n  Spy.prototype.getTargetElement = function() {\n    if (!this.target && this.targetId) {\n      this.target = document.getElementById(this.targetId);\n    }\n    return this.target;\n  };\n\n  Spy.prototype.getTargetPosition = function() {\n    var target = this.getTargetElement();\n    if(target) {\n      return target.getBoundingClientRect();\n    }\n  };\n\n  Spy.prototype.flushTargetCache = function() {\n    if(this.targetId) {\n      this.target = undefined;\n    }\n  };\n\n  return {\n    link: function ($scope, $element, $attr) {\n      var href = $attr.ngHref || $attr.href;\n      var targetId;\n\n      if (href && href.indexOf('#') !== -1) {\n        targetId = href.replace(/.*(?=#[^\\s]+$)/, '').substring(1);\n      } else if($attr.duScrollspy) {\n        targetId = $attr.duScrollspy;\n      }\n      if(!targetId) return;\n\n      // Run this in the next execution loop so that the scroll context has a chance\n      // to initialize\n      $timeout(function() {\n        var spy = new Spy(targetId, $scope, $element, -($attr.offset ? parseInt($attr.offset, 10) : duScrollOffset));\n        spyAPI.addSpy(spy);\n\n        $scope.$on('$destroy', function() {\n          spyAPI.removeSpy(spy);\n        });\n        $scope.$on('$locationChangeSuccess', spy.flushTargetCache.bind(spy));\n        $rootScope.$on('$stateChangeSuccess', spy.flushTargetCache.bind(spy));\n      }, 0, false);\n    }\n  };\n});\n"],"sourceRoot":"/source/"}