/*!

 * Bootstrap v3.3.5 (http://getbootstrap.com)

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under the MIT license

 */



if (typeof jQuery === 'undefined') {

  throw new Error('Bootstrap\'s JavaScript requires jQuery')

}



+function ($) {

  'use strict';

  var version = $.fn.jquery.split(' ')[0].split('.')

  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {

    throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')

  }

}(jQuery);



/* ========================================================================

 * Bootstrap: transition.js v3.3.5

 * http://getbootstrap.com/javascript/#transitions

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)

  // ============================================================



  function transitionEnd() {

    var el = document.createElement('bootstrap')



    var transEndEventNames = {

      WebkitTransition : 'webkitTransitionEnd',

      MozTransition    : 'transitionend',

      OTransition      : 'oTransitionEnd otransitionend',

      transition       : 'transitionend'

    }



    for (var name in transEndEventNames) {

      if (el.style[name] !== undefined) {

        return { end: transEndEventNames[name] }

      }

    }



    return false // explicit for ie8 (  ._.)

  }



  // http://blog.alexmaccaw.com/css-transitions

  $.fn.emulateTransitionEnd = function (duration) {

    var called = false

    var $el = this

    $(this).one('bsTransitionEnd', function () { called = true })

    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }

    setTimeout(callback, duration)

    return this

  }



  $(function () {

    $.support.transition = transitionEnd()



    if (!$.support.transition) return



    $.event.special.bsTransitionEnd = {

      bindType: $.support.transition.end,

      delegateType: $.support.transition.end,

      handle: function (e) {

        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)

      }

    }

  })



}(jQuery);



/* ========================================================================

 * Bootstrap: alert.js v3.3.5

 * http://getbootstrap.com/javascript/#alerts

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // ALERT CLASS DEFINITION

  // ======================



  var dismiss = '[data-dismiss="alert"]'

  var Alert   = function (el) {

    $(el).on('click', dismiss, this.close)

  }



  Alert.VERSION = '3.3.5'



  Alert.TRANSITION_DURATION = 150



  Alert.prototype.close = function (e) {

    var $this    = $(this)

    var selector = $this.attr('data-target')



    if (!selector) {

      selector = $this.attr('href')

      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7

    }



    var $parent = $(selector)



    if (e) e.preventDefault()



    if (!$parent.length) {

      $parent = $this.closest('.alert')

    }



    $parent.trigger(e = $.Event('close.bs.alert'))



    if (e.isDefaultPrevented()) return



    $parent.removeClass('in')



    function removeElement() {

      // detach from parent, fire event then clean up data

      $parent.detach().trigger('closed.bs.alert').remove()

    }



    $.support.transition && $parent.hasClass('fade') ?

      $parent

        .one('bsTransitionEnd', removeElement)

        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :

      removeElement()

  }





  // ALERT PLUGIN DEFINITION

  // =======================



  function Plugin(option) {

    return this.each(function () {

      var $this = $(this)

      var data  = $this.data('bs.alert')



      if (!data) $this.data('bs.alert', (data = new Alert(this)))

      if (typeof option == 'string') data[option].call($this)

    })

  }



  var old = $.fn.alert



  $.fn.alert             = Plugin

  $.fn.alert.Constructor = Alert





  // ALERT NO CONFLICT

  // =================



  $.fn.alert.noConflict = function () {

    $.fn.alert = old

    return this

  }





  // ALERT DATA-API

  // ==============



  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)



}(jQuery);



/* ========================================================================

 * Bootstrap: button.js v3.3.5

 * http://getbootstrap.com/javascript/#buttons

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // BUTTON PUBLIC CLASS DEFINITION

  // ==============================



  var Button = function (element, options) {

    this.$element  = $(element)

    this.options   = $.extend({}, Button.DEFAULTS, options)

    this.isLoading = false

  }



  Button.VERSION  = '3.3.5'



  Button.DEFAULTS = {

    loadingText: 'loading...'

  }



  Button.prototype.setState = function (state) {

    var d    = 'disabled'

    var $el  = this.$element

    var val  = $el.is('input') ? 'val' : 'html'

    var data = $el.data()



    state += 'Text'



    if (data.resetText == null) $el.data('resetText', $el[val]())



    // push to event loop to allow forms to submit

    setTimeout($.proxy(function () {

      $el[val](data[state] == null ? this.options[state] : data[state])



      if (state == 'loadingText') {

        this.isLoading = true

        $el.addClass(d).attr(d, d)

      } else if (this.isLoading) {

        this.isLoading = false

        $el.removeClass(d).removeAttr(d)

      }

    }, this), 0)

  }



  Button.prototype.toggle = function () {

    var changed = true

    var $parent = this.$element.closest('[data-toggle="buttons"]')



    if ($parent.length) {

      var $input = this.$element.find('input')

      if ($input.prop('type') == 'radio') {

        if ($input.prop('checked')) changed = false

        $parent.find('.active').removeClass('active')

        this.$element.addClass('active')

      } else if ($input.prop('type') == 'checkbox') {

        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false

        this.$element.toggleClass('active')

      }

      $input.prop('checked', this.$element.hasClass('active'))

      if (changed) $input.trigger('change')

    } else {

      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))

      this.$element.toggleClass('active')

    }

  }





  // BUTTON PLUGIN DEFINITION

  // ========================



  function Plugin(option) {

    return this.each(function () {

      var $this   = $(this)

      var data    = $this.data('bs.button')

      var options = typeof option == 'object' && option



      if (!data) $this.data('bs.button', (data = new Button(this, options)))



      if (option == 'toggle') data.toggle()

      else if (option) data.setState(option)

    })

  }



  var old = $.fn.button



  $.fn.button             = Plugin

  $.fn.button.Constructor = Button





  // BUTTON NO CONFLICT

  // ==================



  $.fn.button.noConflict = function () {

    $.fn.button = old

    return this

  }





  // BUTTON DATA-API

  // ===============



  $(document)

    .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {

      var $btn = $(e.target)

      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')

      Plugin.call($btn, 'toggle')

      if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()

    })

    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {

      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))

    })



}(jQuery);



/* ========================================================================

 * Bootstrap: carousel.js v3.3.5

 * http://getbootstrap.com/javascript/#carousel

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // CAROUSEL CLASS DEFINITION

  // =========================



  var Carousel = function (element, options) {

    this.$element    = $(element)

    this.$indicators = this.$element.find('.carousel-indicators')

    this.options     = options

    this.paused      = null

    this.sliding     = null

    this.interval    = null

    this.$active     = null

    this.$items      = null



    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))



    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element

      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))

      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))

  }



  Carousel.VERSION  = '3.3.5'



  Carousel.TRANSITION_DURATION = 600



  Carousel.DEFAULTS = {

    interval: 5000,

    pause: 'hover',

    wrap: true,

    keyboard: true

  }



  Carousel.prototype.keydown = function (e) {

    if (/input|textarea/i.test(e.target.tagName)) return

    switch (e.which) {

      case 37: this.prev(); break

      case 39: this.next(); break

      default: return

    }



    e.preventDefault()

  }



  Carousel.prototype.cycle = function (e) {

    e || (this.paused = false)



    this.interval && clearInterval(this.interval)



    this.options.interval

      && !this.paused

      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))



    return this

  }



  Carousel.prototype.getItemIndex = function (item) {

    this.$items = item.parent().children('.item')

    return this.$items.index(item || this.$active)

  }



  Carousel.prototype.getItemForDirection = function (direction, active) {

    var activeIndex = this.getItemIndex(active)

    var willWrap = (direction == 'prev' && activeIndex === 0)

                || (direction == 'next' && activeIndex == (this.$items.length - 1))

    if (willWrap && !this.options.wrap) return active

    var delta = direction == 'prev' ? -1 : 1

    var itemIndex = (activeIndex + delta) % this.$items.length

    return this.$items.eq(itemIndex)

  }



  Carousel.prototype.to = function (pos) {

    var that        = this

    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))



    if (pos > (this.$items.length - 1) || pos < 0) return



    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"

    if (activeIndex == pos) return this.pause().cycle()



    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))

  }



  Carousel.prototype.pause = function (e) {

    e || (this.paused = true)



    if (this.$element.find('.next, .prev').length && $.support.transition) {

      this.$element.trigger($.support.transition.end)

      this.cycle(true)

    }



    this.interval = clearInterval(this.interval)



    return this

  }



  Carousel.prototype.next = function () {

    if (this.sliding) return

    return this.slide('next')

  }



  Carousel.prototype.prev = function () {

    if (this.sliding) return

    return this.slide('prev')

  }



  Carousel.prototype.slide = function (type, next) {

    var $active   = this.$element.find('.item.active')

    var $next     = next || this.getItemForDirection(type, $active)

    var isCycling = this.interval

    var direction = type == 'next' ? 'left' : 'right'

    var that      = this



    if ($next.hasClass('active')) return (this.sliding = false)



    var relatedTarget = $next[0]

    var slideEvent = $.Event('slide.bs.carousel', {

      relatedTarget: relatedTarget,

      direction: direction

    })

    this.$element.trigger(slideEvent)

    if (slideEvent.isDefaultPrevented()) return



    this.sliding = true



    isCycling && this.pause()



    if (this.$indicators.length) {

      this.$indicators.find('.active').removeClass('active')

      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])

      $nextIndicator && $nextIndicator.addClass('active')

    }



    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"

    if ($.support.transition && this.$element.hasClass('slide')) {

      $next.addClass(type)

      $next[0].offsetWidth // force reflow

      $active.addClass(direction)

      $next.addClass(direction)

      $active

        .one('bsTransitionEnd', function () {

          $next.removeClass([type, direction].join(' ')).addClass('active')

          $active.removeClass(['active', direction].join(' '))

          that.sliding = false

          setTimeout(function () {

            that.$element.trigger(slidEvent)

          }, 0)

        })

        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)

    } else {

      $active.removeClass('active')

      $next.addClass('active')

      this.sliding = false

      this.$element.trigger(slidEvent)

    }



    isCycling && this.cycle()



    return this

  }





  // CAROUSEL PLUGIN DEFINITION

  // ==========================



  function Plugin(option) {

    return this.each(function () {

      var $this   = $(this)

      var data    = $this.data('bs.carousel')

      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)

      var action  = typeof option == 'string' ? option : options.slide



      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))

      if (typeof option == 'number') data.to(option)

      else if (action) data[action]()

      else if (options.interval) data.pause().cycle()

    })

  }



  var old = $.fn.carousel



  $.fn.carousel             = Plugin

  $.fn.carousel.Constructor = Carousel





  // CAROUSEL NO CONFLICT

  // ====================



  $.fn.carousel.noConflict = function () {

    $.fn.carousel = old

    return this

  }





  // CAROUSEL DATA-API

  // =================



  var clickHandler = function (e) {

    var href

    var $this   = $(this)

    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7

    if (!$target.hasClass('carousel')) return

    var options = $.extend({}, $target.data(), $this.data())

    var slideIndex = $this.attr('data-slide-to')

    if (slideIndex) options.interval = false



    Plugin.call($target, options)



    if (slideIndex) {

      $target.data('bs.carousel').to(slideIndex)

    }



    e.preventDefault()

  }



  $(document)

    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)

    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)



  $(window).on('load', function () {

    $('[data-ride="carousel"]').each(function () {

      var $carousel = $(this)

      Plugin.call($carousel, $carousel.data())

    })

  })



}(jQuery);



/* ========================================================================

 * Bootstrap: collapse.js v3.3.5

 * http://getbootstrap.com/javascript/#collapse

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // COLLAPSE PUBLIC CLASS DEFINITION

  // ================================



  var Collapse = function (element, options) {

    this.$element      = $(element)

    this.options       = $.extend({}, Collapse.DEFAULTS, options)

    this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +

                           '[data-toggle="collapse"][data-target="#' + element.id + '"]')

    this.transitioning = null



    if (this.options.parent) {

      this.$parent = this.getParent()

    } else {

      this.addAriaAndCollapsedClass(this.$element, this.$trigger)

    }



    if (this.options.toggle) this.toggle()

  }



  Collapse.VERSION  = '3.3.5'



  Collapse.TRANSITION_DURATION = 350



  Collapse.DEFAULTS = {

    toggle: true

  }



  Collapse.prototype.dimension = function () {

    var hasWidth = this.$element.hasClass('width')

    return hasWidth ? 'width' : 'height'

  }



  Collapse.prototype.show = function () {

    if (this.transitioning || this.$element.hasClass('in')) return



    var activesData

    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')



    if (actives && actives.length) {

      activesData = actives.data('bs.collapse')

      if (activesData && activesData.transitioning) return

    }



    var startEvent = $.Event('show.bs.collapse')

    this.$element.trigger(startEvent)

    if (startEvent.isDefaultPrevented()) return



    if (actives && actives.length) {

      Plugin.call(actives, 'hide')

      activesData || actives.data('bs.collapse', null)

    }



    var dimension = this.dimension()



    this.$element

      .removeClass('collapse')

      .addClass('collapsing')[dimension](0)

      .attr('aria-expanded', true)



    this.$trigger

      .removeClass('collapsed')

      .attr('aria-expanded', true)



    this.transitioning = 1



    var complete = function () {

      this.$element

        .removeClass('collapsing')

        .addClass('collapse in')[dimension]('')

      this.transitioning = 0

      this.$element

        .trigger('shown.bs.collapse')

    }



    if (!$.support.transition) return complete.call(this)



    var scrollSize = $.camelCase(['scroll', dimension].join('-'))



    this.$element

      .one('bsTransitionEnd', $.proxy(complete, this))

      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])

  }



  Collapse.prototype.hide = function () {

    if (this.transitioning || !this.$element.hasClass('in')) return



    var startEvent = $.Event('hide.bs.collapse')

    this.$element.trigger(startEvent)

    if (startEvent.isDefaultPrevented()) return



    var dimension = this.dimension()



    this.$element[dimension](this.$element[dimension]())[0].offsetHeight



    this.$element

      .addClass('collapsing')

      .removeClass('collapse in')

      .attr('aria-expanded', false)



    this.$trigger

      .addClass('collapsed')

      .attr('aria-expanded', false)



    this.transitioning = 1



    var complete = function () {

      this.transitioning = 0

      this.$element

        .removeClass('collapsing')

        .addClass('collapse')

        .trigger('hidden.bs.collapse')

    }



    if (!$.support.transition) return complete.call(this)



    this.$element

      [dimension](0)

      .one('bsTransitionEnd', $.proxy(complete, this))

      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)

  }



  Collapse.prototype.toggle = function () {

    this[this.$element.hasClass('in') ? 'hide' : 'show']()

  }



  Collapse.prototype.getParent = function () {

    return $(this.options.parent)

      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')

      .each($.proxy(function (i, element) {

        var $element = $(element)

        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)

      }, this))

      .end()

  }



  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {

    var isOpen = $element.hasClass('in')



    $element.attr('aria-expanded', isOpen)

    $trigger

      .toggleClass('collapsed', !isOpen)

      .attr('aria-expanded', isOpen)

  }



  function getTargetFromTrigger($trigger) {

    var href

    var target = $trigger.attr('data-target')

      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7



    return $(target)

  }





  // COLLAPSE PLUGIN DEFINITION

  // ==========================



  function Plugin(option) {

    return this.each(function () {

      var $this   = $(this)

      var data    = $this.data('bs.collapse')

      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)



      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false

      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))

      if (typeof option == 'string') data[option]()

    })

  }



  var old = $.fn.collapse



  $.fn.collapse             = Plugin

  $.fn.collapse.Constructor = Collapse





  // COLLAPSE NO CONFLICT

  // ====================



  $.fn.collapse.noConflict = function () {

    $.fn.collapse = old

    return this

  }





  // COLLAPSE DATA-API

  // =================



  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {

    var $this   = $(this)



    if (!$this.attr('data-target')) e.preventDefault()



    var $target = getTargetFromTrigger($this)

    var data    = $target.data('bs.collapse')

    var option  = data ? 'toggle' : $this.data()



    Plugin.call($target, option)

  })



}(jQuery);



/* ========================================================================

 * Bootstrap: dropdown.js v3.3.5

 * http://getbootstrap.com/javascript/#dropdowns

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // DROPDOWN CLASS DEFINITION

  // =========================



  var backdrop = '.dropdown-backdrop'

  var toggle   = '[data-toggle="dropdown"]'

  var Dropdown = function (element) {

    $(element).on('click.bs.dropdown', this.toggle)

  }



  Dropdown.VERSION = '3.3.5'



  function getParent($this) {

    var selector = $this.attr('data-target')



    if (!selector) {

      selector = $this.attr('href')

      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7

    }



    var $parent = selector && $(selector)



    return $parent && $parent.length ? $parent : $this.parent()

  }



  function clearMenus(e) {

    if (e && e.which === 3) return

    $(backdrop).remove()

    $(toggle).each(function () {

      var $this         = $(this)

      var $parent       = getParent($this)

      var relatedTarget = { relatedTarget: this }



      if (!$parent.hasClass('open')) return



      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return



      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))



      if (e.isDefaultPrevented()) return



      $this.attr('aria-expanded', 'false')

      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)

    })

  }



  Dropdown.prototype.toggle = function (e) {

    var $this = $(this)



    if ($this.is('.disabled, :disabled')) return



    var $parent  = getParent($this)

    var isActive = $parent.hasClass('open')



    clearMenus()



    if (!isActive) {

      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {

        // if mobile we use a backdrop because click events don't delegate

        $(document.createElement('div'))

          .addClass('dropdown-backdrop')

          .insertAfter($(this))

          .on('click', clearMenus)

      }



      var relatedTarget = { relatedTarget: this }

      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))



      if (e.isDefaultPrevented()) return



      $this

        .trigger('focus')

        .attr('aria-expanded', 'true')



      $parent

        .toggleClass('open')

        .trigger('shown.bs.dropdown', relatedTarget)

    }



    return false

  }



  Dropdown.prototype.keydown = function (e) {

    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return



    var $this = $(this)



    e.preventDefault()

    e.stopPropagation()



    if ($this.is('.disabled, :disabled')) return



    var $parent  = getParent($this)

    var isActive = $parent.hasClass('open')



    if (!isActive && e.which != 27 || isActive && e.which == 27) {

      if (e.which == 27) $parent.find(toggle).trigger('focus')

      return $this.trigger('click')

    }



    var desc = ' li:not(.disabled):visible a'

    var $items = $parent.find('.dropdown-menu' + desc)



    if (!$items.length) return



    var index = $items.index(e.target)



    if (e.which == 38 && index > 0)                 index--         // up

    if (e.which == 40 && index < $items.length - 1) index++         // down

    if (!~index)                                    index = 0



    $items.eq(index).trigger('focus')

  }





  // DROPDOWN PLUGIN DEFINITION

  // ==========================



  function Plugin(option) {

    return this.each(function () {

      var $this = $(this)

      var data  = $this.data('bs.dropdown')



      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))

      if (typeof option == 'string') data[option].call($this)

    })

  }



  var old = $.fn.dropdown



  $.fn.dropdown             = Plugin

  $.fn.dropdown.Constructor = Dropdown





  // DROPDOWN NO CONFLICT

  // ====================



  $.fn.dropdown.noConflict = function () {

    $.fn.dropdown = old

    return this

  }





  // APPLY TO STANDARD DROPDOWN ELEMENTS

  // ===================================



  $(document)

    .on('click.bs.dropdown.data-api', clearMenus)

    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })

    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)

    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)

    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)



}(jQuery);



/* ========================================================================

 * Bootstrap: modal.js v3.3.5

 * http://getbootstrap.com/javascript/#modals

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // MODAL CLASS DEFINITION

  // ======================



  var Modal = function (element, options) {

    this.options             = options

    this.$body               = $(document.body)

    this.$element            = $(element)

    this.$dialog             = this.$element.find('.modal-dialog')

    this.$backdrop           = null

    this.isShown             = null

    this.originalBodyPad     = null

    this.scrollbarWidth      = 0

    this.ignoreBackdropClick = false



    if (this.options.remote) {

      this.$element

        .find('.modal-content')

        .load(this.options.remote, $.proxy(function () {

          this.$element.trigger('loaded.bs.modal')

        }, this))

    }

  }



  Modal.VERSION  = '3.3.5'



  Modal.TRANSITION_DURATION = 300

  Modal.BACKDROP_TRANSITION_DURATION = 150



  Modal.DEFAULTS = {

    backdrop: true,

    keyboard: true,

    show: true

  }



  Modal.prototype.toggle = function (_relatedTarget) {

    return this.isShown ? this.hide() : this.show(_relatedTarget)

  }



  Modal.prototype.show = function (_relatedTarget) {

    var that = this

    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })



    this.$element.trigger(e)



    if (this.isShown || e.isDefaultPrevented()) return



    this.isShown = true



    this.checkScrollbar()

    this.setScrollbar()

    this.$body.addClass('modal-open')



    this.escape()

    this.resize()



    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))



    this.$dialog.on('mousedown.dismiss.bs.modal', function () {

      that.$element.one('mouseup.dismiss.bs.modal', function (e) {

        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true

      })

    })



    this.backdrop(function () {

      var transition = $.support.transition && that.$element.hasClass('fade')



      if (!that.$element.parent().length) {

        that.$element.appendTo(that.$body) // don't move modals dom position

      }



      that.$element

        .show()

        .scrollTop(0)



      that.adjustDialog()



      if (transition) {

        that.$element[0].offsetWidth // force reflow

      }



      that.$element.addClass('in')



      that.enforceFocus()



      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })



      transition ?

        that.$dialog // wait for modal to slide in

          .one('bsTransitionEnd', function () {

            that.$element.trigger('focus').trigger(e)

          })

          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :

        that.$element.trigger('focus').trigger(e)

    })

  }



  Modal.prototype.hide = function (e) {

    if (e) e.preventDefault()



    e = $.Event('hide.bs.modal')



    this.$element.trigger(e)



    if (!this.isShown || e.isDefaultPrevented()) return



    this.isShown = false



    this.escape()

    this.resize()



    $(document).off('focusin.bs.modal')



    this.$element

      .removeClass('in')

      .off('click.dismiss.bs.modal')

      .off('mouseup.dismiss.bs.modal')



    this.$dialog.off('mousedown.dismiss.bs.modal')



    $.support.transition && this.$element.hasClass('fade') ?

      this.$element

        .one('bsTransitionEnd', $.proxy(this.hideModal, this))

        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :

      this.hideModal()

  }



  Modal.prototype.enforceFocus = function () {

    $(document)

      .off('focusin.bs.modal') // guard against infinite focus loop

      .on('focusin.bs.modal', $.proxy(function (e) {

        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {

          this.$element.trigger('focus')

        }

      }, this))

  }



  Modal.prototype.escape = function () {

    if (this.isShown && this.options.keyboard) {

      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {

        e.which == 27 && this.hide()

      }, this))

    } else if (!this.isShown) {

      this.$element.off('keydown.dismiss.bs.modal')

    }

  }



  Modal.prototype.resize = function () {

    if (this.isShown) {

      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))

    } else {

      $(window).off('resize.bs.modal')

    }

  }



  Modal.prototype.hideModal = function () {

    var that = this

    this.$element.hide()

    this.backdrop(function () {

      that.$body.removeClass('modal-open')

      that.resetAdjustments()

      that.resetScrollbar()

      that.$element.trigger('hidden.bs.modal')

    })

  }



  Modal.prototype.removeBackdrop = function () {

    this.$backdrop && this.$backdrop.remove()

    this.$backdrop = null

  }



  Modal.prototype.backdrop = function (callback) {

    var that = this

    var animate = this.$element.hasClass('fade') ? 'fade' : ''



    if (this.isShown && this.options.backdrop) {

      var doAnimate = $.support.transition && animate



      this.$backdrop = $(document.createElement('div'))

        .addClass('modal-backdrop ' + animate)

        .appendTo(this.$body)



      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {

        if (this.ignoreBackdropClick) {

          this.ignoreBackdropClick = false

          return

        }

        if (e.target !== e.currentTarget) return

        this.options.backdrop == 'static'

          ? this.$element[0].focus()

          : this.hide()

      }, this))



      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow



      this.$backdrop.addClass('in')



      if (!callback) return



      doAnimate ?

        this.$backdrop

          .one('bsTransitionEnd', callback)

          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :

        callback()



    } else if (!this.isShown && this.$backdrop) {

      this.$backdrop.removeClass('in')



      var callbackRemove = function () {

        that.removeBackdrop()

        callback && callback()

      }

      $.support.transition && this.$element.hasClass('fade') ?

        this.$backdrop

          .one('bsTransitionEnd', callbackRemove)

          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :

        callbackRemove()



    } else if (callback) {

      callback()

    }

  }



  // these following methods are used to handle overflowing modals



  Modal.prototype.handleUpdate = function () {

    this.adjustDialog()

  }



  Modal.prototype.adjustDialog = function () {

    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight



    this.$element.css({

      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',

      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''

    })

  }



  Modal.prototype.resetAdjustments = function () {

    this.$element.css({

      paddingLeft: '',

      paddingRight: ''

    })

  }



  Modal.prototype.checkScrollbar = function () {

    var fullWindowWidth = window.innerWidth

    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8

      var documentElementRect = document.documentElement.getBoundingClientRect()

      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)

    }

    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth

    this.scrollbarWidth = this.measureScrollbar()

  }



  Modal.prototype.setScrollbar = function () {

    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)

    this.originalBodyPad = document.body.style.paddingRight || ''

    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)

  }



  Modal.prototype.resetScrollbar = function () {

    this.$body.css('padding-right', this.originalBodyPad)

  }



  Modal.prototype.measureScrollbar = function () { // thx walsh

    var scrollDiv = document.createElement('div')

    scrollDiv.className = 'modal-scrollbar-measure'

    this.$body.append(scrollDiv)

    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth

    this.$body[0].removeChild(scrollDiv)

    return scrollbarWidth

  }





  // MODAL PLUGIN DEFINITION

  // =======================



  function Plugin(option, _relatedTarget) {

    return this.each(function () {

      var $this   = $(this)

      var data    = $this.data('bs.modal')

      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)



      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))

      if (typeof option == 'string') data[option](_relatedTarget)

      else if (options.show) data.show(_relatedTarget)

    })

  }



  var old = $.fn.modal



  $.fn.modal             = Plugin

  $.fn.modal.Constructor = Modal





  // MODAL NO CONFLICT

  // =================



  $.fn.modal.noConflict = function () {

    $.fn.modal = old

    return this

  }





  // MODAL DATA-API

  // ==============



  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {

    var $this   = $(this)

    var href    = $this.attr('href')

    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7

    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())



    if ($this.is('a')) e.preventDefault()



    $target.one('show.bs.modal', function (showEvent) {

      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown

      $target.one('hidden.bs.modal', function () {

        $this.is(':visible') && $this.trigger('focus')

      })

    })

    Plugin.call($target, option, this)

  })



}(jQuery);



/* ========================================================================

 * Bootstrap: tooltip.js v3.3.5

 * http://getbootstrap.com/javascript/#tooltip

 * Inspired by the original jQuery.tipsy by Jason Frame

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // TOOLTIP PUBLIC CLASS DEFINITION

  // ===============================



  var Tooltip = function (element, options) {

    this.type       = null

    this.options    = null

    this.enabled    = null

    this.timeout    = null

    this.hoverState = null

    this.$element   = null

    this.inState    = null



    this.init('tooltip', element, options)

  }



  Tooltip.VERSION  = '3.3.5'



  Tooltip.TRANSITION_DURATION = 150



  Tooltip.DEFAULTS = {

    animation: true,

    placement: 'top',

    selector: false,

    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',

    trigger: 'hover focus',

    title: '',

    delay: 0,

    html: false,

    container: false,

    viewport: {

      selector: 'body',

      padding: 0

    }

  }



  Tooltip.prototype.init = function (type, element, options) {

    this.enabled   = true

    this.type      = type

    this.$element  = $(element)

    this.options   = this.getOptions(options)

    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))

    this.inState   = { click: false, hover: false, focus: false }



    if (this.$element[0] instanceof document.constructor && !this.options.selector) {

      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')

    }



    var triggers = this.options.trigger.split(' ')



    for (var i = triggers.length; i--;) {

      var trigger = triggers[i]



      if (trigger == 'click') {

        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))

      } else if (trigger != 'manual') {

        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'

        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'



        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))

        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))

      }

    }



    this.options.selector ?

      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :

      this.fixTitle()

  }



  Tooltip.prototype.getDefaults = function () {

    return Tooltip.DEFAULTS

  }



  Tooltip.prototype.getOptions = function (options) {

    options = $.extend({}, this.getDefaults(), this.$element.data(), options)



    if (options.delay && typeof options.delay == 'number') {

      options.delay = {

        show: options.delay,

        hide: options.delay

      }

    }



    return options

  }



  Tooltip.prototype.getDelegateOptions = function () {

    var options  = {}

    var defaults = this.getDefaults()



    this._options && $.each(this._options, function (key, value) {

      if (defaults[key] != value) options[key] = value

    })



    return options

  }



  Tooltip.prototype.enter = function (obj) {

    var self = obj instanceof this.constructor ?

      obj : $(obj.currentTarget).data('bs.' + this.type)



    if (!self) {

      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())

      $(obj.currentTarget).data('bs.' + this.type, self)

    }



    if (obj instanceof $.Event) {

      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true

    }



    if (self.tip().hasClass('in') || self.hoverState == 'in') {

      self.hoverState = 'in'

      return

    }



    clearTimeout(self.timeout)



    self.hoverState = 'in'



    if (!self.options.delay || !self.options.delay.show) return self.show()



    self.timeout = setTimeout(function () {

      if (self.hoverState == 'in') self.show()

    }, self.options.delay.show)

  }



  Tooltip.prototype.isInStateTrue = function () {

    for (var key in this.inState) {

      if (this.inState[key]) return true

    }



    return false

  }



  Tooltip.prototype.leave = function (obj) {

    var self = obj instanceof this.constructor ?

      obj : $(obj.currentTarget).data('bs.' + this.type)



    if (!self) {

      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())

      $(obj.currentTarget).data('bs.' + this.type, self)

    }



    if (obj instanceof $.Event) {

      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false

    }



    if (self.isInStateTrue()) return



    clearTimeout(self.timeout)



    self.hoverState = 'out'



    if (!self.options.delay || !self.options.delay.hide) return self.hide()



    self.timeout = setTimeout(function () {

      if (self.hoverState == 'out') self.hide()

    }, self.options.delay.hide)

  }



  Tooltip.prototype.show = function () {

    var e = $.Event('show.bs.' + this.type)



    if (this.hasContent() && this.enabled) {

      this.$element.trigger(e)



      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])

      if (e.isDefaultPrevented() || !inDom) return

      var that = this



      var $tip = this.tip()



      var tipId = this.getUID(this.type)



      this.setContent()

      $tip.attr('id', tipId)

      this.$element.attr('aria-describedby', tipId)



      if (this.options.animation) $tip.addClass('fade')



      var placement = typeof this.options.placement == 'function' ?

        this.options.placement.call(this, $tip[0], this.$element[0]) :

        this.options.placement



      var autoToken = /\s?auto?\s?/i

      var autoPlace = autoToken.test(placement)

      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'



      $tip

        .detach()

        .css({ top: 0, left: 0, display: 'block' })

        .addClass(placement)

        .data('bs.' + this.type, this)



      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)

      this.$element.trigger('inserted.bs.' + this.type)



      var pos          = this.getPosition()

      var actualWidth  = $tip[0].offsetWidth

      var actualHeight = $tip[0].offsetHeight



      if (autoPlace) {

        var orgPlacement = placement

        var viewportDim = this.getPosition(this.$viewport)



        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :

                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :

                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :

                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :

                    placement



        $tip

          .removeClass(orgPlacement)

          .addClass(placement)

      }



      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)



      this.applyPlacement(calculatedOffset, placement)



      var complete = function () {

        var prevHoverState = that.hoverState

        that.$element.trigger('shown.bs.' + that.type)

        that.hoverState = null



        if (prevHoverState == 'out') that.leave(that)

      }



      $.support.transition && this.$tip.hasClass('fade') ?

        $tip

          .one('bsTransitionEnd', complete)

          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :

        complete()

    }

  }



  Tooltip.prototype.applyPlacement = function (offset, placement) {

    var $tip   = this.tip()

    var width  = $tip[0].offsetWidth

    var height = $tip[0].offsetHeight



    // manually read margins because getBoundingClientRect includes difference

    var marginTop = parseInt($tip.css('margin-top'), 10)

    var marginLeft = parseInt($tip.css('margin-left'), 10)



    // we must check for NaN for ie 8/9

    if (isNaN(marginTop))  marginTop  = 0

    if (isNaN(marginLeft)) marginLeft = 0



    offset.top  += marginTop

    offset.left += marginLeft



    // $.fn.offset doesn't round pixel values

    // so we use setOffset directly with our own function B-0

    $.offset.setOffset($tip[0], $.extend({

      using: function (props) {

        $tip.css({

          top: Math.round(props.top),

          left: Math.round(props.left)

        })

      }

    }, offset), 0)



    $tip.addClass('in')



    // check to see if placing tip in new offset caused the tip to resize itself

    var actualWidth  = $tip[0].offsetWidth

    var actualHeight = $tip[0].offsetHeight



    if (placement == 'top' && actualHeight != height) {

      offset.top = offset.top + height - actualHeight

    }



    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)



    if (delta.left) offset.left += delta.left

    else offset.top += delta.top



    var isVertical          = /top|bottom/.test(placement)

    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight

    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'



    $tip.offset(offset)

    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)

  }



  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {

    this.arrow()

      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')

      .css(isVertical ? 'top' : 'left', '')

  }



  Tooltip.prototype.setContent = function () {

    var $tip  = this.tip()

    var title = this.getTitle()



    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)

    $tip.removeClass('fade in top bottom left right')

  }



  Tooltip.prototype.hide = function (callback) {

    var that = this

    var $tip = $(this.$tip)

    var e    = $.Event('hide.bs.' + this.type)



    function complete() {

      if (that.hoverState != 'in') $tip.detach()

      that.$element

        .removeAttr('aria-describedby')

        .trigger('hidden.bs.' + that.type)

      callback && callback()

    }



    this.$element.trigger(e)



    if (e.isDefaultPrevented()) return



    $tip.removeClass('in')



    $.support.transition && $tip.hasClass('fade') ?

      $tip

        .one('bsTransitionEnd', complete)

        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :

      complete()



    this.hoverState = null



    return this

  }



  Tooltip.prototype.fixTitle = function () {

    var $e = this.$element

    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {

      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')

    }

  }



  Tooltip.prototype.hasContent = function () {

    return this.getTitle()

  }



  Tooltip.prototype.getPosition = function ($element) {

    $element   = $element || this.$element



    var el     = $element[0]

    var isBody = el.tagName == 'BODY'



    var elRect    = el.getBoundingClientRect()

    if (elRect.width == null) {

      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093

      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })

    }

    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()

    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }

    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null



    return $.extend({}, elRect, scroll, outerDims, elOffset)

  }



  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {

    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :

           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :

           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :

        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }



  }



  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {

    var delta = { top: 0, left: 0 }

    if (!this.$viewport) return delta



    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0

    var viewportDimensions = this.getPosition(this.$viewport)



    if (/right|left/.test(placement)) {

      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll

      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight

      if (topEdgeOffset < viewportDimensions.top) { // top overflow

        delta.top = viewportDimensions.top - topEdgeOffset

      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow

        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset

      }

    } else {

      var leftEdgeOffset  = pos.left - viewportPadding

      var rightEdgeOffset = pos.left + viewportPadding + actualWidth

      if (leftEdgeOffset < viewportDimensions.left) { // left overflow

        delta.left = viewportDimensions.left - leftEdgeOffset

      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow

        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset

      }

    }



    return delta

  }



  Tooltip.prototype.getTitle = function () {

    var title

    var $e = this.$element

    var o  = this.options



    title = $e.attr('data-original-title')

      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)



    return title

  }



  Tooltip.prototype.getUID = function (prefix) {

    do prefix += ~~(Math.random() * 1000000)

    while (document.getElementById(prefix))

    return prefix

  }



  Tooltip.prototype.tip = function () {

    if (!this.$tip) {

      this.$tip = $(this.options.template)

      if (this.$tip.length != 1) {

        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')

      }

    }

    return this.$tip

  }



  Tooltip.prototype.arrow = function () {

    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))

  }



  Tooltip.prototype.enable = function () {

    this.enabled = true

  }



  Tooltip.prototype.disable = function () {

    this.enabled = false

  }



  Tooltip.prototype.toggleEnabled = function () {

    this.enabled = !this.enabled

  }



  Tooltip.prototype.toggle = function (e) {

    var self = this

    if (e) {

      self = $(e.currentTarget).data('bs.' + this.type)

      if (!self) {

        self = new this.constructor(e.currentTarget, this.getDelegateOptions())

        $(e.currentTarget).data('bs.' + this.type, self)

      }

    }



    if (e) {

      self.inState.click = !self.inState.click

      if (self.isInStateTrue()) self.enter(self)

      else self.leave(self)

    } else {

      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)

    }

  }



  Tooltip.prototype.destroy = function () {

    var that = this

    clearTimeout(this.timeout)

    this.hide(function () {

      that.$element.off('.' + that.type).removeData('bs.' + that.type)

      if (that.$tip) {

        that.$tip.detach()

      }

      that.$tip = null

      that.$arrow = null

      that.$viewport = null

    })

  }





  // TOOLTIP PLUGIN DEFINITION

  // =========================



  function Plugin(option) {

    return this.each(function () {

      var $this   = $(this)

      var data    = $this.data('bs.tooltip')

      var options = typeof option == 'object' && option



      if (!data && /destroy|hide/.test(option)) return

      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))

      if (typeof option == 'string') data[option]()

    })

  }



  var old = $.fn.tooltip



  $.fn.tooltip             = Plugin

  $.fn.tooltip.Constructor = Tooltip





  // TOOLTIP NO CONFLICT

  // ===================



  $.fn.tooltip.noConflict = function () {

    $.fn.tooltip = old

    return this

  }



}(jQuery);



/* ========================================================================

 * Bootstrap: popover.js v3.3.5

 * http://getbootstrap.com/javascript/#popovers

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // POPOVER PUBLIC CLASS DEFINITION

  // ===============================



  var Popover = function (element, options) {

    this.init('popover', element, options)

  }



  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')



  Popover.VERSION  = '3.3.5'



  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {

    placement: 'right',

    trigger: 'click',

    content: '',

    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'

  })





  // NOTE: POPOVER EXTENDS tooltip.js

  // ================================



  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)



  Popover.prototype.constructor = Popover



  Popover.prototype.getDefaults = function () {

    return Popover.DEFAULTS

  }



  Popover.prototype.setContent = function () {

    var $tip    = this.tip()

    var title   = this.getTitle()

    var content = this.getContent()



    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)

    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events

      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'

    ](content)



    $tip.removeClass('fade top bottom left right in')



    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do

    // this manually by checking the contents.

    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()

  }



  Popover.prototype.hasContent = function () {

    return this.getTitle() || this.getContent()

  }



  Popover.prototype.getContent = function () {

    var $e = this.$element

    var o  = this.options



    return $e.attr('data-content')

      || (typeof o.content == 'function' ?

            o.content.call($e[0]) :

            o.content)

  }



  Popover.prototype.arrow = function () {

    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))

  }





  // POPOVER PLUGIN DEFINITION

  // =========================



  function Plugin(option) {

    return this.each(function () {

      var $this   = $(this)

      var data    = $this.data('bs.popover')

      var options = typeof option == 'object' && option



      if (!data && /destroy|hide/.test(option)) return

      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))

      if (typeof option == 'string') data[option]()

    })

  }



  var old = $.fn.popover



  $.fn.popover             = Plugin

  $.fn.popover.Constructor = Popover





  // POPOVER NO CONFLICT

  // ===================



  $.fn.popover.noConflict = function () {

    $.fn.popover = old

    return this

  }



}(jQuery);



/* ========================================================================

 * Bootstrap: scrollspy.js v3.3.5

 * http://getbootstrap.com/javascript/#scrollspy

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // SCROLLSPY CLASS DEFINITION

  // ==========================



  function ScrollSpy(element, options) {

    this.$body          = $(document.body)

    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)

    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)

    this.selector       = (this.options.target || '') + ' .nav li > a'

    this.offsets        = []

    this.targets        = []

    this.activeTarget   = null

    this.scrollHeight   = 0



    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))

    this.refresh()

    this.process()

  }



  ScrollSpy.VERSION  = '3.3.5'



  ScrollSpy.DEFAULTS = {

    offset: 10

  }



  ScrollSpy.prototype.getScrollHeight = function () {

    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)

  }



  ScrollSpy.prototype.refresh = function () {

    var that          = this

    var offsetMethod  = 'offset'

    var offsetBase    = 0



    this.offsets      = []

    this.targets      = []

    this.scrollHeight = this.getScrollHeight()



    if (!$.isWindow(this.$scrollElement[0])) {

      offsetMethod = 'position'

      offsetBase   = this.$scrollElement.scrollTop()

    }



    this.$body

      .find(this.selector)

      .map(function () {

        var $el   = $(this)

        var href  = $el.data('target') || $el.attr('href')

        var $href = /^#./.test(href) && $(href)



        return ($href

          && $href.length

          && $href.is(':visible')

          && [[$href[offsetMethod]().top + offsetBase, href]]) || null

      })

      .sort(function (a, b) { return a[0] - b[0] })

      .each(function () {

        that.offsets.push(this[0])

        that.targets.push(this[1])

      })

  }



  ScrollSpy.prototype.process = function () {

    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset

    var scrollHeight = this.getScrollHeight()

    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()

    var offsets      = this.offsets

    var targets      = this.targets

    var activeTarget = this.activeTarget

    var i



    if (this.scrollHeight != scrollHeight) {

      this.refresh()

    }



    if (scrollTop >= maxScroll) {

      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)

    }



    if (activeTarget && scrollTop < offsets[0]) {

      this.activeTarget = null

      return this.clear()

    }



    for (i = offsets.length; i--;) {

      activeTarget != targets[i]

        && scrollTop >= offsets[i]

        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])

        && this.activate(targets[i])

    }

  }



  ScrollSpy.prototype.activate = function (target) {

    this.activeTarget = target



    this.clear()



    var selector = this.selector +

      '[data-target="' + target + '"],' +

      this.selector + '[href="' + target + '"]'



    var active = $(selector)

      .parents('li')

      .addClass('active')



    if (active.parent('.dropdown-menu').length) {

      active = active

        .closest('li.dropdown')

        .addClass('active')

    }



    active.trigger('activate.bs.scrollspy')

  }



  ScrollSpy.prototype.clear = function () {

    $(this.selector)

      .parentsUntil(this.options.target, '.active')

      .removeClass('active')

  }





  // SCROLLSPY PLUGIN DEFINITION

  // ===========================



  function Plugin(option) {

    return this.each(function () {

      var $this   = $(this)

      var data    = $this.data('bs.scrollspy')

      var options = typeof option == 'object' && option



      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))

      if (typeof option == 'string') data[option]()

    })

  }



  var old = $.fn.scrollspy



  $.fn.scrollspy             = Plugin

  $.fn.scrollspy.Constructor = ScrollSpy





  // SCROLLSPY NO CONFLICT

  // =====================



  $.fn.scrollspy.noConflict = function () {

    $.fn.scrollspy = old

    return this

  }





  // SCROLLSPY DATA-API

  // ==================



  $(window).on('load.bs.scrollspy.data-api', function () {

    $('[data-spy="scroll"]').each(function () {

      var $spy = $(this)

      Plugin.call($spy, $spy.data())

    })

  })



}(jQuery);



/* ========================================================================

 * Bootstrap: tab.js v3.3.5

 * http://getbootstrap.com/javascript/#tabs

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // TAB CLASS DEFINITION

  // ====================



  var Tab = function (element) {

    // jscs:disable requireDollarBeforejQueryAssignment

    this.element = $(element)

    // jscs:enable requireDollarBeforejQueryAssignment

  }



  Tab.VERSION = '3.3.5'



  Tab.TRANSITION_DURATION = 150



  Tab.prototype.show = function () {

    var $this    = this.element

    var $ul      = $this.closest('ul:not(.dropdown-menu)')

    var selector = $this.data('target')



    if (!selector) {

      selector = $this.attr('href')

      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7

    }



    if ($this.parent('li').hasClass('active')) return



    var $previous = $ul.find('.active:last a')

    var hideEvent = $.Event('hide.bs.tab', {

      relatedTarget: $this[0]

    })

    var showEvent = $.Event('show.bs.tab', {

      relatedTarget: $previous[0]

    })



    $previous.trigger(hideEvent)

    $this.trigger(showEvent)



    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return



    var $target = $(selector)



    this.activate($this.closest('li'), $ul)

    this.activate($target, $target.parent(), function () {

      $previous.trigger({

        type: 'hidden.bs.tab',

        relatedTarget: $this[0]

      })

      $this.trigger({

        type: 'shown.bs.tab',

        relatedTarget: $previous[0]

      })

    })

  }



  Tab.prototype.activate = function (element, container, callback) {

    var $active    = container.find('> .active')

    var transition = callback

      && $.support.transition

      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)



    function next() {

      $active

        .removeClass('active')

        .find('> .dropdown-menu > .active')

          .removeClass('active')

        .end()

        .find('[data-toggle="tab"]')

          .attr('aria-expanded', false)



      element

        .addClass('active')

        .find('[data-toggle="tab"]')

          .attr('aria-expanded', true)



      if (transition) {

        element[0].offsetWidth // reflow for transition

        element.addClass('in')

      } else {

        element.removeClass('fade')

      }



      if (element.parent('.dropdown-menu').length) {

        element

          .closest('li.dropdown')

            .addClass('active')

          .end()

          .find('[data-toggle="tab"]')

            .attr('aria-expanded', true)

      }



      callback && callback()

    }



    $active.length && transition ?

      $active

        .one('bsTransitionEnd', next)

        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :

      next()



    $active.removeClass('in')

  }





  // TAB PLUGIN DEFINITION

  // =====================



  function Plugin(option) {

    return this.each(function () {

      var $this = $(this)

      var data  = $this.data('bs.tab')



      if (!data) $this.data('bs.tab', (data = new Tab(this)))

      if (typeof option == 'string') data[option]()

    })

  }



  var old = $.fn.tab



  $.fn.tab             = Plugin

  $.fn.tab.Constructor = Tab





  // TAB NO CONFLICT

  // ===============



  $.fn.tab.noConflict = function () {

    $.fn.tab = old

    return this

  }





  // TAB DATA-API

  // ============



  var clickHandler = function (e) {

    e.preventDefault()

    Plugin.call($(this), 'show')

  }



  $(document)

    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)

    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)



}(jQuery);



/* ========================================================================

 * Bootstrap: affix.js v3.3.5

 * http://getbootstrap.com/javascript/#affix

 * ========================================================================

 * Copyright 2011-2015 Twitter, Inc.

 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)

 * ======================================================================== */





+function ($) {

  'use strict';



  // AFFIX CLASS DEFINITION

  // ======================



  var Affix = function (element, options) {

    this.options = $.extend({}, Affix.DEFAULTS, options)



    this.$target = $(this.options.target)

      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))

      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))



    this.$element     = $(element)

    this.affixed      = null

    this.unpin        = null

    this.pinnedOffset = null



    this.checkPosition()

  }



  Affix.VERSION  = '3.3.5'



  Affix.RESET    = 'affix affix-top affix-bottom'



  Affix.DEFAULTS = {

    offset: 0,

    target: window

  }



  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {

    var scrollTop    = this.$target.scrollTop()

    var position     = this.$element.offset()

    var targetHeight = this.$target.height()



    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false



    if (this.affixed == 'bottom') {

      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'

      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'

    }



    var initializing   = this.affixed == null

    var colliderTop    = initializing ? scrollTop : position.top

    var colliderHeight = initializing ? targetHeight : height



    if (offsetTop != null && scrollTop <= offsetTop) return 'top'

    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'



    return false

  }



  Affix.prototype.getPinnedOffset = function () {

    if (this.pinnedOffset) return this.pinnedOffset

    this.$element.removeClass(Affix.RESET).addClass('affix')

    var scrollTop = this.$target.scrollTop()

    var position  = this.$element.offset()

    return (this.pinnedOffset = position.top - scrollTop)

  }



  Affix.prototype.checkPositionWithEventLoop = function () {

    setTimeout($.proxy(this.checkPosition, this), 1)

  }



  Affix.prototype.checkPosition = function () {

    if (!this.$element.is(':visible')) return



    var height       = this.$element.height()

    var offset       = this.options.offset

    var offsetTop    = offset.top

    var offsetBottom = offset.bottom

    var scrollHeight = Math.max($(document).height(), $(document.body).height())



    if (typeof offset != 'object')         offsetBottom = offsetTop = offset

    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)

    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)



    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)



    if (this.affixed != affix) {

      if (this.unpin != null) this.$element.css('top', '')



      var affixType = 'affix' + (affix ? '-' + affix : '')

      var e         = $.Event(affixType + '.bs.affix')



      this.$element.trigger(e)



      if (e.isDefaultPrevented()) return



      this.affixed = affix

      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null



      this.$element

        .removeClass(Affix.RESET)

        .addClass(affixType)

        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')

    }



    if (affix == 'bottom') {

      this.$element.offset({

        top: scrollHeight - height - offsetBottom

      })

    }

  }





  // AFFIX PLUGIN DEFINITION

  // =======================



  function Plugin(option) {

    return this.each(function () {

      var $this   = $(this)

      var data    = $this.data('bs.affix')

      var options = typeof option == 'object' && option



      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))

      if (typeof option == 'string') data[option]()

    })

  }



  var old = $.fn.affix



  $.fn.affix             = Plugin

  $.fn.affix.Constructor = Affix





  // AFFIX NO CONFLICT

  // =================



  $.fn.affix.noConflict = function () {

    $.fn.affix = old

    return this

  }





  // AFFIX DATA-API

  // ==============



  $(window).on('load', function () {

    $('[data-spy="affix"]').each(function () {

      var $spy = $(this)

      var data = $spy.data()



      data.offset = data.offset || {}



      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom

      if (data.offsetTop    != null) data.offset.top    = data.offsetTop



      Plugin.call($spy, data)

    })

  })



}(jQuery);





/*

 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/

 *

 * Uses the built in easing capabilities added In jQuery 1.1

 * to offer multiple easing options

 *

 * TERMS OF USE - jQuery Easing

 * 

 * Open source under the BSD License. 

 * 

 * Copyright © 2008 George McGinley Smith

 * All rights reserved.

 * 

 * Redistribution and use in source and binary forms, with or without modification, 

 * are permitted provided that the following conditions are met:

 * 

 * Redistributions of source code must retain the above copyright notice, this list of 

 * conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice, this list 

 * of conditions and the following disclaimer in the documentation and/or other materials 

 * provided with the distribution.

 * 

 * Neither the name of the author nor the names of contributors may be used to endorse 

 * or promote products derived from this software without specific prior written permission.

 * 

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 

 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 

 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 

 * OF THE POSSIBILITY OF SUCH DAMAGE. 

 *

*/



// t: current time, b: begInnIng value, c: change In value, d: duration

jQuery.easing['jswing'] = jQuery.easing['swing'];



jQuery.extend( jQuery.easing,

{

	def: 'easeOutQuad',

	swing: function (x, t, b, c, d) {

		//alert(jQuery.easing.default);

		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);

	},

	easeInQuad: function (x, t, b, c, d) {

		return c*(t/=d)*t + b;

	},

	easeOutQuad: function (x, t, b, c, d) {

		return -c *(t/=d)*(t-2) + b;

	},

	easeInOutQuad: function (x, t, b, c, d) {

		if ((t/=d/2) < 1) return c/2*t*t + b;

		return -c/2 * ((--t)*(t-2) - 1) + b;

	},

	easeInCubic: function (x, t, b, c, d) {

		return c*(t/=d)*t*t + b;

	},

	easeOutCubic: function (x, t, b, c, d) {

		return c*((t=t/d-1)*t*t + 1) + b;

	},

	easeInOutCubic: function (x, t, b, c, d) {

		if ((t/=d/2) < 1) return c/2*t*t*t + b;

		return c/2*((t-=2)*t*t + 2) + b;

	},

	easeInQuart: function (x, t, b, c, d) {

		return c*(t/=d)*t*t*t + b;

	},

	easeOutQuart: function (x, t, b, c, d) {

		return -c * ((t=t/d-1)*t*t*t - 1) + b;

	},

	easeInOutQuart: function (x, t, b, c, d) {

		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;

		return -c/2 * ((t-=2)*t*t*t - 2) + b;

	},

	easeInQuint: function (x, t, b, c, d) {

		return c*(t/=d)*t*t*t*t + b;

	},

	easeOutQuint: function (x, t, b, c, d) {

		return c*((t=t/d-1)*t*t*t*t + 1) + b;

	},

	easeInOutQuint: function (x, t, b, c, d) {

		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;

		return c/2*((t-=2)*t*t*t*t + 2) + b;

	},

	easeInSine: function (x, t, b, c, d) {

		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;

	},

	easeOutSine: function (x, t, b, c, d) {

		return c * Math.sin(t/d * (Math.PI/2)) + b;

	},

	easeInOutSine: function (x, t, b, c, d) {

		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;

	},

	easeInExpo: function (x, t, b, c, d) {

		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;

	},

	easeOutExpo: function (x, t, b, c, d) {

		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;

	},

	easeInOutExpo: function (x, t, b, c, d) {

		if (t==0) return b;

		if (t==d) return b+c;

		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;

		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;

	},

	easeInCirc: function (x, t, b, c, d) {

		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;

	},

	easeOutCirc: function (x, t, b, c, d) {

		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;

	},

	easeInOutCirc: function (x, t, b, c, d) {

		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;

		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;

	},

	easeInElastic: function (x, t, b, c, d) {

		var s=1.70158;var p=0;var a=c;

		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;

		if (a < Math.abs(c)) { a=c; var s=p/4; }

		else var s = p/(2*Math.PI) * Math.asin (c/a);

		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;

	},

	easeOutElastic: function (x, t, b, c, d) {

		var s=1.70158;var p=0;var a=c;

		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;

		if (a < Math.abs(c)) { a=c; var s=p/4; }

		else var s = p/(2*Math.PI) * Math.asin (c/a);

		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;

	},

	easeInOutElastic: function (x, t, b, c, d) {

		var s=1.70158;var p=0;var a=c;

		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);

		if (a < Math.abs(c)) { a=c; var s=p/4; }

		else var s = p/(2*Math.PI) * Math.asin (c/a);

		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;

		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;

	},

	easeInBack: function (x, t, b, c, d, s) {

		if (s == undefined) s = 1.70158;

		return c*(t/=d)*t*((s+1)*t - s) + b;

	},

	easeOutBack: function (x, t, b, c, d, s) {

		if (s == undefined) s = 1.70158;

		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;

	},

	easeInOutBack: function (x, t, b, c, d, s) {

		if (s == undefined) s = 1.70158; 

		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;

		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;

	},

	easeInBounce: function (x, t, b, c, d) {

		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;

	},

	easeOutBounce: function (x, t, b, c, d) {

		if ((t/=d) < (1/2.75)) {

			return c*(7.5625*t*t) + b;

		} else if (t < (2/2.75)) {

			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;

		} else if (t < (2.5/2.75)) {

			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;

		} else {

			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;

		}

	},

	easeInOutBounce: function (x, t, b, c, d) {

		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;

		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;

	}

});



/*

 *

 * TERMS OF USE - EASING EQUATIONS

 * 

 * Open source under the BSD License. 

 * 

 * Copyright © 2001 Robert Penner

 * All rights reserved.

 * 

 * Redistribution and use in source and binary forms, with or without modification, 

 * are permitted provided that the following conditions are met:

 * 

 * Redistributions of source code must retain the above copyright notice, this list of 

 * conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice, this list 

 * of conditions and the following disclaimer in the documentation and/or other materials 

 * provided with the distribution.

 * 

 * Neither the name of the author nor the names of contributors may be used to endorse 

 * or promote products derived from this software without specific prior written permission.

 * 

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 

 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 

 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 

 * OF THE POSSIBILITY OF SUCH DAMAGE. 

 *

 */



/**


 * Project: Bootstrap Hover Dropdown


 * Author: Cameron Spear


 * Contributors: Mattia Larentis


 *


 * Dependencies: Bootstrap's Dropdown plugin, jQuery


 *


 * A simple plugin to enable Bootstrap dropdowns to active on hover and provide a nice user experience.


 *


 * License: MIT


 *


 * http://cameronspear.com/blog/bootstrap-dropdown-on-hover-plugin/


 */


;(function ($, window, undefined) {


    // outside the scope of the jQuery plugin to


    // keep track of all dropdowns


    var $allDropdowns = $();





    // if instantlyCloseOthers is true, then it will instantly


    // shut other nav items when a new one is hovered over


    $.fn.dropdownHover = function (options) {


        // don't do anything if touch is supported


        // (plugin causes some issues on mobile)


        if('ontouchstart' in document) return this; // don't want to affect chaining





        // the element we really care about


        // is the dropdown-toggle's parent


        $allDropdowns = $allDropdowns.add(this.parent());





        return this.each(function () {


            var $this = $(this),


                $parent = $this.parent(),


                defaults = {


                    delay: 500,


                    instantlyCloseOthers: true


                },


                data = {


                    delay: $(this).data('delay'),


                    instantlyCloseOthers: $(this).data('close-others')


                },


                showEvent   = 'show.bs.dropdown',


                hideEvent   = 'hide.bs.dropdown',


            // shownEvent  = 'shown.bs.dropdown',


            // hiddenEvent = 'hidden.bs.dropdown',


                settings = $.extend(true, {}, defaults, options, data),


                timeout;





            $parent.hover(function (event) {


                // so a neighbor can't open the dropdown


                if(!$parent.hasClass('open') && !$this.is(event.target)) {


                    // stop this event, stop executing any code 


                    // in this callback but continue to propagate


                    return true;


                }





                $allDropdowns.find(':focus').blur();





                if(settings.instantlyCloseOthers === true)


                    $allDropdowns.removeClass('open');





                window.clearTimeout(timeout);


                $parent.addClass('open');


                $this.trigger(showEvent);


            }, function () {


                timeout = window.setTimeout(function () {


                    $parent.removeClass('open');


                    $this.trigger(hideEvent);


                    //}, settings.delay);


                }, 200);


            });





            // this helps with button groups!


            $this.hover(function () {


                $allDropdowns.find(':focus').blur();





                if(settings.instantlyCloseOthers === true)


                    $allDropdowns.removeClass('open');





                window.clearTimeout(timeout);


                $parent.addClass('open');


                $this.trigger(showEvent);


            });





            // handle submenus


            $parent.find('.dropdown-submenu').each(function (){


                var $this = $(this);


                var subTimeout;


                $this.hover(function () {


                    window.clearTimeout(subTimeout);


                    $this.children('.dropdown-menu').show();


                    // always close submenu siblings instantly


                    $this.siblings().children('.dropdown-menu').hide();


                }, function () {


                    var $submenu = $this.children('.dropdown-menu');


                    subTimeout = window.setTimeout(function () {


                        $submenu.hide();


                    }, settings.delay);


                });


            });


        });


    };





    $(document).ready(function () {


        // apply dropdownHover to all elements with the data-hover="dropdown" attribute


        $('[data-hover="dropdown"]').dropdownHover();


    });


})(jQuery, this);



/*!

 * jQuery Cookie Plugin v1.4.1

 * https://github.com/carhartl/jquery-cookie

 *

 * Copyright 2006, 2014 Klaus Hartl

 * Released under the MIT license

 */

(function (factory) {

    if (typeof define === 'function' && define.amd) {

        // AMD (Register as an anonymous module)

        define(['jquery'], factory);

    } else if (typeof exports === 'object') {

        // Node/CommonJS

        module.exports = factory(require('jquery'));

    } else {

        // Browser globals

        factory(jQuery);

    }

}(function ($) {



    var pluses = /\+/g;



    function encode(s) {

        return config.raw ? s : encodeURIComponent(s);

    }



    function decode(s) {

        return config.raw ? s : decodeURIComponent(s);

    }



    function stringifyCookieValue(value) {

        return encode(config.json ? JSON.stringify(value) : String(value));

    }



    function parseCookieValue(s) {

        if (s.indexOf('"') === 0) {

            // This is a quoted cookie as according to RFC2068, unescape...

            s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');

        }



        try {

            // Replace server-side written pluses with spaces.

            // If we can't decode the cookie, ignore it, it's unusable.

            // If we can't parse the cookie, ignore it, it's unusable.

            s = decodeURIComponent(s.replace(pluses, ' '));

            return config.json ? JSON.parse(s) : s;

        } catch(e) {}

    }



    function read(s, converter) {

        var value = config.raw ? s : parseCookieValue(s);

        return $.isFunction(converter) ? converter(value) : value;

    }



    var config = $.cookie = function (key, value, options) {



        // Write



        if (arguments.length > 1 && !$.isFunction(value)) {

            options = $.extend({}, config.defaults, options);



            if (typeof options.expires === 'number') {

                var days = options.expires, t = options.expires = new Date();

                t.setMilliseconds(t.getMilliseconds() + days * 864e+5);

            }



            return (document.cookie = [

                encode(key), '=', stringifyCookieValue(value),

                options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE

                options.path    ? '; path=' + options.path : '',

                options.domain  ? '; domain=' + options.domain : '',

                options.secure  ? '; secure' : ''

            ].join(''));

        }



        // Read



        var result = key ? undefined : {},

        // To prevent the for loop in the first place assign an empty array

        // in case there are no cookies at all. Also prevents odd result when

        // calling $.cookie().

            cookies = document.cookie ? document.cookie.split('; ') : [],

            i = 0,

            l = cookies.length;



        for (; i < l; i++) {

            var parts = cookies[i].split('='),

                name = decode(parts.shift()),

                cookie = parts.join('=');



            if (key === name) {

                // If second argument (value) is a function it's a converter...

                result = read(cookie, value);

                break;

            }



            // Prevent storing a cookie that we couldn't decode.

            if (!key && (cookie = read(cookie)) !== undefined) {

                result[name] = cookie;

            }

        }



        return result;

    };



    config.defaults = {};



    $.removeCookie = function (key, options) {

        // Must not alter options, thus extending a fresh object...

        $.cookie(key, '', $.extend({}, options, { expires: -1 }));

        return !$.cookie(key);

    };



}));



/**

 * Owl Carousel v2.1.4

 * Copyright 2013-2016 David Deutsch

 * Licensed under MIT (https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE)

 */

/**

 * Owl carousel

 * @version 2.1.0

 * @author Bartosz Wojciechowski

 * @author David Deutsch

 * @license The MIT License (MIT)

 * @todo Lazy Load Icon

 * @todo prevent animationend bubling

 * @todo itemsScaleUp

 * @todo Test Zepto

 * @todo stagePadding calculate wrong active classes

 */

;(function($, window, document, undefined) {



    /**

     * Creates a carousel.

     * @class The Owl Carousel.

     * @public

     * @param {HTMLElement|jQuery} element - The element to create the carousel for.

     * @param {Object} [options] - The options

     */

    function Owl(element, options) {



        /**

         * Current settings for the carousel.

         * @public

         */

        this.settings = null;



        /**

         * Current options set by the caller including defaults.

         * @public

         */

        this.options = $.extend({}, Owl.Defaults, options);



        /**

         * Plugin element.

         * @public

         */

        this.$element = $(element);



        /**

         * Proxied event handlers.

         * @protected

         */

        this._handlers = {};



        /**

         * References to the running plugins of this carousel.

         * @protected

         */

        this._plugins = {};



        /**

         * Currently suppressed events to prevent them from beeing retriggered.

         * @protected

         */

        this._supress = {};



        /**

         * Absolute current position.

         * @protected

         */

        this._current = null;



        /**

         * Animation speed in milliseconds.

         * @protected

         */

        this._speed = null;



        /**

         * Coordinates of all items in pixel.

         * @todo The name of this member is missleading.

         * @protected

         */

        this._coordinates = [];



        /**

         * Current breakpoint.

         * @todo Real media queries would be nice.

         * @protected

         */

        this._breakpoint = null;



        /**

         * Current width of the plugin element.

         */

        this._width = null;



        /**

         * All real items.

         * @protected

         */

        this._items = [];



        /**

         * All cloned items.

         * @protected

         */

        this._clones = [];



        /**

         * Merge values of all items.

         * @todo Maybe this could be part of a plugin.

         * @protected

         */

        this._mergers = [];



        /**

         * Widths of all items.

         */

        this._widths = [];



        /**

         * Invalidated parts within the update process.

         * @protected

         */

        this._invalidated = {};



        /**

         * Ordered list of workers for the update process.

         * @protected

         */

        this._pipe = [];



        /**

         * Current state information for the drag operation.

         * @todo #261

         * @protected

         */

        this._drag = {

            time: null,

            target: null,

            pointer: null,

            stage: {

                start: null,

                current: null

            },

            direction: null

        };



        /**

         * Current state information and their tags.

         * @type {Object}

         * @protected

         */

        this._states = {

            current: {},

            tags: {

                'initializing': [ 'busy' ],

                'animating': [ 'busy' ],

                'dragging': [ 'interacting' ]

            }

        };



        $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {

            this._handlers[handler] = $.proxy(this[handler], this);

        }, this));



        $.each(Owl.Plugins, $.proxy(function(key, plugin) {

            this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]

                = new plugin(this);

        }, this));



        $.each(Owl.Workers, $.proxy(function(priority, worker) {

            this._pipe.push({

                'filter': worker.filter,

                'run': $.proxy(worker.run, this)

            });

        }, this));



        this.setup();

        this.initialize();

    }



    /**

     * Default options for the carousel.

     * @public

     */

    Owl.Defaults = {

        items: 3,

        loop: false,

        center: false,

        rewind: false,



        mouseDrag: true,

        touchDrag: true,

        pullDrag: true,

        freeDrag: false,



        margin: 0,

        stagePadding: 0,



        merge: false,

        mergeFit: true,

        autoWidth: false,



        startPosition: 0,

        rtl: false,



        smartSpeed: 250,

        fluidSpeed: false,

        dragEndSpeed: false,



        responsive: {},

        responsiveRefreshRate: 200,

        responsiveBaseElement: window,



        fallbackEasing: 'swing',



        info: false,



        nestedItemSelector: false,

        itemElement: 'div',

        stageElement: 'div',



        refreshClass: 'owl-refresh',

        loadedClass: 'owl-loaded',

        loadingClass: 'owl-loading',

        rtlClass: 'owl-rtl',

        responsiveClass: 'owl-responsive',

        dragClass: 'owl-drag',

        itemClass: 'owl-item',

        stageClass: 'owl-stage',

        stageOuterClass: 'owl-stage-outer',

        grabClass: 'owl-grab'

    };



    /**

     * Enumeration for width.

     * @public

     * @readonly

     * @enum {String}

     */

    Owl.Width = {

        Default: 'default',

        Inner: 'inner',

        Outer: 'outer'

    };



    /**

     * Enumeration for types.

     * @public

     * @readonly

     * @enum {String}

     */

    Owl.Type = {

        Event: 'event',

        State: 'state'

    };



    /**

     * Contains all registered plugins.

     * @public

     */

    Owl.Plugins = {};



    /**

     * List of workers involved in the update process.

     */

    Owl.Workers = [ {

        filter: [ 'width', 'settings' ],

        run: function() {

            this._width = this.$element.width();

        }

    }, {

        filter: [ 'width', 'items', 'settings' ],

        run: function(cache) {

            cache.current = this._items && this._items[this.relative(this._current)];

        }

    }, {

        filter: [ 'items', 'settings' ],

        run: function() {

            this.$stage.children('.cloned').remove();

        }

    }, {

        filter: [ 'width', 'items', 'settings' ],

        run: function(cache) {

            var margin = this.settings.margin || '',

                grid = !this.settings.autoWidth,

                rtl = this.settings.rtl,

                css = {

                    'width': 'auto',

                    'margin-left': rtl ? margin : '',

                    'margin-right': rtl ? '' : margin

                };



            !grid && this.$stage.children().css(css);



            cache.css = css;

        }

    }, {

        filter: [ 'width', 'items', 'settings' ],

        run: function(cache) {

            var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin,

                merge = null,

                iterator = this._items.length,

                grid = !this.settings.autoWidth,

                widths = [];



            cache.items = {

                merge: false,

                width: width

            };



            while (iterator--) {

                merge = this._mergers[iterator];

                merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;



                cache.items.merge = merge > 1 || cache.items.merge;



                widths[iterator] = !grid ? this._items[iterator].width() : width * merge;

            }



            this._widths = widths;

        }

    }, {

        filter: [ 'items', 'settings' ],

        run: function() {

            var clones = [],

                items = this._items,

                settings = this.settings,

                view = Math.max(settings.items * 2, 4),

                size = Math.ceil(items.length / 2) * 2,

                repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,

                append = '',

                prepend = '';



            repeat /= 2;



            while (repeat--) {

                clones.push(this.normalize(clones.length / 2, true));

                append = append + items[clones[clones.length - 1]][0].outerHTML;

                clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));

                prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;

            }



            this._clones = clones;



            $(append).addClass('cloned').appendTo(this.$stage);

            $(prepend).addClass('cloned').prependTo(this.$stage);

        }

    }, {

        filter: [ 'width', 'items', 'settings' ],

        run: function() {

            var rtl = this.settings.rtl ? 1 : -1,

                size = this._clones.length + this._items.length,

                iterator = -1,

                previous = 0,

                current = 0,

                coordinates = [];



            while (++iterator < size) {

                previous = coordinates[iterator - 1] || 0;

                current = this._widths[this.relative(iterator)] + this.settings.margin;

                coordinates.push(previous + current * rtl);

            }



            this._coordinates = coordinates;

        }

    }, {

        filter: [ 'width', 'items', 'settings' ],

        run: function() {

            var padding = this.settings.stagePadding,

                coordinates = this._coordinates,

                css = {

                    'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,

                    'padding-left': padding || '',

                    'padding-right': padding || ''

                };



            this.$stage.css(css);

        }

    }, {

        filter: [ 'width', 'items', 'settings' ],

        run: function(cache) {

            var iterator = this._coordinates.length,

                grid = !this.settings.autoWidth,

                items = this.$stage.children();



            if (grid && cache.items.merge) {

                while (iterator--) {

                    cache.css.width = this._widths[this.relative(iterator)];

                    items.eq(iterator).css(cache.css);

                }

            } else if (grid) {

                cache.css.width = cache.items.width;

                items.css(cache.css);

            }

        }

    }, {

        filter: [ 'items' ],

        run: function() {

            this._coordinates.length < 1 && this.$stage.removeAttr('style');

        }

    }, {

        filter: [ 'width', 'items', 'settings' ],

        run: function(cache) {

            cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;

            cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));

            this.reset(cache.current);

        }

    }, {

        filter: [ 'position' ],

        run: function() {

            this.animate(this.coordinates(this._current));

        }

    }, {

        filter: [ 'width', 'position', 'items', 'settings' ],

        run: function() {

            var rtl = this.settings.rtl ? 1 : -1,

                padding = this.settings.stagePadding * 2,

                begin = this.coordinates(this.current()) + padding,

                end = begin + this.width() * rtl,

                inner, outer, matches = [], i, n;



            for (i = 0, n = this._coordinates.length; i < n; i++) {

                inner = this._coordinates[i - 1] || 0;

                outer = Math.abs(this._coordinates[i]) + padding * rtl;



                if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))

                    || (this.op(outer, '<', begin) && this.op(outer, '>', end))) {

                    matches.push(i);

                }

            }



            this.$stage.children('.active').removeClass('active');

            this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');



            if (this.settings.center) {

                this.$stage.children('.center').removeClass('center');

                this.$stage.children().eq(this.current()).addClass('center');

            }

        }

    } ];



    /**

     * Initializes the carousel.

     * @protected

     */

    Owl.prototype.initialize = function() {

        this.enter('initializing');

        this.trigger('initialize');



        this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);



        if (this.settings.autoWidth && !this.is('pre-loading')) {

            var imgs, nestedSelector, width;

            imgs = this.$element.find('img');

            nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;

            width = this.$element.children(nestedSelector).width();



            if (imgs.length && width <= 0) {

                this.preloadAutoWidthImages(imgs);

            }

        }



        this.$element.addClass(this.options.loadingClass);



        // create stage

        this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>')

            .wrap('<div class="' + this.settings.stageOuterClass + '"/>');



        // append stage

        this.$element.append(this.$stage.parent());



        // append content

        this.replace(this.$element.children().not(this.$stage.parent()));



        // check visibility

        if (this.$element.is(':visible')) {

            // update view

            this.refresh();

        } else {

            // invalidate width

            this.invalidate('width');

        }



        this.$element

            .removeClass(this.options.loadingClass)

            .addClass(this.options.loadedClass);



        // register event handlers

        this.registerEventHandlers();



        this.leave('initializing');

        this.trigger('initialized');

    };



    /**

     * Setups the current settings.

     * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?

     * @todo Support for media queries by using `matchMedia` would be nice.

     * @public

     */

    Owl.prototype.setup = function() {

        var viewport = this.viewport(),

            overwrites = this.options.responsive,

            match = -1,

            settings = null;



        if (!overwrites) {

            settings = $.extend({}, this.options);

        } else {

            $.each(overwrites, function(breakpoint) {

                if (breakpoint <= viewport && breakpoint > match) {

                    match = Number(breakpoint);

                }

            });



            settings = $.extend({}, this.options, overwrites[match]);

            delete settings.responsive;



            // responsive class

            if (settings.responsiveClass) {

                this.$element.attr('class',

                    this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)

                );

            }

        }



        if (this.settings === null || this._breakpoint !== match) {

            this.trigger('change', { property: { name: 'settings', value: settings } });

            this._breakpoint = match;

            this.settings = settings;

            this.invalidate('settings');

            this.trigger('changed', { property: { name: 'settings', value: this.settings } });

        }

    };



    /**

     * Updates option logic if necessery.

     * @protected

     */

    Owl.prototype.optionsLogic = function() {

        if (this.settings.autoWidth) {

            this.settings.stagePadding = false;

            this.settings.merge = false;

        }

    };



    /**

     * Prepares an item before add.

     * @todo Rename event parameter `content` to `item`.

     * @protected

     * @returns {jQuery|HTMLElement} - The item container.

     */

    Owl.prototype.prepare = function(item) {

        var event = this.trigger('prepare', { content: item });



        if (!event.data) {

            event.data = $('<' + this.settings.itemElement + '/>')

                .addClass(this.options.itemClass).append(item)

        }



        this.trigger('prepared', { content: event.data });



        return event.data;

    };



    /**

     * Updates the view.

     * @public

     */

    Owl.prototype.update = function() {

        var i = 0,

            n = this._pipe.length,

            filter = $.proxy(function(p) { return this[p] }, this._invalidated),

            cache = {};



        while (i < n) {

            if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {

                this._pipe[i].run(cache);

            }

            i++;

        }



        this._invalidated = {};



        !this.is('valid') && this.enter('valid');

    };



    /**

     * Gets the width of the view.

     * @public

     * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.

     * @returns {Number} - The width of the view in pixel.

     */

    Owl.prototype.width = function(dimension) {

        dimension = dimension || Owl.Width.Default;

        switch (dimension) {

            case Owl.Width.Inner:

            case Owl.Width.Outer:

                return this._width;

            default:

                return this._width - this.settings.stagePadding * 2 + this.settings.margin;

        }

    };



    /**

     * Refreshes the carousel primarily for adaptive purposes.

     * @public

     */

    Owl.prototype.refresh = function() {

        this.enter('refreshing');

        this.trigger('refresh');



        this.setup();



        this.optionsLogic();



        this.$element.addClass(this.options.refreshClass);



        this.update();



        this.$element.removeClass(this.options.refreshClass);



        this.leave('refreshing');

        this.trigger('refreshed');

    };



    /**

     * Checks window `resize` event.

     * @protected

     */

    Owl.prototype.onThrottledResize = function() {

        window.clearTimeout(this.resizeTimer);

        this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);

    };



    /**

     * Checks window `resize` event.

     * @protected

     */

    Owl.prototype.onResize = function() {

        if (!this._items.length) {

            return false;

        }



        if (this._width === this.$element.width()) {

            return false;

        }



        if (!this.$element.is(':visible')) {

            return false;

        }



        this.enter('resizing');



        if (this.trigger('resize').isDefaultPrevented()) {

            this.leave('resizing');

            return false;

        }



        this.invalidate('width');



        this.refresh();



        this.leave('resizing');

        this.trigger('resized');

    };



    /**

     * Registers event handlers.

     * @todo Check `msPointerEnabled`

     * @todo #261

     * @protected

     */

    Owl.prototype.registerEventHandlers = function() {

        if ($.support.transition) {

            this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));

        }



        if (this.settings.responsive !== false) {

            this.on(window, 'resize', this._handlers.onThrottledResize);

        }



        if (this.settings.mouseDrag) {

            this.$element.addClass(this.options.dragClass);

            this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));

            this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });

        }



        if (this.settings.touchDrag){

            this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));

            this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));

        }

    };



    /**

     * Handles `touchstart` and `mousedown` events.

     * @todo Horizontal swipe threshold as option

     * @todo #261

     * @protected

     * @param {Event} event - The event arguments.

     */

    Owl.prototype.onDragStart = function(event) {

        var stage = null;



        if (event.which === 3) {

            return;

        }



        if ($.support.transform) {

            stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');

            stage = {

                x: stage[stage.length === 16 ? 12 : 4],

                y: stage[stage.length === 16 ? 13 : 5]

            };

        } else {

            stage = this.$stage.position();

            stage = {

                x: this.settings.rtl ?

                    stage.left + this.$stage.width() - this.width() + this.settings.margin :

                    stage.left,

                y: stage.top

            };

        }



        if (this.is('animating')) {

            $.support.transform ? this.animate(stage.x) : this.$stage.stop()

            this.invalidate('position');

        }



        this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');



        this.speed(0);



        this._drag.time = new Date().getTime();

        this._drag.target = $(event.target);

        this._drag.stage.start = stage;

        this._drag.stage.current = stage;

        this._drag.pointer = this.pointer(event);



        $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));



        $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {

            var delta = this.difference(this._drag.pointer, this.pointer(event));



            $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));



            if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {

                return;

            }



            event.preventDefault();



            this.enter('dragging');

            this.trigger('drag');

        }, this));

    };



    /**

     * Handles the `touchmove` and `mousemove` events.

     * @todo #261

     * @protected

     * @param {Event} event - The event arguments.

     */

    Owl.prototype.onDragMove = function(event) {

        var minimum = null,

            maximum = null,

            pull = null,

            delta = this.difference(this._drag.pointer, this.pointer(event)),

            stage = this.difference(this._drag.stage.start, delta);



        if (!this.is('dragging')) {

            return;

        }



        event.preventDefault();



        if (this.settings.loop) {

            minimum = this.coordinates(this.minimum());

            maximum = this.coordinates(this.maximum() + 1) - minimum;

            stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;

        } else {

            minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());

            maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());

            pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;

            stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);

        }



        this._drag.stage.current = stage;



        this.animate(stage.x);

    };



    /**

     * Handles the `touchend` and `mouseup` events.

     * @todo #261

     * @todo Threshold for click event

     * @protected

     * @param {Event} event - The event arguments.

     */

    Owl.prototype.onDragEnd = function(event) {

        var delta = this.difference(this._drag.pointer, this.pointer(event)),

            stage = this._drag.stage.current,

            direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';



        $(document).off('.owl.core');



        this.$element.removeClass(this.options.grabClass);



        if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {

            this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);

            this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));

            this.invalidate('position');

            this.update();



            this._drag.direction = direction;



            if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {

                this._drag.target.one('click.owl.core', function() { return false; });

            }

        }



        if (!this.is('dragging')) {

            return;

        }



        this.leave('dragging');

        this.trigger('dragged');

    };



    /**

     * Gets absolute position of the closest item for a coordinate.

     * @todo Setting `freeDrag` makes `closest` not reusable. See #165.

     * @protected

     * @param {Number} coordinate - The coordinate in pixel.

     * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.

     * @return {Number} - The absolute position of the closest item.

     */

    Owl.prototype.closest = function(coordinate, direction) {

        var position = -1,

            pull = 30,

            width = this.width(),

            coordinates = this.coordinates();



        if (!this.settings.freeDrag) {

            // check closest item

            $.each(coordinates, $.proxy(function(index, value) {

                // on a left pull, check on current index

                if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) {

                    position = index;

                    // on a right pull, check on previous index

                    // to do so, subtract width from value and set position = index + 1

                } else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) {

                    position = index + 1;

                } else if (this.op(coordinate, '<', value)

                    && this.op(coordinate, '>', coordinates[index + 1] || value - width)) {

                    position = direction === 'left' ? index + 1 : index;

                }

                return position === -1;

            }, this));

        }



        if (!this.settings.loop) {

            // non loop boundries

            if (this.op(coordinate, '>', coordinates[this.minimum()])) {

                position = coordinate = this.minimum();

            } else if (this.op(coordinate, '<', coordinates[this.maximum()])) {

                position = coordinate = this.maximum();

            }

        }



        return position;

    };



    /**

     * Animates the stage.

     * @todo #270

     * @public

     * @param {Number} coordinate - The coordinate in pixels.

     */

    Owl.prototype.animate = function(coordinate) {

        var animate = this.speed() > 0;



        this.is('animating') && this.onTransitionEnd();



        if (animate) {

            this.enter('animating');

            this.trigger('translate');

        }



        if ($.support.transform3d && $.support.transition) {

            this.$stage.css({

                transform: 'translate3d(' + coordinate + 'px,0px,0px)',

                transition: (this.speed() / 1000) + 's'

            });

        } else if (animate) {

            this.$stage.animate({

                left: coordinate + 'px'

            }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));

        } else {

            this.$stage.css({

                left: coordinate + 'px'

            });

        }

    };



    /**

     * Checks whether the carousel is in a specific state or not.

     * @param {String} state - The state to check.

     * @returns {Boolean} - The flag which indicates if the carousel is busy.

     */

    Owl.prototype.is = function(state) {

        return this._states.current[state] && this._states.current[state] > 0;

    };



    /**

     * Sets the absolute position of the current item.

     * @public

     * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.

     * @returns {Number} - The absolute position of the current item.

     */

    Owl.prototype.current = function(position) {

        if (position === undefined) {

            return this._current;

        }



        if (this._items.length === 0) {

            return undefined;

        }



        position = this.normalize(position);



        if (this._current !== position) {

            var event = this.trigger('change', { property: { name: 'position', value: position } });



            if (event.data !== undefined) {

                position = this.normalize(event.data);

            }



            this._current = position;



            this.invalidate('position');



            this.trigger('changed', { property: { name: 'position', value: this._current } });

        }



        return this._current;

    };



    /**

     * Invalidates the given part of the update routine.

     * @param {String} [part] - The part to invalidate.

     * @returns {Array.<String>} - The invalidated parts.

     */

    Owl.prototype.invalidate = function(part) {

        if ($.type(part) === 'string') {

            this._invalidated[part] = true;

            this.is('valid') && this.leave('valid');

        }

        return $.map(this._invalidated, function(v, i) { return i });

    };



    /**

     * Resets the absolute position of the current item.

     * @public

     * @param {Number} position - The absolute position of the new item.

     */

    Owl.prototype.reset = function(position) {

        position = this.normalize(position);



        if (position === undefined) {

            return;

        }



        this._speed = 0;

        this._current = position;



        this.suppress([ 'translate', 'translated' ]);



        this.animate(this.coordinates(position));



        this.release([ 'translate', 'translated' ]);

    };



    /**

     * Normalizes an absolute or a relative position of an item.

     * @public

     * @param {Number} position - The absolute or relative position to normalize.

     * @param {Boolean} [relative=false] - Whether the given position is relative or not.

     * @returns {Number} - The normalized position.

     */

    Owl.prototype.normalize = function(position, relative) {

        var n = this._items.length,

            m = relative ? 0 : this._clones.length;



        if (!this.isNumeric(position) || n < 1) {

            position = undefined;

        } else if (position < 0 || position >= n + m) {

            position = ((position - m / 2) % n + n) % n + m / 2;

        }



        return position;

    };



    /**

     * Converts an absolute position of an item into a relative one.

     * @public

     * @param {Number} position - The absolute position to convert.

     * @returns {Number} - The converted position.

     */

    Owl.prototype.relative = function(position) {

        position -= this._clones.length / 2;

        return this.normalize(position, true);

    };



    /**

     * Gets the maximum position for the current item.

     * @public

     * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.

     * @returns {Number}

     */

    Owl.prototype.maximum = function(relative) {

        var settings = this.settings,

            maximum = this._coordinates.length,

            boundary = Math.abs(this._coordinates[maximum - 1]) - this._width,

            i = -1, j;



        if (settings.loop) {

            maximum = this._clones.length / 2 + this._items.length - 1;

        } else if (settings.autoWidth || settings.merge) {

            // binary search

            while (maximum - i > 1) {

                Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary

                    ? i = j : maximum = j;

            }

        } else if (settings.center) {

            maximum = this._items.length - 1;

        } else {

            maximum = this._items.length - settings.items;

        }



        if (relative) {

            maximum -= this._clones.length / 2;

        }



        return Math.max(maximum, 0);

    };



    /**

     * Gets the minimum position for the current item.

     * @public

     * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.

     * @returns {Number}

     */

    Owl.prototype.minimum = function(relative) {

        return relative ? 0 : this._clones.length / 2;

    };



    /**

     * Gets an item at the specified relative position.

     * @public

     * @param {Number} [position] - The relative position of the item.

     * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.

     */

    Owl.prototype.items = function(position) {

        if (position === undefined) {

            return this._items.slice();

        }



        position = this.normalize(position, true);

        return this._items[position];

    };



    /**

     * Gets an item at the specified relative position.

     * @public

     * @param {Number} [position] - The relative position of the item.

     * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.

     */

    Owl.prototype.mergers = function(position) {

        if (position === undefined) {

            return this._mergers.slice();

        }



        position = this.normalize(position, true);

        return this._mergers[position];

    };



    /**

     * Gets the absolute positions of clones for an item.

     * @public

     * @param {Number} [position] - The relative position of the item.

     * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.

     */

    Owl.prototype.clones = function(position) {

        var odd = this._clones.length / 2,

            even = odd + this._items.length,

            map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };



        if (position === undefined) {

            return $.map(this._clones, function(v, i) { return map(i) });

        }



        return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });

    };



    /**

     * Sets the current animation speed.

     * @public

     * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.

     * @returns {Number} - The current animation speed in milliseconds.

     */

    Owl.prototype.speed = function(speed) {

        if (speed !== undefined) {

            this._speed = speed;

        }



        return this._speed;

    };



    /**

     * Gets the coordinate of an item.

     * @todo The name of this method is missleanding.

     * @public

     * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.

     * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.

     */

    Owl.prototype.coordinates = function(position) {

        var multiplier = 1,

            newPosition = position - 1,

            coordinate;



        if (position === undefined) {

            return $.map(this._coordinates, $.proxy(function(coordinate, index) {

                return this.coordinates(index);

            }, this));

        }



        if (this.settings.center) {

            if (this.settings.rtl) {

                multiplier = -1;

                newPosition = position + 1;

            }



            coordinate = this._coordinates[position];

            coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier;

        } else {

            coordinate = this._coordinates[newPosition] || 0;

        }



        coordinate = Math.ceil(coordinate);



        return coordinate;

    };



    /**

     * Calculates the speed for a translation.

     * @protected

     * @param {Number} from - The absolute position of the start item.

     * @param {Number} to - The absolute position of the target item.

     * @param {Number} [factor=undefined] - The time factor in milliseconds.

     * @returns {Number} - The time in milliseconds for the translation.

     */

    Owl.prototype.duration = function(from, to, factor) {

        if (factor === 0) {

            return 0;

        }



        return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));

    };



    /**

     * Slides to the specified item.

     * @public

     * @param {Number} position - The position of the item.

     * @param {Number} [speed] - The time in milliseconds for the transition.

     */

    Owl.prototype.to = function(position, speed) {

        var current = this.current(),

            revert = null,

            distance = position - this.relative(current),

            direction = (distance > 0) - (distance < 0),

            items = this._items.length,

            minimum = this.minimum(),

            maximum = this.maximum();



        if (this.settings.loop) {

            if (!this.settings.rewind && Math.abs(distance) > items / 2) {

                distance += direction * -1 * items;

            }



            position = current + distance;

            revert = ((position - minimum) % items + items) % items + minimum;



            if (revert !== position && revert - distance <= maximum && revert - distance > 0) {

                current = revert - distance;

                position = revert;

                this.reset(current);

            }

        } else if (this.settings.rewind) {

            maximum += 1;

            position = (position % maximum + maximum) % maximum;

        } else {

            position = Math.max(minimum, Math.min(maximum, position));

        }



        this.speed(this.duration(current, position, speed));

        this.current(position);



        if (this.$element.is(':visible')) {

            this.update();

        }

    };



    /**

     * Slides to the next item.

     * @public

     * @param {Number} [speed] - The time in milliseconds for the transition.

     */

    Owl.prototype.next = function(speed) {

        speed = speed || false;

        this.to(this.relative(this.current()) + 1, speed);

    };



    /**

     * Slides to the previous item.

     * @public

     * @param {Number} [speed] - The time in milliseconds for the transition.

     */

    Owl.prototype.prev = function(speed) {

        speed = speed || false;

        this.to(this.relative(this.current()) - 1, speed);

    };



    /**

     * Handles the end of an animation.

     * @protected

     * @param {Event} event - The event arguments.

     */

    Owl.prototype.onTransitionEnd = function(event) {



        // if css2 animation then event object is undefined

        if (event !== undefined) {

            event.stopPropagation();



            // Catch only owl-stage transitionEnd event

            if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {

                return false;

            }

        }



        this.leave('animating');

        this.trigger('translated');

    };



    /**

     * Gets viewport width.

     * @protected

     * @return {Number} - The width in pixel.

     */

    Owl.prototype.viewport = function() {

        var width;

        if (this.options.responsiveBaseElement !== window) {

            width = $(this.options.responsiveBaseElement).width();

        } else if (window.innerWidth) {

            width = window.innerWidth;

        } else if (document.documentElement && document.documentElement.clientWidth) {

            width = document.documentElement.clientWidth;

        } else {

            throw 'Can not detect viewport width.';

        }

        return width;

    };



    /**

     * Replaces the current content.

     * @public

     * @param {HTMLElement|jQuery|String} content - The new content.

     */

    Owl.prototype.replace = function(content) {

        this.$stage.empty();

        this._items = [];



        if (content) {

            content = (content instanceof jQuery) ? content : $(content);

        }



        if (this.settings.nestedItemSelector) {

            content = content.find('.' + this.settings.nestedItemSelector);

        }



        content.filter(function() {

            return this.nodeType === 1;

        }).each($.proxy(function(index, item) {

                item = this.prepare(item);

                this.$stage.append(item);

                this._items.push(item);

                this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);

            }, this));



        this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);



        this.invalidate('items');

    };



    /**

     * Adds an item.

     * @todo Use `item` instead of `content` for the event arguments.

     * @public

     * @param {HTMLElement|jQuery|String} content - The item content to add.

     * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.

     */

    Owl.prototype.add = function(content, position) {

        var current = this.relative(this._current);



        position = position === undefined ? this._items.length : this.normalize(position, true);

        content = content instanceof jQuery ? content : $(content);



        this.trigger('add', { content: content, position: position });



        content = this.prepare(content);



        if (this._items.length === 0 || position === this._items.length) {

            this._items.length === 0 && this.$stage.append(content);

            this._items.length !== 0 && this._items[position - 1].after(content);

            this._items.push(content);

            this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);

        } else {

            this._items[position].before(content);

            this._items.splice(position, 0, content);

            this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);

        }



        this._items[current] && this.reset(this._items[current].index());



        this.invalidate('items');



        this.trigger('added', { content: content, position: position });

    };



    /**

     * Removes an item by its position.

     * @todo Use `item` instead of `content` for the event arguments.

     * @public

     * @param {Number} position - The relative position of the item to remove.

     */

    Owl.prototype.remove = function(position) {

        position = this.normalize(position, true);



        if (position === undefined) {

            return;

        }



        this.trigger('remove', { content: this._items[position], position: position });



        this._items[position].remove();

        this._items.splice(position, 1);

        this._mergers.splice(position, 1);



        this.invalidate('items');



        this.trigger('removed', { content: null, position: position });

    };



    /**

     * Preloads images with auto width.

     * @todo Replace by a more generic approach

     * @protected

     */

    Owl.prototype.preloadAutoWidthImages = function(images) {

        images.each($.proxy(function(i, element) {

            this.enter('pre-loading');

            element = $(element);

            $(new Image()).one('load', $.proxy(function(e) {

                element.attr('src', e.target.src);

                element.css('opacity', 1);

                this.leave('pre-loading');

                !this.is('pre-loading') && !this.is('initializing') && this.refresh();

            }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));

        }, this));

    };



    /**

     * Destroys the carousel.

     * @public

     */

    Owl.prototype.destroy = function() {



        this.$element.off('.owl.core');

        this.$stage.off('.owl.core');

        $(document).off('.owl.core');



        if (this.settings.responsive !== false) {

            window.clearTimeout(this.resizeTimer);

            this.off(window, 'resize', this._handlers.onThrottledResize);

        }



        for (var i in this._plugins) {

            this._plugins[i].destroy();

        }



        this.$stage.children('.cloned').remove();



        this.$stage.unwrap();

        this.$stage.children().contents().unwrap();

        this.$stage.children().unwrap();



        this.$element

            .removeClass(this.options.refreshClass)

            .removeClass(this.options.loadingClass)

            .removeClass(this.options.loadedClass)

            .removeClass(this.options.rtlClass)

            .removeClass(this.options.dragClass)

            .removeClass(this.options.grabClass)

            .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))

            .removeData('owl.carousel');

    };



    /**

     * Operators to calculate right-to-left and left-to-right.

     * @protected

     * @param {Number} [a] - The left side operand.

     * @param {String} [o] - The operator.

     * @param {Number} [b] - The right side operand.

     */

    Owl.prototype.op = function(a, o, b) {

        var rtl = this.settings.rtl;

        switch (o) {

            case '<':

                return rtl ? a > b : a < b;

            case '>':

                return rtl ? a < b : a > b;

            case '>=':

                return rtl ? a <= b : a >= b;

            case '<=':

                return rtl ? a >= b : a <= b;

            default:

                break;

        }

    };



    /**

     * Attaches to an internal event.

     * @protected

     * @param {HTMLElement} element - The event source.

     * @param {String} event - The event name.

     * @param {Function} listener - The event handler to attach.

     * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.

     */

    Owl.prototype.on = function(element, event, listener, capture) {

        if (element.addEventListener) {

            element.addEventListener(event, listener, capture);

        } else if (element.attachEvent) {

            element.attachEvent('on' + event, listener);

        }

    };



    /**

     * Detaches from an internal event.

     * @protected

     * @param {HTMLElement} element - The event source.

     * @param {String} event - The event name.

     * @param {Function} listener - The attached event handler to detach.

     * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.

     */

    Owl.prototype.off = function(element, event, listener, capture) {

        if (element.removeEventListener) {

            element.removeEventListener(event, listener, capture);

        } else if (element.detachEvent) {

            element.detachEvent('on' + event, listener);

        }

    };



    /**

     * Triggers a public event.

     * @todo Remove `status`, `relatedTarget` should be used instead.

     * @protected

     * @param {String} name - The event name.

     * @param {*} [data=null] - The event data.

     * @param {String} [namespace=carousel] - The event namespace.

     * @param {String} [state] - The state which is associated with the event.

     * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.

     * @returns {Event} - The event arguments.

     */

    Owl.prototype.trigger = function(name, data, namespace, state, enter) {

        var status = {

            item: { count: this._items.length, index: this.current() }

        }, handler = $.camelCase(

            $.grep([ 'on', name, namespace ], function(v) { return v })

                .join('-').toLowerCase()

        ), event = $.Event(

            [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),

            $.extend({ relatedTarget: this }, status, data)

        );



        if (!this._supress[name]) {

            $.each(this._plugins, function(name, plugin) {

                if (plugin.onTrigger) {

                    plugin.onTrigger(event);

                }

            });



            this.register({ type: Owl.Type.Event, name: name });

            this.$element.trigger(event);



            if (this.settings && typeof this.settings[handler] === 'function') {

                this.settings[handler].call(this, event);

            }

        }



        return event;

    };



    /**

     * Enters a state.

     * @param name - The state name.

     */

    Owl.prototype.enter = function(name) {

        $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {

            if (this._states.current[name] === undefined) {

                this._states.current[name] = 0;

            }



            this._states.current[name]++;

        }, this));

    };



    /**

     * Leaves a state.

     * @param name - The state name.

     */

    Owl.prototype.leave = function(name) {

        $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {

            this._states.current[name]--;

        }, this));

    };



    /**

     * Registers an event or state.

     * @public

     * @param {Object} object - The event or state to register.

     */

    Owl.prototype.register = function(object) {

        if (object.type === Owl.Type.Event) {

            if (!$.event.special[object.name]) {

                $.event.special[object.name] = {};

            }



            if (!$.event.special[object.name].owl) {

                var _default = $.event.special[object.name]._default;

                $.event.special[object.name]._default = function(e) {

                    if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {

                        return _default.apply(this, arguments);

                    }

                    return e.namespace && e.namespace.indexOf('owl') > -1;

                };

                $.event.special[object.name].owl = true;

            }

        } else if (object.type === Owl.Type.State) {

            if (!this._states.tags[object.name]) {

                this._states.tags[object.name] = object.tags;

            } else {

                this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);

            }



            this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {

                return $.inArray(tag, this._states.tags[object.name]) === i;

            }, this));

        }

    };



    /**

     * Suppresses events.

     * @protected

     * @param {Array.<String>} events - The events to suppress.

     */

    Owl.prototype.suppress = function(events) {

        $.each(events, $.proxy(function(index, event) {

            this._supress[event] = true;

        }, this));

    };



    /**

     * Releases suppressed events.

     * @protected

     * @param {Array.<String>} events - The events to release.

     */

    Owl.prototype.release = function(events) {

        $.each(events, $.proxy(function(index, event) {

            delete this._supress[event];

        }, this));

    };



    /**

     * Gets unified pointer coordinates from event.

     * @todo #261

     * @protected

     * @param {Event} - The `mousedown` or `touchstart` event.

     * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.

     */

    Owl.prototype.pointer = function(event) {

        var result = { x: null, y: null };



        event = event.originalEvent || event || window.event;



        event = event.touches && event.touches.length ?

            event.touches[0] : event.changedTouches && event.changedTouches.length ?

            event.changedTouches[0] : event;



        if (event.pageX) {

            result.x = event.pageX;

            result.y = event.pageY;

        } else {

            result.x = event.clientX;

            result.y = event.clientY;

        }



        return result;

    };



    /**

     * Determines if the input is a Number or something that can be coerced to a Number

     * @protected

     * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested

     * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number

     */

    Owl.prototype.isNumeric = function(number) {

        return !isNaN(parseFloat(number));

    };



    /**

     * Gets the difference of two vectors.

     * @todo #261

     * @protected

     * @param {Object} - The first vector.

     * @param {Object} - The second vector.

     * @returns {Object} - The difference.

     */

    Owl.prototype.difference = function(first, second) {

        return {

            x: first.x - second.x,

            y: first.y - second.y

        };

    };



    /**

     * The jQuery Plugin for the Owl Carousel

     * @todo Navigation plugin `next` and `prev`

     * @public

     */

    $.fn.owlCarousel = function(option) {

        var args = Array.prototype.slice.call(arguments, 1);



        return this.each(function() {

            var $this = $(this),

                data = $this.data('owl.carousel');



            if (!data) {

                data = new Owl(this, typeof option == 'object' && option);

                $this.data('owl.carousel', data);



                $.each([

                    'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'

                ], function(i, event) {

                    data.register({ type: Owl.Type.Event, name: event });

                    data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {

                        if (e.namespace && e.relatedTarget !== this) {

                            this.suppress([ event ]);

                            data[event].apply(this, [].slice.call(arguments, 1));

                            this.release([ event ]);

                        }

                    }, data));

                });

            }



            if (typeof option == 'string' && option.charAt(0) !== '_') {

                data[option].apply(data, args);

            }

        });

    };



    /**

     * The constructor for the jQuery Plugin

     * @public

     */

    $.fn.owlCarousel.Constructor = Owl;



})(window.Zepto || window.jQuery, window, document);



/**

 * AutoRefresh Plugin

 * @version 2.1.0

 * @author Artus Kolanowski

 * @author David Deutsch

 * @license The MIT License (MIT)

 */

;(function($, window, document, undefined) {



    /**

     * Creates the auto refresh plugin.

     * @class The Auto Refresh Plugin

     * @param {Owl} carousel - The Owl Carousel

     */

    var AutoRefresh = function(carousel) {

        /**

         * Reference to the core.

         * @protected

         * @type {Owl}

         */

        this._core = carousel;



        /**

         * Refresh interval.

         * @protected

         * @type {number}

         */

        this._interval = null;



        /**

         * Whether the element is currently visible or not.

         * @protected

         * @type {Boolean}

         */

        this._visible = null;



        /**

         * All event handlers.

         * @protected

         * @type {Object}

         */

        this._handlers = {

            'initialized.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._core.settings.autoRefresh) {

                    this.watch();

                }

            }, this)

        };



        // set default options

        this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);



        // register event handlers

        this._core.$element.on(this._handlers);

    };



    /**

     * Default options.

     * @public

     */

    AutoRefresh.Defaults = {

        autoRefresh: true,

        autoRefreshInterval: 500

    };



    /**

     * Watches the element.

     */

    AutoRefresh.prototype.watch = function() {

        if (this._interval) {

            return;

        }



        this._visible = this._core.$element.is(':visible');

        this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);

    };



    /**

     * Refreshes the element.

     */

    AutoRefresh.prototype.refresh = function() {

        if (this._core.$element.is(':visible') === this._visible) {

            return;

        }



        this._visible = !this._visible;



        this._core.$element.toggleClass('owl-hidden', !this._visible);



        this._visible && (this._core.invalidate('width') && this._core.refresh());

    };



    /**

     * Destroys the plugin.

     */

    AutoRefresh.prototype.destroy = function() {

        var handler, property;



        window.clearInterval(this._interval);



        for (handler in this._handlers) {

            this._core.$element.off(handler, this._handlers[handler]);

        }

        for (property in Object.getOwnPropertyNames(this)) {

            typeof this[property] != 'function' && (this[property] = null);

        }

    };



    $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;



})(window.Zepto || window.jQuery, window, document);



/**

 * Lazy Plugin

 * @version 2.1.0

 * @author Bartosz Wojciechowski

 * @author David Deutsch

 * @license The MIT License (MIT)

 */

;(function($, window, document, undefined) {



    /**

     * Creates the lazy plugin.

     * @class The Lazy Plugin

     * @param {Owl} carousel - The Owl Carousel

     */

    var Lazy = function(carousel) {



        /**

         * Reference to the core.

         * @protected

         * @type {Owl}

         */

        this._core = carousel;



        /**

         * Already loaded items.

         * @protected

         * @type {Array.<jQuery>}

         */

        this._loaded = [];



        /**

         * Event handlers.

         * @protected

         * @type {Object}

         */

        this._handlers = {

            'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy(function(e) {

                if (!e.namespace) {

                    return;

                }



                if (!this._core.settings || !this._core.settings.lazyLoad) {

                    return;

                }



                if ((e.property && e.property.name == 'position') || e.type == 'initialized') {

                    var settings = this._core.settings,

                        n = (settings.center && Math.ceil(settings.items / 2) || settings.items),

                        i = ((settings.center && n * -1) || 0),

                        position = (e.property && e.property.value !== undefined ? e.property.value : this._core.current()) + i,

                        clones = this._core.clones().length,

                        load = $.proxy(function(i, v) { this.load(v) }, this);



                    while (i++ < n) {

                        this.load(clones / 2 + this._core.relative(position));

                        clones && $.each(this._core.clones(this._core.relative(position)), load);

                        position++;

                    }

                }

            }, this)

        };



        // set the default options

        this._core.options = $.extend({}, Lazy.Defaults, this._core.options);



        // register event handler

        this._core.$element.on(this._handlers);

    };



    /**

     * Default options.

     * @public

     */

    Lazy.Defaults = {

        lazyLoad: false

    };



    /**

     * Loads all resources of an item at the specified position.

     * @param {Number} position - The absolute position of the item.

     * @protected

     */

    Lazy.prototype.load = function(position) {

        var $item = this._core.$stage.children().eq(position),

            $elements = $item && $item.find('.owl-lazy');



        if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {

            return;

        }



        $elements.each($.proxy(function(index, element) {

            var $element = $(element), image,

                url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src');



            this._core.trigger('load', { element: $element, url: url }, 'lazy');



            if ($element.is('img')) {

                $element.one('load.owl.lazy', $.proxy(function() {

                    $element.css('opacity', 1);

                    this._core.trigger('loaded', { element: $element, url: url }, 'lazy');

                }, this)).attr('src', url);

            } else {

                image = new Image();

                image.onload = $.proxy(function() {

                    $element.css({

                        'background-image': 'url(' + url + ')',

                        'opacity': '1'

                    });

                    this._core.trigger('loaded', { element: $element, url: url }, 'lazy');

                }, this);

                image.src = url;

            }

        }, this));



        this._loaded.push($item.get(0));

    };



    /**

     * Destroys the plugin.

     * @public

     */

    Lazy.prototype.destroy = function() {

        var handler, property;



        for (handler in this.handlers) {

            this._core.$element.off(handler, this.handlers[handler]);

        }

        for (property in Object.getOwnPropertyNames(this)) {

            typeof this[property] != 'function' && (this[property] = null);

        }

    };



    $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;



})(window.Zepto || window.jQuery, window, document);



/**

 * AutoHeight Plugin

 * @version 2.1.0

 * @author Bartosz Wojciechowski

 * @author David Deutsch

 * @license The MIT License (MIT)

 */

;(function($, window, document, undefined) {



    /**

     * Creates the auto height plugin.

     * @class The Auto Height Plugin

     * @param {Owl} carousel - The Owl Carousel

     */

    var AutoHeight = function(carousel) {

        /**

         * Reference to the core.

         * @protected

         * @type {Owl}

         */

        this._core = carousel;



        /**

         * All event handlers.

         * @protected

         * @type {Object}

         */

        this._handlers = {

            'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._core.settings.autoHeight) {

                    this.update();

                }

            }, this),

            'changed.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){

                    this.update();

                }

            }, this),

            'loaded.owl.lazy': $.proxy(function(e) {

                if (e.namespace && this._core.settings.autoHeight

                    && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) {

                    this.update();

                }

            }, this)

        };



        // set default options

        this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);



        // register event handlers

        this._core.$element.on(this._handlers);

    };



    /**

     * Default options.

     * @public

     */

    AutoHeight.Defaults = {

        autoHeight: false,

        autoHeightClass: 'owl-height'

    };



    /**

     * Updates the view.

     */

    AutoHeight.prototype.update = function() {

        var start = this._core._current,

            end = start + this._core.settings.items,

            visible = this._core.$stage.children().toArray().slice(start, end),

            heights = [],

            maxheight = 0;



        $.each(visible, function(index, item) {

            heights.push($(item).height());

        });



        maxheight = Math.max.apply(null, heights);



        this._core.$stage.parent()

            .height(maxheight)

            .addClass(this._core.settings.autoHeightClass);

    };



    AutoHeight.prototype.destroy = function() {

        var handler, property;



        for (handler in this._handlers) {

            this._core.$element.off(handler, this._handlers[handler]);

        }

        for (property in Object.getOwnPropertyNames(this)) {

            typeof this[property] != 'function' && (this[property] = null);

        }

    };



    $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;



})(window.Zepto || window.jQuery, window, document);



/**

 * Video Plugin

 * @version 2.1.0

 * @author Bartosz Wojciechowski

 * @author David Deutsch

 * @license The MIT License (MIT)

 */

;(function($, window, document, undefined) {



    /**

     * Creates the video plugin.

     * @class The Video Plugin

     * @param {Owl} carousel - The Owl Carousel

     */

    var Video = function(carousel) {

        /**

         * Reference to the core.

         * @protected

         * @type {Owl}

         */

        this._core = carousel;



        /**

         * Cache all video URLs.

         * @protected

         * @type {Object}

         */

        this._videos = {};



        /**

         * Current playing item.

         * @protected

         * @type {jQuery}

         */

        this._playing = null;



        /**

         * All event handlers.

         * @todo The cloned content removale is too late

         * @protected

         * @type {Object}

         */

        this._handlers = {

            'initialized.owl.carousel': $.proxy(function(e) {

                if (e.namespace) {

                    this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] });

                }

            }, this),

            'resize.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._core.settings.video && this.isInFullScreen()) {

                    e.preventDefault();

                }

            }, this),

            'refreshed.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._core.is('resizing')) {

                    this._core.$stage.find('.cloned .owl-video-frame').remove();

                }

            }, this),

            'changed.owl.carousel': $.proxy(function(e) {

                if (e.namespace && e.property.name === 'position' && this._playing) {

                    this.stop();

                }

            }, this),

            'prepared.owl.carousel': $.proxy(function(e) {

                if (!e.namespace) {

                    return;

                }



                var $element = $(e.content).find('.owl-video');



                if ($element.length) {

                    $element.css('display', 'none');

                    this.fetch($element, $(e.content));

                }

            }, this)

        };



        // set default options

        this._core.options = $.extend({}, Video.Defaults, this._core.options);



        // register event handlers

        this._core.$element.on(this._handlers);



        this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {

            this.play(e);

        }, this));

    };



    /**

     * Default options.

     * @public

     */

    Video.Defaults = {

        video: false,

        videoHeight: false,

        videoWidth: false

    };



    /**

     * Gets the video ID and the type (YouTube/Vimeo/vzaar only).

     * @protected

     * @param {jQuery} target - The target containing the video data.

     * @param {jQuery} item - The item containing the video.

     */

    Video.prototype.fetch = function(target, item) {

        var type = (function() {

                if (target.attr('data-vimeo-id')) {

                    return 'vimeo';

                } else if (target.attr('data-vzaar-id')) {

                    return 'vzaar'

                } else {

                    return 'youtube';

                }

            })(),

            id = target.attr('data-vimeo-id') || target.attr('data-youtube-id') || target.attr('data-vzaar-id'),

            width = target.attr('data-width') || this._core.settings.videoWidth,

            height = target.attr('data-height') || this._core.settings.videoHeight,

            url = target.attr('href');



        if (url) {



            /*

             Parses the id's out of the following urls (and probably more):

             https://www.youtube.com/watch?v=:id

             https://youtu.be/:id

             https://vimeo.com/:id

             https://vimeo.com/channels/:channel/:id

             https://vimeo.com/groups/:group/videos/:id

             https://app.vzaar.com/videos/:id



             Visual example: https://regexper.com/#(http%3A%7Chttps%3A%7C)%5C%2F%5C%2F(player.%7Cwww.%7Capp.)%3F(vimeo%5C.com%7Cyoutu(be%5C.com%7C%5C.be%7Cbe%5C.googleapis%5C.com)%7Cvzaar%5C.com)%5C%2F(video%5C%2F%7Cvideos%5C%2F%7Cembed%5C%2F%7Cchannels%5C%2F.%2B%5C%2F%7Cgroups%5C%2F.%2B%5C%2F%7Cwatch%5C%3Fv%3D%7Cv%5C%2F)%3F(%5BA-Za-z0-9._%25-%5D*)(%5C%26%5CS%2B)%3F

             */



            id = url.match(/(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);



            if (id[3].indexOf('youtu') > -1) {

                type = 'youtube';

            } else if (id[3].indexOf('vimeo') > -1) {

                type = 'vimeo';

            } else if (id[3].indexOf('vzaar') > -1) {

                type = 'vzaar';

            } else {

                throw new Error('Video URL not supported.');

            }

            id = id[6];

        } else {

            throw new Error('Missing video URL.');

        }



        this._videos[url] = {

            type: type,

            id: id,

            width: width,

            height: height

        };



        item.attr('data-video', url);



        this.thumbnail(target, this._videos[url]);

    };



    /**

     * Creates video thumbnail.

     * @protected

     * @param {jQuery} target - The target containing the video data.

     * @param {Object} info - The video info object.

     * @see `fetch`

     */

    Video.prototype.thumbnail = function(target, video) {

        var tnLink,

            icon,

            path,

            dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '',

            customTn = target.find('img'),

            srcType = 'src',

            lazyClass = '',

            settings = this._core.settings,

            create = function(path) {

                icon = '<div class="owl-video-play-icon"></div>';



                if (settings.lazyLoad) {

                    tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>';

                } else {

                    tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>';

                }

                target.after(tnLink);

                target.after(icon);

            };



        // wrap video content into owl-video-wrapper div

        target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>');



        if (this._core.settings.lazyLoad) {

            srcType = 'data-src';

            lazyClass = 'owl-lazy';

        }



        // custom thumbnail

        if (customTn.length) {

            create(customTn.attr(srcType));

            customTn.remove();

            return false;

        }



        if (video.type === 'youtube') {

            path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg";

            create(path);

        } else if (video.type === 'vimeo') {

            $.ajax({

                type: 'GET',

                url: '//vimeo.com/api/v2/video/' + video.id + '.json',

                jsonp: 'callback',

                dataType: 'jsonp',

                success: function(data) {

                    path = data[0].thumbnail_large;

                    create(path);

                }

            });

        } else if (video.type === 'vzaar') {

            $.ajax({

                type: 'GET',

                url: '//vzaar.com/api/videos/' + video.id + '.json',

                jsonp: 'callback',

                dataType: 'jsonp',

                success: function(data) {

                    path = data.framegrab_url;

                    create(path);

                }

            });

        }

    };



    /**

     * Stops the current video.

     * @public

     */

    Video.prototype.stop = function() {

        this._core.trigger('stop', null, 'video');

        this._playing.find('.owl-video-frame').remove();

        this._playing.removeClass('owl-video-playing');

        this._playing = null;

        this._core.leave('playing');

        this._core.trigger('stopped', null, 'video');

    };



    /**

     * Starts the current video.

     * @public

     * @param {Event} event - The event arguments.

     */

    Video.prototype.play = function(event) {

        var target = $(event.target),

            item = target.closest('.' + this._core.settings.itemClass),

            video = this._videos[item.attr('data-video')],

            width = video.width || '100%',

            height = video.height || this._core.$stage.height(),

            html;



        if (this._playing) {

            return;

        }



        this._core.enter('playing');

        this._core.trigger('play', null, 'video');



        item = this._core.items(this._core.relative(item.index()));



        this._core.reset(item.index());



        if (video.type === 'youtube') {

            html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' +

                video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>';

        } else if (video.type === 'vimeo') {

            html = '<iframe src="//player.vimeo.com/video/' + video.id +

                '?autoplay=1" width="' + width + '" height="' + height +

                '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';

        } else if (video.type === 'vzaar') {

            html = '<iframe frameborder="0"' + 'height="' + height + '"' + 'width="' + width +

                '" allowfullscreen mozallowfullscreen webkitAllowFullScreen ' +

                'src="//view.vzaar.com/' + video.id + '/player?autoplay=true"></iframe>';

        }



        $('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video'));



        this._playing = item.addClass('owl-video-playing');

    };



    /**

     * Checks whether an video is currently in full screen mode or not.

     * @todo Bad style because looks like a readonly method but changes members.

     * @protected

     * @returns {Boolean}

     */

    Video.prototype.isInFullScreen = function() {

        var element = document.fullscreenElement || document.mozFullScreenElement ||

            document.webkitFullscreenElement;



        return element && $(element).parent().hasClass('owl-video-frame');

    };



    /**

     * Destroys the plugin.

     */

    Video.prototype.destroy = function() {

        var handler, property;



        this._core.$element.off('click.owl.video');



        for (handler in this._handlers) {

            this._core.$element.off(handler, this._handlers[handler]);

        }

        for (property in Object.getOwnPropertyNames(this)) {

            typeof this[property] != 'function' && (this[property] = null);

        }

    };



    $.fn.owlCarousel.Constructor.Plugins.Video = Video;



})(window.Zepto || window.jQuery, window, document);



/**

 * Animate Plugin

 * @version 2.1.0

 * @author Bartosz Wojciechowski

 * @author David Deutsch

 * @license The MIT License (MIT)

 */

;(function($, window, document, undefined) {



    /**

     * Creates the animate plugin.

     * @class The Navigation Plugin

     * @param {Owl} scope - The Owl Carousel

     */

    var Animate = function(scope) {

        this.core = scope;

        this.core.options = $.extend({}, Animate.Defaults, this.core.options);

        this.swapping = true;

        this.previous = undefined;

        this.next = undefined;



        this.handlers = {

            'change.owl.carousel': $.proxy(function(e) {

                if (e.namespace && e.property.name == 'position') {

                    this.previous = this.core.current();

                    this.next = e.property.value;

                }

            }, this),

            'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {

                if (e.namespace) {

                    this.swapping = e.type == 'translated';

                }

            }, this),

            'translate.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {

                    this.swap();

                }

            }, this)

        };



        this.core.$element.on(this.handlers);

    };



    /**

     * Default options.

     * @public

     */

    Animate.Defaults = {

        animateOut: false,

        animateIn: false

    };



    /**

     * Toggles the animation classes whenever an translations starts.

     * @protected

     * @returns {Boolean|undefined}

     */

    Animate.prototype.swap = function() {



        if (this.core.settings.items !== 1) {

            return;

        }



        if (!$.support.animation || !$.support.transition) {

            return;

        }



        this.core.speed(0);



        var left,

            clear = $.proxy(this.clear, this),

            previous = this.core.$stage.children().eq(this.previous),

            next = this.core.$stage.children().eq(this.next),

            incoming = this.core.settings.animateIn,

            outgoing = this.core.settings.animateOut;



        if (this.core.current() === this.previous) {

            return;

        }



        if (outgoing) {

            left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);

            previous.one($.support.animation.end, clear)

                .css( { 'left': left + 'px' } )

                .addClass('animated owl-animated-out')

                .addClass(outgoing);

        }



        if (incoming) {

            next.one($.support.animation.end, clear)

                .addClass('animated owl-animated-in')

                .addClass(incoming);

        }

    };



    Animate.prototype.clear = function(e) {

        $(e.target).css( { 'left': '' } )

            .removeClass('animated owl-animated-out owl-animated-in')

            .removeClass(this.core.settings.animateIn)

            .removeClass(this.core.settings.animateOut);

        this.core.onTransitionEnd();

    };



    /**

     * Destroys the plugin.

     * @public

     */

    Animate.prototype.destroy = function() {

        var handler, property;



        for (handler in this.handlers) {

            this.core.$element.off(handler, this.handlers[handler]);

        }

        for (property in Object.getOwnPropertyNames(this)) {

            typeof this[property] != 'function' && (this[property] = null);

        }

    };



    $.fn.owlCarousel.Constructor.Plugins.Animate = Animate;



})(window.Zepto || window.jQuery, window, document);



/**

 * Autoplay Plugin

 * @version 2.1.0

 * @author Bartosz Wojciechowski

 * @author Artus Kolanowski

 * @author David Deutsch

 * @license The MIT License (MIT)

 */

;(function($, window, document, undefined) {



    /**

     * Creates the autoplay plugin.

     * @class The Autoplay Plugin

     * @param {Owl} scope - The Owl Carousel

     */

    var Autoplay = function(carousel) {

        /**

         * Reference to the core.

         * @protected

         * @type {Owl}

         */

        this._core = carousel;



        /**

         * The autoplay timeout.

         * @type {Timeout}

         */

        this._timeout = null;



        /**

         * Indicates whenever the autoplay is paused.

         * @type {Boolean}

         */

        this._paused = false;



        /**

         * All event handlers.

         * @protected

         * @type {Object}

         */

        this._handlers = {

            'changed.owl.carousel': $.proxy(function(e) {

                if (e.namespace && e.property.name === 'settings') {

                    if (this._core.settings.autoplay) {

                        this.play();

                    } else {

                        this.stop();

                    }

                } else if (e.namespace && e.property.name === 'position') {

                    //console.log('play?', e);

                    if (this._core.settings.autoplay) {

                        this._setAutoPlayInterval();

                    }

                }

            }, this),

            'initialized.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._core.settings.autoplay) {

                    this.play();

                }

            }, this),

            'play.owl.autoplay': $.proxy(function(e, t, s) {

                if (e.namespace) {

                    this.play(t, s);

                }

            }, this),

            'stop.owl.autoplay': $.proxy(function(e) {

                if (e.namespace) {

                    this.stop();

                }

            }, this),

            'mouseover.owl.autoplay': $.proxy(function() {

                if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {

                    this.pause();

                }

            }, this),

            'mouseleave.owl.autoplay': $.proxy(function() {

                if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {

                    this.play();

                }

            }, this),

            'touchstart.owl.core': $.proxy(function() {

                if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {

                    this.pause();

                }

            }, this),

            'touchend.owl.core': $.proxy(function() {

                if (this._core.settings.autoplayHoverPause) {

                    this.play();

                }

            }, this)

        };



        // register event handlers

        this._core.$element.on(this._handlers);



        // set default options

        this._core.options = $.extend({}, Autoplay.Defaults, this._core.options);

    };



    /**

     * Default options.

     * @public

     */

    Autoplay.Defaults = {

        autoplay: false,

        autoplayTimeout: 5000,

        autoplayHoverPause: false,

        autoplaySpeed: false

    };



    /**

     * Starts the autoplay.

     * @public

     * @param {Number} [timeout] - The interval before the next animation starts.

     * @param {Number} [speed] - The animation speed for the animations.

     */

    Autoplay.prototype.play = function(timeout, speed) {

        this._paused = false;



        if (this._core.is('rotating')) {

            return;

        }



        this._core.enter('rotating');



        this._setAutoPlayInterval();

    };



    /**

     * Gets a new timeout

     * @private

     * @param {Number} [timeout] - The interval before the next animation starts.

     * @param {Number} [speed] - The animation speed for the animations.

     * @return {Timeout}

     */

    Autoplay.prototype._getNextTimeout = function(timeout, speed) {

        if ( this._timeout ) {

            window.clearTimeout(this._timeout);

        }

        return window.setTimeout($.proxy(function() {

            if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) {

                return;

            }

            this._core.next(speed || this._core.settings.autoplaySpeed);

        }, this), timeout || this._core.settings.autoplayTimeout);

    };



    /**

     * Sets autoplay in motion.

     * @private

     */

    Autoplay.prototype._setAutoPlayInterval = function() {

        this._timeout = this._getNextTimeout();

    };



    /**

     * Stops the autoplay.

     * @public

     */

    Autoplay.prototype.stop = function() {

        if (!this._core.is('rotating')) {

            return;

        }



        window.clearTimeout(this._timeout);

        this._core.leave('rotating');

    };



    /**

     * Stops the autoplay.

     * @public

     */

    Autoplay.prototype.pause = function() {

        if (!this._core.is('rotating')) {

            return;

        }



        this._paused = true;

    };



    /**

     * Destroys the plugin.

     */

    Autoplay.prototype.destroy = function() {

        var handler, property;



        this.stop();



        for (handler in this._handlers) {

            this._core.$element.off(handler, this._handlers[handler]);

        }

        for (property in Object.getOwnPropertyNames(this)) {

            typeof this[property] != 'function' && (this[property] = null);

        }

    };



    $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;



})(window.Zepto || window.jQuery, window, document);



/**

 * Navigation Plugin

 * @version 2.1.0

 * @author Artus Kolanowski

 * @author David Deutsch

 * @license The MIT License (MIT)

 */

;(function($, window, document, undefined) {

    'use strict';



    /**

     * Creates the navigation plugin.

     * @class The Navigation Plugin

     * @param {Owl} carousel - The Owl Carousel.

     */

    var Navigation = function(carousel) {

        /**

         * Reference to the core.

         * @protected

         * @type {Owl}

         */

        this._core = carousel;



        /**

         * Indicates whether the plugin is initialized or not.

         * @protected

         * @type {Boolean}

         */

        this._initialized = false;



        /**

         * The current paging indexes.

         * @protected

         * @type {Array}

         */

        this._pages = [];



        /**

         * All DOM elements of the user interface.

         * @protected

         * @type {Object}

         */

        this._controls = {};



        /**

         * Markup for an indicator.

         * @protected

         * @type {Array.<String>}

         */

        this._templates = [];



        /**

         * The carousel element.

         * @type {jQuery}

         */

        this.$element = this._core.$element;



        /**

         * Overridden methods of the carousel.

         * @protected

         * @type {Object}

         */

        this._overrides = {

            next: this._core.next,

            prev: this._core.prev,

            to: this._core.to

        };



        /**

         * All event handlers.

         * @protected

         * @type {Object}

         */

        this._handlers = {

            'prepared.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._core.settings.dotsData) {

                    this._templates.push('<div class="' + this._core.settings.dotClass + '">' +

                        $(e.content).find('[data-dot]').addBack('[data-dot]').attr('data-dot') + '</div>');

                }

            }, this),

            'added.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._core.settings.dotsData) {

                    this._templates.splice(e.position, 0, this._templates.pop());

                }

            }, this),

            'remove.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._core.settings.dotsData) {

                    this._templates.splice(e.position, 1);

                }

            }, this),

            'changed.owl.carousel': $.proxy(function(e) {

                if (e.namespace && e.property.name == 'position') {

                    this.draw();

                }

            }, this),

            'initialized.owl.carousel': $.proxy(function(e) {

                if (e.namespace && !this._initialized) {

                    this._core.trigger('initialize', null, 'navigation');

                    this.initialize();

                    this.update();

                    this.draw();

                    this._initialized = true;

                    this._core.trigger('initialized', null, 'navigation');

                }

            }, this),

            'refreshed.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._initialized) {

                    this._core.trigger('refresh', null, 'navigation');

                    this.update();

                    this.draw();

                    this._core.trigger('refreshed', null, 'navigation');

                }

            }, this)

        };



        // set default options

        this._core.options = $.extend({}, Navigation.Defaults, this._core.options);



        // register event handlers

        this.$element.on(this._handlers);

    };



    /**

     * Default options.

     * @public

     * @todo Rename `slideBy` to `navBy`

     */

    Navigation.Defaults = {

        nav: false,

        navText: [ 'prev', 'next' ],

        navSpeed: false,

        navElement: 'div',

        navContainer: false,

        navContainerClass: 'owl-nav',

        navClass: [ 'owl-prev', 'owl-next' ],

        slideBy: 1,

        dotClass: 'owl-dot',

        dotsClass: 'owl-dots',

        dots: true,

        dotsEach: false,

        dotsData: false,

        dotsSpeed: false,

        dotsContainer: false

    };



    /**

     * Initializes the layout of the plugin and extends the carousel.

     * @protected

     */

    Navigation.prototype.initialize = function() {

        var override,

            settings = this._core.settings;



        // create DOM structure for relative navigation

        this._controls.$relative = (settings.navContainer ? $(settings.navContainer)

            : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled');



        this._controls.$previous = $('<' + settings.navElement + '>')

            .addClass(settings.navClass[0])

            .html(settings.navText[0])

            .prependTo(this._controls.$relative)

            .on('click', $.proxy(function(e) {

                this.prev(settings.navSpeed);

            }, this));

        this._controls.$next = $('<' + settings.navElement + '>')

            .addClass(settings.navClass[1])

            .html(settings.navText[1])

            .appendTo(this._controls.$relative)

            .on('click', $.proxy(function(e) {

                this.next(settings.navSpeed);

            }, this));



        // create DOM structure for absolute navigation

        if (!settings.dotsData) {

            this._templates = [ $('<div>')

                .addClass(settings.dotClass)

                .append($('<span>'))

                .prop('outerHTML') ];

        }



        this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer)

            : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled');



        this._controls.$absolute.on('click', 'div', $.proxy(function(e) {

            var index = $(e.target).parent().is(this._controls.$absolute)

                ? $(e.target).index() : $(e.target).parent().index();



            e.preventDefault();



            this.to(index, settings.dotsSpeed);

        }, this));



        // override public methods of the carousel

        for (override in this._overrides) {

            this._core[override] = $.proxy(this[override], this);

        }

    };



    /**

     * Destroys the plugin.

     * @protected

     */

    Navigation.prototype.destroy = function() {

        var handler, control, property, override;



        for (handler in this._handlers) {

            this.$element.off(handler, this._handlers[handler]);

        }

        for (control in this._controls) {

            this._controls[control].remove();

        }

        for (override in this.overides) {

            this._core[override] = this._overrides[override];

        }

        for (property in Object.getOwnPropertyNames(this)) {

            typeof this[property] != 'function' && (this[property] = null);

        }

    };



    /**

     * Updates the internal state.

     * @protected

     */

    Navigation.prototype.update = function() {

        var i, j, k,

            lower = this._core.clones().length / 2,

            upper = lower + this._core.items().length,

            maximum = this._core.maximum(true),

            settings = this._core.settings,

            size = settings.center || settings.autoWidth || settings.dotsData

                ? 1 : settings.dotsEach || settings.items;



        if (settings.slideBy !== 'page') {

            settings.slideBy = Math.min(settings.slideBy, settings.items);

        }



        if (settings.dots || settings.slideBy == 'page') {

            this._pages = [];



            for (i = lower, j = 0, k = 0; i < upper; i++) {

                if (j >= size || j === 0) {

                    this._pages.push({

                        start: Math.min(maximum, i - lower),

                        end: i - lower + size - 1

                    });

                    if (Math.min(maximum, i - lower) === maximum) {

                        break;

                    }

                    j = 0, ++k;

                }

                j += this._core.mergers(this._core.relative(i));

            }

        }

    };



    /**

     * Draws the user interface.

     * @todo The option `dotsData` wont work.

     * @protected

     */

    Navigation.prototype.draw = function() {

        var difference,

            settings = this._core.settings,

            disabled = this._core.items().length <= settings.items,

            index = this._core.relative(this._core.current()),

            loop = settings.loop || settings.rewind;



        this._controls.$relative.toggleClass('disabled', !settings.nav || disabled);



        if (settings.nav) {

            this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true));

            this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true));

        }



        this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled);



        if (settings.dots) {

            difference = this._pages.length - this._controls.$absolute.children().length;



            if (settings.dotsData && difference !== 0) {

                this._controls.$absolute.html(this._templates.join(''));

            } else if (difference > 0) {

                this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0]));

            } else if (difference < 0) {

                this._controls.$absolute.children().slice(difference).remove();

            }



            this._controls.$absolute.find('.active').removeClass('active');

            this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active');

        }

    };



    /**

     * Extends event data.

     * @protected

     * @param {Event} event - The event object which gets thrown.

     */

    Navigation.prototype.onTrigger = function(event) {

        var settings = this._core.settings;



        event.page = {

            index: $.inArray(this.current(), this._pages),

            count: this._pages.length,

            size: settings && (settings.center || settings.autoWidth || settings.dotsData

                ? 1 : settings.dotsEach || settings.items)

        };

    };



    /**

     * Gets the current page position of the carousel.

     * @protected

     * @returns {Number}

     */

    Navigation.prototype.current = function() {

        var current = this._core.relative(this._core.current());

        return $.grep(this._pages, $.proxy(function(page, index) {

            return page.start <= current && page.end >= current;

        }, this)).pop();

    };



    /**

     * Gets the current succesor/predecessor position.

     * @protected

     * @returns {Number}

     */

    Navigation.prototype.getPosition = function(successor) {

        var position, length,

            settings = this._core.settings;



        if (settings.slideBy == 'page') {

            position = $.inArray(this.current(), this._pages);

            length = this._pages.length;

            successor ? ++position : --position;

            position = this._pages[((position % length) + length) % length].start;

        } else {

            position = this._core.relative(this._core.current());

            length = this._core.items().length;

            successor ? position += settings.slideBy : position -= settings.slideBy;

        }



        return position;

    };



    /**

     * Slides to the next item or page.

     * @public

     * @param {Number} [speed=false] - The time in milliseconds for the transition.

     */

    Navigation.prototype.next = function(speed) {

        $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);

    };



    /**

     * Slides to the previous item or page.

     * @public

     * @param {Number} [speed=false] - The time in milliseconds for the transition.

     */

    Navigation.prototype.prev = function(speed) {

        $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);

    };



    /**

     * Slides to the specified item or page.

     * @public

     * @param {Number} position - The position of the item or page.

     * @param {Number} [speed] - The time in milliseconds for the transition.

     * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.

     */

    Navigation.prototype.to = function(position, speed, standard) {

        var length;



        if (!standard && this._pages.length) {

            length = this._pages.length;

            $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);

        } else {

            $.proxy(this._overrides.to, this._core)(position, speed);

        }

    };



    $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;



})(window.Zepto || window.jQuery, window, document);



/**

 * Hash Plugin

 * @version 2.1.0

 * @author Artus Kolanowski

 * @author David Deutsch

 * @license The MIT License (MIT)

 */

;(function($, window, document, undefined) {

    'use strict';



    /**

     * Creates the hash plugin.

     * @class The Hash Plugin

     * @param {Owl} carousel - The Owl Carousel

     */

    var Hash = function(carousel) {

        /**

         * Reference to the core.

         * @protected

         * @type {Owl}

         */

        this._core = carousel;



        /**

         * Hash index for the items.

         * @protected

         * @type {Object}

         */

        this._hashes = {};



        /**

         * The carousel element.

         * @type {jQuery}

         */

        this.$element = this._core.$element;



        /**

         * All event handlers.

         * @protected

         * @type {Object}

         */

        this._handlers = {

            'initialized.owl.carousel': $.proxy(function(e) {

                if (e.namespace && this._core.settings.startPosition === 'URLHash') {

                    $(window).trigger('hashchange.owl.navigation');

                }

            }, this),

            'prepared.owl.carousel': $.proxy(function(e) {

                if (e.namespace) {

                    var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash');



                    if (!hash) {

                        return;

                    }



                    this._hashes[hash] = e.content;

                }

            }, this),

            'changed.owl.carousel': $.proxy(function(e) {

                if (e.namespace && e.property.name === 'position') {

                    var current = this._core.items(this._core.relative(this._core.current())),

                        hash = $.map(this._hashes, function(item, hash) {

                            return item === current ? hash : null;

                        }).join();



                    if (!hash || window.location.hash.slice(1) === hash) {

                        return;

                    }



                    window.location.hash = hash;

                }

            }, this)

        };



        // set default options

        this._core.options = $.extend({}, Hash.Defaults, this._core.options);



        // register the event handlers

        this.$element.on(this._handlers);



        // register event listener for hash navigation

        $(window).on('hashchange.owl.navigation', $.proxy(function(e) {

            var hash = window.location.hash.substring(1),

                items = this._core.$stage.children(),

                position = this._hashes[hash] && items.index(this._hashes[hash]);



            if (position === undefined || position === this._core.current()) {

                return;

            }



            this._core.to(this._core.relative(position), false, true);

        }, this));

    };



    /**

     * Default options.

     * @public

     */

    Hash.Defaults = {

        URLhashListener: false

    };



    /**

     * Destroys the plugin.

     * @public

     */

    Hash.prototype.destroy = function() {

        var handler, property;



        $(window).off('hashchange.owl.navigation');



        for (handler in this._handlers) {

            this._core.$element.off(handler, this._handlers[handler]);

        }

        for (property in Object.getOwnPropertyNames(this)) {

            typeof this[property] != 'function' && (this[property] = null);

        }

    };



    $.fn.owlCarousel.Constructor.Plugins.Hash = Hash;



})(window.Zepto || window.jQuery, window, document);



/**

 * Support Plugin

 *

 * @version 2.1.0

 * @author Vivid Planet Software GmbH

 * @author Artus Kolanowski

 * @author David Deutsch

 * @license The MIT License (MIT)

 */

;(function($, window, document, undefined) {



    var style = $('<support>').get(0).style,

        prefixes = 'Webkit Moz O ms'.split(' '),

        events = {

            transition: {

                end: {

                    WebkitTransition: 'webkitTransitionEnd',

                    MozTransition: 'transitionend',

                    OTransition: 'oTransitionEnd',

                    transition: 'transitionend'

                }

            },

            animation: {

                end: {

                    WebkitAnimation: 'webkitAnimationEnd',

                    MozAnimation: 'animationend',

                    OAnimation: 'oAnimationEnd',

                    animation: 'animationend'

                }

            }

        },

        tests = {

            csstransforms: function() {

                return !!test('transform');

            },

            csstransforms3d: function() {

                return !!test('perspective');

            },

            csstransitions: function() {

                return !!test('transition');

            },

            cssanimations: function() {

                return !!test('animation');

            }

        };



    function test(property, prefixed) {

        var result = false,

            upper = property.charAt(0).toUpperCase() + property.slice(1);



        $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) {

            if (style[property] !== undefined) {

                result = prefixed ? property : true;

                return false;

            }

        });



        return result;

    }



    function prefixed(property) {

        return test(property, true);

    }



    if (tests.csstransitions()) {

        /* jshint -W053 */

        $.support.transition = new String(prefixed('transition'))

        $.support.transition.end = events.transition.end[ $.support.transition ];

    }



    if (tests.cssanimations()) {

        /* jshint -W053 */

        $.support.animation = new String(prefixed('animation'))

        $.support.animation.end = events.animation.end[ $.support.animation ];

    }



    if (tests.csstransforms()) {

        /* jshint -W053 */

        $.support.transform = new String(prefixed('transform'));

        $.support.transform3d = tests.csstransforms3d();

    }



})(window.Zepto || window.jQuery, window, document);



// Easy Responsive Tabs Plugin


// Author: Samson.Onna <Email : samson3d@gmail.com>


(function ($) {


    $.fn.extend({


        easyResponsiveTabs: function (options) {


            //Set the default values, use comma to separate the settings, example:


            var defaults = {


                type: 'default', //default, vertical, accordion;


                width: 'auto',


                fit: true,


                closed: false,


                activate: function(){}


            }


            //Variables


            var options = $.extend(defaults, options);


            var opt = options, jtype = opt.type, jfit = opt.fit, jwidth = opt.width, vtabs = 'vertical', accord = 'accordion';


            var hash = window.location.hash;


            var historyApi = !!(window.history && history.replaceState);





            //Events


            $(this).bind('tabactivate', function(e, currentTab) {


                if(typeof options.activate === 'function') {


                    options.activate.call(currentTab, e)


                }


            });





            //Main function


            this.each(function () {


                var $respTabs = $(this);


                var $respTabsList = $respTabs.find('ul.resp-tabs-list');


                var respTabsId = $respTabs.attr('id');


                $respTabs.find('ul.resp-tabs-list li').addClass('resp-tab-item');


                $respTabs.css({


                    'display': 'block',


                    'width': jwidth


                });





                $respTabs.find('.resp-tabs-container > div').addClass('resp-tab-content');


                jtab_options();


                //Properties Function


                function jtab_options() {


                    if (jtype == vtabs) {


                        $respTabs.addClass('resp-vtabs');


                    }


                    if (jfit == true) {


                        $respTabs.css({ width: '100%' });


                    }


                    if (jtype == accord) {


                        $respTabs.addClass('resp-easy-accordion');


                        $respTabs.find('.resp-tabs-list').css('display', 'none');


                    }


                }





                //Assigning the h2 markup to accordion title


                var $tabItemh2;


                $respTabs.find('.resp-tab-content').before("<h2 class='resp-accordion' role='tab'><span class='resp-arrow'></span></h2>");





                var itemCount = 0;


                $respTabs.find('.resp-accordion').each(function () {


                    $tabItemh2 = $(this);


                    var $tabItem = $respTabs.find('.resp-tab-item:eq(' + itemCount + ')');


                    var $accItem = $respTabs.find('.resp-accordion:eq(' + itemCount + ')');


                    $accItem.append($tabItem.html());


                    $accItem.data($tabItem.data());


                    $tabItemh2.attr('aria-controls', 'tab_item-' + (itemCount));


                    itemCount++;


                });





                //Assigning the 'aria-controls' to Tab items


                var count = 0,


                    $tabContent;


                $respTabs.find('.resp-tab-item').each(function () {


                    $tabItem = $(this);


                    $tabItem.attr('aria-controls', 'tab_item-' + (count));


                    $tabItem.attr('role', 'tab');





                    //Assigning the 'aria-labelledby' attr to tab-content


                    var tabcount = 0;


                    $respTabs.find('.resp-tab-content').each(function () {


                        $tabContent = $(this);


                        $tabContent.attr('aria-labelledby', 'tab_item-' + (tabcount));


                        tabcount++;


                    });


                    count++;


                });





                // Show correct content area


                var tabNum = 0;


                if(hash!='') {


                    var matches = hash.match(new RegExp(respTabsId+"([0-9]+)"));


                    if (matches!==null && matches.length===2) {


                        tabNum = parseInt(matches[1],10)-1;


                        if (tabNum > count) {


                            tabNum = 0;


                        }


                    }


                }





                //Active correct tab


                $($respTabs.find('.resp-tab-item')[tabNum]).addClass('resp-tab-active');





                //keep closed if option = 'closed' or option is 'accordion' and the element is in accordion mode


                if(options.closed !== true && !(options.closed === 'accordion' && !$respTabsList.is(':visible')) && !(options.closed === 'tabs' && $respTabsList.is(':visible'))) {


                    $($respTabs.find('.resp-accordion')[tabNum]).addClass('resp-tab-active');


                    $($respTabs.find('.resp-tab-content')[tabNum]).addClass('resp-tab-content-active').attr('style', 'display:block');


                }


                //assign proper classes for when tabs mode is activated before making a selection in accordion mode


                else {


                    $($respTabs.find('.resp-tab-content')[tabNum]).addClass('resp-tab-content-active resp-accordion-closed')


                }





                //Tab Click action function


                $respTabs.find("[role=tab]").each(function () {





                    var $currentTab = $(this);


                    $currentTab.click(function () {





                        var $currentTab = $(this);


                        var $tabAria = $currentTab.attr('aria-controls');





                        if ($currentTab.hasClass('resp-accordion') && $currentTab.hasClass('resp-tab-active')) {


                            $respTabs.find('.resp-tab-content-active').slideUp('', function () { $(this).addClass('resp-accordion-closed'); });


                            $currentTab.removeClass('resp-tab-active');


                            return false;


                        }


                        if (!$currentTab.hasClass('resp-tab-active') && $currentTab.hasClass('resp-accordion')) {


                            $respTabs.find('.resp-tab-active').removeClass('resp-tab-active');


                            $respTabs.find('.resp-tab-content-active').slideUp().removeClass('resp-tab-content-active resp-accordion-closed');


                            $respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active');





                            $respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + ']').slideDown().addClass('resp-tab-content-active');


                        } else {


                            $respTabs.find('.resp-tab-active').removeClass('resp-tab-active');


                            $respTabs.find('.resp-tab-content-active').removeAttr('style').removeClass('resp-tab-content-active').removeClass('resp-accordion-closed');


                            $respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active');


                            $respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + ']').addClass('resp-tab-content-active').attr('style', 'display:block');


                        }


                        //Trigger tab activation event


                        $currentTab.trigger('tabactivate', $currentTab);





                        //Update Browser History


                        if(historyApi) {


                            /*var currentHash = window.location.hash;


                            var newHash = respTabsId+(parseInt($tabAria.substring(9),10)+1).toString();


                            if (currentHash!="") {


                                var re = new RegExp(respTabsId+"[0-9]+");


                                if (currentHash.match(re)!=null) {


                                    newHash = currentHash.replace(re,newHash);


                                }


                                else {


                                    newHash = currentHash+"|"+newHash;


                                }


                            }


                            else {


                                newHash = '#'+newHash;


                            }





                            history.replaceState(null,null,newHash);*/


                        }


                    });





                });





                //Window resize function


                $(window).resize(function () {


                    $respTabs.find('.resp-accordion-closed').removeAttr('style');


                });


            });


        }


    });


})(jQuery);









/*!

 * hoverIntent r7 // 2013.03.11 // jQuery 1.9.1+

 * http://cherne.net/brian/resources/jquery.hoverIntent.html

 *

 * You may use hoverIntent under the terms of the MIT license. Basically that

 * means you are free to use hoverIntent as long as this header is left intact.

 * Copyright 2007, 2013 Brian Cherne

 */

 

/* hoverIntent is similar to jQuery's built-in "hover" method except that

 * instead of firing the handlerIn function immediately, hoverIntent checks

 * to see if the user's mouse has slowed down (beneath the sensitivity

 * threshold) before firing the event. The handlerOut function is only

 * called after a matching handlerIn.

 *

 * // basic usage ... just like .hover()

 * .hoverIntent( handlerIn, handlerOut )

 * .hoverIntent( handlerInOut )

 *

 * // basic usage ... with event delegation!

 * .hoverIntent( handlerIn, handlerOut, selector )

 * .hoverIntent( handlerInOut, selector )

 *

 * // using a basic configuration object

 * .hoverIntent( config )

 *

 * @param  handlerIn   function OR configuration object

 * @param  handlerOut  function OR selector for delegation OR undefined

 * @param  selector    selector OR undefined

 * @author Brian Cherne <brian(at)cherne(dot)net>

 */

(function($) {

    $.fn.hoverIntent = function(handlerIn,handlerOut,selector) {



        // default configuration values

        var cfg = {

            interval: 100,

            sensitivity: 7,

            timeout: 0

        };



        if ( typeof handlerIn === "object" ) {

            cfg = $.extend(cfg, handlerIn );

        } else if ($.isFunction(handlerOut)) {

            cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } );

        } else {

            cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } );

        }



        // instantiate variables

        // cX, cY = current X and Y position of mouse, updated by mousemove event

        // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval

        var cX, cY, pX, pY;



        // A private function for getting mouse position

        var track = function(ev) {

            cX = ev.pageX;

            cY = ev.pageY;

        };



        // A private function for comparing current and previous mouse position

        var compare = function(ev,ob) {

            ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);

            // compare mouse positions to see if they've crossed the threshold

            if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {

                $(ob).off("mousemove.hoverIntent",track);

                // set hoverIntent state to true (so mouseOut can be called)

                ob.hoverIntent_s = 1;

                return cfg.over.apply(ob,[ev]);

            } else {

                // set previous coordinates for next time

                pX = cX; pY = cY;

                // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)

                ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );

            }

        };



        // A private function for delaying the mouseOut function

        var delay = function(ev,ob) {

            ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);

            ob.hoverIntent_s = 0;

            return cfg.out.apply(ob,[ev]);

        };



        // A private function for handling mouse 'hovering'

        var handleHover = function(e) {

            // copy objects to be passed into t (required for event object to be passed in IE)

            var ev = jQuery.extend({},e);

            var ob = this;



            // cancel hoverIntent timer if it exists

            if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }



            // if e.type == "mouseenter"

            if (e.type == "mouseenter") {

                // set "previous" X and Y position based on initial entry point

                pX = ev.pageX; pY = ev.pageY;

                // update "current" X and Y position based on mousemove

                $(ob).on("mousemove.hoverIntent",track);

                // start polling interval (self-calling timeout) to compare mouse coordinates over time

                if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}



                // else e.type == "mouseleave"

            } else {

                // unbind expensive mousemove event

                $(ob).off("mousemove.hoverIntent",track);

                // if hoverIntent state is true, then call the mouseOut function after the specified delay

                if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}

            }

        };



        // listen for mouseenter and mouseleave

        return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector);

    };

})(jQuery);



/**

 * jQuery CSS Customizable Scrollbar

 *

 * Copyright 2014, Yuriy Khabarov

 * Dual licensed under the MIT or GPL Version 2 licenses.

 *

 * If you found bug, please contact me via email <13real008@gmail.com>

 *

 * @author Yuriy Khabarov aka Gromo

 * @version 0.2.5

 * @url https://github.com/gromo/jquery.scrollbar/

 *

 */

;

(function($, doc, win){

    'use strict';



    // init flags & variables

    var debug = false;

    var lmb = 1, px = "px";

    var rtl = false;



    var browser = {

        data: {

            index: 0,

            name: 'scrollbar'

        },

        macosx: /mac/i.test(navigator.platform),

        mobile: /android|webos|iphone|ipad|ipod|blackberry/i.test(navigator.userAgent),

        overlay: null,

        scroll: null,

        scrolls: [],

        webkit: /webkit/i.test(navigator.userAgent) && !/edge\/\d+/i.test(navigator.userAgent),



        log: debug ? function(data, toString){

            var output = data;

            if(toString && typeof data != "string"){

                output = [];

                $.each(data, function(i, v){

                    output.push('"' + i + '": ' + v);

                });

                output = output.join(", ");

            }

            if(win.console && win.console.log){

                //win.console.log(output);

            } else {

                //alert(output);

            }

        } : function(){



        }

    };



    var defaults = {

        "autoScrollSize": true,     // automatically calculate scrollsize

        "autoUpdate": true,         // update scrollbar if content/container size changed

        "debug": false,             // debug mode

        "disableBodyScroll": false, // disable body scroll if mouse over container

        "duration": 200,            // scroll animate duration in ms

        "ignoreMobile": true,       // ignore mobile devices

        "ignoreOverlay": true,      // ignore browsers with overlay scrollbars (mobile, MacOS)

        "scrollStep": 30,           // scroll step for scrollbar arrows

        "showArrows": false,        // add class to show arrows

        "stepScrolling": true,      // when scrolling to scrollbar mousedown position

        "type":"simple",            // [advanced|simple] scrollbar html type



        "scrollx": null,            // horizontal scroll element

        "scrolly": null,            // vertical scroll element



        "onDestroy": null,          // callback function on destroy,

        "onInit": null,             // callback function on first initialization

        "onScroll": null,           // callback function on content scrolling

        "onUpdate": null            // callback function on init/resize (before scrollbar size calculation)

    };





    var customScrollbar = function(container, options){



        rtl = $('body').hasClass('rtl');



        if(!browser.scroll){

            browser.log("Init jQuery Scrollbar v0.2.5");

            browser.overlay = isScrollOverlaysContent();

            browser.scroll = getBrowserScrollSize();

            updateScrollbars();



            $(win).resize(function(){

                var forceUpdate = false;

                if(browser.scroll && (browser.scroll.height || browser.scroll.width)){

                    var scroll = getBrowserScrollSize();

                    if(scroll.height != browser.scroll.height || scroll.width != browser.scroll.width){

                        browser.scroll = scroll;

                        forceUpdate = true; // handle page zoom

                    }

                }

                updateScrollbars(forceUpdate);

            });

        }



        this.container = container;

        this.options = $.extend({}, defaults, win.jQueryScrollbarOptions || {});

        this.scrollTo = null;

        this.scrollx = {};

        this.scrolly = {};



        this.init(options);

    };



    customScrollbar.prototype = {



        destroy: function(){



            if(!this.wrapper){

                return;

            }



            // init variables

            var scrollLeft = this.container.scrollLeft();

            var scrollTop  = this.container.scrollTop();



            this.container.insertBefore(this.wrapper).css({

                "height":"",

                "margin":""

            })

                .removeClass("scroll-content")

                .removeClass("scroll-scrollx_visible")

                .removeClass("scroll-scrolly_visible")

                .off(".scrollbar")

                .scrollLeft(scrollLeft)

                .scrollTop(scrollTop);



            this.scrollx.scrollbar.removeClass("scroll-scrollx_visible").find("div").andSelf().off(".scrollbar");

            this.scrolly.scrollbar.removeClass("scroll-scrolly_visible").find("div").andSelf().off(".scrollbar");



            this.wrapper.remove();



            $(doc).add("body").off(".scrollbar");



            if($.isFunction(this.options.onDestroy))

                this.options.onDestroy.apply(this, [this.container]);

        },







        getScrollbar: function(d){



            var scrollbar = this.options["scroll" + d];

            var html = {

                "advanced":

                    '<div class="scroll-element_corner"></div>' +

                        '<div class="scroll-arrow scroll-arrow_less"></div>' +

                        '<div class="scroll-arrow scroll-arrow_more"></div>' +

                        '<div class="scroll-element_outer">' +

                        '    <div class="scroll-element_size"></div>' + // required! used for scrollbar size calculation !

                        '    <div class="scroll-element_inner-wrapper">' +

                        '        <div class="scroll-element_inner scroll-element_track">'  + // used for handling scrollbar click

                        '            <div class="scroll-element_inner-bottom"></div>' +

                        '        </div>' +

                        '    </div>' +

                        '    <div class="scroll-bar">' +

                        '        <div class="scroll-bar_body">' +

                        '            <div class="scroll-bar_body-inner"></div>' +

                        '        </div>' +

                        '        <div class="scroll-bar_bottom"></div>' +

                        '        <div class="scroll-bar_center"></div>' +

                        '    </div>' +

                        '</div>',



                "simple":

                    '<div class="scroll-element_outer">' +

                        '    <div class="scroll-element_size"></div>'  + // required! used for scrollbar size calculation !

                        '    <div class="scroll-element_track"></div>' + // used for handling scrollbar click

                        '    <div class="scroll-bar"></div>' +

                        '</div>'

            };

            var type = html[this.options.type] ? this.options.type : "advanced";



            if(scrollbar){

                if(typeof(scrollbar) == "string"){

                    scrollbar = $(scrollbar).appendTo(this.wrapper);

                } else {

                    scrollbar = $(scrollbar);

                }

            } else {

                scrollbar = $("<div>").addClass("scroll-element").html(html[type]).appendTo(this.wrapper);

            }



            if(this.options.showArrows){

                scrollbar.addClass("scroll-element_arrows_visible");

            }



            return scrollbar.addClass("scroll-" + d);

        },







        init: function(options){



            // init variables

            var S = this;



            var c = this.container;

            var cw = this.containerWrapper || c;

            var o = $.extend(this.options, options || {});

            var s = {

                "x": this.scrollx,

                "y": this.scrolly

            };

            var w = this.wrapper;



            var initScroll = {

                "scrollLeft": c.scrollLeft(),

                "scrollTop": c.scrollTop()

            };



            // do not init if in ignorable browser

            if ((browser.mobile && o.ignoreMobile)

                || (browser.overlay && o.ignoreOverlay)

                || (browser.macosx && !browser.webkit) // still required to ignore nonWebKit browsers on Mac

                ) {

                return false;

            }



            // init scroll container

            if(!w){

                this.wrapper = w = $('<div>').addClass('scroll-wrapper').addClass(c.attr('class'))

                    .css('position', c.css('position') == 'absolute' ? 'absolute' : 'relative')

                    .insertBefore(c).append(c);



                if(c.is('textarea')){

                    this.containerWrapper = cw = $('<div>').insertBefore(c).append(c);

                    w.addClass('scroll-textarea');

                }



                if (rtl) {

                    cw.addClass("scroll-content").css({

                        "height":"",

                        "margin-bottom": browser.scroll.height * -1 + px,

                        "margin-left":  browser.scroll.width  * -1 + px

                    });

                } else {

                    cw.addClass("scroll-content").css({

                        "height":"",

                        "margin-bottom": browser.scroll.height * -1 + px,

                        "margin-right":  browser.scroll.width  * -1 + px

                    });

                }



                c.on("scroll.scrollbar", function(event){

                    if($.isFunction(o.onScroll)){

                        o.onScroll.call(S, {

                            "maxScroll": s.y.maxScrollOffset,

                            "scroll": c.scrollTop(),

                            "size": s.y.size,

                            "visible": s.y.visible

                        }, {

                            "maxScroll": s.x.maxScrollOffset,

                            "scroll": c.scrollLeft(),

                            "size": s.x.size,

                            "visible": s.x.visible

                        });

                    }

                    s.x.isVisible && s.x.scroller.css(rtl?"right":"left", c.scrollLeft() * s.x.kx + px);

                    s.y.isVisible && s.y.scroller.css("top",  c.scrollTop()  * s.y.kx + px);

                });



                /* prevent native scrollbars to be visible on #anchor click */

                w.on("scroll", function(){

                    w.scrollTop(0).scrollLeft(0);

                });



                if(o.disableBodyScroll){

                    var handleMouseScroll = function(event){

                        isVerticalScroll(event) ?

                            s.y.isVisible && s.y.mousewheel(event) :

                            s.x.isVisible && s.x.mousewheel(event);

                        event.preventDefault();

                        return false;

                    };

                    w.on({

                        "MozMousePixelScroll.scrollbar": handleMouseScroll,

                        "mousewheel.scrollbar": handleMouseScroll

                    });



                    if(browser.mobile){

                        w.on("touchstart.scrollbar", function(event){

                            var touch = event.originalEvent.touches && event.originalEvent.touches[0] || event;

                            var originalTouch = {

                                "pageX": touch.pageX,

                                "pageY": touch.pageY

                            };

                            if (rtl) {

                                var originalScroll = {

                                    "right": c.scrollLeft(),

                                    "top": c.scrollTop()

                                };

                            } else {

                                var originalScroll = {

                                    "left": c.scrollLeft(),

                                    "top": c.scrollTop()

                                };

                            }

                            $(doc).on({

                                "touchmove.scrollbar": function(event){

                                    var touch = event.originalEvent.targetTouches && event.originalEvent.targetTouches[0] || event;

                                    c.scrollLeft(rtl?originalScroll.right:originalScroll.left + originalTouch.pageX - touch.pageX);

                                    c.scrollTop(originalScroll.top + originalTouch.pageY - touch.pageY);

                                    event.preventDefault();

                                },

                                "touchend.scrollbar": function(){

                                    $(doc).off(".scrollbar");

                                }

                            });

                        });

                    }

                }

                if($.isFunction(o.onInit))

                    o.onInit.apply(this, [c]);

            } else {

                if (rtl) {

                    cw.css({

                        "height":"",

                        "margin-bottom": browser.scroll.height * -1 + px,

                        "margin-left":  browser.scroll.width  * -1 + px

                    });

                } else {

                    cw.css({

                        "height":"",

                        "margin-bottom": browser.scroll.height * -1 + px,

                        "margin-right":  browser.scroll.width  * -1 + px

                    });

                }

            }



            // init scrollbars & recalculate sizes

            $.each(s, function(d, scrollx){



                var scrollCallback = null;

                var scrollForward = 1;

                var scrollOffset = (d == "x") ? "scrollLeft" : "scrollTop";

                var scrollStep = o.scrollStep;

                var scrollTo = function(){

                    var currentOffset = c[scrollOffset]();

                    c[scrollOffset](currentOffset + scrollStep);

                    if(scrollForward == 1 && (currentOffset + scrollStep) >= scrollToValue)

                        currentOffset = c[scrollOffset]();

                    if(scrollForward == -1 && (currentOffset + scrollStep) <= scrollToValue)

                        currentOffset = c[scrollOffset]();

                    if(c[scrollOffset]() == currentOffset && scrollCallback){

                        scrollCallback();

                    }

                }

                var scrollToValue = 0;



                if(!scrollx.scrollbar){



                    scrollx.scrollbar = S.getScrollbar(d);

                    scrollx.scroller = scrollx.scrollbar.find(".scroll-bar");



                    scrollx.mousewheel = function(event){



                        if(!scrollx.isVisible || (d == 'x' && isVerticalScroll(event))){

                            return true;

                        }

                        if(d == 'y' && !isVerticalScroll(event)){

                            s.x.mousewheel(event);

                            return true;

                        }



                        var delta = event.originalEvent.wheelDelta * -1 || event.originalEvent.detail;

                        var maxScrollValue = scrollx.size - scrollx.visible - scrollx.offset;



                        if(!((scrollToValue <= 0 && delta < 0) || (scrollToValue >= maxScrollValue && delta > 0))){

                            scrollToValue = scrollToValue + delta;

                            if(scrollToValue < 0)

                                scrollToValue = 0;

                            if(scrollToValue > maxScrollValue)

                                scrollToValue = maxScrollValue;



                            S.scrollTo = S.scrollTo || {};

                            S.scrollTo[scrollOffset] = scrollToValue;

                            setTimeout(function(){

                                if(S.scrollTo){

                                    c.stop().animate(S.scrollTo, 240, 'linear', function(){

                                        scrollToValue = c[scrollOffset]();

                                    });

                                    S.scrollTo = null;

                                }

                            }, 1);

                        } else {

                            return true;

                        }



                        event.preventDefault();

                        return false;

                    };



                    scrollx.scrollbar.on({

                        "MozMousePixelScroll.scrollbar": scrollx.mousewheel,

                        "mousewheel.scrollbar": scrollx.mousewheel,

                        "mouseenter.scrollbar": function(){

                            scrollToValue = c[scrollOffset]();

                        }

                    });



                    scrollx.triggerEvent = function(event) {

                        var ret = scrollx.mousewheel(event);

                        if (!ret) {

                            event.preventDefault;

                            return false;

                        }

                        return true;

                    }



                    w.on({

                        "MozMousePixelScroll.scrollbar": scrollx.triggerEvent,

                        "mousewheel.scrollbar": scrollx.triggerEvent,

                        "mouseenter.scrollbar": function(){

                            scrollToValue = c[scrollOffset]();

                        }

                    });



                    // handle arrows & scroll inner mousedown event

                    scrollx.scrollbar.find(".scroll-arrow, .scroll-element_track")

                        .on("mousedown.scrollbar", function(event){



                            if(event.which != lmb)

                                return true;



                            scrollForward = 1;



                            var data = {

                                "eventOffset": event[(d == "x") ? "pageX" : "pageY"],

                                "maxScrollValue": scrollx.size - scrollx.visible - scrollx.offset,

                                "scrollbarOffset": scrollx.scroller.offset()[(d == "x") ? rtl?"right":"left" : "top"],

                                "scrollbarSize": scrollx.scroller[(d == "x") ? "outerWidth" : "outerHeight"]()

                            };

                            var timeout = 0, timer = 0;



                            if($(this).hasClass('scroll-arrow')){

                                scrollForward = $(this).hasClass("scroll-arrow_more") ? 1 : -1;

                                scrollStep = o.scrollStep * scrollForward;

                                scrollToValue = scrollForward > 0 ? data.maxScrollValue : 0;

                            } else {

                                scrollForward = (data.eventOffset > (data.scrollbarOffset + data.scrollbarSize) ? 1

                                    : (data.eventOffset < data.scrollbarOffset ? -1 : 0));

                                scrollStep = Math.round(scrollx.visible * 0.75) * scrollForward;

                                scrollToValue = (data.eventOffset - data.scrollbarOffset -

                                    (o.stepScrolling ? (scrollForward == 1 ? data.scrollbarSize : 0)

                                        : Math.round(data.scrollbarSize / 2)));

                                scrollToValue = c[scrollOffset]() + (scrollToValue / scrollx.kx);

                            }



                            S.scrollTo = S.scrollTo || {};

                            S.scrollTo[scrollOffset] = o.stepScrolling ? c[scrollOffset]() + scrollStep : scrollToValue;



                            if(o.stepScrolling){

                                scrollCallback = function(){

                                    scrollToValue = c[scrollOffset]();

                                    clearInterval(timer);

                                    clearTimeout(timeout);

                                    timeout = 0;

                                    timer = 0;

                                };

                                timeout = setTimeout(function(){

                                    timer = setInterval(scrollTo, 40);

                                }, o.duration + 100);

                            }



                            setTimeout(function(){

                                if(S.scrollTo){

                                    c.animate(S.scrollTo, o.duration);

                                    S.scrollTo = null;

                                }

                            }, 1);



                            return handleMouseDown(scrollCallback, event);

                        });



                    // handle scrollbar drag'n'drop

                    scrollx.scroller.on("mousedown.scrollbar", function(event){



                        if(event.which != lmb)

                            return true;



                        var eventPosition = event[(d == "x")? "pageX" : "pageY"];

                        var initOffset = c[scrollOffset]();



                        scrollx.scrollbar.addClass("scroll-draggable");



                        $(doc).on("mousemove.scrollbar", function(event){

                            var diff = parseInt((event[(d == "x")? "pageX" : "pageY"] - eventPosition) / scrollx.kx, 10);

                            c[scrollOffset](initOffset + diff);

                        });



                        return handleMouseDown(function(){

                            scrollx.scrollbar.removeClass("scroll-draggable");

                            scrollToValue = c[scrollOffset]();

                        }, event);

                    });

                }

            });



            // remove classes & reset applied styles

            $.each(s, function(d, scrollx){

                var scrollClass = "scroll-scroll" + d + "_visible";

                var scrolly = (d == "x") ? s.y : s.x;



                scrollx.scrollbar.removeClass(scrollClass);

                scrolly.scrollbar.removeClass(scrollClass);

                cw.removeClass(scrollClass);

            });



            // calculate init sizes

            $.each(s, function(d, scrollx){

                $.extend(scrollx, (d == "x") ? {

                    "offset": parseInt(c.css(rtl?"right":"left"), 10) || 0,

                    "size": c.prop("scrollWidth"),

                    "visible": w.width()

                } : {

                    "offset": parseInt(c.css("top"), 10) || 0,

                    "size": c.prop("scrollHeight"),

                    "visible": w.height()

                });

            });





            var updateScroll = function(d, scrollx){



                var scrollClass = "scroll-scroll" + d + "_visible";

                var scrolly = (d == "x") ? s.y : s.x;

                var offset = parseInt(c.css((d == "x") ? rtl?"right":"left" : "top"), 10) || 0;



                var AreaSize = scrollx.size;

                var AreaVisible = scrollx.visible + offset;



                scrollx.isVisible = (AreaSize - AreaVisible) > 1; // bug in IE9/11 with 1px diff

                if(scrollx.isVisible){

                    scrollx.scrollbar.addClass(scrollClass);

                    scrolly.scrollbar.addClass(scrollClass);

                    cw.addClass(scrollClass);

                } else {

                    scrollx.scrollbar.removeClass(scrollClass);

                    scrolly.scrollbar.removeClass(scrollClass);

                    cw.removeClass(scrollClass);

                }



                if(d == "y" && (scrollx.isVisible || scrollx.size < scrollx.visible)){

                    cw.css("height", (AreaVisible + browser.scroll.height) + px);

                }



                if(s.x.size != c.prop("scrollWidth")

                    || s.y.size != c.prop("scrollHeight")

                    || s.x.visible != w.width()

                    || s.y.visible != w.height()

                    || s.x.offset  != (parseInt(c.css(rtl?"right":"left"), 10) || 0)

                    || s.y.offset  != (parseInt(c.css("top"), 10) || 0)

                    ){

                    $.each(s, function(d, scrollx){

                        $.extend(scrollx, (d == "x") ? {

                            "offset": parseInt(c.css(rtl?"right":"left"), 10) || 0,

                            "size": c.prop("scrollWidth"),

                            "visible": w.width()

                        } : {

                            "offset": parseInt(c.css("top"), 10) || 0,

                            "size": c.prop("scrollHeight"),

                            "visible": w.height()

                        });

                    });

                    updateScroll(d == "x" ? "y" : "x", scrolly);

                }

            };

            $.each(s, updateScroll);



            if($.isFunction(o.onUpdate))

                o.onUpdate.apply(this, [c]);



            // calculate scroll size

            $.each(s, function(d, scrollx){



                var cssOffset = (d == "x") ? rtl?"right":"left" : "top";

                var cssFullSize = (d == "x") ? "outerWidth" : "outerHeight";

                var cssSize = (d == "x") ? "width" : "height";

                var offset = parseInt(c.css(cssOffset), 10) || 0;



                var AreaSize = scrollx.size;

                var AreaVisible = scrollx.visible + offset;



                var scrollSize = scrollx.scrollbar.find(".scroll-element_size");

                scrollSize = scrollSize[cssFullSize]() + (parseInt(scrollSize.css(cssOffset), 10) || 0);



                if(o.autoScrollSize){

                    scrollx.scrollbarSize = parseInt(scrollSize * AreaVisible / AreaSize, 10);

                    scrollx.scroller.css(cssSize, scrollx.scrollbarSize + px);

                }



                scrollx.scrollbarSize = scrollx.scroller[cssFullSize]();

                scrollx.kx = ((scrollSize - scrollx.scrollbarSize) / (AreaSize - AreaVisible)) || 1;

                scrollx.maxScrollOffset = AreaSize - AreaVisible;

            });



            c.scrollLeft(initScroll.scrollLeft).scrollTop(initScroll.scrollTop).trigger("scroll");

        }

    };



    /*

     * Extend jQuery as plugin

     *

     * @param {object|string} options or command to execute

     * @param {object|array} args additional arguments as array []

     */

    $.fn.scrollbar = function(options, args){



        var toReturn = this;



        if(options === "get")

            toReturn = null;



        this.each(function() {



            var container = $(this);



            if(container.hasClass("scroll-wrapper")

                || container.get(0).nodeName == "body"){

                return true;

            }



            var instance = container.data("scrollbar");

            if(instance){

                if(options === "get"){

                    toReturn = instance;

                    return false;

                }



                var func = (typeof options == "string" && instance[options]) ? options : "init";

                instance[func].apply(instance, $.isArray(args) ? args : []);



                if(options === "destroy"){

                    container.removeData("scrollbar");

                    while($.inArray(instance, browser.scrolls) >= 0)

                        browser.scrolls.splice($.inArray(instance, browser.scrolls), 1);

                }

            } else {

                if(typeof options != "string"){

                    instance = new customScrollbar(container, options);

                    container.data("scrollbar", instance);

                    browser.scrolls.push(instance);

                }

            }

            return true;

        });



        return toReturn;

    };



    /**

     * Connect default options to global object

     */

    $.fn.scrollbar.options = defaults;



    /**

     * Extend AngularJS as UI directive

     *

     *

     */

    if(win.angular){

        (function(angular){

            var app = angular.module('jQueryScrollbar', []);

            app.directive('jqueryScrollbar', function(){

                return {

                    "link": function(scope, element){

                        element.scrollbar(scope.options).on('$destroy', function(){

                            element.scrollbar('destroy');

                        });

                    },

                    "restring": "AC",

                    "scope": {

                        "options": "=jqueryScrollbar"

                    }

                };

            });

        })(win.angular);

    }



    /**

     * Check if scroll content/container size is changed

     */

    var timer = 0, timerCounter = 0;

    var updateScrollbars = function(force){

        var i, c, o, s, w, x, y;

        for( i = 0; i < browser.scrolls.length; i++){

            s = browser.scrolls[i];

            c = s.container;

            o = s.options;

            w = s.wrapper;

            x = s.scrollx;

            y = s.scrolly;

            if(force || (o.autoUpdate && w && w.is(":visible") &&

                (c.prop("scrollWidth") != x.size

                    || c.prop("scrollHeight") != y.size

                    || w.width()  != x.visible

                    || w.height() != y.visible

                    ))){

                s.init();



                if(debug){

                    browser.log({

                        "scrollHeight":  c.prop("scrollHeight") + ":" + s.scrolly.size,

                        "scrollWidth":   c.prop("scrollWidth") + ":" + s.scrollx.size,

                        "visibleHeight": w.height() + ":" + s.scrolly.visible,

                        "visibleWidth":  w.width() + ":" + s.scrollx.visible

                    }, true);

                    timerCounter++;

                }

            }

        }

        if(debug && timerCounter > 10){

            browser.log("Scroll updates exceed 10");

            updateScrollbars = function(){};

        } else {

            clearTimeout(timer);

            timer = setTimeout(updateScrollbars, 300);

        }

    };



    /* ADDITIONAL FUNCTIONS */

    /**

     * Get native browser scrollbar size (height/width)

     *

     * @param {Boolean} actual size or CSS size, default - CSS size

     * @returns {Object} with height, width

     */

    function getBrowserScrollSize(actualSize){



        if(browser.webkit && !actualSize){

            return {

                "height": 0,

                "width": 0

            };

        }



        var css = {

            "border":  "none",

            "box-sizing": "content-box",

            "height":  "200px",

            "margin":  "0",

            "padding": "0",

            "width":   "200px"

        };

        browser.data.inner = $("<div>").css($.extend({}, css));

        browser.data.outer = $("<div>").css($.extend({

            "left":       "-1000px",

            "overflow":   "scroll",

            "position":   "absolute",

            "top":        "-1000px",

            "direction":  "ltr"

        }, css)).append(browser.data.inner).appendTo("body");



        browser.data.outer.scrollLeft(1000).scrollTop(1000);



        var ret = {

            "height": Math.ceil((browser.data.outer.offset().top - browser.data.inner.offset().top) || 0),

            "width": Math.ceil((browser.data.outer.offset().left - browser.data.inner.offset().left) || 0)

        };



        browser.data.inner.remove();

        browser.data.outer.remove();



        return ret;

    }



    function handleMouseDown(callback, event){

        $(doc).on({

            "blur.scrollbar": function(){

                $(doc).add('body').off('.scrollbar');

                callback && callback();

            },

            "dragstart.scrollbar": function(event){

                event.preventDefault();

                return false;

            },

            "mouseup.scrollbar": function(){

                $(doc).add('body').off('.scrollbar');

                callback && callback();

            }

        });

        $("body").on({

            "selectstart.scrollbar": function(event){

                event.preventDefault();

                return false;

            }

        });

        event && event.preventDefault();

        return false;

    }



    /**

     * Check if native browser scrollbars overlay content

     *

     * @returns {Boolean}

     */

    function isScrollOverlaysContent(){

        var scrollSize = getBrowserScrollSize(true);

        return !(scrollSize.height || scrollSize.width);

    }



    function isVerticalScroll(event){

        var e = event.originalEvent;

        if (e.axis && e.axis === e.HORIZONTAL_AXIS)

            return false;

        if (e.wheelDeltaX)

            return false;

        return true;

    }



})(jQuery, document, window);



/*global jQuery: true */



/*!

   --------------------------------

   Infinite Scroll

   --------------------------------

   + https://github.com/paulirish/infinite-scroll

   + version 2.1.0

   + Copyright 2011/12 Paul Irish & Luke Shumard

   + Licensed under the MIT license



   + Documentation: http://infinite-scroll.com/

*/



// Uses AMD or browser globals to create a jQuery plugin.

(function (factory) {

    if (typeof define === 'function' && define.amd) {

        // AMD. Register as an anonymous module.

        define(['jquery'], factory);

    } else {

        // Browser globals

        factory(jQuery);

    }

}(function ($, undefined) {

    'use strict';



    $.infinitescroll = function infscr(options, callback, element) {

        this.element = $(element);



        // Flag the object in the event of a failed creation

        if (!this._create(options, callback)) {

            this.failed = true;

        }

    };



    $.infinitescroll.defaults = {

        loading: {

            finished: undefined,

            finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>",

            img: 'data:image/gif;base64, ',

            msg: null,

            msgText: '<em>Loading the next set of posts...</em>',

            selector: null,

            speed: 'fast',

            start: undefined

        },

        state: {

            isDuringAjax: false,

            isInvalidPage: false,

            isDestroyed: false,

            isDone: false, // For when it goes all the way through the archive.

            isPaused: false,

            isBeyondMaxPage: false,

            currPage: 1

        },

        debug: false,

        behavior: undefined,

        binder: $(window), // used to cache the selector

        nextSelector: 'div.navigation a:first',

        navSelector: 'div.navigation',

        contentSelector: null, // rename to pageFragment

        extraScrollPx: 150,

        itemSelector: 'div.post',

        animate: false,

        pathParse: undefined,

        dataType: 'html',

        appendCallback: true,

        bufferPx: 40,

        errorCallback: function () { },

        infid: 0, //Instance ID

        pixelsFromNavToBottom: undefined,

        path: undefined, // Either parts of a URL as an array (e.g. ["/page/", "/"] or a function that takes in the page number and returns a URL

        prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted

        maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work)

    };



    $.infinitescroll.prototype = {



        /*

            ----------------------------

            Private methods

            ----------------------------

            */



        // Bind or unbind from scroll

        _binding: function infscr_binding(binding) {



            var instance = this,

            opts = instance.options;



            opts.v = '2.0b2.120520';



            // if behavior is defined and this function is extended, call that instead of default

            if (!!opts.behavior && this['_binding_'+opts.behavior] !== undefined) {

                this['_binding_'+opts.behavior].call(this);

                return;

            }



            if (binding !== 'bind' && binding !== 'unbind') {

                this._debug('Binding value  ' + binding + ' not valid');

                return false;

            }



            if (binding === 'unbind') {

                (this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid);

            } else {

                (this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () {

                    instance.scroll();

                });

            }



            this._debug('Binding', binding);

        },



        // Fundamental aspects of the plugin are initialized

        _create: function infscr_create(options, callback) {



            // Add custom options to defaults

            var opts = $.extend(true, {}, $.infinitescroll.defaults, options);

            this.options = opts;

            var $window = $(window);

            var instance = this;



            // Validate selectors

            if (!instance._validate(options)) {

                return false;

            }



            // Validate page fragment path

            var path = $(opts.nextSelector).attr('href');

            if (!path) {

                this._debug('Navigation selector not found');

                return false;

            }



            // Set the path to be a relative URL from root.

            opts.path = opts.path || this._determinepath(path);



            // contentSelector is 'page fragment' option for .load() / .ajax() calls

            opts.contentSelector = opts.contentSelector || this.element;



            // loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector

            opts.loading.selector = opts.loading.selector || opts.contentSelector;



            // Define loading.msg

            opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>');



            // Preload loading.img

            (new Image()).src = opts.loading.img;



            // distance from nav links to bottom

            // computed as: height of the document + top offset of container - top offset of nav link

            if(opts.pixelsFromNavToBottom === undefined) {

                opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top;

                this._debug('pixelsFromNavToBottom: ' + opts.pixelsFromNavToBottom);

            }



            var self = this;



            // determine loading.start actions

            opts.loading.start = opts.loading.start || function() {

                $(opts.navSelector).hide();

                opts.loading.msg

                .appendTo(opts.loading.selector)

                .show(opts.loading.speed, $.proxy(function() {

                    this.beginAjax(opts);

                }, self));

            };



            // determine loading.finished actions

            opts.loading.finished = opts.loading.finished || function() {

                if (!opts.state.isBeyondMaxPage)

                    opts.loading.msg.fadeOut(opts.loading.speed);

            };



            // callback loading

            opts.callback = function(instance, data, url) {

                if (!!opts.behavior && instance['_callback_'+opts.behavior] !== undefined) {

                    instance['_callback_'+opts.behavior].call($(opts.contentSelector)[0], data, url);

                }



                if (callback) {

                    callback.call($(opts.contentSelector)[0], data, opts, url);

                }



                if (opts.prefill) {

                    $window.bind('resize.infinite-scroll', instance._prefill);

                }

            };



            if (options.debug) {

                // Tell IE9 to use its built-in console

                if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === 'object') {

                    ['log','info','warn','error','assert','dir','clear','profile','profileEnd']

                        .forEach(function (method) {

                            console[method] = this.call(console[method], console);

                        }, Function.prototype.bind);

                }

            }



            this._setup();



            // Setups the prefill method for use

            if (opts.prefill) {

                this._prefill();

            }



            // Return true to indicate successful creation

            return true;

        },



        _prefill: function infscr_prefill() {

            var instance = this;

            var $window = $(window);



            function needsPrefill() {

                return ( $(instance.options.contentSelector).height() <= $window.height() );

            }



            this._prefill = function() {

                if (needsPrefill()) {

                    instance.scroll();

                }



                $window.bind('resize.infinite-scroll', function() {

                    if (needsPrefill()) {

                        $window.unbind('resize.infinite-scroll');

                        instance.scroll();

                    }

                });

            };



            // Call self after setting up the new function

            this._prefill();

        },



        // Console log wrapper

        _debug: function infscr_debug() {

            if (true !== this.options.debug) {

                return;

            }



            if (typeof console !== 'undefined' && typeof console.log === 'function') {

                // Modern browsers

                // Single argument, which is a string

                if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') {

                    //console.log( (Array.prototype.slice.call(arguments)).toString() );

                } else {

                    //console.log( Array.prototype.slice.call(arguments) );

                }

            } else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') {

                // IE8

                Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));

            }

        },



        // find the number to increment in the path.

        _determinepath: function infscr_determinepath(path) {



            var opts = this.options;



            // if behavior is defined and this function is extended, call that instead of default

            if (!!opts.behavior && this['_determinepath_'+opts.behavior] !== undefined) {

                return this['_determinepath_'+opts.behavior].call(this,path);

            }



            if (!!opts.pathParse) {



                this._debug('pathParse manual');

                return opts.pathParse(path, this.options.state.currPage+1);



            } else if (path.match(/^(.*?)\b2\b(.*?$)/)) {

                path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1);



                // if there is any 2 in the url at all.

            } else if (path.match(/^(.*?)2(.*?$)/)) {



                // page= is used in django:

                // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127

                if (path.match(/^(.*?page=)2(\/.*|$)/)) {

                    path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1);

                    return path;

                }



                path = path.match(/^(.*?)2(.*?$)/).slice(1);



            } else {



                // page= is used in drupal too but second page is page=1 not page=2:

                // thx Jerod Fritz, vladikoff

                if (path.match(/^(.*?page=)1(\/.*|$)/)) {

                    path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1);

                    return path;

                } else {

                    this._debug("Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.");

                    // Get rid of isInvalidPage to allow permalink to state

                    opts.state.isInvalidPage = true;  //prevent it from running on this page.

                }

            }

            this._debug('determinePath', path);

            return path;



        },



        // Custom error

        _error: function infscr_error(xhr) {



            var opts = this.options;



            // if behavior is defined and this function is extended, call that instead of default

            if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) {

                this['_error_'+opts.behavior].call(this,xhr);

                return;

            }



            if (xhr !== 'destroy' && xhr !== 'end') {

                xhr = 'unknown';

            }



            this._debug('Error', xhr);



            if (xhr === 'end' || opts.state.isBeyondMaxPage) {

                this._showdonemsg();

            }



            opts.state.isDone = true;

            opts.state.currPage = 1; // if you need to go back to this instance

            opts.state.isPaused = false;

            opts.state.isBeyondMaxPage = false;

            this._binding('unbind');



        },



        // Load Callback

        _loadcallback: function infscr_loadcallback(box, data, url) {

            var opts = this.options,

            callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK

            result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append',

            frag;



            // if behavior is defined and this function is extended, call that instead of default

            if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) {

                this['_loadcallback_'+opts.behavior].call(this,box,data);

                return;

            }



            switch (result) {

                case 'done':

                    this._showdonemsg();

                    return false;



                case 'no-append':

                    if (opts.dataType === 'html') {

                        data = '<div>' + data + '</div>';

                        data = $(data).find(opts.itemSelector);

                    }



                    // if it didn't return anything

                    if (data.length === 0) {

                        return this._error('end');

                    }



                    break;



                case 'append':

                    var children = box.children();

                    // if it didn't return anything

                    if (children.length === 0) {

                        return this._error('end');

                    }



                    // use a documentFragment because it works when content is going into a table or UL

                    frag = document.createDocumentFragment();

                    while (box[0].firstChild) {

                        frag.appendChild(box[0].firstChild);

                    }



                    this._debug('contentSelector', $(opts.contentSelector)[0]);

                    $(opts.contentSelector)[0].appendChild(frag);

                    // previously, we would pass in the new DOM element as context for the callback

                    // however we're now using a documentfragment, which doesn't have parents or children,

                    // so the context is the contentContainer guy, and we pass in an array

                    // of the elements collected as the first argument.



                    data = children.get();

                    break;

            }



            // loadingEnd function

            opts.loading.finished.call($(opts.contentSelector)[0],opts);



            // smooth scroll to ease in the new content

            if (opts.animate) {

                var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px';

                $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; });

            }



            if (!opts.animate) {

                // once the call is done, we can allow it again.

                opts.state.isDuringAjax = false;

            }



            callback(this, data, url);



            if (opts.prefill) {

                this._prefill();

            }

        },



        _nearbottom: function infscr_nearbottom() {



            var opts = this.options,

            pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height();



            // if behavior is defined and this function is extended, call that instead of default

            if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) {

                return this['_nearbottom_'+opts.behavior].call(this);

            }



            this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom);



            // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom....

            return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom);



        },



        // Pause / temporarily disable plugin from firing

        _pausing: function infscr_pausing(pause) {



            var opts = this.options;



            // if behavior is defined and this function is extended, call that instead of default

            if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) {

                this['_pausing_'+opts.behavior].call(this,pause);

                return;

            }



            // If pause is not 'pause' or 'resume', toggle it's value

            if (pause !== 'pause' && pause !== 'resume' && pause !== null) {

                this._debug('Invalid argument. Toggling pause value instead');

            }



            pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle';



            switch (pause) {

                case 'pause':

                    opts.state.isPaused = true;

                break;



                case 'resume':

                    opts.state.isPaused = false;

                break;



                case 'toggle':

                    opts.state.isPaused = !opts.state.isPaused;

                break;

            }



            this._debug('Paused', opts.state.isPaused);

            return false;



        },



        // Behavior is determined

        // If the behavior option is undefined, it will set to default and bind to scroll

        _setup: function infscr_setup() {



            var opts = this.options;



            // if behavior is defined and this function is extended, call that instead of default

            if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) {

                this['_setup_'+opts.behavior].call(this);

                return;

            }



            this._binding('bind');



            return false;



        },



        // Show done message

        _showdonemsg: function infscr_showdonemsg() {



            var opts = this.options;



            // if behavior is defined and this function is extended, call that instead of default

            if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) {

                this['_showdonemsg_'+opts.behavior].call(this);

                return;

            }



            opts.loading.msg

            .find('img')

            .hide()

            .parent()

            .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () {

                $(this).parent().fadeOut(opts.loading.speed);

            });



            // user provided callback when done

            opts.errorCallback.call($(opts.contentSelector)[0],'done');

        },



        // grab each selector option and see if any fail

        _validate: function infscr_validate(opts) {

            for (var key in opts) {

                if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) {

                    this._debug('Your ' + key + ' found no elements.');

                    return false;

                }

            }



            return true;

        },



        /*

            ----------------------------

            Public methods

            ----------------------------

            */



        // Bind to scroll

        bind: function infscr_bind() {

            this._binding('bind');

        },



        // Destroy current instance of plugin

        destroy: function infscr_destroy() {

            this.options.state.isDestroyed = true;

            this.options.loading.finished();

            return this._error('destroy');

        },



        // Set pause value to false

        pause: function infscr_pause() {

            this._pausing('pause');

        },



        // Set pause value to false

        resume: function infscr_resume() {

            this._pausing('resume');

        },



        beginAjax: function infscr_ajax(opts) {

            var instance = this,

                path = opts.path,

                box, desturl, method, condition;



            // increment the URL bit. e.g. /page/3/

            opts.state.currPage++;



            // Manually control maximum page

            if ( opts.maxPage !== undefined && opts.state.currPage > opts.maxPage ){

                opts.state.isBeyondMaxPage = true;

                this.destroy();

                return;

            }



            // if we're dealing with a table we can't use DIVs

            box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>');



            desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage);

            instance._debug('heading into ajax', desturl);



            method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback';

            if (opts.appendCallback && opts.dataType === 'html') {

                method += '+callback';

            }



            switch (method) {

                case 'html+callback':

                    instance._debug('Using HTML via .load() method');

                    box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) {

                        instance._loadcallback(box, responseText, desturl);

                    });



                    break;



                case 'html':

                    instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');

                    $.ajax({

                        // params

                        url: desturl,

                        dataType: opts.dataType,

                        complete: function infscr_ajax_callback(jqXHR, textStatus) {

                            condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified');

                            if (condition) {

                                instance._loadcallback(box, jqXHR.responseText, desturl);

                            } else {

                                instance._error('end');

                            }

                        }

                    });



                    break;

                case 'json':

                    instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');

                    $.ajax({

                        dataType: 'json',

                        type: 'GET',

                        url: desturl,

                        success: function (data, textStatus, jqXHR) {

                            condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified');

                            if (opts.appendCallback) {

                                // if appendCallback is true, you must defined template in options.

                                // note that data passed into _loadcallback is already an html (after processed in opts.template(data)).

                                if (opts.template !== undefined) {

                                    var theData = opts.template(data);

                                    box.append(theData);

                                    if (condition) {

                                        instance._loadcallback(box, theData);

                                    } else {

                                        instance._error('end');

                                    }

                                } else {

                                    instance._debug('template must be defined.');

                                    instance._error('end');

                                }

                            } else {

                                // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback.

                                if (condition) {

                                    instance._loadcallback(box, data, desturl);

                                } else {

                                    instance._error('end');

                                }

                            }

                        },

                        error: function() {

                            instance._debug('JSON ajax request failed.');

                            instance._error('end');

                        }

                    });



                    break;

            }

        },



        // Retrieve next set of content items

        retrieve: function infscr_retrieve(pageNum) {

            pageNum = pageNum || null;



            var instance = this,

            opts = instance.options;



            // if behavior is defined and this function is extended, call that instead of default

            if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) {

                this['retrieve_'+opts.behavior].call(this,pageNum);

                return;

            }



            // for manual triggers, if destroyed, get out of here

            if (opts.state.isDestroyed) {

                this._debug('Instance is destroyed');

                return false;

            }



            // we dont want to fire the ajax multiple times

            opts.state.isDuringAjax = true;



            opts.loading.start.call($(opts.contentSelector)[0],opts);

        },



        // Check to see next page is needed

        scroll: function infscr_scroll() {



            var opts = this.options,

            state = opts.state;



            // if behavior is defined and this function is extended, call that instead of default

            if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) {

                this['scroll_'+opts.behavior].call(this);

                return;

            }



            if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) {

                return;

            }



            if (!this._nearbottom()) {

                return;

            }



            this.retrieve();



        },



        // Toggle pause value

        toggle: function infscr_toggle() {

            this._pausing();

        },



        // Unbind from scroll

        unbind: function infscr_unbind() {

            this._binding('unbind');

        },



        // update options

        update: function infscr_options(key) {

            if ($.isPlainObject(key)) {

                this.options = $.extend(true,this.options,key);

            }

        }

    };





    /*

        ----------------------------

        Infinite Scroll function

        ----------------------------



        Borrowed logic from the following...



        jQuery UI

        - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js



        jCarousel

        - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js



        Masonry

        - https://github.com/desandro/masonry/blob/master/jquery.masonry.js



*/



    $.fn.infinitescroll = function infscr_init(options, callback) {





        var thisCall = typeof options;



        switch (thisCall) {



            // method

            case 'string':

                var args = Array.prototype.slice.call(arguments, 1);



                this.each(function () {

                    var instance = $.data(this, 'infinitescroll');



                    if (!instance) {

                        // not setup yet

                        // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup');

                        return false;

                    }



                    if (!$.isFunction(instance[options]) || options.charAt(0) === '_') {

                        // return $.error('No such method ' + options + ' for Infinite Scroll');

                        return false;

                    }



                    // no errors!

                    instance[options].apply(instance, args);

                });



            break;



            // creation

            case 'object':



                this.each(function () {



                var instance = $.data(this, 'infinitescroll');



                if (instance) {



                    // update options of current instance

                    instance.update(options);



                } else {



                    // initialize new instance

                    instance = new $.infinitescroll(options, callback, this);



                    // don't attach if instantiation failed

                    if (!instance.failed) {

                        $.data(this, 'infinitescroll', instance);

                    }



                }



            });



            break;



        }



        return this;

    };







    /*

     * smartscroll: debounced scroll event for jQuery *

     * https://github.com/lukeshumard/smartscroll

     * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js *

     * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. *

     */



    var event = $.event,

    scrollTimeout;



    event.special.smartscroll = {

        setup: function () {

            $(this).bind('scroll', event.special.smartscroll.handler);

        },

        teardown: function () {

            $(this).unbind('scroll', event.special.smartscroll.handler);

        },

        handler: function (event, execAsap) {

            // Save the context

            var context = this,

            args = arguments;



            // set correct event type

            event.type = 'smartscroll';



            if (scrollTimeout) { clearTimeout(scrollTimeout); }

            scrollTimeout = setTimeout(function () {

                $(context).trigger('smartscroll', args);

            }, execAsap === 'execAsap' ? 0 : 100);

        }

    };



    $.fn.smartscroll = function (fn) {

        return fn ? this.bind('smartscroll', fn) : this.trigger('smartscroll', ['execAsap']);

    };



}));





/*!


 * Packery PACKAGED v2.1.1


 * Gapless, draggable grid layouts


 *


 * Licensed GPLv3 for open source use


 * or Packery Commercial License for commercial use


 *


 * http://packery.metafizzy.co


 * Copyright 2016 Metafizzy


 */





/**


 * Bridget makes jQuery widgets


 * v2.0.0


 * MIT license


 */





/* jshint browser: true, strict: true, undef: true, unused: true */





( function( window, factory ) {


    'use strict';


    /* globals define: false, module: false, require: false */





    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {


            factory( window, jQuery );


        });


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            window,


            require('jquery')


        );


    } else {


        // browser global


        window.jQueryBridget = factory(


            window,


            window.jQuery


        );


    }





}( window, function factory( window, jQuery ) {


    'use strict';





// ----- utils ----- //





    var arraySlice = Array.prototype.slice;





// helper function for logging errors


// $.error breaks jQuery chaining


    var console = window.console;


    var logError = typeof console == 'undefined' ? function() {} :


        function( message ) {


            console.error( message );


        };





// ----- jQueryBridget ----- //





    function jQueryBridget( namespace, PluginClass, $ ) {


        $ = $ || jQuery || window.jQuery;


        if ( !$ ) {


            return;


        }





        // add option method -> $().plugin('option', {...})


        if ( !PluginClass.prototype.option ) {


            // option setter


            PluginClass.prototype.option = function( opts ) {


                // bail out if not an object


                if ( !$.isPlainObject( opts ) ){


                    return;


                }


                this.options = $.extend( true, this.options, opts );


            };


        }





        // make jQuery plugin


        $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {


            if ( typeof arg0 == 'string' ) {


                // method call $().plugin( 'methodName', { options } )


                // shift arguments by 1


                var args = arraySlice.call( arguments, 1 );


                return methodCall( this, arg0, args );


            }


            // just $().plugin({ options })


            plainCall( this, arg0 );


            return this;


        };





        // $().plugin('methodName')


        function methodCall( $elems, methodName, args ) {


            var returnValue;


            var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';





            $elems.each( function( i, elem ) {


                // get instance


                var instance = $.data( elem, namespace );


                if ( !instance ) {


                    logError( namespace + ' not initialized. Cannot call methods, i.e. ' +


                        pluginMethodStr );


                    return;


                }





                var method = instance[ methodName ];


                if ( !method || methodName.charAt(0) == '_' ) {


                    logError( pluginMethodStr + ' is not a valid method' );


                    return;


                }





                // apply method, get return value


                var value = method.apply( instance, args );


                // set return value if value is returned, use only first value


                returnValue = returnValue === undefined ? value : returnValue;


            });





            return returnValue !== undefined ? returnValue : $elems;


        }





        function plainCall( $elems, options ) {


            $elems.each( function( i, elem ) {


                var instance = $.data( elem, namespace );


                if ( instance ) {


                    // set options & init


                    instance.option( options );


                    instance._init();


                } else {


                    // initialize new instance


                    instance = new PluginClass( elem, options );


                    $.data( elem, namespace, instance );


                }


            });


        }





        updateJQuery( $ );





    }





// ----- updateJQuery ----- //





// set $.bridget for v1 backwards compatibility


    function updateJQuery( $ ) {


        if ( !$ || ( $ && $.bridget ) ) {


            return;


        }


        $.bridget = jQueryBridget;


    }





    updateJQuery( jQuery || window.jQuery );





// -----  ----- //





    return jQueryBridget;





}));





/*!


 * getSize v2.0.2


 * measure size of elements


 * MIT license


 */





/*jshint browser: true, strict: true, undef: true, unused: true */


/*global define: false, module: false, console: false */





( function( window, factory ) {


    'use strict';





    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'get-size/get-size',[],function() {


            return factory();


        });


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory();


    } else {


        // browser global


        window.getSize = factory();


    }





})( window, function factory() {


    'use strict';





// -------------------------- helpers -------------------------- //





// get a number from a string, not a percentage


    function getStyleSize( value ) {


        var num = parseFloat( value );


        // not a percent like '100%', and a number


        var isValid = value.indexOf('%') == -1 && !isNaN( num );


        return isValid && num;


    }





    function noop() {}





    var logError = typeof console == 'undefined' ? noop :


        function( message ) {


            console.error( message );


        };





// -------------------------- measurements -------------------------- //





    var measurements = [


        'paddingLeft',


        'paddingRight',


        'paddingTop',


        'paddingBottom',


        'marginLeft',


        'marginRight',


        'marginTop',


        'marginBottom',


        'borderLeftWidth',


        'borderRightWidth',


        'borderTopWidth',


        'borderBottomWidth'


    ];





    var measurementsLength = measurements.length;





    function getZeroSize() {


        var size = {


            width: 0,


            height: 0,


            innerWidth: 0,


            innerHeight: 0,


            outerWidth: 0,


            outerHeight: 0


        };


        for ( var i=0; i < measurementsLength; i++ ) {


            var measurement = measurements[i];


            size[ measurement ] = 0;


        }


        return size;


    }





// -------------------------- getStyle -------------------------- //





    /**


     * getStyle, get style of element, check for Firefox bug


     * https://bugzilla.mozilla.org/show_bug.cgi?id=548397


     */


    function getStyle( elem ) {


        var style = getComputedStyle( elem );


        if ( !style ) {


            logError( 'Style returned ' + style +


                '. Are you running this code in a hidden iframe on Firefox? ' +


                'See http://bit.ly/getsizebug1' );


        }


        return style;


    }





// -------------------------- setup -------------------------- //





    var isSetup = false;





    var isBoxSizeOuter;





    /**


     * setup


     * check isBoxSizerOuter


     * do on first getSize() rather than on page load for Firefox bug


     */


    function setup() {


        // setup once


        if ( isSetup ) {


            return;


        }


        isSetup = true;





        // -------------------------- box sizing -------------------------- //





        /**


         * WebKit measures the outer-width on style.width on border-box elems


         * IE & Firefox<29 measures the inner-width


         */


        var div = document.createElement('div');


        div.style.width = '200px';


        div.style.padding = '1px 2px 3px 4px';


        div.style.borderStyle = 'solid';


        div.style.borderWidth = '1px 2px 3px 4px';


        div.style.boxSizing = 'border-box';





        var body = document.body || document.documentElement;


        body.appendChild( div );


        var style = getStyle( div );





        getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200;


        body.removeChild( div );





    }





// -------------------------- getSize -------------------------- //





    function getSize( elem ) {


        setup();





        // use querySeletor if elem is string


        if ( typeof elem == 'string' ) {


            elem = document.querySelector( elem );


        }





        // do not proceed on non-objects


        if ( !elem || typeof elem != 'object' || !elem.nodeType ) {


            return;


        }





        var style = getStyle( elem );





        // if hidden, everything is 0


        if ( style.display == 'none' ) {


            return getZeroSize();


        }





        var size = {};


        size.width = elem.offsetWidth;


        size.height = elem.offsetHeight;





        var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';





        // get all measurements


        for ( var i=0; i < measurementsLength; i++ ) {


            var measurement = measurements[i];


            var value = style[ measurement ];


            var num = parseFloat( value );


            // any 'auto', 'medium' value will be 0


            size[ measurement ] = !isNaN( num ) ? num : 0;


        }





        var paddingWidth = size.paddingLeft + size.paddingRight;


        var paddingHeight = size.paddingTop + size.paddingBottom;


        var marginWidth = size.marginLeft + size.marginRight;


        var marginHeight = size.marginTop + size.marginBottom;


        var borderWidth = size.borderLeftWidth + size.borderRightWidth;


        var borderHeight = size.borderTopWidth + size.borderBottomWidth;





        var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;





        // overwrite width and height if we can get it from style


        var styleWidth = getStyleSize( style.width );


        if ( styleWidth !== false ) {


            size.width = styleWidth +


                // add padding and border unless it's already including it


                ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );


        }





        var styleHeight = getStyleSize( style.height );


        if ( styleHeight !== false ) {


            size.height = styleHeight +


                // add padding and border unless it's already including it


                ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );


        }





        size.innerWidth = size.width - ( paddingWidth + borderWidth );


        size.innerHeight = size.height - ( paddingHeight + borderHeight );





        size.outerWidth = size.width + marginWidth;


        size.outerHeight = size.height + marginHeight;





        return size;


    }





    return getSize;





});





/**


 * EvEmitter v1.0.2


 * Lil' event emitter


 * MIT License


 */





/* jshint unused: true, undef: true, strict: true */





( function( global, factory ) {


    // universal module definition


    /* jshint strict: false */ /* globals define, module */


    if ( typeof define == 'function' && define.amd ) {


        // AMD - RequireJS


        define( 'ev-emitter/ev-emitter',factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS - Browserify, Webpack


        module.exports = factory();


    } else {


        // Browser globals


        global.EvEmitter = factory();


    }





}( this, function() {











    function EvEmitter() {}





    var proto = EvEmitter.prototype;





    proto.on = function( eventName, listener ) {


        if ( !eventName || !listener ) {


            return;


        }


        // set events hash


        var events = this._events = this._events || {};


        // set listeners array


        var listeners = events[ eventName ] = events[ eventName ] || [];


        // only add once


        if ( listeners.indexOf( listener ) == -1 ) {


            listeners.push( listener );


        }





        return this;


    };





    proto.once = function( eventName, listener ) {


        if ( !eventName || !listener ) {


            return;


        }


        // add event


        this.on( eventName, listener );


        // set once flag


        // set onceEvents hash


        var onceEvents = this._onceEvents = this._onceEvents || {};


        // set onceListeners object


        var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};


        // set flag


        onceListeners[ listener ] = true;





        return this;


    };





    proto.off = function( eventName, listener ) {


        var listeners = this._events && this._events[ eventName ];


        if ( !listeners || !listeners.length ) {


            return;


        }


        var index = listeners.indexOf( listener );


        if ( index != -1 ) {


            listeners.splice( index, 1 );


        }





        return this;


    };





    proto.emitEvent = function( eventName, args ) {


        var listeners = this._events && this._events[ eventName ];


        if ( !listeners || !listeners.length ) {


            return;


        }


        var i = 0;


        var listener = listeners[i];


        args = args || [];


        // once stuff


        var onceListeners = this._onceEvents && this._onceEvents[ eventName ];





        while ( listener ) {


            var isOnce = onceListeners && onceListeners[ listener ];


            if ( isOnce ) {


                // remove listener


                // remove before trigger to prevent recursion


                this.off( eventName, listener );


                // unset once flag


                delete onceListeners[ listener ];


            }


            // trigger listener


            listener.apply( this, args );


            // get next listener


            i += isOnce ? 0 : 1;


            listener = listeners[i];


        }





        return this;


    };





    return EvEmitter;





}));





/**


 * matchesSelector v2.0.1


 * matchesSelector( element, '.selector' )


 * MIT license


 */





/*jshint browser: true, strict: true, undef: true, unused: true */





( function( window, factory ) {


    /*global define: false, module: false */


    'use strict';


    // universal module definition


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'desandro-matches-selector/matches-selector',factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory();


    } else {


        // browser global


        window.matchesSelector = factory();


    }





}( window, function factory() {


    'use strict';





    var matchesMethod = ( function() {


        var ElemProto = Element.prototype;


        // check for the standard method name first


        if ( ElemProto.matches ) {


            return 'matches';


        }


        // check un-prefixed


        if ( ElemProto.matchesSelector ) {


            return 'matchesSelector';


        }


        // check vendor prefixes


        var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];





        for ( var i=0; i < prefixes.length; i++ ) {


            var prefix = prefixes[i];


            var method = prefix + 'MatchesSelector';


            if ( ElemProto[ method ] ) {


                return method;


            }


        }


    })();





    return function matchesSelector( elem, selector ) {


        return elem[ matchesMethod ]( selector );


    };





}));





/**


 * Fizzy UI utils v2.0.1


 * MIT license


 */





/*jshint browser: true, undef: true, unused: true, strict: true */





( function( window, factory ) {


    // universal module definition


    /*jshint strict: false */ /*globals define, module, require */





    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'fizzy-ui-utils/utils',[


            'desandro-matches-selector/matches-selector'


        ], function( matchesSelector ) {


            return factory( window, matchesSelector );


        });


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            window,


            require('desandro-matches-selector')


        );


    } else {


        // browser global


        window.fizzyUIUtils = factory(


            window,


            window.matchesSelector


        );


    }





}( window, function factory( window, matchesSelector ) {











    var utils = {};





// ----- extend ----- //





// extends objects


    utils.extend = function( a, b ) {


        for ( var prop in b ) {


            a[ prop ] = b[ prop ];


        }


        return a;


    };





// ----- modulo ----- //





    utils.modulo = function( num, div ) {


        return ( ( num % div ) + div ) % div;


    };





// ----- makeArray ----- //





// turn element or nodeList into an array


    utils.makeArray = function( obj ) {


        var ary = [];


        if ( Array.isArray( obj ) ) {


            // use object if already an array


            ary = obj;


        } else if ( obj && typeof obj.length == 'number' ) {


            // convert nodeList to array


            for ( var i=0; i < obj.length; i++ ) {


                ary.push( obj[i] );


            }


        } else {


            // array of single index


            ary.push( obj );


        }


        return ary;


    };





// ----- removeFrom ----- //





    utils.removeFrom = function( ary, obj ) {


        var index = ary.indexOf( obj );


        if ( index != -1 ) {


            ary.splice( index, 1 );


        }


    };





// ----- getParent ----- //





    utils.getParent = function( elem, selector ) {


        while ( elem != document.body ) {


            elem = elem.parentNode;


            if ( matchesSelector( elem, selector ) ) {


                return elem;


            }


        }


    };





// ----- getQueryElement ----- //





// use element as selector string


    utils.getQueryElement = function( elem ) {


        if ( typeof elem == 'string' ) {


            return document.querySelector( elem );


        }


        return elem;


    };





// ----- handleEvent ----- //





// enable .ontype to trigger from .addEventListener( elem, 'type' )


    utils.handleEvent = function( event ) {


        var method = 'on' + event.type;


        if ( this[ method ] ) {


            this[ method ]( event );


        }


    };





// ----- filterFindElements ----- //





    utils.filterFindElements = function( elems, selector ) {


        // make array of elems


        elems = utils.makeArray( elems );


        var ffElems = [];





        elems.forEach( function( elem ) {


            // check that elem is an actual element


            if ( !( elem instanceof HTMLElement ) ) {


                return;


            }


            // add elem if no selector


            if ( !selector ) {


                ffElems.push( elem );


                return;


            }


            // filter & find items if we have a selector


            // filter


            if ( matchesSelector( elem, selector ) ) {


                ffElems.push( elem );


            }


            // find children


            var childElems = elem.querySelectorAll( selector );


            // concat childElems to filterFound array


            for ( var i=0; i < childElems.length; i++ ) {


                ffElems.push( childElems[i] );


            }


        });





        return ffElems;


    };





// ----- debounceMethod ----- //





    utils.debounceMethod = function( _class, methodName, threshold ) {


        // original method


        var method = _class.prototype[ methodName ];


        var timeoutName = methodName + 'Timeout';





        _class.prototype[ methodName ] = function() {


            var timeout = this[ timeoutName ];


            if ( timeout ) {


                clearTimeout( timeout );


            }


            var args = arguments;





            var _this = this;


            this[ timeoutName ] = setTimeout( function() {


                method.apply( _this, args );


                delete _this[ timeoutName ];


            }, threshold || 100 );


        };


    };





// ----- docReady ----- //





    utils.docReady = function( callback ) {


        if ( document.readyState == 'complete' ) {


            callback();


        } else {


            document.addEventListener( 'DOMContentLoaded', callback );


        }


    };





// ----- htmlInit ----- //





// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/


    utils.toDashed = function( str ) {


        return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {


            return $1 + '-' + $2;


        }).toLowerCase();


    };





    var console = window.console;


    /**


     * allow user to initialize classes via [data-namespace] or .js-namespace class


     * htmlInit( Widget, 'widgetName' )


     * options are parsed from data-namespace-options


     */


    utils.htmlInit = function( WidgetClass, namespace ) {


        utils.docReady( function() {


            var dashedNamespace = utils.toDashed( namespace );


            var dataAttr = 'data-' + dashedNamespace;


            var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );


            var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );


            var elems = utils.makeArray( dataAttrElems )


                .concat( utils.makeArray( jsDashElems ) );


            var dataOptionsAttr = dataAttr + '-options';


            var jQuery = window.jQuery;





            elems.forEach( function( elem ) {


                var attr = elem.getAttribute( dataAttr ) ||


                    elem.getAttribute( dataOptionsAttr );


                var options;


                try {


                    options = attr && JSON.parse( attr );


                } catch ( error ) {


                    // log error, do not initialize


                    if ( console ) {


                        console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +


                            ': ' + error );


                    }


                    return;


                }


                // initialize


                var instance = new WidgetClass( elem, options );


                // make available via $().data('layoutname')


                if ( jQuery ) {


                    jQuery.data( elem, namespace, instance );


                }


            });





        });


    };





// -----  ----- //





    return utils;





}));





/**


 * Outlayer Item


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /* globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD - RequireJS


        define( 'outlayer/item',[


            'ev-emitter/ev-emitter',


            'get-size/get-size'


        ],


            factory


        );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS - Browserify, Webpack


        module.exports = factory(


            require('ev-emitter'),


            require('get-size')


        );


    } else {


        // browser global


        window.Outlayer = {};


        window.Outlayer.Item = factory(


            window.EvEmitter,


            window.getSize


        );


    }





}( window, function factory( EvEmitter, getSize ) {


    'use strict';





// ----- helpers ----- //





    function isEmptyObj( obj ) {


        for ( var prop in obj ) {


            return false;


        }


        prop = null;


        return true;


    }





// -------------------------- CSS3 support -------------------------- //








    var docElemStyle = document.documentElement.style;





    var transitionProperty = typeof docElemStyle.transition == 'string' ?


        'transition' : 'WebkitTransition';


    var transformProperty = typeof docElemStyle.transform == 'string' ?


        'transform' : 'WebkitTransform';





    var transitionEndEvent = {


        WebkitTransition: 'webkitTransitionEnd',


        transition: 'transitionend'


    }[ transitionProperty ];





// cache all vendor properties that could have vendor prefix


    var vendorProperties = {


        transform: transformProperty,


        transition: transitionProperty,


        transitionDuration: transitionProperty + 'Duration',


        transitionProperty: transitionProperty + 'Property',


        transitionDelay: transitionProperty + 'Delay'


    };





// -------------------------- Item -------------------------- //





    function Item( element, layout ) {


        if ( !element ) {


            return;


        }





        this.element = element;


        // parent layout class, i.e. Masonry, Isotope, or Packery


        this.layout = layout;


        this.position = {


            x: 0,


            y: 0


        };





        this._create();


    }





// inherit EvEmitter


    var proto = Item.prototype = Object.create( EvEmitter.prototype );


    proto.constructor = Item;





    proto._create = function() {


        // transition objects


        this._transn = {


            ingProperties: {},


            clean: {},


            onEnd: {}


        };





        this.css({


            position: 'absolute'


        });


    };





// trigger specified handler for event type


    proto.handleEvent = function( event ) {


        var method = 'on' + event.type;


        if ( this[ method ] ) {


            this[ method ]( event );


        }


    };





    proto.getSize = function() {


        this.size = getSize( this.element );


    };





    /**


     * apply CSS styles to element


     * @param {Object} style


     */


    proto.css = function( style ) {


        var elemStyle = this.element.style;





        for ( var prop in style ) {


            // use vendor property if available


            var supportedProp = vendorProperties[ prop ] || prop;


            elemStyle[ supportedProp ] = style[ prop ];


        }


    };





    // measure position, and sets it


    proto.getPosition = function() {


        var style = getComputedStyle( this.element );


        var isOriginLeft = this.layout._getOption('originLeft');


        var isOriginTop = this.layout._getOption('originTop');


        var xValue = style[ isOriginLeft ? 'left' : 'right' ];


        var yValue = style[ isOriginTop ? 'top' : 'bottom' ];


        // convert percent to pixels


        var layoutSize = this.layout.size;


        var x = xValue.indexOf('%') != -1 ?


            ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );


        var y = yValue.indexOf('%') != -1 ?


            ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );





        // clean up 'auto' or other non-integer values


        x = isNaN( x ) ? 0 : x;


        y = isNaN( y ) ? 0 : y;


        // remove padding from measurement


        x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;


        y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;





        this.position.x = x;


        this.position.y = y;


    };





// set settled position, apply padding


    proto.layoutPosition = function() {


        var layoutSize = this.layout.size;


        var style = {};


        var isOriginLeft = this.layout._getOption('originLeft');


        var isOriginTop = this.layout._getOption('originTop');





        // x


        var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';


        var xProperty = isOriginLeft ? 'left' : 'right';


        var xResetProperty = isOriginLeft ? 'right' : 'left';





        var x = this.position.x + layoutSize[ xPadding ];


        // set in percentage or pixels


        style[ xProperty ] = this.getXValue( x );


        // reset other property


        style[ xResetProperty ] = '';





        // y


        var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';


        var yProperty = isOriginTop ? 'top' : 'bottom';


        var yResetProperty = isOriginTop ? 'bottom' : 'top';





        var y = this.position.y + layoutSize[ yPadding ];


        // set in percentage or pixels


        style[ yProperty ] = this.getYValue( y );


        // reset other property


        style[ yResetProperty ] = '';





        this.css( style );


        this.emitEvent( 'layout', [ this ] );


    };





    proto.getXValue = function( x ) {


        var isHorizontal = this.layout._getOption('horizontal');


        return this.layout.options.percentPosition && !isHorizontal ?


            ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';


    };





    proto.getYValue = function( y ) {


        var isHorizontal = this.layout._getOption('horizontal');


        return this.layout.options.percentPosition && isHorizontal ?


            ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';


    };





    proto._transitionTo = function( x, y ) {


        this.getPosition();


        // get current x & y from top/left


        var curX = this.position.x;


        var curY = this.position.y;





        var compareX = parseInt( x, 10 );


        var compareY = parseInt( y, 10 );


        var didNotMove = compareX === this.position.x && compareY === this.position.y;





        // save end position


        this.setPosition( x, y );





        // if did not move and not transitioning, just go to layout


        if ( didNotMove && !this.isTransitioning ) {


            this.layoutPosition();


            return;


        }





        var transX = x - curX;


        var transY = y - curY;


        var transitionStyle = {};


        transitionStyle.transform = this.getTranslate( transX, transY );





        this.transition({


            to: transitionStyle,


            onTransitionEnd: {


                transform: this.layoutPosition


            },


            isCleaning: true


        });


    };





    proto.getTranslate = function( x, y ) {


        // flip cooridinates if origin on right or bottom


        var isOriginLeft = this.layout._getOption('originLeft');


        var isOriginTop = this.layout._getOption('originTop');


        x = isOriginLeft ? x : -x;


        y = isOriginTop ? y : -y;


        return 'translate3d(' + x + 'px, ' + y + 'px, 0)';


    };





// non transition + transform support


    proto.goTo = function( x, y ) {


        this.setPosition( x, y );


        this.layoutPosition();


    };





    proto.moveTo = proto._transitionTo;





    proto.setPosition = function( x, y ) {


        this.position.x = parseInt( x, 10 );


        this.position.y = parseInt( y, 10 );


    };





// ----- transition ----- //





    /**


     * @param {Object} style - CSS


     * @param {Function} onTransitionEnd


     */





// non transition, just trigger callback


    proto._nonTransition = function( args ) {


        this.css( args.to );


        if ( args.isCleaning ) {


            this._removeStyles( args.to );


        }


        for ( var prop in args.onTransitionEnd ) {


            args.onTransitionEnd[ prop ].call( this );


        }


    };





    /**


     * proper transition


     * @param {Object} args - arguments


     *   @param {Object} to - style to transition to


     *   @param {Object} from - style to start transition from


     *   @param {Boolean} isCleaning - removes transition styles after transition


     *   @param {Function} onTransitionEnd - callback


     */


    proto.transition = function( args ) {


        // redirect to nonTransition if no transition duration


        if ( !parseFloat( this.layout.options.transitionDuration ) ) {


            this._nonTransition( args );


            return;


        }





        var _transition = this._transn;


        // keep track of onTransitionEnd callback by css property


        for ( var prop in args.onTransitionEnd ) {


            _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];


        }


        // keep track of properties that are transitioning


        for ( prop in args.to ) {


            _transition.ingProperties[ prop ] = true;


            // keep track of properties to clean up when transition is done


            if ( args.isCleaning ) {


                _transition.clean[ prop ] = true;


            }


        }





        // set from styles


        if ( args.from ) {


            this.css( args.from );


            // force redraw. http://blog.alexmaccaw.com/css-transitions


            var h = this.element.offsetHeight;


            // hack for JSHint to hush about unused var


            h = null;


        }


        // enable transition


        this.enableTransition( args.to );


        // set styles that are transitioning


        this.css( args.to );





        this.isTransitioning = true;





    };





// dash before all cap letters, including first for


// WebkitTransform => -webkit-transform


    function toDashedAll( str ) {


        return str.replace( /([A-Z])/g, function( $1 ) {


            return '-' + $1.toLowerCase();


        });


    }





    var transitionProps = 'opacity,' + toDashedAll( transformProperty );





    proto.enableTransition = function(/* style */) {


        // HACK changing transitionProperty during a transition


        // will cause transition to jump


        if ( this.isTransitioning ) {


            return;


        }





        // make `transition: foo, bar, baz` from style object


        // HACK un-comment this when enableTransition can work


        // while a transition is happening


        // var transitionValues = [];


        // for ( var prop in style ) {


        //   // dash-ify camelCased properties like WebkitTransition


        //   prop = vendorProperties[ prop ] || prop;


        //   transitionValues.push( toDashedAll( prop ) );


        // }


        // munge number to millisecond, to match stagger


        var duration = this.layout.options.transitionDuration;


        duration = typeof duration == 'number' ? duration + 'ms' : duration;


        // enable transition styles


        this.css({


            transitionProperty: transitionProps,


            transitionDuration: duration,


            transitionDelay: this.staggerDelay || 0


        });


        // listen for transition end event


        this.element.addEventListener( transitionEndEvent, this, false );


    };





// ----- events ----- //





    proto.onwebkitTransitionEnd = function( event ) {


        this.ontransitionend( event );


    };





    proto.onotransitionend = function( event ) {


        this.ontransitionend( event );


    };





// properties that I munge to make my life easier


    var dashedVendorProperties = {


        '-webkit-transform': 'transform'


    };





    proto.ontransitionend = function( event ) {


        // disregard bubbled events from children


        if ( event.target !== this.element ) {


            return;


        }


        var _transition = this._transn;


        // get property name of transitioned property, convert to prefix-free


        var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;





        // remove property that has completed transitioning


        delete _transition.ingProperties[ propertyName ];


        // check if any properties are still transitioning


        if ( isEmptyObj( _transition.ingProperties ) ) {


            // all properties have completed transitioning


            this.disableTransition();


        }


        // clean style


        if ( propertyName in _transition.clean ) {


            // clean up style


            this.element.style[ event.propertyName ] = '';


            delete _transition.clean[ propertyName ];


        }


        // trigger onTransitionEnd callback


        if ( propertyName in _transition.onEnd ) {


            var onTransitionEnd = _transition.onEnd[ propertyName ];


            onTransitionEnd.call( this );


            delete _transition.onEnd[ propertyName ];


        }





        this.emitEvent( 'transitionEnd', [ this ] );


    };





    proto.disableTransition = function() {


        this.removeTransitionStyles();


        this.element.removeEventListener( transitionEndEvent, this, false );


        this.isTransitioning = false;


    };





    /**


     * removes style property from element


     * @param {Object} style


     **/


    proto._removeStyles = function( style ) {


        // clean up transition styles


        var cleanStyle = {};


        for ( var prop in style ) {


            cleanStyle[ prop ] = '';


        }


        this.css( cleanStyle );


    };





    var cleanTransitionStyle = {


        transitionProperty: '',


        transitionDuration: '',


        transitionDelay: ''


    };





    proto.removeTransitionStyles = function() {


        // remove transition


        this.css( cleanTransitionStyle );


    };





// ----- stagger ----- //





    proto.stagger = function( delay ) {


        delay = isNaN( delay ) ? 0 : delay;


        this.staggerDelay = delay + 'ms';


    };





// ----- show/hide/remove ----- //





// remove element from DOM


    proto.removeElem = function() {


        this.element.parentNode.removeChild( this.element );


        // remove display: none


        this.css({ display: '' });


        this.emitEvent( 'remove', [ this ] );


    };





    proto.remove = function() {


        // just remove element if no transition support or no transition


        if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {


            this.removeElem();


            return;


        }





        // start transition


        this.once( 'transitionEnd', function() {


            this.removeElem();


        });


        this.hide();


    };





    proto.reveal = function() {


        delete this.isHidden;


        // remove display: none


        this.css({ display: '' });





        var options = this.layout.options;





        var onTransitionEnd = {};


        var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');


        onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;





        this.transition({


            from: options.hiddenStyle,


            to: options.visibleStyle,


            isCleaning: true,


            onTransitionEnd: onTransitionEnd


        });


    };





    proto.onRevealTransitionEnd = function() {


        // check if still visible


        // during transition, item may have been hidden


        if ( !this.isHidden ) {


            this.emitEvent('reveal');


        }


    };





    /**


     * get style property use for hide/reveal transition end


     * @param {String} styleProperty - hiddenStyle/visibleStyle


     * @returns {String}


     */


    proto.getHideRevealTransitionEndProperty = function( styleProperty ) {


        var optionStyle = this.layout.options[ styleProperty ];


        // use opacity


        if ( optionStyle.opacity ) {


            return 'opacity';


        }


        // get first property


        for ( var prop in optionStyle ) {


            return prop;


        }


    };





    proto.hide = function() {


        // set flag


        this.isHidden = true;


        // remove display: none


        this.css({ display: '' });





        var options = this.layout.options;





        var onTransitionEnd = {};


        var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');


        onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;





        this.transition({


            from: options.visibleStyle,


            to: options.hiddenStyle,


            // keep hidden stuff hidden


            isCleaning: true,


            onTransitionEnd: onTransitionEnd


        });


    };





    proto.onHideTransitionEnd = function() {


        // check if still hidden


        // during transition, item may have been un-hidden


        if ( this.isHidden ) {


            this.css({ display: 'none' });


            this.emitEvent('hide');


        }


    };





    proto.destroy = function() {


        this.css({


            position: '',


            left: '',


            right: '',


            top: '',


            bottom: '',


            transition: '',


            transform: ''


        });


    };





    return Item;





}));





/*!


 * Outlayer v2.1.0


 * the brains and guts of a layout library


 * MIT license


 */





( function( window, factory ) {


    'use strict';


    // universal module definition


    /* jshint strict: false */ /* globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD - RequireJS


        define( 'outlayer/outlayer',[


            'ev-emitter/ev-emitter',


            'get-size/get-size',


            'fizzy-ui-utils/utils',


            './item'


        ],


            function( EvEmitter, getSize, utils, Item ) {


                return factory( window, EvEmitter, getSize, utils, Item);


            }


        );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS - Browserify, Webpack


        module.exports = factory(


            window,


            require('ev-emitter'),


            require('get-size'),


            require('fizzy-ui-utils'),


            require('./item')


        );


    } else {


        // browser global


        window.Outlayer = factory(


            window,


            window.EvEmitter,


            window.getSize,


            window.fizzyUIUtils,


            window.Outlayer.Item


        );


    }





}( window, function factory( window, EvEmitter, getSize, utils, Item ) {


    'use strict';





// ----- vars ----- //





    var console = window.console;


    var jQuery = window.jQuery;


    var noop = function() {};





// -------------------------- Outlayer -------------------------- //





// globally unique identifiers


    var GUID = 0;


// internal store of all Outlayer intances


    var instances = {};








    /**


     * @param {Element, String} element


     * @param {Object} options


     * @constructor


     */


    function Outlayer( element, options ) {


        var queryElement = utils.getQueryElement( element );


        if ( !queryElement ) {


            if ( console ) {


                console.error( 'Bad element for ' + this.constructor.namespace +


                    ': ' + ( queryElement || element ) );


            }


            return;


        }


        this.element = queryElement;


        // add jQuery


        if ( jQuery ) {


            this.$element = jQuery( this.element );


        }





        // options


        this.options = utils.extend( {}, this.constructor.defaults );


        this.option( options );





        // add id for Outlayer.getFromElement


        var id = ++GUID;


        this.element.outlayerGUID = id; // expando


        instances[ id ] = this; // associate via id





        // kick it off


        this._create();





        var isInitLayout = this._getOption('initLayout');


        if ( isInitLayout ) {


            this.layout();


        }


    }





// settings are for internal use only


    Outlayer.namespace = 'outlayer';


    Outlayer.Item = Item;





// default options


    Outlayer.defaults = {


        containerStyle: {


            position: 'relative'


        },


        initLayout: true,


        originLeft: true,


        originTop: true,


        resize: true,


        resizeContainer: true,


        // item options


        transitionDuration: '0.4s',


        hiddenStyle: {


            opacity: 0,


            transform: 'scale(0.001)'


        },


        visibleStyle: {


            opacity: 1,


            transform: 'scale(1)'


        }


    };





    var proto = Outlayer.prototype;


// inherit EvEmitter


    utils.extend( proto, EvEmitter.prototype );





    /**


     * set options


     * @param {Object} opts


     */


    proto.option = function( opts ) {


        utils.extend( this.options, opts );


    };





    /**


     * get backwards compatible option value, check old name


     */


    proto._getOption = function( option ) {


        var oldOption = this.constructor.compatOptions[ option ];


        return oldOption && this.options[ oldOption ] !== undefined ?


            this.options[ oldOption ] : this.options[ option ];


    };





    Outlayer.compatOptions = {


        // currentName: oldName


        initLayout: 'isInitLayout',


        horizontal: 'isHorizontal',


        layoutInstant: 'isLayoutInstant',


        originLeft: 'isOriginLeft',


        originTop: 'isOriginTop',


        resize: 'isResizeBound',


        resizeContainer: 'isResizingContainer'


    };





    proto._create = function() {


        // get items from children


        this.reloadItems();


        // elements that affect layout, but are not laid out


        this.stamps = [];


        this.stamp( this.options.stamp );


        // set container style


        utils.extend( this.element.style, this.options.containerStyle );





        // bind resize method


        var canBindResize = this._getOption('resize');


        if ( canBindResize ) {


            this.bindResize();


        }


    };





// goes through all children again and gets bricks in proper order


    proto.reloadItems = function() {


        // collection of item elements


        this.items = this._itemize( this.element.children );


    };








    /**


     * turn elements into Outlayer.Items to be used in layout


     * @param {Array or NodeList or HTMLElement} elems


     * @returns {Array} items - collection of new Outlayer Items


     */


    proto._itemize = function( elems ) {





        var itemElems = this._filterFindItemElements( elems );


        var Item = this.constructor.Item;





        // create new Outlayer Items for collection


        var items = [];


        for ( var i=0; i < itemElems.length; i++ ) {


            var elem = itemElems[i];


            var item = new Item( elem, this );


            items.push( item );


        }





        return items;


    };





    /**


     * get item elements to be used in layout


     * @param {Array or NodeList or HTMLElement} elems


     * @returns {Array} items - item elements


     */


    proto._filterFindItemElements = function( elems ) {


        return utils.filterFindElements( elems, this.options.itemSelector );


    };





    /**


     * getter method for getting item elements


     * @returns {Array} elems - collection of item elements


     */


    proto.getItemElements = function() {


        return this.items.map( function( item ) {


            return item.element;


        });


    };





// ----- init & layout ----- //





    /**


     * lays out all items


     */


    proto.layout = function() {


        this._resetLayout();


        this._manageStamps();





        // don't animate first layout


        var layoutInstant = this._getOption('layoutInstant');


        var isInstant = layoutInstant !== undefined ?


            layoutInstant : !this._isLayoutInited;


        this.layoutItems( this.items, isInstant );





        // flag for initalized


        this._isLayoutInited = true;


    };





// _init is alias for layout


    proto._init = proto.layout;





    /**


     * logic before any new layout


     */


    proto._resetLayout = function() {


        this.getSize();


    };








    proto.getSize = function() {


        this.size = getSize( this.element );


    };





    /**


     * get measurement from option, for columnWidth, rowHeight, gutter


     * if option is String -> get element from selector string, & get size of element


     * if option is Element -> get size of element


     * else use option as a number


     *


     * @param {String} measurement


     * @param {String} size - width or height


     * @private


     */


    proto._getMeasurement = function( measurement, size ) {


        var option = this.options[ measurement ];


        var elem;


        if ( !option ) {


            // default to 0


            this[ measurement ] = 0;


        } else {


            // use option as an element


            if ( typeof option == 'string' ) {


                elem = this.element.querySelector( option );


            } else if ( option instanceof HTMLElement ) {


                elem = option;


            }


            // use size of element, if element


            this[ measurement ] = elem ? getSize( elem )[ size ] : option;


        }


    };





    /**


     * layout a collection of item elements


     * @api public


     */


    proto.layoutItems = function( items, isInstant ) {


        items = this._getItemsForLayout( items );





        this._layoutItems( items, isInstant );





        this._postLayout();


    };





    /**


     * get the items to be laid out


     * you may want to skip over some items


     * @param {Array} items


     * @returns {Array} items


     */


    proto._getItemsForLayout = function( items ) {


        return items.filter( function( item ) {


            return !item.isIgnored;


        });


    };





    /**


     * layout items


     * @param {Array} items


     * @param {Boolean} isInstant


     */


    proto._layoutItems = function( items, isInstant ) {


        this._emitCompleteOnItems( 'layout', items );





        if ( !items || !items.length ) {


            // no items, emit event with empty array


            return;


        }





        var queue = [];





        items.forEach( function( item ) {


            // get x/y object from method


            var position = this._getItemLayoutPosition( item );


            // enqueue


            position.item = item;


            position.isInstant = isInstant || item.isLayoutInstant;


            queue.push( position );


        }, this );





        this._processLayoutQueue( queue );


    };





    /**


     * get item layout position


     * @param {Outlayer.Item} item


     * @returns {Object} x and y position


     */


    proto._getItemLayoutPosition = function( /* item */ ) {


        return {


            x: 0,


            y: 0


        };


    };





    /**


     * iterate over array and position each item


     * Reason being - separating this logic prevents 'layout invalidation'


     * thx @paul_irish


     * @param {Array} queue


     */


    proto._processLayoutQueue = function( queue ) {


        this.updateStagger();


        queue.forEach( function( obj, i ) {


            this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );


        }, this );


    };





// set stagger from option in milliseconds number


    proto.updateStagger = function() {


        var stagger = this.options.stagger;


        if ( stagger === null || stagger === undefined ) {


            this.stagger = 0;


            return;


        }


        this.stagger = getMilliseconds( stagger );


        return this.stagger;


    };





    /**


     * Sets position of item in DOM


     * @param {Outlayer.Item} item


     * @param {Number} x - horizontal position


     * @param {Number} y - vertical position


     * @param {Boolean} isInstant - disables transitions


     */


    proto._positionItem = function( item, x, y, isInstant, i ) {


        if ( isInstant ) {


            // if not transition, just set CSS


            item.goTo( x, y );


        } else {


            item.stagger( i * this.stagger );


            item.moveTo( x, y );


        }


    };





    /**


     * Any logic you want to do after each layout,


     * i.e. size the container


     */


    proto._postLayout = function() {


        this.resizeContainer();


    };





    proto.resizeContainer = function() {


        var isResizingContainer = this._getOption('resizeContainer');


        if ( !isResizingContainer ) {


            return;


        }


        var size = this._getContainerSize();


        if ( size ) {


            this._setContainerMeasure( size.width, true );


            this._setContainerMeasure( size.height, false );


        }


    };





    /**


     * Sets width or height of container if returned


     * @returns {Object} size


     *   @param {Number} width


     *   @param {Number} height


     */


    proto._getContainerSize = noop;





    /**


     * @param {Number} measure - size of width or height


     * @param {Boolean} isWidth


     */


    proto._setContainerMeasure = function( measure, isWidth ) {


        if ( measure === undefined ) {


            return;


        }





        var elemSize = this.size;


        // add padding and border width if border box


        if ( elemSize.isBorderBox ) {


            measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +


                elemSize.borderLeftWidth + elemSize.borderRightWidth :


                elemSize.paddingBottom + elemSize.paddingTop +


                    elemSize.borderTopWidth + elemSize.borderBottomWidth;


        }





        measure = Math.max( measure, 0 );


        this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';


    };





    /**


     * emit eventComplete on a collection of items events


     * @param {String} eventName


     * @param {Array} items - Outlayer.Items


     */


    proto._emitCompleteOnItems = function( eventName, items ) {


        var _this = this;


        function onComplete() {


            _this.dispatchEvent( eventName + 'Complete', null, [ items ] );


        }





        var count = items.length;


        if ( !items || !count ) {


            onComplete();


            return;


        }





        var doneCount = 0;


        function tick() {


            doneCount++;


            if ( doneCount == count ) {


                onComplete();


            }


        }





        // bind callback


        items.forEach( function( item ) {


            item.once( eventName, tick );


        });


    };





    /**


     * emits events via EvEmitter and jQuery events


     * @param {String} type - name of event


     * @param {Event} event - original event


     * @param {Array} args - extra arguments


     */


    proto.dispatchEvent = function( type, event, args ) {


        // add original event to arguments


        var emitArgs = event ? [ event ].concat( args ) : args;


        this.emitEvent( type, emitArgs );





        if ( jQuery ) {


            // set this.$element


            this.$element = this.$element || jQuery( this.element );


            if ( event ) {


                // create jQuery event


                var $event = jQuery.Event( event );


                $event.type = type;


                this.$element.trigger( $event, args );


            } else {


                // just trigger with type if no event available


                this.$element.trigger( type, args );


            }


        }


    };





// -------------------------- ignore & stamps -------------------------- //








    /**


     * keep item in collection, but do not lay it out


     * ignored items do not get skipped in layout


     * @param {Element} elem


     */


    proto.ignore = function( elem ) {


        var item = this.getItem( elem );


        if ( item ) {


            item.isIgnored = true;


        }


    };





    /**


     * return item to layout collection


     * @param {Element} elem


     */


    proto.unignore = function( elem ) {


        var item = this.getItem( elem );


        if ( item ) {


            delete item.isIgnored;


        }


    };





    /**


     * adds elements to stamps


     * @param {NodeList, Array, Element, or String} elems


     */


    proto.stamp = function( elems ) {


        elems = this._find( elems );


        if ( !elems ) {


            return;


        }





        this.stamps = this.stamps.concat( elems );


        // ignore


        elems.forEach( this.ignore, this );


    };





    /**


     * removes elements to stamps


     * @param {NodeList, Array, or Element} elems


     */


    proto.unstamp = function( elems ) {


        elems = this._find( elems );


        if ( !elems ){


            return;


        }





        elems.forEach( function( elem ) {


            // filter out removed stamp elements


            utils.removeFrom( this.stamps, elem );


            this.unignore( elem );


        }, this );


    };





    /**


     * finds child elements


     * @param {NodeList, Array, Element, or String} elems


     * @returns {Array} elems


     */


    proto._find = function( elems ) {


        if ( !elems ) {


            return;


        }


        // if string, use argument as selector string


        if ( typeof elems == 'string' ) {


            elems = this.element.querySelectorAll( elems );


        }


        elems = utils.makeArray( elems );


        return elems;


    };





    proto._manageStamps = function() {


        if ( !this.stamps || !this.stamps.length ) {


            return;


        }





        this._getBoundingRect();





        this.stamps.forEach( this._manageStamp, this );


    };





// update boundingLeft / Top


    proto._getBoundingRect = function() {


        // get bounding rect for container element


        var boundingRect = this.element.getBoundingClientRect();


        var size = this.size;


        this._boundingRect = {


            left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,


            top: boundingRect.top + size.paddingTop + size.borderTopWidth,


            right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),


            bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )


        };


    };





    /**


     * @param {Element} stamp


     **/


    proto._manageStamp = noop;





    /**


     * get x/y position of element relative to container element


     * @param {Element} elem


     * @returns {Object} offset - has left, top, right, bottom


     */


    proto._getElementOffset = function( elem ) {


        var boundingRect = elem.getBoundingClientRect();


        var thisRect = this._boundingRect;


        var size = getSize( elem );


        var offset = {


            left: boundingRect.left - thisRect.left - size.marginLeft,


            top: boundingRect.top - thisRect.top - size.marginTop,


            right: thisRect.right - boundingRect.right - size.marginRight,


            bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom


        };


        return offset;


    };





// -------------------------- resize -------------------------- //





// enable event handlers for listeners


// i.e. resize -> onresize


    proto.handleEvent = utils.handleEvent;





    /**


     * Bind layout to window resizing


     */


    proto.bindResize = function() {


        window.addEventListener( 'resize', this );


        this.isResizeBound = true;


    };





    /**


     * Unbind layout to window resizing


     */


    proto.unbindResize = function() {


        window.removeEventListener( 'resize', this );


        this.isResizeBound = false;


    };





    proto.onresize = function() {


        this.resize();


    };





    utils.debounceMethod( Outlayer, 'onresize', 100 );





    proto.resize = function() {


        // don't trigger if size did not change


        // or if resize was unbound. See #9


        if ( !this.isResizeBound || !this.needsResizeLayout() ) {


            return;


        }





        this.layout();


    };





    /**


     * check if layout is needed post layout


     * @returns Boolean


     */


    proto.needsResizeLayout = function() {


        var size = getSize( this.element );


        // check that this.size and size are there


        // IE8 triggers resize on body size change, so they might not be


        var hasSizes = this.size && size;


        return hasSizes && size.innerWidth !== this.size.innerWidth;


    };





// -------------------------- methods -------------------------- //





    /**


     * add items to Outlayer instance


     * @param {Array or NodeList or Element} elems


     * @returns {Array} items - Outlayer.Items


     **/


    proto.addItems = function( elems ) {


        var items = this._itemize( elems );


        // add items to collection


        if ( items.length ) {


            this.items = this.items.concat( items );


        }


        return items;


    };





    /**


     * Layout newly-appended item elements


     * @param {Array or NodeList or Element} elems


     */


    proto.appended = function( elems ) {


        var items = this.addItems( elems );


        if ( !items.length ) {


            return;


        }


        // layout and reveal just the new items


        this.layoutItems( items, true );


        this.reveal( items );


    };





    /**


     * Layout prepended elements


     * @param {Array or NodeList or Element} elems


     */


    proto.prepended = function( elems ) {


        var items = this._itemize( elems );


        if ( !items.length ) {


            return;


        }


        // add items to beginning of collection


        var previousItems = this.items.slice(0);


        this.items = items.concat( previousItems );


        // start new layout


        this._resetLayout();


        this._manageStamps();


        // layout new stuff without transition


        this.layoutItems( items, true );


        this.reveal( items );


        // layout previous items


        this.layoutItems( previousItems );


    };





    /**


     * reveal a collection of items


     * @param {Array of Outlayer.Items} items


     */


    proto.reveal = function( items ) {


        this._emitCompleteOnItems( 'reveal', items );


        if ( !items || !items.length ) {


            return;


        }


        var stagger = this.updateStagger();


        items.forEach( function( item, i ) {


            item.stagger( i * stagger );


            item.reveal();


        });


    };





    /**


     * hide a collection of items


     * @param {Array of Outlayer.Items} items


     */


    proto.hide = function( items ) {


        this._emitCompleteOnItems( 'hide', items );


        if ( !items || !items.length ) {


            return;


        }


        var stagger = this.updateStagger();


        items.forEach( function( item, i ) {


            item.stagger( i * stagger );


            item.hide();


        });


    };





    /**


     * reveal item elements


     * @param {Array}, {Element}, {NodeList} items


     */


    proto.revealItemElements = function( elems ) {


        var items = this.getItems( elems );


        this.reveal( items );


    };





    /**


     * hide item elements


     * @param {Array}, {Element}, {NodeList} items


     */


    proto.hideItemElements = function( elems ) {


        var items = this.getItems( elems );


        this.hide( items );


    };





    /**


     * get Outlayer.Item, given an Element


     * @param {Element} elem


     * @param {Function} callback


     * @returns {Outlayer.Item} item


     */


    proto.getItem = function( elem ) {


        // loop through items to get the one that matches


        for ( var i=0; i < this.items.length; i++ ) {


            var item = this.items[i];


            if ( item.element == elem ) {


                // return item


                return item;


            }


        }


    };





    /**


     * get collection of Outlayer.Items, given Elements


     * @param {Array} elems


     * @returns {Array} items - Outlayer.Items


     */


    proto.getItems = function( elems ) {


        elems = utils.makeArray( elems );


        var items = [];


        elems.forEach( function( elem ) {


            var item = this.getItem( elem );


            if ( item ) {


                items.push( item );


            }


        }, this );





        return items;


    };





    /**


     * remove element(s) from instance and DOM


     * @param {Array or NodeList or Element} elems


     */


    proto.remove = function( elems ) {


        var removeItems = this.getItems( elems );





        this._emitCompleteOnItems( 'remove', removeItems );





        // bail if no items to remove


        if ( !removeItems || !removeItems.length ) {


            return;


        }





        removeItems.forEach( function( item ) {


            item.remove();


            // remove item from collection


            utils.removeFrom( this.items, item );


        }, this );


    };





// ----- destroy ----- //





// remove and disable Outlayer instance


    proto.destroy = function() {


        // clean up dynamic styles


        var style = this.element.style;


        style.height = '';


        style.position = '';


        style.width = '';


        // destroy items


        this.items.forEach( function( item ) {


            item.destroy();


        });





        this.unbindResize();





        var id = this.element.outlayerGUID;


        delete instances[ id ]; // remove reference to instance by id


        delete this.element.outlayerGUID;


        // remove data for jQuery


        if ( jQuery ) {


            jQuery.removeData( this.element, this.constructor.namespace );


        }





    };





// -------------------------- data -------------------------- //





    /**


     * get Outlayer instance from element


     * @param {Element} elem


     * @returns {Outlayer}


     */


    Outlayer.data = function( elem ) {


        elem = utils.getQueryElement( elem );


        var id = elem && elem.outlayerGUID;


        return id && instances[ id ];


    };








// -------------------------- create Outlayer class -------------------------- //





    /**


     * create a layout class


     * @param {String} namespace


     */


    Outlayer.create = function( namespace, options ) {


        // sub-class Outlayer


        var Layout = subclass( Outlayer );


        // apply new options and compatOptions


        Layout.defaults = utils.extend( {}, Outlayer.defaults );


        utils.extend( Layout.defaults, options );


        Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions  );





        Layout.namespace = namespace;





        Layout.data = Outlayer.data;





        // sub-class Item


        Layout.Item = subclass( Item );





        // -------------------------- declarative -------------------------- //





        utils.htmlInit( Layout, namespace );





        // -------------------------- jQuery bridge -------------------------- //





        // make into jQuery plugin


        if ( jQuery && jQuery.bridget ) {


            jQuery.bridget( namespace, Layout );


        }





        return Layout;


    };





    function subclass( Parent ) {


        function SubClass() {


            Parent.apply( this, arguments );


        }





        SubClass.prototype = Object.create( Parent.prototype );


        SubClass.prototype.constructor = SubClass;





        return SubClass;


    }





// ----- helpers ----- //





// how many milliseconds are in each unit


    var msUnits = {


        ms: 1,


        s: 1000


    };





// munge time-like parameter into millisecond number


// '0.4s' -> 40


    function getMilliseconds( time ) {


        if ( typeof time == 'number' ) {


            return time;


        }


        var matches = time.match( /(^\d*\.?\d*)(\w*)/ );


        var num = matches && matches[1];


        var unit = matches && matches[2];


        if ( !num.length ) {


            return 0;


        }


        num = parseFloat( num );


        var mult = msUnits[ unit ] || 1;


        return num * mult;


    }





// ----- fin ----- //





// back in global


    Outlayer.Item = Item;





    return Outlayer;





}));





/**


 * Rect


 * low-level utility class for basic geometry


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /* globals define, module */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'packery/js/rect',factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory();


    } else {


        // browser global


        window.Packery = window.Packery || {};


        window.Packery.Rect = factory();


    }





}( window, function factory() {


    'use strict';





// -------------------------- Rect -------------------------- //





    function Rect( props ) {


        // extend properties from defaults


        for ( var prop in Rect.defaults ) {


            this[ prop ] = Rect.defaults[ prop ];


        }





        for ( prop in props ) {


            this[ prop ] = props[ prop ];


        }





    }





    Rect.defaults = {


        x: 0,


        y: 0,


        width: 0,


        height: 0


    };





    var proto = Rect.prototype;





    /**


     * Determines whether or not this rectangle wholly encloses another rectangle or point.


     * @param {Rect} rect


     * @returns {Boolean}


     **/


    proto.contains = function( rect ) {


        // points don't have width or height


        var otherWidth = rect.width || 0;


        var otherHeight = rect.height || 0;


        return this.x <= rect.x &&


            this.y <= rect.y &&


            this.x + this.width >= rect.x + otherWidth &&


            this.y + this.height >= rect.y + otherHeight;


    };





    /**


     * Determines whether or not the rectangle intersects with another.


     * @param {Rect} rect


     * @returns {Boolean}


     **/


    proto.overlaps = function( rect ) {


        var thisRight = this.x + this.width;


        var thisBottom = this.y + this.height;


        var rectRight = rect.x + rect.width;


        var rectBottom = rect.y + rect.height;





        // http://stackoverflow.com/a/306332


        return this.x < rectRight &&


            thisRight > rect.x &&


            this.y < rectBottom &&


            thisBottom > rect.y;


    };





    /**


     * @param {Rect} rect - the overlapping rect


     * @returns {Array} freeRects - rects representing the area around the rect


     **/


    proto.getMaximalFreeRects = function( rect ) {





        // if no intersection, return false


        if ( !this.overlaps( rect ) ) {


            return false;


        }





        var freeRects = [];


        var freeRect;





        var thisRight = this.x + this.width;


        var thisBottom = this.y + this.height;


        var rectRight = rect.x + rect.width;


        var rectBottom = rect.y + rect.height;





        // top


        if ( this.y < rect.y ) {


            freeRect = new Rect({


                x: this.x,


                y: this.y,


                width: this.width,


                height: rect.y - this.y


            });


            freeRects.push( freeRect );


        }





        // right


        if ( thisRight > rectRight ) {


            freeRect = new Rect({


                x: rectRight,


                y: this.y,


                width: thisRight - rectRight,


                height: this.height


            });


            freeRects.push( freeRect );


        }





        // bottom


        if ( thisBottom > rectBottom ) {


            freeRect = new Rect({


                x: this.x,


                y: rectBottom,


                width: this.width,


                height: thisBottom - rectBottom


            });


            freeRects.push( freeRect );


        }





        // left


        if ( this.x < rect.x ) {


            freeRect = new Rect({


                x: this.x,


                y: this.y,


                width: rect.x - this.x,


                height: this.height


            });


            freeRects.push( freeRect );


        }





        return freeRects;


    };





    proto.canFit = function( rect ) {


        return this.width >= rect.width && this.height >= rect.height;


    };





    return Rect;





}));





/**


 * Packer


 * bin-packing algorithm


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /* globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'packery/js/packer',[ './rect' ], factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            require('./rect')


        );


    } else {


        // browser global


        var Packery = window.Packery = window.Packery || {};


        Packery.Packer = factory( Packery.Rect );


    }





}( window, function factory( Rect ) {


    'use strict';





// -------------------------- Packer -------------------------- //





    /**


     * @param {Number} width


     * @param {Number} height


     * @param {String} sortDirection


     *   topLeft for vertical, leftTop for horizontal


     */


    function Packer( width, height, sortDirection ) {


        this.width = width || 0;


        this.height = height || 0;


        this.sortDirection = sortDirection || 'downwardLeftToRight';





        this.reset();


    }





    var proto = Packer.prototype;





    proto.reset = function() {


        this.spaces = [];





        var initialSpace = new Rect({


            x: 0,


            y: 0,


            width: this.width,


            height: this.height


        });





        this.spaces.push( initialSpace );


        // set sorter


        this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight;


    };





// change x and y of rect to fit with in Packer's available spaces


    proto.pack = function( rect ) {


        for ( var i=0; i < this.spaces.length; i++ ) {


            var space = this.spaces[i];


            if ( space.canFit( rect ) ) {


                this.placeInSpace( rect, space );


                break;


            }


        }


    };





    proto.columnPack = function( rect ) {


        for ( var i=0; i < this.spaces.length; i++ ) {


            var space = this.spaces[i];


            var canFitInSpaceColumn = space.x <= rect.x &&


                space.x + space.width >= rect.x + rect.width &&


                space.height >= rect.height - 0.01; // fudge number for rounding error


            if ( canFitInSpaceColumn ) {


                rect.y = space.y;


                this.placed( rect );


                break;


            }


        }


    };





    proto.rowPack = function( rect ) {


        for ( var i=0; i < this.spaces.length; i++ ) {


            var space = this.spaces[i];


            var canFitInSpaceRow = space.y <= rect.y &&


                space.y + space.height >= rect.y + rect.height &&


                space.width >= rect.width - 0.01; // fudge number for rounding error


            if ( canFitInSpaceRow ) {


                rect.x = space.x;


                this.placed( rect );


                break;


            }


        }


    };





    proto.placeInSpace = function( rect, space ) {


        // place rect in space


        rect.x = space.x;


        rect.y = space.y;





        this.placed( rect );


    };





// update spaces with placed rect


    proto.placed = function( rect ) {


        // update spaces


        var revisedSpaces = [];


        for ( var i=0; i < this.spaces.length; i++ ) {


            var space = this.spaces[i];


            var newSpaces = space.getMaximalFreeRects( rect );


            // add either the original space or the new spaces to the revised spaces


            if ( newSpaces ) {


                revisedSpaces.push.apply( revisedSpaces, newSpaces );


            } else {


                revisedSpaces.push( space );


            }


        }





        this.spaces = revisedSpaces;





        this.mergeSortSpaces();


    };





    proto.mergeSortSpaces = function() {


        // remove redundant spaces


        Packer.mergeRects( this.spaces );


        this.spaces.sort( this.sorter );


    };





// add a space back


    proto.addSpace = function( rect ) {


        this.spaces.push( rect );


        this.mergeSortSpaces();


    };





// -------------------------- utility functions -------------------------- //





    /**


     * Remove redundant rectangle from array of rectangles


     * @param {Array} rects: an array of Rects


     * @returns {Array} rects: an array of Rects


     **/


    Packer.mergeRects = function( rects ) {


        var i = 0;


        var rect = rects[i];





        rectLoop:


            while ( rect ) {


                var j = 0;


                var compareRect = rects[ i + j ];





                while ( compareRect ) {


                    if  ( compareRect == rect ) {


                        j++; // next


                    } else if ( compareRect.contains( rect ) ) {


                        // remove rect


                        rects.splice( i, 1 );


                        rect = rects[i]; // set next rect


                        continue rectLoop; // bail on compareLoop


                    } else if ( rect.contains( compareRect ) ) {


                        // remove compareRect


                        rects.splice( i + j, 1 );


                    } else {


                        j++;


                    }


                    compareRect = rects[ i + j ]; // set next compareRect


                }


                i++;


                rect = rects[i];


            }





        return rects;


    };








// -------------------------- sorters -------------------------- //





// functions for sorting rects in order


    var sorters = {


        // top down, then left to right


        downwardLeftToRight: function( a, b ) {


            return a.y - b.y || a.x - b.x;


        },


        // left to right, then top down


        rightwardTopToBottom: function( a, b ) {


            return a.x - b.x || a.y - b.y;


        }


    };








// --------------------------  -------------------------- //





    return Packer;





}));





/**


 * Packery Item Element


 **/





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /* globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'packery/js/item',[


            'outlayer/outlayer',


            './rect'


        ],


            factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            require('outlayer'),


            require('./rect')


        );


    } else {


        // browser global


        window.Packery.Item = factory(


            window.Outlayer,


            window.Packery.Rect


        );


    }





}( window, function factory( Outlayer, Rect ) {


    'use strict';





// -------------------------- Item -------------------------- //





    var docElemStyle = document.documentElement.style;





    var transformProperty = typeof docElemStyle.transform == 'string' ?


        'transform' : 'WebkitTransform';





// sub-class Item


    var Item = function PackeryItem() {


        Outlayer.Item.apply( this, arguments );


    };





    var proto = Item.prototype = Object.create( Outlayer.Item.prototype );





    var __create = proto._create;


    proto._create = function() {


        // call default _create logic


        __create.call( this );


        this.rect = new Rect();


    };





    var _moveTo = proto.moveTo;


    proto.moveTo = function( x, y ) {


        // don't shift 1px while dragging


        var dx = Math.abs( this.position.x - x );


        var dy = Math.abs( this.position.y - y );





        var canHackGoTo = this.layout.dragItemCount && !this.isPlacing &&


            !this.isTransitioning && dx < 1 && dy < 1;


        if ( canHackGoTo ) {


            this.goTo( x, y );


            return;


        }


        _moveTo.apply( this, arguments );


    };





// -------------------------- placing -------------------------- //





    proto.enablePlacing = function() {


        this.removeTransitionStyles();


        // remove transform property from transition


        if ( this.isTransitioning && transformProperty ) {


            this.element.style[ transformProperty ] = 'none';


        }


        this.isTransitioning = false;


        this.getSize();


        this.layout._setRectSize( this.element, this.rect );


        this.isPlacing = true;


    };





    proto.disablePlacing = function() {


        this.isPlacing = false;


    };





// -----  ----- //





// remove element from DOM


    proto.removeElem = function() {


        this.element.parentNode.removeChild( this.element );


        // add space back to packer


        this.layout.packer.addSpace( this.rect );


        this.emitEvent( 'remove', [ this ] );


    };





// ----- dropPlaceholder ----- //





    proto.showDropPlaceholder = function() {


        var dropPlaceholder = this.dropPlaceholder;


        if ( !dropPlaceholder ) {


            // create dropPlaceholder


            dropPlaceholder = this.dropPlaceholder = document.createElement('div');


            dropPlaceholder.className = 'packery-drop-placeholder';


            dropPlaceholder.style.position = 'absolute';


        }





        dropPlaceholder.style.width = this.size.width + 'px';


        dropPlaceholder.style.height = this.size.height + 'px';


        this.positionDropPlaceholder();


        this.layout.element.appendChild( dropPlaceholder );


    };





    proto.positionDropPlaceholder = function() {


        this.dropPlaceholder.style[ transformProperty ] = 'translate(' +


            this.rect.x + 'px, ' + this.rect.y + 'px)';


    };





    proto.hideDropPlaceholder = function() {


        // only remove once, #333


        var parent = this.dropPlaceholder.parentNode;


        if ( parent ) {


            parent.removeChild( this.dropPlaceholder );


        }


    };





// -----  ----- //





    return Item;





}));





/*!


 * Packery v2.1.1


 * Gapless, draggable grid layouts


 *


 * Licensed GPLv3 for open source use


 * or Packery Commercial License for commercial use


 *


 * http://packery.metafizzy.co


 * Copyright 2016 Metafizzy


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /* globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( [


            'get-size/get-size',


            'outlayer/outlayer',


            'packery/js/rect',


            'packery/js/packer',


            'packery/js/item'


        ],


            factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            require('get-size'),


            require('outlayer'),


            require('./rect'),


            require('./packer'),


            require('./item')


        );


    } else {


        // browser global


        window.Packery = factory(


            window.getSize,


            window.Outlayer,


            window.Packery.Rect,


            window.Packery.Packer,


            window.Packery.Item


        );


    }





}( window, function factory( getSize, Outlayer, Rect, Packer, Item ) {


    'use strict';





// ----- Rect ----- //





// allow for pixel rounding errors IE8-IE11 & Firefox; #227


    Rect.prototype.canFit = function( rect ) {


        return this.width >= rect.width - 1 && this.height >= rect.height - 1;


    };





// -------------------------- Packery -------------------------- //





// create an Outlayer layout class


    var Packery = Outlayer.create('packery');


    Packery.Item = Item;





    var proto = Packery.prototype;





    proto._create = function() {


        // call super


        Outlayer.prototype._create.call( this );





        // initial properties


        this.packer = new Packer();


        // packer for drop targets


        this.shiftPacker = new Packer();


        this.isEnabled = true;





        this.dragItemCount = 0;





        // create drag handlers


        var _this = this;


        this.handleDraggabilly = {


            dragStart: function() {


                _this.itemDragStart( this.element );


            },


            dragMove: function() {


                _this.itemDragMove( this.element, this.position.x, this.position.y );


            },


            dragEnd: function() {


                _this.itemDragEnd( this.element );


            }


        };





        this.handleUIDraggable = {


            start: function handleUIDraggableStart( event, ui ) {


                // HTML5 may trigger dragstart, dismiss HTML5 dragging


                if ( !ui ) {


                    return;


                }


                _this.itemDragStart( event.currentTarget );


            },


            drag: function handleUIDraggableDrag( event, ui ) {


                if ( !ui ) {


                    return;


                }


                _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top );


            },


            stop: function handleUIDraggableStop( event, ui ) {


                if ( !ui ) {


                    return;


                }


                _this.itemDragEnd( event.currentTarget );


            }


        };





    };








// ----- init & layout ----- //





    /**


     * logic before any new layout


     */


    proto._resetLayout = function() {


        this.getSize();





        this._getMeasurements();





        // reset packer


        var width, height, sortDirection;


        // packer settings, if horizontal or vertical


        if ( this._getOption('horizontal') ) {


            width = Infinity;


            height = this.size.innerHeight + this.gutter;


            sortDirection = 'rightwardTopToBottom';


        } else {


            width = this.size.innerWidth + this.gutter;


            height = Infinity;


            sortDirection = 'downwardLeftToRight';


        }





        this.packer.width = this.shiftPacker.width = width;


        this.packer.height = this.shiftPacker.height = height;


        this.packer.sortDirection = this.shiftPacker.sortDirection = sortDirection;





        this.packer.reset();





        // layout


        this.maxY = 0;


        this.maxX = 0;


    };





    /**


     * update columnWidth, rowHeight, & gutter


     * @private


     */


    proto._getMeasurements = function() {


        this._getMeasurement( 'columnWidth', 'width' );


        this._getMeasurement( 'rowHeight', 'height' );


        this._getMeasurement( 'gutter', 'width' );


    };





    proto._getItemLayoutPosition = function( item ) {


        this._setRectSize( item.element, item.rect );


        if ( this.isShifting || this.dragItemCount > 0 ) {


            var packMethod = this._getPackMethod();


            this.packer[ packMethod ]( item.rect );


        } else {


            this.packer.pack( item.rect );


        }





        this._setMaxXY( item.rect );


        return item.rect;


    };





    proto.shiftLayout = function() {


        this.isShifting = true;


        this.layout();


        delete this.isShifting;


    };





    proto._getPackMethod = function() {


        return this._getOption('horizontal') ? 'rowPack' : 'columnPack';


    };








    /**


     * set max X and Y value, for size of container


     * @param {Packery.Rect} rect


     * @private


     */


    proto._setMaxXY = function( rect ) {


        this.maxX = Math.max( rect.x + rect.width, this.maxX );


        this.maxY = Math.max( rect.y + rect.height, this.maxY );


    };





    /**


     * set the width and height of a rect, applying columnWidth and rowHeight


     * @param {Element} elem


     * @param {Packery.Rect} rect


     */


    proto._setRectSize = function( elem, rect ) {


        var size = getSize( elem );


        var w = size.outerWidth;


        var h = size.outerHeight;


        // size for columnWidth and rowHeight, if available


        // only check if size is non-zero, #177


        if ( w || h ) {


            w = this._applyGridGutter( w, this.columnWidth );


            h = this._applyGridGutter( h, this.rowHeight );


        }


        // rect must fit in packer


        rect.width = Math.min( w, this.packer.width );


        rect.height = Math.min( h, this.packer.height );


    };





    /**


     * fits item to columnWidth/rowHeight and adds gutter


     * @param {Number} measurement - item width or height


     * @param {Number} gridSize - columnWidth or rowHeight


     * @returns measurement


     */


    proto._applyGridGutter = function( measurement, gridSize ) {


        // just add gutter if no gridSize


        if ( !gridSize ) {


            return measurement + this.gutter;


        }


        gridSize += this.gutter;


        // fit item to columnWidth/rowHeight


        var remainder = measurement % gridSize;


        var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';


        measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize;


        return measurement;


    };





    proto._getContainerSize = function() {


        if ( this._getOption('horizontal') ) {


            return {


                width: this.maxX - this.gutter


            };


        } else {


            return {


                height: this.maxY - this.gutter


            };


        }


    };








// -------------------------- stamp -------------------------- //





    /**


     * makes space for element


     * @param {Element} elem


     */


    proto._manageStamp = function( elem ) {





        var item = this.getItem( elem );


        var rect;


        if ( item && item.isPlacing ) {


            rect = item.rect;


        } else {


            var offset = this._getElementOffset( elem );


            rect = new Rect({


                x: this._getOption('originLeft') ? offset.left : offset.right,


                y: this._getOption('originTop') ? offset.top : offset.bottom


            });


        }





        this._setRectSize( elem, rect );


        // save its space in the packer


        this.packer.placed( rect );


        this._setMaxXY( rect );


    };





// -------------------------- methods -------------------------- //





    function verticalSorter( a, b ) {


        return a.position.y - b.position.y || a.position.x - b.position.x;


    }





    function horizontalSorter( a, b ) {


        return a.position.x - b.position.x || a.position.y - b.position.y;


    }





    proto.sortItemsByPosition = function() {


        var sorter = this._getOption('horizontal') ? horizontalSorter : verticalSorter;


        this.items.sort( sorter );


    };





    /**


     * Fit item element in its current position


     * Packery will position elements around it


     * useful for expanding elements


     *


     * @param {Element} elem


     * @param {Number} x - horizontal destination position, optional


     * @param {Number} y - vertical destination position, optional


     */


    proto.fit = function( elem, x, y ) {


        var item = this.getItem( elem );


        if ( !item ) {


            return;


        }





        // stamp item to get it out of layout


        this.stamp( item.element );


        // set placing flag


        item.enablePlacing();


        this.updateShiftTargets( item );


        // fall back to current position for fitting


        x = x === undefined ? item.rect.x: x;


        y = y === undefined ? item.rect.y: y;


        // position it best at its destination


        this.shift( item, x, y );


        this._bindFitEvents( item );


        item.moveTo( item.rect.x, item.rect.y );


        // layout everything else


        this.shiftLayout();


        // return back to regularly scheduled programming


        this.unstamp( item.element );


        this.sortItemsByPosition();


        item.disablePlacing();


    };





    /**


     * emit event when item is fit and other items are laid out


     * @param {Packery.Item} item


     * @private


     */


    proto._bindFitEvents = function( item ) {


        var _this = this;


        var ticks = 0;


        function onLayout() {


            ticks++;


            if ( ticks != 2 ) {


                return;


            }


            _this.dispatchEvent( 'fitComplete', null, [ item ] );


        }


        // when item is laid out


        item.once( 'layout', onLayout );


        // when all items are laid out


        this.once( 'layoutComplete', onLayout );


    };





// -------------------------- resize -------------------------- //





// debounced, layout on resize


    proto.resize = function() {


        // don't trigger if size did not change


        // or if resize was unbound. See #285, outlayer#9


        if ( !this.isResizeBound || !this.needsResizeLayout() ) {


            return;


        }





        if ( this.options.shiftPercentResize ) {


            this.resizeShiftPercentLayout();


        } else {


            this.layout();


        }


    };





    /**


     * check if layout is needed post layout


     * @returns Boolean


     */


    proto.needsResizeLayout = function() {


        var size = getSize( this.element );


        var innerSize = this._getOption('horizontal') ? 'innerHeight' : 'innerWidth';


        return size[ innerSize ] != this.size[ innerSize ];


    };





    proto.resizeShiftPercentLayout = function() {


        var items = this._getItemsForLayout( this.items );





        var isHorizontal = this._getOption('horizontal');


        var coord = isHorizontal ? 'y' : 'x';


        var measure = isHorizontal ? 'height' : 'width';


        var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth';


        var innerSize = isHorizontal ? 'innerHeight' : 'innerWidth';





        // proportional re-align items


        var previousSegment = this[ segmentName ];


        previousSegment = previousSegment && previousSegment + this.gutter;





        if ( previousSegment ) {


            this._getMeasurements();


            var currentSegment = this[ segmentName ] + this.gutter;


            items.forEach( function( item ) {


                var seg = Math.round( item.rect[ coord ] / previousSegment );


                item.rect[ coord ] = seg * currentSegment;


            });


        } else {


            var currentSize = getSize( this.element )[ innerSize ] + this.gutter;


            var previousSize = this.packer[ measure ];


            items.forEach( function( item ) {


                item.rect[ coord ] = ( item.rect[ coord ] / previousSize ) * currentSize;


            });


        }





        this.shiftLayout();


    };





// -------------------------- drag -------------------------- //





    /**


     * handle an item drag start event


     * @param {Element} elem


     */


    proto.itemDragStart = function( elem ) {


        if ( !this.isEnabled ) {


            return;


        }


        this.stamp( elem );


        // this.ignore( elem );


        var item = this.getItem( elem );


        if ( !item ) {


            return;


        }





        item.enablePlacing();


        item.showDropPlaceholder();


        this.dragItemCount++;


        this.updateShiftTargets( item );


    };





    proto.updateShiftTargets = function( dropItem ) {


        this.shiftPacker.reset();





        // pack stamps


        this._getBoundingRect();


        var isOriginLeft = this._getOption('originLeft');


        var isOriginTop = this._getOption('originTop');


        this.stamps.forEach( function( stamp ) {


            // ignore dragged item


            var item = this.getItem( stamp );


            if ( item && item.isPlacing ) {


                return;


            }


            var offset = this._getElementOffset( stamp );


            var rect = new Rect({


                x: isOriginLeft ? offset.left : offset.right,


                y: isOriginTop ? offset.top : offset.bottom


            });


            this._setRectSize( stamp, rect );


            // save its space in the packer


            this.shiftPacker.placed( rect );


        }, this );





        // reset shiftTargets


        var isHorizontal = this._getOption('horizontal');


        var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth';


        var measure = isHorizontal ? 'height' : 'width';





        this.shiftTargetKeys = [];


        this.shiftTargets = [];


        var boundsSize;


        var segment = this[ segmentName ];


        segment = segment && segment + this.gutter;





        if ( segment ) {


            var segmentSpan = Math.ceil( dropItem.rect[ measure ] / segment );


            var segs = Math.floor( ( this.shiftPacker[ measure ] + this.gutter ) / segment );


            boundsSize = ( segs - segmentSpan ) * segment;


            // add targets on top


            for ( var i=0; i < segs; i++ ) {


                var initialX = isHorizontal ? 0 : i * segment;


                var initialY = isHorizontal ? i * segment : 0;


                this._addShiftTarget( initialX, initialY, boundsSize );


            }


        } else {


            boundsSize = ( this.shiftPacker[ measure ] + this.gutter ) - dropItem.rect[ measure ];


            this._addShiftTarget( 0, 0, boundsSize );


        }





        // pack each item to measure where shiftTargets are


        var items = this._getItemsForLayout( this.items );


        var packMethod = this._getPackMethod();


        items.forEach( function( item ) {


            var rect = item.rect;


            this._setRectSize( item.element, rect );


            this.shiftPacker[ packMethod ]( rect );





            // add top left corner


            this._addShiftTarget( rect.x, rect.y, boundsSize );


            // add bottom left / top right corner


            var cornerX = isHorizontal ? rect.x + rect.width : rect.x;


            var cornerY = isHorizontal ? rect.y : rect.y + rect.height;


            this._addShiftTarget( cornerX, cornerY, boundsSize );





            if ( segment ) {


                // add targets for each column on bottom / row on right


                var segSpan = Math.round( rect[ measure ] / segment );


                for ( var i=1; i < segSpan; i++ ) {


                    var segX = isHorizontal ? cornerX : rect.x + segment * i;


                    var segY = isHorizontal ? rect.y + segment * i : cornerY;


                    this._addShiftTarget( segX, segY, boundsSize );


                }


            }


        }, this );





    };





    proto._addShiftTarget = function( x, y, boundsSize ) {


        var checkCoord = this._getOption('horizontal') ? y : x;


        if ( checkCoord !== 0 && checkCoord > boundsSize ) {


            return;


        }


        // create string for a key, easier to keep track of what targets


        var key = x + ',' + y;


        var hasKey = this.shiftTargetKeys.indexOf( key ) != -1;


        if ( hasKey ) {


            return;


        }


        this.shiftTargetKeys.push( key );


        this.shiftTargets.push({ x: x, y: y });


    };





// -------------------------- drop -------------------------- //





    proto.shift = function( item, x, y ) {


        var shiftPosition;


        var minDistance = Infinity;


        var position = { x: x, y: y };


        this.shiftTargets.forEach( function( target ) {


            var distance = getDistance( target, position );


            if ( distance < minDistance ) {


                shiftPosition = target;


                minDistance = distance;


            }


        });


        item.rect.x = shiftPosition.x;


        item.rect.y = shiftPosition.y;


    };





    function getDistance( a, b ) {


        var dx = b.x - a.x;


        var dy = b.y - a.y;


        return Math.sqrt( dx * dx + dy * dy );


    }





// -------------------------- drag move -------------------------- //





    var DRAG_THROTTLE_TIME = 120;





    /**


     * handle an item drag move event


     * @param {Element} elem


     * @param {Number} x - horizontal change in position


     * @param {Number} y - vertical change in position


     */


    proto.itemDragMove = function( elem, x, y ) {


        var item = this.isEnabled && this.getItem( elem );


        if ( !item ) {


            return;


        }





        x -= this.size.paddingLeft;


        y -= this.size.paddingTop;





        var _this = this;


        function onDrag() {


            _this.shift( item, x, y );


            item.positionDropPlaceholder();


            _this.layout();


        }





        // throttle


        var now = new Date();


        if ( this._itemDragTime && now - this._itemDragTime < DRAG_THROTTLE_TIME ) {


            clearTimeout( this.dragTimeout );


            this.dragTimeout = setTimeout( onDrag, DRAG_THROTTLE_TIME );


        } else {


            onDrag();


            this._itemDragTime = now;


        }


    };





// -------------------------- drag end -------------------------- //





    /**


     * handle an item drag end event


     * @param {Element} elem


     */


    proto.itemDragEnd = function( elem ) {


        var item = this.isEnabled && this.getItem( elem );


        if ( !item ) {


            return;


        }





        clearTimeout( this.dragTimeout );


        item.element.classList.add('is-positioning-post-drag');





        var completeCount = 0;


        var _this = this;


        function onDragEndLayoutComplete() {


            completeCount++;


            if ( completeCount != 2 ) {


                return;


            }


            // reset drag item


            item.element.classList.remove('is-positioning-post-drag');


            item.hideDropPlaceholder();


            _this.dispatchEvent( 'dragItemPositioned', null, [ item ] );


        }





        item.once( 'layout', onDragEndLayoutComplete );


        this.once( 'layoutComplete', onDragEndLayoutComplete );


        item.moveTo( item.rect.x, item.rect.y );


        this.layout();


        this.dragItemCount = Math.max( 0, this.dragItemCount - 1 );


        this.sortItemsByPosition();


        item.disablePlacing();


        this.unstamp( item.element );


    };





    /**


     * binds Draggabilly events


     * @param {Draggabilly} draggie


     */


    proto.bindDraggabillyEvents = function( draggie ) {


        this._bindDraggabillyEvents( draggie, 'on' );


    };





    proto.unbindDraggabillyEvents = function( draggie ) {


        this._bindDraggabillyEvents( draggie, 'off' );


    };





    proto._bindDraggabillyEvents = function( draggie, method ) {


        var handlers = this.handleDraggabilly;


        draggie[ method ]( 'dragStart', handlers.dragStart );


        draggie[ method ]( 'dragMove', handlers.dragMove );


        draggie[ method ]( 'dragEnd', handlers.dragEnd );


    };





    /**


     * binds jQuery UI Draggable events


     * @param {jQuery} $elems


     */


    proto.bindUIDraggableEvents = function( $elems ) {


        this._bindUIDraggableEvents( $elems, 'on' );


    };





    proto.unbindUIDraggableEvents = function( $elems ) {


        this._bindUIDraggableEvents( $elems, 'off' );


    };





    proto._bindUIDraggableEvents = function( $elems, method ) {


        var handlers = this.handleUIDraggable;


        $elems


            [ method ]( 'dragstart', handlers.start )


            [ method ]( 'drag', handlers.drag )


            [ method ]( 'dragstop', handlers.stop );


    };





// ----- destroy ----- //





    var _destroy = proto.destroy;


    proto.destroy = function() {


        _destroy.apply( this, arguments );


        // disable flag; prevent drag events from triggering. #72


        this.isEnabled = false;


    };





// -----  ----- //





    Packery.Rect = Rect;


    Packery.Packer = Packer;





    return Packery;





}));






/*!


 * Isotope PACKAGED v3.0.1


 *


 * Licensed GPLv3 for open source use


 * or Isotope Commercial License for commercial use


 *


 * http://isotope.metafizzy.co


 * Copyright 2016 Metafizzy


 */





/**


 * Bridget makes jQuery widgets


 * v2.0.0


 * MIT license


 */





/* jshint browser: true, strict: true, undef: true, unused: true */





( function( window, factory ) {


    'use strict';


    /* globals define: false, module: false, require: false */





    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {


            factory( window, jQuery );


        });


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            window,


            require('jquery')


        );


    } else {


        // browser global


        window.jQueryBridget = factory(


            window,


            window.jQuery


        );


    }





}( window, function factory( window, jQuery ) {


    'use strict';





// ----- utils ----- //





    var arraySlice = Array.prototype.slice;





// helper function for logging errors


// $.error breaks jQuery chaining


    var console = window.console;


    var logError = typeof console == 'undefined' ? function() {} :


        function( message ) {


            console.error( message );


        };





// ----- jQueryBridget ----- //





    function jQueryBridget( namespace, PluginClass, $ ) {


        $ = $ || jQuery || window.jQuery;


        if ( !$ ) {


            return;


        }





        // add option method -> $().plugin('option', {...})


        if ( !PluginClass.prototype.option ) {


            // option setter


            PluginClass.prototype.option = function( opts ) {


                // bail out if not an object


                if ( !$.isPlainObject( opts ) ){


                    return;


                }


                this.options = $.extend( true, this.options, opts );


            };


        }





        // make jQuery plugin


        $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {


            if ( typeof arg0 == 'string' ) {


                // method call $().plugin( 'methodName', { options } )


                // shift arguments by 1


                var args = arraySlice.call( arguments, 1 );


                return methodCall( this, arg0, args );


            }


            // just $().plugin({ options })


            plainCall( this, arg0 );


            return this;


        };





        // $().plugin('methodName')


        function methodCall( $elems, methodName, args ) {


            var returnValue;


            var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';





            $elems.each( function( i, elem ) {


                // get instance


                var instance = $.data( elem, namespace );


                if ( !instance ) {


                    logError( namespace + ' not initialized. Cannot call methods, i.e. ' +


                        pluginMethodStr );


                    return;


                }





                var method = instance[ methodName ];


                if ( !method || methodName.charAt(0) == '_' ) {


                    logError( pluginMethodStr + ' is not a valid method' );


                    return;


                }





                // apply method, get return value


                var value = method.apply( instance, args );


                // set return value if value is returned, use only first value


                returnValue = returnValue === undefined ? value : returnValue;


            });





            return returnValue !== undefined ? returnValue : $elems;


        }





        function plainCall( $elems, options ) {


            $elems.each( function( i, elem ) {


                var instance = $.data( elem, namespace );


                if ( instance ) {


                    // set options & init


                    instance.option( options );


                    instance._init();


                } else {


                    // initialize new instance


                    instance = new PluginClass( elem, options );


                    $.data( elem, namespace, instance );


                }


            });


        }





        updateJQuery( $ );





    }





// ----- updateJQuery ----- //





// set $.bridget for v1 backwards compatibility


    function updateJQuery( $ ) {


        if ( !$ || ( $ && $.bridget ) ) {


            return;


        }


        $.bridget = jQueryBridget;


    }





    updateJQuery( jQuery || window.jQuery );





// -----  ----- //





    return jQueryBridget;





}));





/**


 * EvEmitter v1.0.3


 * Lil' event emitter


 * MIT License


 */





/* jshint unused: true, undef: true, strict: true */





( function( global, factory ) {


    // universal module definition


    /* jshint strict: false */ /* globals define, module, window */


    if ( typeof define == 'function' && define.amd ) {


        // AMD - RequireJS


        define( 'ev-emitter/ev-emitter',factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS - Browserify, Webpack


        module.exports = factory();


    } else {


        // Browser globals


        global.EvEmitter = factory();


    }





}( typeof window != 'undefined' ? window : this, function() {











    function EvEmitter() {}





    var proto = EvEmitter.prototype;





    proto.on = function( eventName, listener ) {


        if ( !eventName || !listener ) {


            return;


        }


        // set events hash


        var events = this._events = this._events || {};


        // set listeners array


        var listeners = events[ eventName ] = events[ eventName ] || [];


        // only add once


        if ( listeners.indexOf( listener ) == -1 ) {


            listeners.push( listener );


        }





        return this;


    };





    proto.once = function( eventName, listener ) {


        if ( !eventName || !listener ) {


            return;


        }


        // add event


        this.on( eventName, listener );


        // set once flag


        // set onceEvents hash


        var onceEvents = this._onceEvents = this._onceEvents || {};


        // set onceListeners object


        var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};


        // set flag


        onceListeners[ listener ] = true;





        return this;


    };





    proto.off = function( eventName, listener ) {


        var listeners = this._events && this._events[ eventName ];


        if ( !listeners || !listeners.length ) {


            return;


        }


        var index = listeners.indexOf( listener );


        if ( index != -1 ) {


            listeners.splice( index, 1 );


        }





        return this;


    };





    proto.emitEvent = function( eventName, args ) {


        var listeners = this._events && this._events[ eventName ];


        if ( !listeners || !listeners.length ) {


            return;


        }


        var i = 0;


        var listener = listeners[i];


        args = args || [];


        // once stuff


        var onceListeners = this._onceEvents && this._onceEvents[ eventName ];





        while ( listener ) {


            var isOnce = onceListeners && onceListeners[ listener ];


            if ( isOnce ) {


                // remove listener


                // remove before trigger to prevent recursion


                this.off( eventName, listener );


                // unset once flag


                delete onceListeners[ listener ];


            }


            // trigger listener


            listener.apply( this, args );


            // get next listener


            i += isOnce ? 0 : 1;


            listener = listeners[i];


        }





        return this;


    };





    return EvEmitter;





}));





/*!


 * getSize v2.0.2


 * measure size of elements


 * MIT license


 */





/*jshint browser: true, strict: true, undef: true, unused: true */


/*global define: false, module: false, console: false */





( function( window, factory ) {


    'use strict';





    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'get-size/get-size',[],function() {


            return factory();


        });


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory();


    } else {


        // browser global


        window.getSize = factory();


    }





})( window, function factory() {


    'use strict';





// -------------------------- helpers -------------------------- //





// get a number from a string, not a percentage


    function getStyleSize( value ) {


        var num = parseFloat( value );


        // not a percent like '100%', and a number


        var isValid = value.indexOf('%') == -1 && !isNaN( num );


        return isValid && num;


    }





    function noop() {}





    var logError = typeof console == 'undefined' ? noop :


        function( message ) {


            console.error( message );


        };





// -------------------------- measurements -------------------------- //





    var measurements = [


        'paddingLeft',


        'paddingRight',


        'paddingTop',


        'paddingBottom',


        'marginLeft',


        'marginRight',


        'marginTop',


        'marginBottom',


        'borderLeftWidth',


        'borderRightWidth',


        'borderTopWidth',


        'borderBottomWidth'


    ];





    var measurementsLength = measurements.length;





    function getZeroSize() {


        var size = {


            width: 0,


            height: 0,


            innerWidth: 0,


            innerHeight: 0,


            outerWidth: 0,


            outerHeight: 0


        };


        for ( var i=0; i < measurementsLength; i++ ) {


            var measurement = measurements[i];


            size[ measurement ] = 0;


        }


        return size;


    }





// -------------------------- getStyle -------------------------- //





    /**


     * getStyle, get style of element, check for Firefox bug


     * https://bugzilla.mozilla.org/show_bug.cgi?id=548397


     */


    function getStyle( elem ) {


        var style = getComputedStyle( elem );


        if ( !style ) {


            logError( 'Style returned ' + style +


                '. Are you running this code in a hidden iframe on Firefox? ' +


                'See http://bit.ly/getsizebug1' );


        }


        return style;


    }





// -------------------------- setup -------------------------- //





    var isSetup = false;





    var isBoxSizeOuter;





    /**


     * setup


     * check isBoxSizerOuter


     * do on first getSize() rather than on page load for Firefox bug


     */


    function setup() {


        // setup once


        if ( isSetup ) {


            return;


        }


        isSetup = true;





        // -------------------------- box sizing -------------------------- //





        /**


         * WebKit measures the outer-width on style.width on border-box elems


         * IE & Firefox<29 measures the inner-width


         */


        var div = document.createElement('div');


        div.style.width = '200px';


        div.style.padding = '1px 2px 3px 4px';


        div.style.borderStyle = 'solid';


        div.style.borderWidth = '1px 2px 3px 4px';


        div.style.boxSizing = 'border-box';





        var body = document.body || document.documentElement;


        body.appendChild( div );


        var style = getStyle( div );





        getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200;


        body.removeChild( div );





    }





// -------------------------- getSize -------------------------- //





    function getSize( elem ) {


        setup();





        // use querySeletor if elem is string


        if ( typeof elem == 'string' ) {


            elem = document.querySelector( elem );


        }





        // do not proceed on non-objects


        if ( !elem || typeof elem != 'object' || !elem.nodeType ) {


            return;


        }





        var style = getStyle( elem );





        // if hidden, everything is 0


        if ( style.display == 'none' ) {


            return getZeroSize();


        }





        var size = {};


        size.width = elem.offsetWidth;


        size.height = elem.offsetHeight;





        var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';





        // get all measurements


        for ( var i=0; i < measurementsLength; i++ ) {


            var measurement = measurements[i];


            var value = style[ measurement ];


            var num = parseFloat( value );


            // any 'auto', 'medium' value will be 0


            size[ measurement ] = !isNaN( num ) ? num : 0;


        }





        var paddingWidth = size.paddingLeft + size.paddingRight;


        var paddingHeight = size.paddingTop + size.paddingBottom;


        var marginWidth = size.marginLeft + size.marginRight;


        var marginHeight = size.marginTop + size.marginBottom;


        var borderWidth = size.borderLeftWidth + size.borderRightWidth;


        var borderHeight = size.borderTopWidth + size.borderBottomWidth;





        var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;





        // overwrite width and height if we can get it from style


        var styleWidth = getStyleSize( style.width );


        if ( styleWidth !== false ) {


            size.width = styleWidth +


                // add padding and border unless it's already including it


                ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );


        }





        var styleHeight = getStyleSize( style.height );


        if ( styleHeight !== false ) {


            size.height = styleHeight +


                // add padding and border unless it's already including it


                ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );


        }





        size.innerWidth = size.width - ( paddingWidth + borderWidth );


        size.innerHeight = size.height - ( paddingHeight + borderHeight );





        size.outerWidth = size.width + marginWidth;


        size.outerHeight = size.height + marginHeight;





        return size;


    }





    return getSize;





});





/**


 * matchesSelector v2.0.1


 * matchesSelector( element, '.selector' )


 * MIT license


 */





/*jshint browser: true, strict: true, undef: true, unused: true */





( function( window, factory ) {


    /*global define: false, module: false */


    'use strict';


    // universal module definition


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'desandro-matches-selector/matches-selector',factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory();


    } else {


        // browser global


        window.matchesSelector = factory();


    }





}( window, function factory() {


    'use strict';





    var matchesMethod = ( function() {


        var ElemProto = Element.prototype;


        // check for the standard method name first


        if ( ElemProto.matches ) {


            return 'matches';


        }


        // check un-prefixed


        if ( ElemProto.matchesSelector ) {


            return 'matchesSelector';


        }


        // check vendor prefixes


        var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];





        for ( var i=0; i < prefixes.length; i++ ) {


            var prefix = prefixes[i];


            var method = prefix + 'MatchesSelector';


            if ( ElemProto[ method ] ) {


                return method;


            }


        }


    })();





    return function matchesSelector( elem, selector ) {


        return elem[ matchesMethod ]( selector );


    };





}));





/**


 * Fizzy UI utils v2.0.2


 * MIT license


 */





/*jshint browser: true, undef: true, unused: true, strict: true */





( function( window, factory ) {


    // universal module definition


    /*jshint strict: false */ /*globals define, module, require */





    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'fizzy-ui-utils/utils',[


            'desandro-matches-selector/matches-selector'


        ], function( matchesSelector ) {


            return factory( window, matchesSelector );


        });


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            window,


            require('desandro-matches-selector')


        );


    } else {


        // browser global


        window.fizzyUIUtils = factory(


            window,


            window.matchesSelector


        );


    }





}( window, function factory( window, matchesSelector ) {











    var utils = {};





// ----- extend ----- //





// extends objects


    utils.extend = function( a, b ) {


        for ( var prop in b ) {


            a[ prop ] = b[ prop ];


        }


        return a;


    };





// ----- modulo ----- //





    utils.modulo = function( num, div ) {


        return ( ( num % div ) + div ) % div;


    };





// ----- makeArray ----- //





// turn element or nodeList into an array


    utils.makeArray = function( obj ) {


        var ary = [];


        if ( Array.isArray( obj ) ) {


            // use object if already an array


            ary = obj;


        } else if ( obj && typeof obj.length == 'number' ) {


            // convert nodeList to array


            for ( var i=0; i < obj.length; i++ ) {


                ary.push( obj[i] );


            }


        } else {


            // array of single index


            ary.push( obj );


        }


        return ary;


    };





// ----- removeFrom ----- //





    utils.removeFrom = function( ary, obj ) {


        var index = ary.indexOf( obj );


        if ( index != -1 ) {


            ary.splice( index, 1 );


        }


    };





// ----- getParent ----- //





    utils.getParent = function( elem, selector ) {


        while ( elem != document.body ) {


            elem = elem.parentNode;


            if ( matchesSelector( elem, selector ) ) {


                return elem;


            }


        }


    };





// ----- getQueryElement ----- //





// use element as selector string


    utils.getQueryElement = function( elem ) {


        if ( typeof elem == 'string' ) {


            return document.querySelector( elem );


        }


        return elem;


    };





// ----- handleEvent ----- //





// enable .ontype to trigger from .addEventListener( elem, 'type' )


    utils.handleEvent = function( event ) {


        var method = 'on' + event.type;


        if ( this[ method ] ) {


            this[ method ]( event );


        }


    };





// ----- filterFindElements ----- //





    utils.filterFindElements = function( elems, selector ) {


        // make array of elems


        elems = utils.makeArray( elems );


        var ffElems = [];





        elems.forEach( function( elem ) {


            // check that elem is an actual element


            if ( !( elem instanceof HTMLElement ) ) {


                return;


            }


            // add elem if no selector


            if ( !selector ) {


                ffElems.push( elem );


                return;


            }


            // filter & find items if we have a selector


            // filter


            if ( matchesSelector( elem, selector ) ) {


                ffElems.push( elem );


            }


            // find children


            var childElems = elem.querySelectorAll( selector );


            // concat childElems to filterFound array


            for ( var i=0; i < childElems.length; i++ ) {


                ffElems.push( childElems[i] );


            }


        });





        return ffElems;


    };





// ----- debounceMethod ----- //





    utils.debounceMethod = function( _class, methodName, threshold ) {


        // original method


        var method = _class.prototype[ methodName ];


        var timeoutName = methodName + 'Timeout';





        _class.prototype[ methodName ] = function() {


            var timeout = this[ timeoutName ];


            if ( timeout ) {


                clearTimeout( timeout );


            }


            var args = arguments;





            var _this = this;


            this[ timeoutName ] = setTimeout( function() {


                method.apply( _this, args );


                delete _this[ timeoutName ];


            }, threshold || 100 );


        };


    };





// ----- docReady ----- //





    utils.docReady = function( callback ) {


        var readyState = document.readyState;


        if ( readyState == 'complete' || readyState == 'interactive' ) {


            callback();


        } else {


            document.addEventListener( 'DOMContentLoaded', callback );


        }


    };





// ----- htmlInit ----- //





// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/


    utils.toDashed = function( str ) {


        return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {


            return $1 + '-' + $2;


        }).toLowerCase();


    };





    var console = window.console;


    /**


     * allow user to initialize classes via [data-namespace] or .js-namespace class


     * htmlInit( Widget, 'widgetName' )


     * options are parsed from data-namespace-options


     */


    utils.htmlInit = function( WidgetClass, namespace ) {


        utils.docReady( function() {


            var dashedNamespace = utils.toDashed( namespace );


            var dataAttr = 'data-' + dashedNamespace;


            var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );


            var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );


            var elems = utils.makeArray( dataAttrElems )


                .concat( utils.makeArray( jsDashElems ) );


            var dataOptionsAttr = dataAttr + '-options';


            var jQuery = window.jQuery;





            elems.forEach( function( elem ) {


                var attr = elem.getAttribute( dataAttr ) ||


                    elem.getAttribute( dataOptionsAttr );


                var options;


                try {


                    options = attr && JSON.parse( attr );


                } catch ( error ) {


                    // log error, do not initialize


                    if ( console ) {


                        console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +


                            ': ' + error );


                    }


                    return;


                }


                // initialize


                var instance = new WidgetClass( elem, options );


                // make available via $().data('layoutname')


                if ( jQuery ) {


                    jQuery.data( elem, namespace, instance );


                }


            });





        });


    };





// -----  ----- //





    return utils;





}));





/**


 * Outlayer Item


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /* globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD - RequireJS


        define( 'outlayer/item',[


            'ev-emitter/ev-emitter',


            'get-size/get-size'


        ],


            factory


        );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS - Browserify, Webpack


        module.exports = factory(


            require('ev-emitter'),


            require('get-size')


        );


    } else {


        // browser global


        window.Outlayer = {};


        window.Outlayer.Item = factory(


            window.EvEmitter,


            window.getSize


        );


    }





}( window, function factory( EvEmitter, getSize ) {


    'use strict';





// ----- helpers ----- //





    function isEmptyObj( obj ) {


        for ( var prop in obj ) {


            return false;


        }


        prop = null;


        return true;


    }





// -------------------------- CSS3 support -------------------------- //








    var docElemStyle = document.documentElement.style;





    var transitionProperty = typeof docElemStyle.transition == 'string' ?


        'transition' : 'WebkitTransition';


    var transformProperty = typeof docElemStyle.transform == 'string' ?


        'transform' : 'WebkitTransform';





    var transitionEndEvent = {


        WebkitTransition: 'webkitTransitionEnd',


        transition: 'transitionend'


    }[ transitionProperty ];





// cache all vendor properties that could have vendor prefix


    var vendorProperties = {


        transform: transformProperty,


        transition: transitionProperty,


        transitionDuration: transitionProperty + 'Duration',


        transitionProperty: transitionProperty + 'Property',


        transitionDelay: transitionProperty + 'Delay'


    };





// -------------------------- Item -------------------------- //





    function Item( element, layout ) {


        if ( !element ) {


            return;


        }





        this.element = element;


        // parent layout class, i.e. Masonry, Isotope, or Packery


        this.layout = layout;


        this.position = {


            x: 0,


            y: 0


        };





        this._create();


    }





// inherit EvEmitter


    var proto = Item.prototype = Object.create( EvEmitter.prototype );


    proto.constructor = Item;





    proto._create = function() {


        // transition objects


        this._transn = {


            ingProperties: {},


            clean: {},


            onEnd: {}


        };





        this.css({


            position: 'absolute'


        });


    };





// trigger specified handler for event type


    proto.handleEvent = function( event ) {


        var method = 'on' + event.type;


        if ( this[ method ] ) {


            this[ method ]( event );


        }


    };





    proto.getSize = function() {


        this.size = getSize( this.element );


    };





    /**


     * apply CSS styles to element


     * @param {Object} style


     */


    proto.css = function( style ) {


        var elemStyle = this.element.style;





        for ( var prop in style ) {


            // use vendor property if available


            var supportedProp = vendorProperties[ prop ] || prop;


            elemStyle[ supportedProp ] = style[ prop ];


        }


    };





    // measure position, and sets it


    proto.getPosition = function() {


        var style = getComputedStyle( this.element );


        var isOriginLeft = this.layout._getOption('originLeft');


        var isOriginTop = this.layout._getOption('originTop');


        var xValue = style[ isOriginLeft ? 'left' : 'right' ];


        var yValue = style[ isOriginTop ? 'top' : 'bottom' ];


        // convert percent to pixels


        var layoutSize = this.layout.size;


        var x = xValue.indexOf('%') != -1 ?


            ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );


        var y = yValue.indexOf('%') != -1 ?


            ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );





        // clean up 'auto' or other non-integer values


        x = isNaN( x ) ? 0 : x;


        y = isNaN( y ) ? 0 : y;


        // remove padding from measurement


        x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;


        y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;





        this.position.x = x;


        this.position.y = y;


    };





// set settled position, apply padding


    proto.layoutPosition = function() {


        var layoutSize = this.layout.size;


        var style = {};


        var isOriginLeft = this.layout._getOption('originLeft');


        var isOriginTop = this.layout._getOption('originTop');





        // x


        var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';


        var xProperty = isOriginLeft ? 'left' : 'right';


        var xResetProperty = isOriginLeft ? 'right' : 'left';





        var x = this.position.x + layoutSize[ xPadding ];


        // set in percentage or pixels


        style[ xProperty ] = this.getXValue( x );


        // reset other property


        style[ xResetProperty ] = '';





        // y


        var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';


        var yProperty = isOriginTop ? 'top' : 'bottom';


        var yResetProperty = isOriginTop ? 'bottom' : 'top';





        var y = this.position.y + layoutSize[ yPadding ];


        // set in percentage or pixels


        style[ yProperty ] = this.getYValue( y );


        // reset other property


        style[ yResetProperty ] = '';





        this.css( style );


        this.emitEvent( 'layout', [ this ] );


    };





    proto.getXValue = function( x ) {


        var isHorizontal = this.layout._getOption('horizontal');


        return this.layout.options.percentPosition && !isHorizontal ?


            ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';


    };





    proto.getYValue = function( y ) {


        var isHorizontal = this.layout._getOption('horizontal');


        return this.layout.options.percentPosition && isHorizontal ?


            ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';


    };





    proto._transitionTo = function( x, y ) {


        this.getPosition();


        // get current x & y from top/left


        var curX = this.position.x;


        var curY = this.position.y;





        var compareX = parseInt( x, 10 );


        var compareY = parseInt( y, 10 );


        var didNotMove = compareX === this.position.x && compareY === this.position.y;





        // save end position


        this.setPosition( x, y );





        // if did not move and not transitioning, just go to layout


        if ( didNotMove && !this.isTransitioning ) {


            this.layoutPosition();


            return;


        }





        var transX = x - curX;


        var transY = y - curY;


        var transitionStyle = {};


        transitionStyle.transform = this.getTranslate( transX, transY );





        this.transition({


            to: transitionStyle,


            onTransitionEnd: {


                transform: this.layoutPosition


            },


            isCleaning: true


        });


    };





    proto.getTranslate = function( x, y ) {


        // flip cooridinates if origin on right or bottom


        var isOriginLeft = this.layout._getOption('originLeft');


        var isOriginTop = this.layout._getOption('originTop');


        x = isOriginLeft ? x : -x;


        y = isOriginTop ? y : -y;


        return 'translate3d(' + x + 'px, ' + y + 'px, 0)';


    };





// non transition + transform support


    proto.goTo = function( x, y ) {


        this.setPosition( x, y );


        this.layoutPosition();


    };





    proto.moveTo = proto._transitionTo;





    proto.setPosition = function( x, y ) {


        this.position.x = parseInt( x, 10 );


        this.position.y = parseInt( y, 10 );


    };





// ----- transition ----- //





    /**


     * @param {Object} style - CSS


     * @param {Function} onTransitionEnd


     */





// non transition, just trigger callback


    proto._nonTransition = function( args ) {


        this.css( args.to );


        if ( args.isCleaning ) {


            this._removeStyles( args.to );


        }


        for ( var prop in args.onTransitionEnd ) {


            args.onTransitionEnd[ prop ].call( this );


        }


    };





    /**


     * proper transition


     * @param {Object} args - arguments


     *   @param {Object} to - style to transition to


     *   @param {Object} from - style to start transition from


     *   @param {Boolean} isCleaning - removes transition styles after transition


     *   @param {Function} onTransitionEnd - callback


     */


    proto.transition = function( args ) {


        // redirect to nonTransition if no transition duration


        if ( !parseFloat( this.layout.options.transitionDuration ) ) {


            this._nonTransition( args );


            return;


        }





        var _transition = this._transn;


        // keep track of onTransitionEnd callback by css property


        for ( var prop in args.onTransitionEnd ) {


            _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];


        }


        // keep track of properties that are transitioning


        for ( prop in args.to ) {


            _transition.ingProperties[ prop ] = true;


            // keep track of properties to clean up when transition is done


            if ( args.isCleaning ) {


                _transition.clean[ prop ] = true;


            }


        }





        // set from styles


        if ( args.from ) {


            this.css( args.from );


            // force redraw. http://blog.alexmaccaw.com/css-transitions


            var h = this.element.offsetHeight;


            // hack for JSHint to hush about unused var


            h = null;


        }


        // enable transition


        this.enableTransition( args.to );


        // set styles that are transitioning


        this.css( args.to );





        this.isTransitioning = true;





    };





// dash before all cap letters, including first for


// WebkitTransform => -webkit-transform


    function toDashedAll( str ) {


        return str.replace( /([A-Z])/g, function( $1 ) {


            return '-' + $1.toLowerCase();


        });


    }





    var transitionProps = 'opacity,' + toDashedAll( transformProperty );





    proto.enableTransition = function(/* style */) {


        // HACK changing transitionProperty during a transition


        // will cause transition to jump


        if ( this.isTransitioning ) {


            return;


        }





        // make `transition: foo, bar, baz` from style object


        // HACK un-comment this when enableTransition can work


        // while a transition is happening


        // var transitionValues = [];


        // for ( var prop in style ) {


        //   // dash-ify camelCased properties like WebkitTransition


        //   prop = vendorProperties[ prop ] || prop;


        //   transitionValues.push( toDashedAll( prop ) );


        // }


        // munge number to millisecond, to match stagger


        var duration = this.layout.options.transitionDuration;


        duration = typeof duration == 'number' ? duration + 'ms' : duration;


        // enable transition styles


        this.css({


            transitionProperty: transitionProps,


            transitionDuration: duration,


            transitionDelay: this.staggerDelay || 0


        });


        // listen for transition end event


        this.element.addEventListener( transitionEndEvent, this, false );


    };





// ----- events ----- //





    proto.onwebkitTransitionEnd = function( event ) {


        this.ontransitionend( event );


    };





    proto.onotransitionend = function( event ) {


        this.ontransitionend( event );


    };





// properties that I munge to make my life easier


    var dashedVendorProperties = {


        '-webkit-transform': 'transform'


    };





    proto.ontransitionend = function( event ) {


        // disregard bubbled events from children


        if ( event.target !== this.element ) {


            return;


        }


        var _transition = this._transn;


        // get property name of transitioned property, convert to prefix-free


        var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;





        // remove property that has completed transitioning


        delete _transition.ingProperties[ propertyName ];


        // check if any properties are still transitioning


        if ( isEmptyObj( _transition.ingProperties ) ) {


            // all properties have completed transitioning


            this.disableTransition();


        }


        // clean style


        if ( propertyName in _transition.clean ) {


            // clean up style


            this.element.style[ event.propertyName ] = '';


            delete _transition.clean[ propertyName ];


        }


        // trigger onTransitionEnd callback


        if ( propertyName in _transition.onEnd ) {


            var onTransitionEnd = _transition.onEnd[ propertyName ];


            onTransitionEnd.call( this );


            delete _transition.onEnd[ propertyName ];


        }





        this.emitEvent( 'transitionEnd', [ this ] );


    };





    proto.disableTransition = function() {


        this.removeTransitionStyles();


        this.element.removeEventListener( transitionEndEvent, this, false );


        this.isTransitioning = false;


    };





    /**


     * removes style property from element


     * @param {Object} style


     **/


    proto._removeStyles = function( style ) {


        // clean up transition styles


        var cleanStyle = {};


        for ( var prop in style ) {


            cleanStyle[ prop ] = '';


        }


        this.css( cleanStyle );


    };





    var cleanTransitionStyle = {


        transitionProperty: '',


        transitionDuration: '',


        transitionDelay: ''


    };





    proto.removeTransitionStyles = function() {


        // remove transition


        this.css( cleanTransitionStyle );


    };





// ----- stagger ----- //





    proto.stagger = function( delay ) {


        delay = isNaN( delay ) ? 0 : delay;


        this.staggerDelay = delay + 'ms';


    };





// ----- show/hide/remove ----- //





// remove element from DOM


    proto.removeElem = function() {


        this.element.parentNode.removeChild( this.element );


        // remove display: none


        this.css({ display: '' });


        this.emitEvent( 'remove', [ this ] );


    };





    proto.remove = function() {


        // just remove element if no transition support or no transition


        if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {


            this.removeElem();


            return;


        }





        // start transition


        this.once( 'transitionEnd', function() {


            this.removeElem();


        });


        this.hide();


    };





    proto.reveal = function() {


        delete this.isHidden;


        // remove display: none


        this.css({ display: '' });





        var options = this.layout.options;





        var onTransitionEnd = {};


        var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');


        onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;





        this.transition({


            from: options.hiddenStyle,


            to: options.visibleStyle,


            isCleaning: true,


            onTransitionEnd: onTransitionEnd


        });


    };





    proto.onRevealTransitionEnd = function() {


        // check if still visible


        // during transition, item may have been hidden


        if ( !this.isHidden ) {


            this.emitEvent('reveal');


        }


    };





    /**


     * get style property use for hide/reveal transition end


     * @param {String} styleProperty - hiddenStyle/visibleStyle


     * @returns {String}


     */


    proto.getHideRevealTransitionEndProperty = function( styleProperty ) {


        var optionStyle = this.layout.options[ styleProperty ];


        // use opacity


        if ( optionStyle.opacity ) {


            return 'opacity';


        }


        // get first property


        for ( var prop in optionStyle ) {


            return prop;


        }


    };





    proto.hide = function() {


        // set flag


        this.isHidden = true;


        // remove display: none


        this.css({ display: '' });





        var options = this.layout.options;





        var onTransitionEnd = {};


        var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');


        onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;





        this.transition({


            from: options.visibleStyle,


            to: options.hiddenStyle,


            // keep hidden stuff hidden


            isCleaning: true,


            onTransitionEnd: onTransitionEnd


        });


    };





    proto.onHideTransitionEnd = function() {


        // check if still hidden


        // during transition, item may have been un-hidden


        if ( this.isHidden ) {


            this.css({ display: 'none' });


            this.emitEvent('hide');


        }


    };





    proto.destroy = function() {


        this.css({


            position: '',


            left: '',


            right: '',


            top: '',


            bottom: '',


            transition: '',


            transform: ''


        });


    };





    return Item;





}));





/*!


 * Outlayer v2.1.0


 * the brains and guts of a layout library


 * MIT license


 */





( function( window, factory ) {


    'use strict';


    // universal module definition


    /* jshint strict: false */ /* globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD - RequireJS


        define( 'outlayer/outlayer',[


            'ev-emitter/ev-emitter',


            'get-size/get-size',


            'fizzy-ui-utils/utils',


            './item'


        ],


            function( EvEmitter, getSize, utils, Item ) {


                return factory( window, EvEmitter, getSize, utils, Item);


            }


        );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS - Browserify, Webpack


        module.exports = factory(


            window,


            require('ev-emitter'),


            require('get-size'),


            require('fizzy-ui-utils'),


            require('./item')


        );


    } else {


        // browser global


        window.Outlayer = factory(


            window,


            window.EvEmitter,


            window.getSize,


            window.fizzyUIUtils,


            window.Outlayer.Item


        );


    }





}( window, function factory( window, EvEmitter, getSize, utils, Item ) {


    'use strict';





// ----- vars ----- //





    var console = window.console;


    var jQuery = window.jQuery;


    var noop = function() {};





// -------------------------- Outlayer -------------------------- //





// globally unique identifiers


    var GUID = 0;


// internal store of all Outlayer intances


    var instances = {};








    /**


     * @param {Element, String} element


     * @param {Object} options


     * @constructor


     */


    function Outlayer( element, options ) {


        var queryElement = utils.getQueryElement( element );


        if ( !queryElement ) {


            if ( console ) {


                console.error( 'Bad element for ' + this.constructor.namespace +


                    ': ' + ( queryElement || element ) );


            }


            return;


        }


        this.element = queryElement;


        // add jQuery


        if ( jQuery ) {


            this.$element = jQuery( this.element );


        }





        // options


        this.options = utils.extend( {}, this.constructor.defaults );


        this.option( options );





        // add id for Outlayer.getFromElement


        var id = ++GUID;


        this.element.outlayerGUID = id; // expando


        instances[ id ] = this; // associate via id





        // kick it off


        this._create();





        var isInitLayout = this._getOption('initLayout');


        if ( isInitLayout ) {


            this.layout();


        }


    }





// settings are for internal use only


    Outlayer.namespace = 'outlayer';


    Outlayer.Item = Item;





// default options


    Outlayer.defaults = {


        containerStyle: {


            position: 'relative'


        },


        initLayout: true,


        originLeft: true,


        originTop: true,


        resize: true,


        resizeContainer: true,


        // item options


        transitionDuration: '0.4s',


        hiddenStyle: {


            opacity: 0,


            transform: 'scale(0.001)'


        },


        visibleStyle: {


            opacity: 1,


            transform: 'scale(1)'


        }


    };





    var proto = Outlayer.prototype;


// inherit EvEmitter


    utils.extend( proto, EvEmitter.prototype );





    /**


     * set options


     * @param {Object} opts


     */


    proto.option = function( opts ) {


        utils.extend( this.options, opts );


    };





    /**


     * get backwards compatible option value, check old name


     */


    proto._getOption = function( option ) {


        var oldOption = this.constructor.compatOptions[ option ];


        return oldOption && this.options[ oldOption ] !== undefined ?


            this.options[ oldOption ] : this.options[ option ];


    };





    Outlayer.compatOptions = {


        // currentName: oldName


        initLayout: 'isInitLayout',


        horizontal: 'isHorizontal',


        layoutInstant: 'isLayoutInstant',


        originLeft: 'isOriginLeft',


        originTop: 'isOriginTop',


        resize: 'isResizeBound',


        resizeContainer: 'isResizingContainer'


    };





    proto._create = function() {


        // get items from children


        this.reloadItems();


        // elements that affect layout, but are not laid out


        this.stamps = [];


        this.stamp( this.options.stamp );


        // set container style


        utils.extend( this.element.style, this.options.containerStyle );





        // bind resize method


        var canBindResize = this._getOption('resize');


        if ( canBindResize ) {


            this.bindResize();


        }


    };





// goes through all children again and gets bricks in proper order


    proto.reloadItems = function() {


        // collection of item elements


        this.items = this._itemize( this.element.children );


    };








    /**


     * turn elements into Outlayer.Items to be used in layout


     * @param {Array or NodeList or HTMLElement} elems


     * @returns {Array} items - collection of new Outlayer Items


     */


    proto._itemize = function( elems ) {





        var itemElems = this._filterFindItemElements( elems );


        var Item = this.constructor.Item;





        // create new Outlayer Items for collection


        var items = [];


        for ( var i=0; i < itemElems.length; i++ ) {


            var elem = itemElems[i];


            var item = new Item( elem, this );


            items.push( item );


        }





        return items;


    };





    /**


     * get item elements to be used in layout


     * @param {Array or NodeList or HTMLElement} elems


     * @returns {Array} items - item elements


     */


    proto._filterFindItemElements = function( elems ) {


        return utils.filterFindElements( elems, this.options.itemSelector );


    };





    /**


     * getter method for getting item elements


     * @returns {Array} elems - collection of item elements


     */


    proto.getItemElements = function() {


        return this.items.map( function( item ) {


            return item.element;


        });


    };





// ----- init & layout ----- //





    /**


     * lays out all items


     */


    proto.layout = function() {


        this._resetLayout();


        this._manageStamps();





        // don't animate first layout


        var layoutInstant = this._getOption('layoutInstant');


        var isInstant = layoutInstant !== undefined ?


            layoutInstant : !this._isLayoutInited;


        this.layoutItems( this.items, isInstant );





        // flag for initalized


        this._isLayoutInited = true;


    };





// _init is alias for layout


    proto._init = proto.layout;





    /**


     * logic before any new layout


     */


    proto._resetLayout = function() {


        this.getSize();


    };








    proto.getSize = function() {


        this.size = getSize( this.element );


    };





    /**


     * get measurement from option, for columnWidth, rowHeight, gutter


     * if option is String -> get element from selector string, & get size of element


     * if option is Element -> get size of element


     * else use option as a number


     *


     * @param {String} measurement


     * @param {String} size - width or height


     * @private


     */


    proto._getMeasurement = function( measurement, size ) {


        var option = this.options[ measurement ];


        var elem;


        if ( !option ) {


            // default to 0


            this[ measurement ] = 0;


        } else {


            // use option as an element


            if ( typeof option == 'string' ) {


                elem = this.element.querySelector( option );


            } else if ( option instanceof HTMLElement ) {


                elem = option;


            }


            // use size of element, if element


            this[ measurement ] = elem ? getSize( elem )[ size ] : option;


        }


    };





    /**


     * layout a collection of item elements


     * @api public


     */


    proto.layoutItems = function( items, isInstant ) {


        items = this._getItemsForLayout( items );





        this._layoutItems( items, isInstant );





        this._postLayout();


    };





    /**


     * get the items to be laid out


     * you may want to skip over some items


     * @param {Array} items


     * @returns {Array} items


     */


    proto._getItemsForLayout = function( items ) {


        return items.filter( function( item ) {


            return !item.isIgnored;


        });


    };





    /**


     * layout items


     * @param {Array} items


     * @param {Boolean} isInstant


     */


    proto._layoutItems = function( items, isInstant ) {


        this._emitCompleteOnItems( 'layout', items );





        if ( !items || !items.length ) {


            // no items, emit event with empty array


            return;


        }





        var queue = [];





        items.forEach( function( item ) {


            // get x/y object from method


            var position = this._getItemLayoutPosition( item );


            // enqueue


            position.item = item;


            position.isInstant = isInstant || item.isLayoutInstant;


            queue.push( position );


        }, this );





        this._processLayoutQueue( queue );


    };





    /**


     * get item layout position


     * @param {Outlayer.Item} item


     * @returns {Object} x and y position


     */


    proto._getItemLayoutPosition = function( /* item */ ) {


        return {


            x: 0,


            y: 0


        };


    };





    /**


     * iterate over array and position each item


     * Reason being - separating this logic prevents 'layout invalidation'


     * thx @paul_irish


     * @param {Array} queue


     */


    proto._processLayoutQueue = function( queue ) {


        this.updateStagger();


        queue.forEach( function( obj, i ) {


            this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );


        }, this );


    };





// set stagger from option in milliseconds number


    proto.updateStagger = function() {


        var stagger = this.options.stagger;


        if ( stagger === null || stagger === undefined ) {


            this.stagger = 0;


            return;


        }


        this.stagger = getMilliseconds( stagger );


        return this.stagger;


    };





    /**


     * Sets position of item in DOM


     * @param {Outlayer.Item} item


     * @param {Number} x - horizontal position


     * @param {Number} y - vertical position


     * @param {Boolean} isInstant - disables transitions


     */


    proto._positionItem = function( item, x, y, isInstant, i ) {


        if ( isInstant ) {


            // if not transition, just set CSS


            item.goTo( x, y );


        } else {


            item.stagger( i * this.stagger );


            item.moveTo( x, y );


        }


    };





    /**


     * Any logic you want to do after each layout,


     * i.e. size the container


     */


    proto._postLayout = function() {


        this.resizeContainer();


    };





    proto.resizeContainer = function() {


        var isResizingContainer = this._getOption('resizeContainer');


        if ( !isResizingContainer ) {


            return;


        }


        var size = this._getContainerSize();


        if ( size ) {


            this._setContainerMeasure( size.width, true );


            this._setContainerMeasure( size.height, false );


        }


    };





    /**


     * Sets width or height of container if returned


     * @returns {Object} size


     *   @param {Number} width


     *   @param {Number} height


     */


    proto._getContainerSize = noop;





    /**


     * @param {Number} measure - size of width or height


     * @param {Boolean} isWidth


     */


    proto._setContainerMeasure = function( measure, isWidth ) {


        if ( measure === undefined ) {


            return;


        }





        var elemSize = this.size;


        // add padding and border width if border box


        if ( elemSize.isBorderBox ) {


            measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +


                elemSize.borderLeftWidth + elemSize.borderRightWidth :


                elemSize.paddingBottom + elemSize.paddingTop +


                    elemSize.borderTopWidth + elemSize.borderBottomWidth;


        }





        measure = Math.max( measure, 0 );


        this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';


    };





    /**


     * emit eventComplete on a collection of items events


     * @param {String} eventName


     * @param {Array} items - Outlayer.Items


     */


    proto._emitCompleteOnItems = function( eventName, items ) {


        var _this = this;


        function onComplete() {


            _this.dispatchEvent( eventName + 'Complete', null, [ items ] );


        }





        var count = items.length;


        if ( !items || !count ) {


            onComplete();


            return;


        }





        var doneCount = 0;


        function tick() {


            doneCount++;


            if ( doneCount == count ) {


                onComplete();


            }


        }





        // bind callback


        items.forEach( function( item ) {


            item.once( eventName, tick );


        });


    };





    /**


     * emits events via EvEmitter and jQuery events


     * @param {String} type - name of event


     * @param {Event} event - original event


     * @param {Array} args - extra arguments


     */


    proto.dispatchEvent = function( type, event, args ) {


        // add original event to arguments


        var emitArgs = event ? [ event ].concat( args ) : args;


        this.emitEvent( type, emitArgs );





        if ( jQuery ) {


            // set this.$element


            this.$element = this.$element || jQuery( this.element );


            if ( event ) {


                // create jQuery event


                var $event = jQuery.Event( event );


                $event.type = type;


                this.$element.trigger( $event, args );


            } else {


                // just trigger with type if no event available


                this.$element.trigger( type, args );


            }


        }


    };





// -------------------------- ignore & stamps -------------------------- //








    /**


     * keep item in collection, but do not lay it out


     * ignored items do not get skipped in layout


     * @param {Element} elem


     */


    proto.ignore = function( elem ) {


        var item = this.getItem( elem );


        if ( item ) {


            item.isIgnored = true;


        }


    };





    /**


     * return item to layout collection


     * @param {Element} elem


     */


    proto.unignore = function( elem ) {


        var item = this.getItem( elem );


        if ( item ) {


            delete item.isIgnored;


        }


    };





    /**


     * adds elements to stamps


     * @param {NodeList, Array, Element, or String} elems


     */


    proto.stamp = function( elems ) {


        elems = this._find( elems );


        if ( !elems ) {


            return;


        }





        this.stamps = this.stamps.concat( elems );


        // ignore


        elems.forEach( this.ignore, this );


    };





    /**


     * removes elements to stamps


     * @param {NodeList, Array, or Element} elems


     */


    proto.unstamp = function( elems ) {


        elems = this._find( elems );


        if ( !elems ){


            return;


        }





        elems.forEach( function( elem ) {


            // filter out removed stamp elements


            utils.removeFrom( this.stamps, elem );


            this.unignore( elem );


        }, this );


    };





    /**


     * finds child elements


     * @param {NodeList, Array, Element, or String} elems


     * @returns {Array} elems


     */


    proto._find = function( elems ) {


        if ( !elems ) {


            return;


        }


        // if string, use argument as selector string


        if ( typeof elems == 'string' ) {


            elems = this.element.querySelectorAll( elems );


        }


        elems = utils.makeArray( elems );


        return elems;


    };





    proto._manageStamps = function() {


        if ( !this.stamps || !this.stamps.length ) {


            return;


        }





        this._getBoundingRect();





        this.stamps.forEach( this._manageStamp, this );


    };





// update boundingLeft / Top


    proto._getBoundingRect = function() {


        // get bounding rect for container element


        var boundingRect = this.element.getBoundingClientRect();


        var size = this.size;


        this._boundingRect = {


            left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,


            top: boundingRect.top + size.paddingTop + size.borderTopWidth,


            right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),


            bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )


        };


    };





    /**


     * @param {Element} stamp


     **/


    proto._manageStamp = noop;





    /**


     * get x/y position of element relative to container element


     * @param {Element} elem


     * @returns {Object} offset - has left, top, right, bottom


     */


    proto._getElementOffset = function( elem ) {


        var boundingRect = elem.getBoundingClientRect();


        var thisRect = this._boundingRect;


        var size = getSize( elem );


        var offset = {


            left: boundingRect.left - thisRect.left - size.marginLeft,


            top: boundingRect.top - thisRect.top - size.marginTop,


            right: thisRect.right - boundingRect.right - size.marginRight,


            bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom


        };


        return offset;


    };





// -------------------------- resize -------------------------- //





// enable event handlers for listeners


// i.e. resize -> onresize


    proto.handleEvent = utils.handleEvent;





    /**


     * Bind layout to window resizing


     */


    proto.bindResize = function() {


        window.addEventListener( 'resize', this );


        this.isResizeBound = true;


    };





    /**


     * Unbind layout to window resizing


     */


    proto.unbindResize = function() {


        window.removeEventListener( 'resize', this );


        this.isResizeBound = false;


    };





    proto.onresize = function() {


        this.resize();


    };





    utils.debounceMethod( Outlayer, 'onresize', 100 );





    proto.resize = function() {


        // don't trigger if size did not change


        // or if resize was unbound. See #9


        if ( !this.isResizeBound || !this.needsResizeLayout() ) {


            return;


        }





        this.layout();


    };





    /**


     * check if layout is needed post layout


     * @returns Boolean


     */


    proto.needsResizeLayout = function() {


        var size = getSize( this.element );


        // check that this.size and size are there


        // IE8 triggers resize on body size change, so they might not be


        var hasSizes = this.size && size;


        return hasSizes && size.innerWidth !== this.size.innerWidth;


    };





// -------------------------- methods -------------------------- //





    /**


     * add items to Outlayer instance


     * @param {Array or NodeList or Element} elems


     * @returns {Array} items - Outlayer.Items


     **/


    proto.addItems = function( elems ) {


        var items = this._itemize( elems );


        // add items to collection


        if ( items.length ) {


            this.items = this.items.concat( items );


        }


        return items;


    };





    /**


     * Layout newly-appended item elements


     * @param {Array or NodeList or Element} elems


     */


    proto.appended = function( elems ) {


        var items = this.addItems( elems );


        if ( !items.length ) {


            return;


        }


        // layout and reveal just the new items


        this.layoutItems( items, true );


        this.reveal( items );


    };





    /**


     * Layout prepended elements


     * @param {Array or NodeList or Element} elems


     */


    proto.prepended = function( elems ) {


        var items = this._itemize( elems );


        if ( !items.length ) {


            return;


        }


        // add items to beginning of collection


        var previousItems = this.items.slice(0);


        this.items = items.concat( previousItems );


        // start new layout


        this._resetLayout();


        this._manageStamps();


        // layout new stuff without transition


        this.layoutItems( items, true );


        this.reveal( items );


        // layout previous items


        this.layoutItems( previousItems );


    };





    /**


     * reveal a collection of items


     * @param {Array of Outlayer.Items} items


     */


    proto.reveal = function( items ) {


        this._emitCompleteOnItems( 'reveal', items );


        if ( !items || !items.length ) {


            return;


        }


        var stagger = this.updateStagger();


        items.forEach( function( item, i ) {


            item.stagger( i * stagger );


            item.reveal();


        });


    };





    /**


     * hide a collection of items


     * @param {Array of Outlayer.Items} items


     */


    proto.hide = function( items ) {


        this._emitCompleteOnItems( 'hide', items );


        if ( !items || !items.length ) {


            return;


        }


        var stagger = this.updateStagger();


        items.forEach( function( item, i ) {


            item.stagger( i * stagger );


            item.hide();


        });


    };





    /**


     * reveal item elements


     * @param {Array}, {Element}, {NodeList} items


     */


    proto.revealItemElements = function( elems ) {


        var items = this.getItems( elems );


        this.reveal( items );


    };





    /**


     * hide item elements


     * @param {Array}, {Element}, {NodeList} items


     */


    proto.hideItemElements = function( elems ) {


        var items = this.getItems( elems );


        this.hide( items );


    };





    /**


     * get Outlayer.Item, given an Element


     * @param {Element} elem


     * @param {Function} callback


     * @returns {Outlayer.Item} item


     */


    proto.getItem = function( elem ) {


        // loop through items to get the one that matches


        for ( var i=0; i < this.items.length; i++ ) {


            var item = this.items[i];


            if ( item.element == elem ) {


                // return item


                return item;


            }


        }


    };





    /**


     * get collection of Outlayer.Items, given Elements


     * @param {Array} elems


     * @returns {Array} items - Outlayer.Items


     */


    proto.getItems = function( elems ) {


        elems = utils.makeArray( elems );


        var items = [];


        elems.forEach( function( elem ) {


            var item = this.getItem( elem );


            if ( item ) {


                items.push( item );


            }


        }, this );





        return items;


    };





    /**


     * remove element(s) from instance and DOM


     * @param {Array or NodeList or Element} elems


     */


    proto.remove = function( elems ) {


        var removeItems = this.getItems( elems );





        this._emitCompleteOnItems( 'remove', removeItems );





        // bail if no items to remove


        if ( !removeItems || !removeItems.length ) {


            return;


        }





        removeItems.forEach( function( item ) {


            item.remove();


            // remove item from collection


            utils.removeFrom( this.items, item );


        }, this );


    };





// ----- destroy ----- //





// remove and disable Outlayer instance


    proto.destroy = function() {


        // clean up dynamic styles


        var style = this.element.style;


        style.height = '';


        style.position = '';


        style.width = '';


        // destroy items


        this.items.forEach( function( item ) {


            item.destroy();


        });





        this.unbindResize();





        var id = this.element.outlayerGUID;


        delete instances[ id ]; // remove reference to instance by id


        delete this.element.outlayerGUID;


        // remove data for jQuery


        if ( jQuery ) {


            jQuery.removeData( this.element, this.constructor.namespace );


        }





    };





// -------------------------- data -------------------------- //





    /**


     * get Outlayer instance from element


     * @param {Element} elem


     * @returns {Outlayer}


     */


    Outlayer.data = function( elem ) {


        elem = utils.getQueryElement( elem );


        var id = elem && elem.outlayerGUID;


        return id && instances[ id ];


    };








// -------------------------- create Outlayer class -------------------------- //





    /**


     * create a layout class


     * @param {String} namespace


     */


    Outlayer.create = function( namespace, options ) {


        // sub-class Outlayer


        var Layout = subclass( Outlayer );


        // apply new options and compatOptions


        Layout.defaults = utils.extend( {}, Outlayer.defaults );


        utils.extend( Layout.defaults, options );


        Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions  );





        Layout.namespace = namespace;





        Layout.data = Outlayer.data;





        // sub-class Item


        Layout.Item = subclass( Item );





        // -------------------------- declarative -------------------------- //





        utils.htmlInit( Layout, namespace );





        // -------------------------- jQuery bridge -------------------------- //





        // make into jQuery plugin


        if ( jQuery && jQuery.bridget ) {


            jQuery.bridget( namespace, Layout );


        }





        return Layout;


    };





    function subclass( Parent ) {


        function SubClass() {


            Parent.apply( this, arguments );


        }





        SubClass.prototype = Object.create( Parent.prototype );


        SubClass.prototype.constructor = SubClass;





        return SubClass;


    }





// ----- helpers ----- //





// how many milliseconds are in each unit


    var msUnits = {


        ms: 1,


        s: 1000


    };





// munge time-like parameter into millisecond number


// '0.4s' -> 40


    function getMilliseconds( time ) {


        if ( typeof time == 'number' ) {


            return time;


        }


        var matches = time.match( /(^\d*\.?\d*)(\w*)/ );


        var num = matches && matches[1];


        var unit = matches && matches[2];


        if ( !num.length ) {


            return 0;


        }


        num = parseFloat( num );


        var mult = msUnits[ unit ] || 1;


        return num * mult;


    }





// ----- fin ----- //





// back in global


    Outlayer.Item = Item;





    return Outlayer;





}));





/**


 * Isotope Item


 **/





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /*globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'isotope/js/item',[


            'outlayer/outlayer'


        ],


            factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            require('outlayer')


        );


    } else {


        // browser global


        window.Isotope = window.Isotope || {};


        window.Isotope.Item = factory(


            window.Outlayer


        );


    }





}( window, function factory( Outlayer ) {


    'use strict';





// -------------------------- Item -------------------------- //





// sub-class Outlayer Item


    function Item() {


        Outlayer.Item.apply( this, arguments );


    }





    var proto = Item.prototype = Object.create( Outlayer.Item.prototype );





    var _create = proto._create;


    proto._create = function() {


        // assign id, used for original-order sorting


        this.id = this.layout.itemGUID++;


        _create.call( this );


        this.sortData = {};


    };





    proto.updateSortData = function() {


        if ( this.isIgnored ) {


            return;


        }


        // default sorters


        this.sortData.id = this.id;


        // for backward compatibility


        this.sortData['original-order'] = this.id;


        this.sortData.random = Math.random();


        // go thru getSortData obj and apply the sorters


        var getSortData = this.layout.options.getSortData;


        var sorters = this.layout._sorters;


        for ( var key in getSortData ) {


            var sorter = sorters[ key ];


            this.sortData[ key ] = sorter( this.element, this );


        }


    };





    var _destroy = proto.destroy;


    proto.destroy = function() {


        // call super


        _destroy.apply( this, arguments );


        // reset display, #741


        this.css({


            display: ''


        });


    };





    return Item;





}));





/**


 * Isotope LayoutMode


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /*globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'isotope/js/layout-mode',[


            'get-size/get-size',


            'outlayer/outlayer'


        ],


            factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            require('get-size'),


            require('outlayer')


        );


    } else {


        // browser global


        window.Isotope = window.Isotope || {};


        window.Isotope.LayoutMode = factory(


            window.getSize,


            window.Outlayer


        );


    }





}( window, function factory( getSize, Outlayer ) {


    'use strict';





    // layout mode class


    function LayoutMode( isotope ) {


        this.isotope = isotope;


        // link properties


        if ( isotope ) {


            this.options = isotope.options[ this.namespace ];


            this.element = isotope.element;


            this.items = isotope.filteredItems;


            this.size = isotope.size;


        }


    }





    var proto = LayoutMode.prototype;





    /**


     * some methods should just defer to default Outlayer method


     * and reference the Isotope instance as `this`


     **/


    var facadeMethods = [


        '_resetLayout',


        '_getItemLayoutPosition',


        '_manageStamp',


        '_getContainerSize',


        '_getElementOffset',


        'needsResizeLayout',


        '_getOption'


    ];





    facadeMethods.forEach( function( methodName ) {


        proto[ methodName ] = function() {


            return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );


        };


    });





    // -----  ----- //





    // for horizontal layout modes, check vertical size


    proto.needsVerticalResizeLayout = function() {


        // don't trigger if size did not change


        var size = getSize( this.isotope.element );


        // check that this.size and size are there


        // IE8 triggers resize on body size change, so they might not be


        var hasSizes = this.isotope.size && size;


        return hasSizes && size.innerHeight != this.isotope.size.innerHeight;


    };





    // ----- measurements ----- //





    proto._getMeasurement = function() {


        this.isotope._getMeasurement.apply( this, arguments );


    };





    proto.getColumnWidth = function() {


        this.getSegmentSize( 'column', 'Width' );


    };





    proto.getRowHeight = function() {


        this.getSegmentSize( 'row', 'Height' );


    };





    /**


     * get columnWidth or rowHeight


     * segment: 'column' or 'row'


     * size 'Width' or 'Height'


     **/


    proto.getSegmentSize = function( segment, size ) {


        var segmentName = segment + size;


        var outerSize = 'outer' + size;


        // columnWidth / outerWidth // rowHeight / outerHeight


        this._getMeasurement( segmentName, outerSize );


        // got rowHeight or columnWidth, we can chill


        if ( this[ segmentName ] ) {


            return;


        }


        // fall back to item of first element


        var firstItemSize = this.getFirstItemSize();


        this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||


            // or size of container


            this.isotope.size[ 'inner' + size ];


    };





    proto.getFirstItemSize = function() {


        var firstItem = this.isotope.filteredItems[0];


        return firstItem && firstItem.element && getSize( firstItem.element );


    };





    // ----- methods that should reference isotope ----- //





    proto.layout = function() {


        this.isotope.layout.apply( this.isotope, arguments );


    };





    proto.getSize = function() {


        this.isotope.getSize();


        this.size = this.isotope.size;


    };





    // -------------------------- create -------------------------- //





    LayoutMode.modes = {};





    LayoutMode.create = function( namespace, options ) {





        function Mode() {


            LayoutMode.apply( this, arguments );


        }





        Mode.prototype = Object.create( proto );


        Mode.prototype.constructor = Mode;





        // default options


        if ( options ) {


            Mode.options = options;


        }





        Mode.prototype.namespace = namespace;


        // register in Isotope


        LayoutMode.modes[ namespace ] = Mode;





        return Mode;


    };





    return LayoutMode;





}));





/*!


 * Masonry v4.1.0


 * Cascading grid layout library


 * http://masonry.desandro.com


 * MIT License


 * by David DeSandro


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /*globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'masonry/masonry',[


            'outlayer/outlayer',


            'get-size/get-size'


        ],


            factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            require('outlayer'),


            require('get-size')


        );


    } else {


        // browser global


        window.Masonry = factory(


            window.Outlayer,


            window.getSize


        );


    }





}( window, function factory( Outlayer, getSize ) {











// -------------------------- masonryDefinition -------------------------- //





    // create an Outlayer layout class


    var Masonry = Outlayer.create('masonry');


    // isFitWidth -> fitWidth


    Masonry.compatOptions.fitWidth = 'isFitWidth';





    Masonry.prototype._resetLayout = function() {


        this.getSize();


        this._getMeasurement( 'columnWidth', 'outerWidth' );


        this._getMeasurement( 'gutter', 'outerWidth' );


        this.measureColumns();





        // reset column Y


        this.colYs = [];


        for ( var i=0; i < this.cols; i++ ) {


            this.colYs.push( 0 );


        }





        this.maxY = 0;


    };





    Masonry.prototype.measureColumns = function() {


        this.getContainerWidth();


        // if columnWidth is 0, default to outerWidth of first item


        if ( !this.columnWidth ) {


            var firstItem = this.items[0];


            var firstItemElem = firstItem && firstItem.element;


            // columnWidth fall back to item of first element


            this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||


                // if first elem has no width, default to size of container


                this.containerWidth;


        }





        var columnWidth = this.columnWidth += this.gutter;





        // calculate columns


        var containerWidth = this.containerWidth + this.gutter;


        var cols = containerWidth / columnWidth;


        // fix rounding errors, typically with gutters


        var excess = columnWidth - containerWidth % columnWidth;


        // if overshoot is less than a pixel, round up, otherwise floor it


        var mathMethod = excess && excess < 1 ? 'round' : 'floor';


        cols = Math[ mathMethod ]( cols );


        this.cols = Math.max( cols, 1 );


    };





    Masonry.prototype.getContainerWidth = function() {


        // container is parent if fit width


        var isFitWidth = this._getOption('fitWidth');


        var container = isFitWidth ? this.element.parentNode : this.element;


        // check that this.size and size are there


        // IE8 triggers resize on body size change, so they might not be


        var size = getSize( container );


        this.containerWidth = size && size.innerWidth;


    };





    Masonry.prototype._getItemLayoutPosition = function( item ) {


        item.getSize();


        // how many columns does this brick span


        var remainder = item.size.outerWidth % this.columnWidth;


        var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';


        // round if off by 1 pixel, otherwise use ceil


        var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );


        colSpan = Math.min( colSpan, this.cols );





        var colGroup = this._getColGroup( colSpan );


        // get the minimum Y value from the columns


        var minimumY = Math.min.apply( Math, colGroup );


        var shortColIndex = colGroup.indexOf( minimumY );





        // position the brick


        var position = {


            x: this.columnWidth * shortColIndex,


            y: minimumY


        };





        // apply setHeight to necessary columns


        var setHeight = minimumY + item.size.outerHeight;


        var setSpan = this.cols + 1 - colGroup.length;


        for ( var i = 0; i < setSpan; i++ ) {


            this.colYs[ shortColIndex + i ] = setHeight;


        }





        return position;


    };





    /**


     * @param {Number} colSpan - number of columns the element spans


     * @returns {Array} colGroup


     */


    Masonry.prototype._getColGroup = function( colSpan ) {


        if ( colSpan < 2 ) {


            // if brick spans only one column, use all the column Ys


            return this.colYs;


        }





        var colGroup = [];


        // how many different places could this brick fit horizontally


        var groupCount = this.cols + 1 - colSpan;


        // for each group potential horizontal position


        for ( var i = 0; i < groupCount; i++ ) {


            // make an array of colY values for that one group


            var groupColYs = this.colYs.slice( i, i + colSpan );


            // and get the max value of the array


            colGroup[i] = Math.max.apply( Math, groupColYs );


        }


        return colGroup;


    };





    Masonry.prototype._manageStamp = function( stamp ) {


        var stampSize = getSize( stamp );


        var offset = this._getElementOffset( stamp );


        // get the columns that this stamp affects


        var isOriginLeft = this._getOption('originLeft');


        var firstX = isOriginLeft ? offset.left : offset.right;


        var lastX = firstX + stampSize.outerWidth;


        var firstCol = Math.floor( firstX / this.columnWidth );


        firstCol = Math.max( 0, firstCol );


        var lastCol = Math.floor( lastX / this.columnWidth );


        // lastCol should not go over if multiple of columnWidth #425


        lastCol -= lastX % this.columnWidth ? 0 : 1;


        lastCol = Math.min( this.cols - 1, lastCol );


        // set colYs to bottom of the stamp





        var isOriginTop = this._getOption('originTop');


        var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +


            stampSize.outerHeight;


        for ( var i = firstCol; i <= lastCol; i++ ) {


            this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );


        }


    };





    Masonry.prototype._getContainerSize = function() {


        this.maxY = Math.max.apply( Math, this.colYs );


        var size = {


            height: this.maxY


        };





        if ( this._getOption('fitWidth') ) {


            size.width = this._getContainerFitWidth();


        }





        return size;


    };





    Masonry.prototype._getContainerFitWidth = function() {


        var unusedCols = 0;


        // count unused columns


        var i = this.cols;


        while ( --i ) {


            if ( this.colYs[i] !== 0 ) {


                break;


            }


            unusedCols++;


        }


        // fit container to columns that have been used


        return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;


    };





    Masonry.prototype.needsResizeLayout = function() {


        var previousWidth = this.containerWidth;


        this.getContainerWidth();


        return previousWidth != this.containerWidth;


    };





    return Masonry;





}));





/*!


 * Masonry layout mode


 * sub-classes Masonry


 * http://masonry.desandro.com


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /*globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'isotope/js/layout-modes/masonry',[


            '../layout-mode',


            'masonry/masonry'


        ],


            factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            require('../layout-mode'),


            require('masonry-layout')


        );


    } else {


        // browser global


        factory(


            window.Isotope.LayoutMode,


            window.Masonry


        );


    }





}( window, function factory( LayoutMode, Masonry ) {


    'use strict';





// -------------------------- masonryDefinition -------------------------- //





    // create an Outlayer layout class


    var MasonryMode = LayoutMode.create('masonry');





    var proto = MasonryMode.prototype;





    var keepModeMethods = {


        _getElementOffset: true,


        layout: true,


        _getMeasurement: true


    };





    // inherit Masonry prototype


    for ( var method in Masonry.prototype ) {


        // do not inherit mode methods


        if ( !keepModeMethods[ method ] ) {


            proto[ method ] = Masonry.prototype[ method ];


        }


    }





    var measureColumns = proto.measureColumns;


    proto.measureColumns = function() {


        // set items, used if measuring first item


        this.items = this.isotope.filteredItems;


        measureColumns.call( this );


    };





    // point to mode options for fitWidth


    var _getOption = proto._getOption;


    proto._getOption = function( option ) {


        if ( option == 'fitWidth' ) {


            return this.options.isFitWidth !== undefined ?


                this.options.isFitWidth : this.options.fitWidth;


        }


        return _getOption.apply( this.isotope, arguments );


    };





    return MasonryMode;





}));





/**


 * fitRows layout mode


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /*globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'isotope/js/layout-modes/fit-rows',[


            '../layout-mode'


        ],


            factory );


    } else if ( typeof exports == 'object' ) {


        // CommonJS


        module.exports = factory(


            require('../layout-mode')


        );


    } else {


        // browser global


        factory(


            window.Isotope.LayoutMode


        );


    }





}( window, function factory( LayoutMode ) {


    'use strict';





    var FitRows = LayoutMode.create('fitRows');





    var proto = FitRows.prototype;





    proto._resetLayout = function() {


        this.x = 0;


        this.y = 0;


        this.maxY = 0;


        this._getMeasurement( 'gutter', 'outerWidth' );


    };





    proto._getItemLayoutPosition = function( item ) {


        item.getSize();





        var itemWidth = item.size.outerWidth + this.gutter;


        // if this element cannot fit in the current row


        var containerWidth = this.isotope.size.innerWidth + this.gutter;


        if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {


            this.x = 0;


            this.y = this.maxY;


        }





        var position = {


            x: this.x,


            y: this.y


        };





        this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );


        this.x += itemWidth;





        return position;


    };





    proto._getContainerSize = function() {


        return { height: this.maxY };


    };





    return FitRows;





}));





/**


 * vertical layout mode


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /*globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( 'isotope/js/layout-modes/vertical',[


            '../layout-mode'


        ],


            factory );


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            require('../layout-mode')


        );


    } else {


        // browser global


        factory(


            window.Isotope.LayoutMode


        );


    }





}( window, function factory( LayoutMode ) {


    'use strict';





    var Vertical = LayoutMode.create( 'vertical', {


        horizontalAlignment: 0


    });





    var proto = Vertical.prototype;





    proto._resetLayout = function() {


        this.y = 0;


    };





    proto._getItemLayoutPosition = function( item ) {


        item.getSize();


        var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *


            this.options.horizontalAlignment;


        var y = this.y;


        this.y += item.size.outerHeight;


        return { x: x, y: y };


    };





    proto._getContainerSize = function() {


        return { height: this.y };


    };





    return Vertical;





}));





/*!


 * Isotope v3.0.1


 *


 * Licensed GPLv3 for open source use


 * or Isotope Commercial License for commercial use


 *


 * http://isotope.metafizzy.co


 * Copyright 2016 Metafizzy


 */





( function( window, factory ) {


    // universal module definition


    /* jshint strict: false */ /*globals define, module, require */


    if ( typeof define == 'function' && define.amd ) {


        // AMD


        define( [


            'outlayer/outlayer',


            'get-size/get-size',


            'desandro-matches-selector/matches-selector',


            'fizzy-ui-utils/utils',


            'isotope/js/item',


            'isotope/js/layout-mode',


            // include default layout modes


            'isotope/js/layout-modes/masonry',


            'isotope/js/layout-modes/fit-rows',


            'isotope/js/layout-modes/vertical'


        ],


            function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {


                return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );


            });


    } else if ( typeof module == 'object' && module.exports ) {


        // CommonJS


        module.exports = factory(


            window,


            require('outlayer'),


            require('get-size'),


            require('desandro-matches-selector'),


            require('fizzy-ui-utils'),


            require('isotope/js/item'),


            require('isotope/js/layout-mode'),


            // include default layout modes


            require('isotope/js/layout-modes/masonry'),


            require('isotope/js/layout-modes/fit-rows'),


            require('isotope/js/layout-modes/vertical')


        );


    } else {


        // browser global


        window.Isotope = factory(


            window,


            window.Outlayer,


            window.getSize,


            window.matchesSelector,


            window.fizzyUIUtils,


            window.Isotope.Item,


            window.Isotope.LayoutMode


        );


    }





}( window, function factory( window, Outlayer, getSize, matchesSelector, utils,


                             Item, LayoutMode ) {











// -------------------------- vars -------------------------- //





    var jQuery = window.jQuery;





// -------------------------- helpers -------------------------- //





    var trim = String.prototype.trim ?


        function( str ) {


            return str.trim();


        } :


        function( str ) {


            return str.replace( /^\s+|\s+$/g, '' );


        };





// -------------------------- isotopeDefinition -------------------------- //





    // create an Outlayer layout class


    var Isotope = Outlayer.create( 'isotope', {


        layoutMode: 'masonry',


        isJQueryFiltering: true,


        sortAscending: true


    });





    Isotope.Item = Item;


    Isotope.LayoutMode = LayoutMode;





    var proto = Isotope.prototype;





    proto._create = function() {


        this.itemGUID = 0;


        // functions that sort items


        this._sorters = {};


        this._getSorters();


        // call super


        Outlayer.prototype._create.call( this );





        // create layout modes


        this.modes = {};


        // start filteredItems with all items


        this.filteredItems = this.items;


        // keep of track of sortBys


        this.sortHistory = [ 'original-order' ];


        // create from registered layout modes


        for ( var name in LayoutMode.modes ) {


            this._initLayoutMode( name );


        }


    };





    proto.reloadItems = function() {


        // reset item ID counter


        this.itemGUID = 0;


        // call super


        Outlayer.prototype.reloadItems.call( this );


    };





    proto._itemize = function() {


        var items = Outlayer.prototype._itemize.apply( this, arguments );


        // assign ID for original-order


        for ( var i=0; i < items.length; i++ ) {


            var item = items[i];


            item.id = this.itemGUID++;


        }


        this._updateItemsSortData( items );


        return items;


    };








    // -------------------------- layout -------------------------- //





    proto._initLayoutMode = function( name ) {


        var Mode = LayoutMode.modes[ name ];


        // set mode options


        // HACK extend initial options, back-fill in default options


        var initialOpts = this.options[ name ] || {};


        this.options[ name ] = Mode.options ?


            utils.extend( Mode.options, initialOpts ) : initialOpts;


        // init layout mode instance


        this.modes[ name ] = new Mode( this );


    };








    proto.layout = function() {


        // if first time doing layout, do all magic


        if ( !this._isLayoutInited && this._getOption('initLayout') ) {


            this.arrange();


            return;


        }


        this._layout();


    };





    // private method to be used in layout() & magic()


    proto._layout = function() {


        // don't animate first layout


        var isInstant = this._getIsInstant();


        // layout flow


        this._resetLayout();


        this._manageStamps();


        this.layoutItems( this.filteredItems, isInstant );





        // flag for initalized


        this._isLayoutInited = true;


    };





    // filter + sort + layout


    proto.arrange = function( opts ) {


        // set any options pass


        this.option( opts );


        this._getIsInstant();


        // filter, sort, and layout





        // filter


        var filtered = this._filter( this.items );


        this.filteredItems = filtered.matches;





        this._bindArrangeComplete();





        if ( this._isInstant ) {


            this._noTransition( this._hideReveal, [ filtered ] );


        } else {


            this._hideReveal( filtered );


        }





        this._sort();


        this._layout();


    };


    // alias to _init for main plugin method


    proto._init = proto.arrange;





    proto._hideReveal = function( filtered ) {


        this.reveal( filtered.needReveal );


        this.hide( filtered.needHide );


    };





    // HACK


    // Don't animate/transition first layout


    // Or don't animate/transition other layouts


    proto._getIsInstant = function() {


        var isLayoutInstant = this._getOption('layoutInstant');


        var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :


            !this._isLayoutInited;


        this._isInstant = isInstant;


        return isInstant;


    };





    // listen for layoutComplete, hideComplete and revealComplete


    // to trigger arrangeComplete


    proto._bindArrangeComplete = function() {


        // listen for 3 events to trigger arrangeComplete


        var isLayoutComplete, isHideComplete, isRevealComplete;


        var _this = this;


        function arrangeParallelCallback() {


            if ( isLayoutComplete && isHideComplete && isRevealComplete ) {


                _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );


            }


        }


        this.once( 'layoutComplete', function() {


            isLayoutComplete = true;


            arrangeParallelCallback();


        });


        this.once( 'hideComplete', function() {


            isHideComplete = true;


            arrangeParallelCallback();


        });


        this.once( 'revealComplete', function() {


            isRevealComplete = true;


            arrangeParallelCallback();


        });


    };





    // -------------------------- filter -------------------------- //





    proto._filter = function( items ) {


        var filter = this.options.filter;


        filter = filter || '*';


        var matches = [];


        var hiddenMatched = [];


        var visibleUnmatched = [];





        var test = this._getFilterTest( filter );





        // test each item


        for ( var i=0; i < items.length; i++ ) {


            var item = items[i];


            if ( item.isIgnored ) {


                continue;


            }


            // add item to either matched or unmatched group


            var isMatched = test( item );


            // item.isFilterMatched = isMatched;


            // add to matches if its a match


            if ( isMatched ) {


                matches.push( item );


            }


            // add to additional group if item needs to be hidden or revealed


            if ( isMatched && item.isHidden ) {


                hiddenMatched.push( item );


            } else if ( !isMatched && !item.isHidden ) {


                visibleUnmatched.push( item );


            }


        }





        // return collections of items to be manipulated


        return {


            matches: matches,


            needReveal: hiddenMatched,


            needHide: visibleUnmatched


        };


    };





    // get a jQuery, function, or a matchesSelector test given the filter


    proto._getFilterTest = function( filter ) {


        if ( jQuery && this.options.isJQueryFiltering ) {


            // use jQuery


            return function( item ) {


                return jQuery( item.element ).is( filter );


            };


        }


        if ( typeof filter == 'function' ) {


            // use filter as function


            return function( item ) {


                return filter( item.element );


            };


        }


        // default, use filter as selector string


        return function( item ) {


            return matchesSelector( item.element, filter );


        };


    };





    // -------------------------- sorting -------------------------- //





    /**


     * @params {Array} elems


     * @public


     */


    proto.updateSortData = function( elems ) {


        // get items


        var items;


        if ( elems ) {


            elems = utils.makeArray( elems );


            items = this.getItems( elems );


        } else {


            // update all items if no elems provided


            items = this.items;


        }





        this._getSorters();


        this._updateItemsSortData( items );


    };





    proto._getSorters = function() {


        var getSortData = this.options.getSortData;


        for ( var key in getSortData ) {


            var sorter = getSortData[ key ];


            this._sorters[ key ] = mungeSorter( sorter );


        }


    };





    /**


     * @params {Array} items - of Isotope.Items


     * @private


     */


    proto._updateItemsSortData = function( items ) {


        // do not update if no items


        var len = items && items.length;





        for ( var i=0; len && i < len; i++ ) {


            var item = items[i];


            item.updateSortData();


        }


    };





    // ----- munge sorter ----- //





    // encapsulate this, as we just need mungeSorter


    // other functions in here are just for munging


    var mungeSorter = ( function() {


        // add a magic layer to sorters for convienent shorthands


        // `.foo-bar` will use the text of .foo-bar querySelector


        // `[foo-bar]` will use attribute


        // you can also add parser


        // `.foo-bar parseInt` will parse that as a number


        function mungeSorter( sorter ) {


            // if not a string, return function or whatever it is


            if ( typeof sorter != 'string' ) {


                return sorter;


            }


            // parse the sorter string


            var args = trim( sorter ).split(' ');


            var query = args[0];


            // check if query looks like [an-attribute]


            var attrMatch = query.match( /^\[(.+)\]$/ );


            var attr = attrMatch && attrMatch[1];


            var getValue = getValueGetter( attr, query );


            // use second argument as a parser


            var parser = Isotope.sortDataParsers[ args[1] ];


            // parse the value, if there was a parser


            sorter = parser ? function( elem ) {


                return elem && parser( getValue( elem ) );


            } :


                // otherwise just return value


                function( elem ) {


                    return elem && getValue( elem );


                };





            return sorter;


        }





        // get an attribute getter, or get text of the querySelector


        function getValueGetter( attr, query ) {


            // if query looks like [foo-bar], get attribute


            if ( attr ) {


                return function getAttribute( elem ) {


                    return elem.getAttribute( attr );


                };


            }





            // otherwise, assume its a querySelector, and get its text


            return function getChildText( elem ) {


                var child = elem.querySelector( query );


                return child && child.textContent;


            };


        }





        return mungeSorter;


    })();





    // parsers used in getSortData shortcut strings


    Isotope.sortDataParsers = {


        'parseInt': function( val ) {


            return parseInt( val, 10 );


        },


        'parseFloat': function( val ) {


            return parseFloat( val );


        }


    };





    // ----- sort method ----- //





    // sort filteredItem order


    proto._sort = function() {


        var sortByOpt = this.options.sortBy;


        if ( !sortByOpt ) {


            return;


        }


        // concat all sortBy and sortHistory


        var sortBys = [].concat.apply( sortByOpt, this.sortHistory );


        // sort magic


        var itemSorter = getItemSorter( sortBys, this.options.sortAscending );


        this.filteredItems.sort( itemSorter );


        // keep track of sortBy History


        if ( sortByOpt != this.sortHistory[0] ) {


            // add to front, oldest goes in last


            this.sortHistory.unshift( sortByOpt );


        }


    };





    // returns a function used for sorting


    function getItemSorter( sortBys, sortAsc ) {


        return function sorter( itemA, itemB ) {


            // cycle through all sortKeys


            for ( var i = 0; i < sortBys.length; i++ ) {


                var sortBy = sortBys[i];


                var a = itemA.sortData[ sortBy ];


                var b = itemB.sortData[ sortBy ];


                if ( a > b || a < b ) {


                    // if sortAsc is an object, use the value given the sortBy key


                    var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;


                    var direction = isAscending ? 1 : -1;


                    return ( a > b ? 1 : -1 ) * direction;


                }


            }


            return 0;


        };


    }





    // -------------------------- methods -------------------------- //





    // get layout mode


    proto._mode = function() {


        var layoutMode = this.options.layoutMode;


        var mode = this.modes[ layoutMode ];


        if ( !mode ) {


            // TODO console.error


            throw new Error( 'No layout mode: ' + layoutMode );


        }


        // HACK sync mode's options


        // any options set after init for layout mode need to be synced


        mode.options = this.options[ layoutMode ];


        return mode;


    };





    proto._resetLayout = function() {


        // trigger original reset layout


        Outlayer.prototype._resetLayout.call( this );


        this._mode()._resetLayout();


    };





    proto._getItemLayoutPosition = function( item  ) {


        return this._mode()._getItemLayoutPosition( item );


    };





    proto._manageStamp = function( stamp ) {


        this._mode()._manageStamp( stamp );


    };





    proto._getContainerSize = function() {


        return this._mode()._getContainerSize();


    };





    proto.needsResizeLayout = function() {


        return this._mode().needsResizeLayout();


    };





    // -------------------------- adding & removing -------------------------- //





    // HEADS UP overwrites default Outlayer appended


    proto.appended = function( elems ) {


        var items = this.addItems( elems );


        if ( !items.length ) {


            return;


        }


        // filter, layout, reveal new items


        var filteredItems = this._filterRevealAdded( items );


        // add to filteredItems


        this.filteredItems = this.filteredItems.concat( filteredItems );


    };





    // HEADS UP overwrites default Outlayer prepended


    proto.prepended = function( elems ) {


        var items = this._itemize( elems );


        if ( !items.length ) {


            return;


        }


        // start new layout


        this._resetLayout();


        this._manageStamps();


        // filter, layout, reveal new items


        var filteredItems = this._filterRevealAdded( items );


        // layout previous items


        this.layoutItems( this.filteredItems );


        // add to items and filteredItems


        this.filteredItems = filteredItems.concat( this.filteredItems );


        this.items = items.concat( this.items );


    };





    proto._filterRevealAdded = function( items ) {


        var filtered = this._filter( items );


        this.hide( filtered.needHide );


        // reveal all new items


        this.reveal( filtered.matches );


        // layout new items, no transition


        this.layoutItems( filtered.matches, true );


        return filtered.matches;


    };





    /**


     * Filter, sort, and layout newly-appended item elements


     * @param {Array or NodeList or Element} elems


     */


    proto.insert = function( elems ) {


        var items = this.addItems( elems );


        if ( !items.length ) {


            return;


        }


        // append item elements


        var i, item;


        var len = items.length;


        for ( i=0; i < len; i++ ) {


            item = items[i];


            this.element.appendChild( item.element );


        }


        // filter new stuff


        var filteredInsertItems = this._filter( items ).matches;


        // set flag


        for ( i=0; i < len; i++ ) {


            items[i].isLayoutInstant = true;


        }


        this.arrange();


        // reset flag


        for ( i=0; i < len; i++ ) {


            delete items[i].isLayoutInstant;


        }


        this.reveal( filteredInsertItems );


    };





    var _remove = proto.remove;


    proto.remove = function( elems ) {


        elems = utils.makeArray( elems );


        var removeItems = this.getItems( elems );


        // do regular thing


        _remove.call( this, elems );


        // bail if no items to remove


        var len = removeItems && removeItems.length;


        // remove elems from filteredItems


        for ( var i=0; len && i < len; i++ ) {


            var item = removeItems[i];


            // remove item from collection


            utils.removeFrom( this.filteredItems, item );


        }


    };





    proto.shuffle = function() {


        // update random sortData


        for ( var i=0; i < this.items.length; i++ ) {


            var item = this.items[i];


            item.sortData.random = Math.random();


        }


        this.options.sortBy = 'random';


        this._sort();


        this._layout();


    };





    /**


     * trigger fn without transition


     * kind of hacky to have this in the first place


     * @param {Function} fn


     * @param {Array} args


     * @returns ret


     * @private


     */


    proto._noTransition = function( fn, args ) {


        // save transitionDuration before disabling


        var transitionDuration = this.options.transitionDuration;


        // disable transition


        this.options.transitionDuration = 0;


        // do it


        var returnValue = fn.apply( this, args );


        // re-enable transition for reveal


        this.options.transitionDuration = transitionDuration;


        return returnValue;


    };





    // ----- helper methods ----- //





    /**


     * getter method for getting filtered item elements


     * @returns {Array} elems - collection of item elements


     */


    proto.getFilteredItemElements = function() {


        return this.filteredItems.map( function( item ) {


            return item.element;


        });


    };





    // -----  ----- //





    return Isotope;





}));



/*

 * jQuery.appear

 * https://github.com/bas2k/jquery.appear/

 * http://code.google.com/p/jquery-appear/

 * http://bas2k.ru/

 *

 * Copyright (c) 2009 Michael Hixson

 * Copyright (c) 2012-2014 Alexander Brovikov

 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)

 */

(function($) {

    $.fn.appear = function(fn, options) {



        var settings = $.extend({



            //arbitrary data to pass to fn

            data: undefined,



            //call fn only on the first appear?

            one: true,



            // X & Y accuracy

            accX: 0,

            accY: 0



        }, options);



        return this.each(function() {



            var t = $(this);



            //whether the element is currently visible

            t.appeared = false;



            if (!fn) {



                //trigger the custom event

                t.trigger('appear', settings.data);

                return;

            }



            var w = $(window);



            //fires the appear event when appropriate

            var check = function() {



                //is the element hidden?

                if (!t.is(':visible')) {



                    //it became hidden

                    t.appeared = false;

                    return;

                }



                //is the element inside the visible window?

                var a = w.scrollLeft();

                var b = w.scrollTop();

                var o = t.offset();

                var x = o.left;

                var y = o.top;



                var ax = settings.accX;

                var ay = settings.accY;

                var th = t.height();

                var wh = w.height();

                var tw = t.width();

                var ww = w.width();



                if (y + th + ay >= b &&

                    y <= b + wh + ay &&

                    x + tw + ax >= a &&

                    x <= a + ww + ax) {



                    //trigger the custom event

                    if (!t.appeared) t.trigger('appear', settings.data);



                } else {



                    //it scrolled out of view

                    t.appeared = false;

                }

            };



            //create a modified fn with some additional logic

            var modifiedFn = function() {



                //mark the element as visible

                t.appeared = true;



                //is this supposed to happen only once?

                if (settings.one) {



                    //remove the check

                    w.unbind('scroll', check);

                    var i = $.inArray(check, $.fn.appear.checks);

                    if (i >= 0) $.fn.appear.checks.splice(i, 1);

                }



                //trigger the original fn

                fn.apply(this, arguments);

            };



            //bind the modified fn to the element

            if (settings.one) t.one('appear', settings.data, modifiedFn);

            else t.bind('appear', settings.data, modifiedFn);



            //check whenever the window scrolls

            w.scroll(check);



            //check whenever the dom changes

            $.fn.appear.checks.push(check);



            //check now

            (check)();

        });

    };



    //keep a queue of appearance checks

    $.extend($.fn.appear, {



        checks: [],

        timeout: null,



        //process the queue

        checkAll: function() {

            var length = $.fn.appear.checks.length;

            if (length > 0) while (length--) {

                if (typeof $.fn.appear.checks[length] == 'function')

                    ($.fn.appear.checks[length])();

            }

        },



        //check the queue asynchronously

        run: function() {

            if ($.fn.appear.timeout) clearTimeout($.fn.appear.timeout);

            $.fn.appear.timeout = setTimeout($.fn.appear.checkAll, 20);

        }

    });



    //run checks when these methods are called

    $.each(['append', 'prepend', 'after', 'before', 'attr',

        'removeAttr', 'addClass', 'removeClass', 'toggleClass',

        'remove', 'css', 'show', 'hide'], function(i, n) {

        var old = $.fn[n];

        if (old) {

            $.fn[n] = function() {

                var r = old.apply(this, arguments);

                $.fn.appear.run();

                return r;

            }

        }

    });



})(jQuery);



/**!

 * easyPieChart

 * Lightweight plugin to render simple, animated and retina optimized pie charts

 *

 * @license 

 * @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)

 * @version 2.1.4

 **/



(function(root, factory) {

    if(typeof exports === 'object') {

        module.exports = factory(require('jquery'));

    }

    else if(typeof define === 'function' && define.amd) {

        define(['jquery'], factory);

    }

    else {

        factory(root.jQuery);

    }

}(this, function($) {

/**

 * Renderer to render the chart on a canvas object

 * @param {DOMElement} el      DOM element to host the canvas (root of the plugin)

 * @param {object}     options options object of the plugin

 */

var CanvasRenderer = function(el, options) {

	var cachedBackground;

	var canvas = document.createElement('canvas');



	el.appendChild(canvas);



	if (typeof(G_vmlCanvasManager) !== 'undefined') {

		G_vmlCanvasManager.initElement(canvas);

	}



	var ctx = canvas.getContext('2d');



	canvas.width = canvas.height = options.size;



	// canvas on retina devices

	var scaleBy = 1;

	if (window.devicePixelRatio > 1) {

		scaleBy = window.devicePixelRatio;

		canvas.style.width = canvas.style.height = [options.size, 'px'].join('');

		canvas.width = canvas.height = options.size * scaleBy;

		ctx.scale(scaleBy, scaleBy);

	}



	// move 0,0 coordinates to the center

	ctx.translate(options.size / 2, options.size / 2);



	// rotate canvas -90deg

	ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);



	var radius = (options.size - options.lineWidth) / 2;

	if (options.scaleColor && options.scaleLength) {

		radius -= options.scaleLength + 2; // 2 is the distance between scale and bar

	}



	// IE polyfill for Date

	Date.now = Date.now || function() {

		return +(new Date());

	};



	/**

	 * Draw a circle around the center of the canvas

	 * @param {strong} color     Valid CSS color string

	 * @param {number} lineWidth Width of the line in px

	 * @param {number} percent   Percentage to draw (float between -1 and 1)

	 */

	var drawCircle = function(color, lineWidth, percent) {

		percent = Math.min(Math.max(-1, percent || 0), 1);

		var isNegative = percent <= 0 ? true : false;



		ctx.beginPath();

		ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);



		ctx.strokeStyle = color;

		ctx.lineWidth = lineWidth;



		ctx.stroke();

	};



	/**

	 * Draw the scale of the chart

	 */

	var drawScale = function() {

		var offset;

		var length;



		ctx.lineWidth = 1;

		ctx.fillStyle = options.scaleColor;



		ctx.save();

		for (var i = 24; i > 0; --i) {

			if (i % 6 === 0) {

				length = options.scaleLength;

				offset = 0;

			} else {

				length = options.scaleLength * 0.6;

				offset = options.scaleLength - length;

			}

			ctx.fillRect(-options.size/2 + offset, 0, length, 1);

			ctx.rotate(Math.PI / 12);

		}

		ctx.restore();

	};



	/**

	 * Request animation frame wrapper with polyfill

	 * @return {function} Request animation frame method or timeout fallback

	 */

	var reqAnimationFrame = (function() {

		return  window.requestAnimationFrame ||

				window.webkitRequestAnimationFrame ||

				window.mozRequestAnimationFrame ||

				function(callback) {

					window.setTimeout(callback, 1000 / 60);

				};

	}());



	/**

	 * Draw the background of the plugin including the scale and the track

	 */

	var drawBackground = function() {

		if(options.scaleColor) drawScale();

		if(options.trackColor) drawCircle(options.trackColor, options.lineWidth, 1);

	};



  /**

    * Canvas accessor

   */

  this.getCanvas = function() {

    return canvas;

  };

  

  /**

    * Canvas 2D context 'ctx' accessor

   */

  this.getCtx = function() {

    return ctx;

  };



	/**

	 * Clear the complete canvas

	 */

	this.clear = function() {

		ctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);

	};



	/**

	 * Draw the complete chart

	 * @param {number} percent Percent shown by the chart between -100 and 100

	 */

	this.draw = function(percent) {

		// do we need to render a background

		if (!!options.scaleColor || !!options.trackColor) {

			// getImageData and putImageData are supported

			if (ctx.getImageData && ctx.putImageData) {

				if (!cachedBackground) {

					drawBackground();

					cachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);

				} else {

					ctx.putImageData(cachedBackground, 0, 0);

				}

			} else {

				this.clear();

				drawBackground();

			}

		} else {

			this.clear();

		}



		ctx.lineCap = options.lineCap;



		// if barcolor is a function execute it and pass the percent as a value

		var color;

		if (typeof(options.barColor) === 'function') {

			color = options.barColor(percent);

		} else {

			color = options.barColor;

		}



		// draw bar

		drawCircle(color, options.lineWidth, percent / 100);

	}.bind(this);



	/**

	 * Animate from some percent to some other percentage

	 * @param {number} from Starting percentage

	 * @param {number} to   Final percentage

	 */

	this.animate = function(from, to) {

		var startTime = Date.now();

		options.onStart(from, to);

		var animation = function() {

			var process = Math.min(Date.now() - startTime, options.animate.duration);

			var currentValue = options.easing(this, process, from, to - from, options.animate.duration);

			this.draw(currentValue);

			options.onStep(from, to, currentValue);

			if (process >= options.animate.duration) {

				options.onStop(from, to);

			} else {

				reqAnimationFrame(animation);

			}

		}.bind(this);



		reqAnimationFrame(animation);

	}.bind(this);

};



var EasyPieChart = function(el, opts) {

	var defaultOptions = {

		barColor: '#ef1e25',

		trackColor: '#f9f9f9',

		scaleColor: '#dfe0e0',

		scaleLength: 5,

		lineCap: 'round',

		lineWidth: 3,

		size: 110,

		rotate: 0,

		animate: {

			duration: 1000,

			enabled: true

		},

		easing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/

			t = t / (d/2);

			if (t < 1) {

				return c / 2 * t * t + b;

			}

			return -c/2 * ((--t)*(t-2) - 1) + b;

		},

		onStart: function(from, to) {

			return;

		},

		onStep: function(from, to, currentValue) {

			return;

		},

		onStop: function(from, to) {

			return;

		}

	};



	// detect present renderer

	if (typeof(CanvasRenderer) !== 'undefined') {

		defaultOptions.renderer = CanvasRenderer;

	} else if (typeof(SVGRenderer) !== 'undefined') {

		defaultOptions.renderer = SVGRenderer;

	} else {

		throw new Error('Please load either the SVG- or the CanvasRenderer');

	}



	var options = {};

	var currentValue = 0;



	/**

	 * Initialize the plugin by creating the options object and initialize rendering

	 */

	var init = function() {

		this.el = el;

		this.options = options;



		// merge user options into default options

		for (var i in defaultOptions) {

			if (defaultOptions.hasOwnProperty(i)) {

				options[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];

				if (typeof(options[i]) === 'function') {

					options[i] = options[i].bind(this);

				}

			}

		}



		// check for jQuery easing

		if (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {

			options.easing = jQuery.easing[options.easing];

		} else {

			options.easing = defaultOptions.easing;

		}



		// process earlier animate option to avoid bc breaks

		if (typeof(options.animate) === 'number') {

			options.animate = {

				duration: options.animate,

				enabled: true

			};

		}



		if (typeof(options.animate) === 'boolean' && !options.animate) {

			options.animate = {

				duration: 1000,

				enabled: options.animate

			};

		}



		// create renderer

		this.renderer = new options.renderer(el, options);



		// initial draw

		this.renderer.draw(currentValue);



		// initial update

		if (el.dataset && el.dataset.percent) {

			this.update(parseFloat(el.dataset.percent));

		} else if (el.getAttribute && el.getAttribute('data-percent')) {

			this.update(parseFloat(el.getAttribute('data-percent')));

		}

	}.bind(this);



	/**

	 * Update the value of the chart

	 * @param  {number} newValue Number between 0 and 100

	 * @return {object}          Instance of the plugin for method chaining

	 */

	this.update = function(newValue) {

		newValue = parseFloat(newValue);

		if (options.animate.enabled) {

			this.renderer.animate(currentValue, newValue);

		} else {

			this.renderer.draw(newValue);

		}

		currentValue = newValue;

		return this;

	}.bind(this);



	/**

	 * Disable animation

	 * @return {object} Instance of the plugin for method chaining

	 */

	this.disableAnimation = function() {

		options.animate.enabled = false;

		return this;

	};



	/**

	 * Enable animation

	 * @return {object} Instance of the plugin for method chaining

	 */

	this.enableAnimation = function() {

		options.animate.enabled = true;

		return this;

	};



	init();

};



$.fn.easyPieChart = function(options) {

	return this.each(function() {

		var instanceOptions;



		if (!$.data(this, 'easyPieChart')) {

			instanceOptions = $.extend({}, options, $(this).data());

			$.data(this, 'easyPieChart', new EasyPieChart(this, instanceOptions));

		}

	});

};



}));





/*global jQuery */

/*jshint browser:true */

/*!

* FitVids 1.1

*

* Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com

* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/

* Released under the WTFPL license - http://sam.zoy.org/wtfpl/

*

*/



(function( $ ){



  "use strict";



  $.fn.fitVids = function( options ) {

    var settings = {

      customSelector: null

    };



    if(!document.getElementById('fit-vids-style')) {

      // appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js

      var head = document.head || document.getElementsByTagName('head')[0];

      var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';

      var div = document.createElement('div');

      div.innerHTML = '<p>x</p><style id="fit-vids-style">' + css + '</style>';

      head.appendChild(div.childNodes[1]);

    }



    if ( options ) {

      $.extend( settings, options );

    }



    return this.each(function(){

      var selectors = [

        "iframe[src*='player.vimeo.com']",

        "iframe[src*='youtube.com']",

        "iframe[src*='youtube-nocookie.com']",

        "iframe[src*='kickstarter.com'][src*='video.html']",

        "object",

        "embed"

      ];



      if (settings.customSelector) {

        selectors.push(settings.customSelector);

      }



      var $allVideos = $(this).find(selectors.join(','));

      $allVideos = $allVideos.not("object object"); // SwfObj conflict patch



      $allVideos.each(function(){

        var $this = $(this);

        if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }

        var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),

            width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),

            aspectRatio = height / width;

        if(!$this.attr('id')){

          var videoID = 'fitvid' + Math.floor(Math.random()*999999);

          $this.attr('id', videoID);

        }

        $this.wrap('<div class="fluid-width-video-wrapper"></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+"%");

        $this.removeAttr('height').removeAttr('width');

      });

    });

  };

// Works with either jQuery or Zepto

})( window.jQuery || window.Zepto );





/*

 *	jQuery elevateZoom 3.0.8

 *	Demo's and documentation:

 *	www.elevateweb.co.uk/image-zoom

 *

 *	Copyright (c) 2012 Andrew Eades

 *	www.elevateweb.co.uk

 *

 *	Dual licensed under the GPL and MIT licenses.

 *	http://en.wikipedia.org/wiki/MIT_License

 *	http://en.wikipedia.org/wiki/GNU_General_Public_License

 *



/*

 *	jQuery elevateZoom 3.0.3

 *	Demo's and documentation:

 *	www.elevateweb.co.uk/image-zoom

 *

 *	Copyright (c) 2012 Andrew Eades

 *	www.elevateweb.co.uk

 *

 *	Dual licensed under the GPL and MIT licenses.

 *	http://en.wikipedia.org/wiki/MIT_License

 *	http://en.wikipedia.org/wiki/GNU_General_Public_License

 */





if ( typeof Object.create !== 'function' ) {

	Object.create = function( obj ) {

		function F() {};

		F.prototype = obj;

		return new F();

	};

}



(function( $, window, document, undefined ) {

	var ElevateZoom = {

			init: function( options, elem ) {

				var self = this;



				self.elem = elem;

				self.$elem = $( elem );

                

				self.imageSrc = self.$elem.data("zoom-image") ? self.$elem.data("zoom-image") : self.$elem.attr("src");



				self.options = $.extend( {}, $.fn.elevateZoom.options, options );



				//TINT OVERRIDE SETTINGS

				if(self.options.tint) {

					self.options.lensColour = "none", //colour of the lens background

					self.options.lensOpacity =  "1" //opacity of the lens

				}

				//INNER OVERRIDE SETTINGS

				if(self.options.zoomType == "inner") {self.options.showLens = false;}



                // INIT CONTAINER

                if (self.options.zoomContainer)

                    self.$container = $( self.options.zoomContainer );

                else

                    self.$container = $( 'body' );



				//Remove alt on hover



				self.$elem.parent().removeAttr('title').removeAttr('alt');



				self.zoomImage = self.imageSrc;



				self.refresh( 1 );







				//Create the image swap from the gallery 

				$('#'+self.options.gallery + ' a').click( function(e) { 



					//Set a class on the currently active gallery image

					if(self.options.galleryActiveClass){

						$('#'+self.options.gallery + ' a').removeClass(self.options.galleryActiveClass);

						$(this).addClass(self.options.galleryActiveClass);

					}

					//stop any link on the a tag from working

					e.preventDefault();



					//call the swap image function            

					if($(this).data("zoom-image")){self.zoomImagePre = $(this).data("zoom-image")}

					else{self.zoomImagePre = $(this).data("image");}

					self.swaptheimage($(this).data("image"), self.zoomImagePre);

					return false;

				});



			},



			refresh: function( length ) {

				var self = this;



				setTimeout(function() {

					self.fetch(self.imageSrc);



				}, length || self.options.refresh );

			},



			fetch: function(imgsrc) {

				//get the image

				var self = this;

				var newImg = new Image();

				newImg.onload = function() {

					//set the large image dimensions - used to calculte ratio's

					self.largeWidth = newImg.width;

					self.largeHeight = newImg.height;

					//once image is loaded start the calls

					self.startZoom();

					self.currentImage = self.imageSrc;

					//let caller know image has been loaded

					self.options.onZoomedImageLoaded(self.$elem);

				}

				newImg.src = imgsrc; // this must be done AFTER setting onload



				return;



			},



			startZoom: function( ) {

				var self = this;

				//get dimensions of the non zoomed image

				self.nzWidth = self.$elem.width();

				self.nzHeight = self.$elem.height();



				//activated elements

				self.isWindowActive = false;

				self.isLensActive = false;

				self.isTintActive = false;

				self.overWindow = false;    



				//CrossFade Wrappe

				if(self.options.imageCrossfade){

					self.zoomWrap = self.$elem.wrap('<div style="height:'+self.nzHeight+'px;width:'+self.nzWidth+'px;" class="zoomWrapper" />');        

					self.$elem.css('position', 'absolute'); 

				}



				self.zoomLock = 1;

				self.scrollingLock = false;

				self.changeBgSize = false;

				self.currentZoomLevel = self.options.zoomLevel;





				//get offset of the non zoomed image

				self.nzOffset = self.$elem.offset();

                //get offset of the container

                self.ctOffset = self.$container.offset();

				//calculate the width ratio of the large/small image

				self.widthRatio = (self.largeWidth/self.currentZoomLevel) / self.nzWidth;

				self.heightRatio = (self.largeHeight/self.currentZoomLevel) / self.nzHeight; 





				//if window zoom        

				if(self.options.zoomType == "window") {

					self.zoomWindowStyle = "overflow: hidden;"

						+ "background-position: 0px 0px;text-align:center;"  

						+ "background-color: " + String(self.options.zoomWindowBgColour)            

						+ ";width: " + String(self.options.zoomWindowWidth) + "px;"

						+ "height: " + String(self.options.zoomWindowHeight)

						+ "px;float: left;"

						+ "background-size: "+ self.largeWidth/self.currentZoomLevel+ "px " +self.largeHeight/self.currentZoomLevel + "px;"

						+ "display: none;z-index:100;"

						+ "border: " + String(self.options.borderSize) 

						+ "px solid " + self.options.borderColour 

						+ ";background-repeat: no-repeat;"

						+ "position: absolute;";

				}    





				//if inner  zoom    

				if(self.options.zoomType == "inner") {

					//has a border been put on the image? Lets cater for this



					var borderWidth = self.$elem.css("border-left-width");



					self.zoomWindowStyle = "overflow: hidden;"

						+ "margin-left: -" + String(self.options.borderSize) + "px;" 

						+ "margin-top: -" + String(self.options.borderSize) + "px;"         

						+ "background-position: 0px 0px;"

						+ "width: " + String(self.nzWidth) + "px;"

						+ "height: " + String(self.nzHeight)

						+ "px;float: left;"

						+ "display: none;"

						+ "cursor:"+(self.options.cursor)+";"

                        + "border: " + String(self.options.borderSize)

						+ "px solid " + self.options.borderColour 

						+ ";background-repeat: no-repeat;"

						+ "position: absolute;";

				}    







				//lens style for window zoom

				if(self.options.zoomType == "window") {





					// adjust images less than the window height



					if(self.nzHeight < self.options.zoomWindowWidth/self.widthRatio){

						lensHeight = self.nzHeight;              

					}

					else{

						lensHeight = String((self.options.zoomWindowHeight/self.heightRatio))

					}

					if(self.largeWidth < self.options.zoomWindowWidth){

						lensWidth = self.nzWidth;

					}       

					else{

						lensWidth =  (self.options.zoomWindowWidth/self.widthRatio);

					}





					self.lensStyle = "background-position: 0px 0px;width: " + String((self.options.zoomWindowWidth)/self.widthRatio) + "px;height: " + String((self.options.zoomWindowHeight)/self.heightRatio)

					+ "px;float: right;display: none;"

					+ "overflow: hidden;"

					+ "z-index: 999;"   

					+ "-webkit-transform: translateZ(0);"               

					+ "opacity:"+(self.options.lensOpacity)+";filter: alpha(opacity = "+(self.options.lensOpacity*100)+"); zoom:1;"

					+ "width:"+lensWidth+"px;"

					+ "height:"+lensHeight+"px;"

					+ "background-color:"+(self.options.lensColour)+";"					

					+ "cursor:"+(self.options.cursor)+";"

					+ "border: "+(self.options.lensBorderSize)+"px" +

					" solid "+(self.options.lensBorderColour)+";background-repeat: no-repeat;position: absolute;";

				} 





				//tint style

				self.tintStyle = "display: block;"

					+ "position: absolute;"

					+ "background-color: "+self.options.tintColour+";"	

					+ "filter:alpha(opacity=0);"		

					+ "opacity: 0;"	

					+ "width: " + self.nzWidth + "px;"

					+ "height: " + self.nzHeight + "px;"



					;



				//lens style for lens zoom with optional round for modern browsers

				self.lensRound = '';



				if(self.options.zoomType == "lens") {



					self.lensStyle = "background-position: 0px 0px;"

						+ "float: left;display: none;"

						+ "border: " + String(self.options.borderSize) + "px solid " + self.options.borderColour+";"

						+ "width:"+ String(self.options.lensSize) +"px;"

						+ "height:"+ String(self.options.lensSize)+"px;"

						+ "background-repeat: no-repeat;position: absolute;";





				}





				//does not round in all browsers

				if(self.options.lensShape == "round") {

					self.lensRound = "border-top-left-radius: " + String(self.options.lensSize / 2 + self.options.borderSize) + "px;"

					+ "border-top-right-radius: " + String(self.options.lensSize / 2 + self.options.borderSize) + "px;"

					+ "border-bottom-left-radius: " + String(self.options.lensSize / 2 + self.options.borderSize) + "px;"

					+ "border-bottom-right-radius: " + String(self.options.lensSize / 2 + self.options.borderSize) + "px;";



				}



				//create the div's                                                + ""

				//self.zoomContainer = $('<div/>').addClass('zoomContainer').css({"position":"relative", "height":self.nzHeight, "width":self.nzWidth});



                if (typeof self.ctOffset == 'undefined')

                    return;

                if (self.$container.find('.zoomContainer').length)

                    self.$container.find('.zoomContainer').remove();

				self.zoomContainer = $('<div class="zoomContainer" style="-webkit-transform: translateZ(0);position:absolute;left:'+(self.nzOffset.left-self.ctOffset.left)+'px;top:'+(self.nzOffset.top-self.ctOffset.top)+'px;height:'+self.nzHeight+'px;width:'+self.nzWidth+'px;"></div>');

				self.$container.append(self.zoomContainer);	





				//this will add overflow hidden and contrain the lens on lens mode       

				if(self.options.containLensZoom && self.options.zoomType == "lens"){

					self.zoomContainer.css("overflow", "hidden");

				}

				if(self.options.zoomType != "inner") {

					self.zoomLens = $("<div class='zoomLens' style='" + self.lensStyle + self.lensRound +"'>&nbsp;</div>")

					.appendTo(self.zoomContainer)

					.click(function () {

						self.$elem.trigger('click');

					});





					if(self.options.tint) {

						self.tintContainer = $('<div/>').addClass('tintContainer');	

						self.zoomTint = $("<div class='zoomTint' style='"+self.tintStyle+"'></div>");





						self.zoomLens.wrap(self.tintContainer);





						self.zoomTintcss = self.zoomLens.after(self.zoomTint);	



						//if tint enabled - set an image to show over the tint



						self.zoomTintImage = $('<img style="position: absolute; left: 0px; top: 0px; max-width: none; width: '+self.nzWidth+'px; height: '+self.nzHeight+'px;" src="'+self.imageSrc+'">')

						.appendTo(self.zoomLens)

						.click(function () {



							self.$elem.trigger('click');

						});



					}          



				}



				//create zoom window 

				if(isNaN(self.options.zoomWindowPosition)){

					self.zoomWindow = $("<div style='z-index:999;left:"+(self.windowOffsetLeft)+"px;top:"+(self.windowOffsetTop)+"px;" + self.zoomWindowStyle + "' class='zoomWindow'>&nbsp;</div>")

					.appendTo(self.$container)

					.click(function () {

						self.$elem.trigger('click');

					});

				}else{

					self.zoomWindow = $("<div style='z-index:999;left:"+(self.windowOffsetLeft)+"px;top:"+(self.windowOffsetTop)+"px;" + self.zoomWindowStyle + "' class='zoomWindow'>&nbsp;</div>")

					.appendTo(self.zoomContainer)

					.click(function () {

						self.$elem.trigger('click');

					});

				}              

				self.zoomWindowContainer = $('<div/>').addClass('zoomWindowContainer').css("width",self.options.zoomWindowWidth);

				self.zoomWindow.wrap(self.zoomWindowContainer);



				//  self.captionStyle = "text-align: left;background-color: black;color: white;font-weight: bold;padding: 10px;font-family: sans-serif;font-size: 11px";                                                           

				// self.zoomCaption = $('<div class="elevatezoom-caption" style="'+self.captionStyle+'display: block; width: 280px;">INSERT ALT TAG</div>').appendTo(self.zoomWindow.parent());



				if(self.options.zoomType == "lens") {

					self.zoomLens.css({ backgroundImage: "url('" + self.imageSrc + "')" }); 

				}

				if(self.options.zoomType == "window") {

					self.zoomWindow.css({ backgroundImage: "url('" + self.imageSrc + "')" }); 

				}

				if(self.options.zoomType == "inner") {

					self.zoomWindow.css({ backgroundImage: "url('" + self.imageSrc + "')" }); 

				}

				/*-------------------END THE ZOOM WINDOW AND LENS----------------------------------*/

				//touch events

				self.$elem.bind('touchmove', function(e){    

					e.preventDefault();

					var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];  

					self.setPosition(touch);



				});  

				self.zoomContainer.bind('touchmove', function(e){ 

					if(self.options.zoomType == "inner") {

						self.showHideWindow("show");



					}

					e.preventDefault();

					var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];  

					self.setPosition(touch); 



				});  	

				self.zoomContainer.bind('touchend', function(e){ 

					self.showHideWindow("hide");

					if(self.options.showLens) {self.showHideLens("hide");}

					if(self.options.tint && self.options.zoomType != "inner") {self.showHideTint("hide");}

				});  	



				self.$elem.bind('touchend', function(e){ 

					self.showHideWindow("hide");

					if(self.options.showLens) {self.showHideLens("hide");}

					if(self.options.tint && self.options.zoomType != "inner") {self.showHideTint("hide");}

				});  	

				if(self.options.showLens) {

					self.zoomLens.bind('touchmove', function(e){ 



						e.preventDefault();

						var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];  

						self.setPosition(touch); 

					});    





					self.zoomLens.bind('touchend', function(e){ 

						self.showHideWindow("hide");

						if(self.options.showLens) {self.showHideLens("hide");}

						if(self.options.tint && self.options.zoomType != "inner") {self.showHideTint("hide");}

					});  

				}

				//Needed to work in IE

				self.$elem.bind('mousemove', function(e){   

					if(self.overWindow == false){self.setElements("show");}

					//make sure on orientation change the setposition is not fired

					if(self.lastX !== e.clientX || self.lastY !== e.clientY){

						self.setPosition(e);

						self.currentLoc = e;

					}   

					self.lastX = e.clientX;

					self.lastY = e.clientY;    



				});  	



				self.zoomContainer.bind('mousemove', function(e){ 



					if(self.overWindow == false){self.setElements("show");} 



					//make sure on orientation change the setposition is not fired 

					if(self.lastX !== e.clientX || self.lastY !== e.clientY){

						self.setPosition(e);

						self.currentLoc = e;

					}   

					self.lastX = e.clientX;

					self.lastY = e.clientY;    

				});  	

				if(self.options.zoomType != "inner") {

					self.zoomLens.bind('mousemove', function(e){      

						//make sure on orientation change the setposition is not fired

						if(self.lastX !== e.clientX || self.lastY !== e.clientY){

							self.setPosition(e);

							self.currentLoc = e;

						}   

						self.lastX = e.clientX;

						self.lastY = e.clientY;    

					});

				}

				if(self.options.tint && self.options.zoomType != "inner") {

					self.zoomTint.bind('mousemove', function(e){ 

						//make sure on orientation change the setposition is not fired

						if(self.lastX !== e.clientX || self.lastY !== e.clientY){

							self.setPosition(e);

							self.currentLoc = e;

						}   

						self.lastX = e.clientX;

						self.lastY = e.clientY;    

					});



				}

				if(self.options.zoomType == "inner") {

					self.zoomWindow.bind('mousemove', function(e) {

						//self.overWindow = true;

						//make sure on orientation change the setposition is not fired

						if(self.lastX !== e.clientX || self.lastY !== e.clientY){

							self.setPosition(e);

							self.currentLoc = e;

						}   

						self.lastX = e.clientX;

						self.lastY = e.clientY;    

					});



				}



				//  lensFadeOut: 500,  zoomTintFadeIn

				self.zoomContainer.add(self.$elem).mouseenter(function(){



					if(self.overWindow == false){self.setElements("show");} 





				}).mouseleave(function(){

					if(!self.scrollLock){

						self.setElements("hide");

					}

				});

				//end ove image



				if(self.options.zoomType != "inner") {

					self.zoomWindow.mouseenter(function(){

						self.overWindow = true;   

						self.setElements("hide");                  

					}).mouseleave(function(){



						self.overWindow = false;

					});

				}

				//end ove image





                //	var delta = parseInt(e.originalEvent.wheelDelta || -e.originalEvent.detail);



				//  $(this).empty();    

				//  return false;



				//fix for initial zoom setting

				if (self.options.zoomLevel != 1){

					//	self.changeZoomLevel(self.currentZoomLevel);

				}

				//set the min zoomlevel

				if(self.options.minZoomLevel){

					self.minZoomLevel = self.options.minZoomLevel;

				}

				else{

					self.minZoomLevel = self.options.scrollZoomIncrement * 2;

				}





				if(self.options.scrollZoom){





					self.zoomContainer.add(self.$elem).bind('mousewheel DOMMouseScroll MozMousePixelScroll', function(e){





//						in IE there is issue with firing of mouseleave - So check whether still scrolling

//						and on mouseleave check if scrolllock          

						self.scrollLock = true;

						clearTimeout($.data(this, 'timer'));

						$.data(this, 'timer', setTimeout(function() {

							self.scrollLock = false;

							//do something

						}, 250));



						var theEvent = e.originalEvent.wheelDelta || e.originalEvent.detail*-1





						//this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;

						//   e.preventDefault();





						e.stopImmediatePropagation();

						e.stopPropagation();

						e.preventDefault();





						if(theEvent /120 > 0) {

							//scrolling up

							if(self.currentZoomLevel >= self.minZoomLevel){ 

								self.changeZoomLevel(self.currentZoomLevel-self.options.scrollZoomIncrement);        

							}



						}

						else{

							//scrolling down





							if(self.options.maxZoomLevel){

								if(self.currentZoomLevel <= self.options.maxZoomLevel){           

									self.changeZoomLevel(parseFloat(self.currentZoomLevel)+self.options.scrollZoomIncrement);

								}

							}

							else{

								//andy 



								self.changeZoomLevel(parseFloat(self.currentZoomLevel)+self.options.scrollZoomIncrement);

							}



						}

						return false;

					});

				}





			},

			setElements: function(type) {

				var self = this;

        if(!self.options.zoomEnabled){return false;}

				if(type=="show"){

					if(self.isWindowSet){

						if(self.options.zoomType == "inner") {self.showHideWindow("show");}

						if(self.options.zoomType == "window") {self.showHideWindow("show");}

						if(self.options.showLens) {self.showHideLens("show");}

						if(self.options.tint && self.options.zoomType != "inner") {self.showHideTint("show");

						}

					}

				}



				if(type=="hide"){

					if(self.options.zoomType == "window") {self.showHideWindow("hide");}

					if(!self.options.tint) {self.showHideWindow("hide");}

					if(self.options.showLens) {self.showHideLens("hide");}

					if(self.options.tint) {	self.showHideTint("hide");}

				}   

			},

			setPosition: function(e) {

      

				var self = this;

        

        if(!self.options.zoomEnabled){return false;}



				//recaclc offset each time in case the image moves

				//this can be caused by other on page elements

				self.nzHeight = self.$elem.height();

				self.nzWidth = self.$elem.width();

				self.nzOffset = self.$elem.offset();

                self.ctOffset = self.$container.offset();



				if(self.options.tint && self.options.zoomType != "inner") {

					self.zoomTint.css({ top: 0});

					self.zoomTint.css({ left: 0});

				}

				//set responsive       

				//will checking if the image needs changing before running this code work faster?

				if(self.options.responsive && !self.options.scrollZoom){

					if(self.options.showLens){ 

						if(self.nzHeight < self.options.zoomWindowWidth/self.widthRatio){

							lensHeight = self.nzHeight;              

						}

						else{

							lensHeight = String((self.options.zoomWindowHeight/self.heightRatio))

						}

						if(self.largeWidth < self.options.zoomWindowWidth){

							lensWidth = self.nzWidth;

						}       

						else{

							lensWidth =  (self.options.zoomWindowWidth/self.widthRatio);

						}

						self.widthRatio = self.largeWidth / self.nzWidth;

						self.heightRatio = self.largeHeight / self.nzHeight;        

						if(self.options.zoomType != "lens") {





							//possibly dont need to keep recalcalculating

							//if the lens is heigher than the image, then set lens size to image size

							if(self.nzHeight < self.options.zoomWindowWidth/self.widthRatio){

								lensHeight = self.nzHeight;  



							}

							else{

								lensHeight = String((self.options.zoomWindowHeight/self.heightRatio))

							}



							if(self.options.zoomWindowWidth < self.options.zoomWindowWidth){

								lensWidth = self.nzWidth;

							}       

							else{

								lensWidth =  (self.options.zoomWindowWidth/self.widthRatio);

							}            



							self.zoomLens.css('width', lensWidth);    

							self.zoomLens.css('height', lensHeight); 



							if(self.options.tint){    

								self.zoomTintImage.css('width', self.nzWidth);    

								self.zoomTintImage.css('height', self.nzHeight); 

							}



						}                     

						if(self.options.zoomType == "lens") {  



							self.zoomLens.css({ width: String(self.options.lensSize) + 'px', height: String(self.options.lensSize) + 'px' })      





						}        

						//end responsive image change

					}

				}



				//container fix

				self.zoomContainer.css({ top: self.nzOffset.top - self.ctOffset.top});

				self.zoomContainer.css({ left: self.nzOffset.left - self.ctOffset.left});

				self.mouseLeft = parseInt(e.pageX - self.nzOffset.left);

				self.mouseTop = parseInt(e.pageY - self.nzOffset.top);

				//calculate the Location of the Lens



				//calculate the bound regions - but only if zoom window

				if(self.options.zoomType == "window") {

					self.Etoppos = (self.mouseTop < (self.zoomLens.height()/2));

					self.Eboppos = (self.mouseTop > self.nzHeight - (self.zoomLens.height()/2)-(self.options.lensBorderSize*2));

					self.Eloppos = (self.mouseLeft < 0+((self.zoomLens.width()/2))); 

					self.Eroppos = (self.mouseLeft > (self.nzWidth - (self.zoomLens.width()/2)-(self.options.lensBorderSize*2)));  

				}

				//calculate the bound regions - but only for inner zoom

				if(self.options.zoomType == "inner"){ 

					self.Etoppos = (self.mouseTop < ((self.nzHeight/2)/self.heightRatio) );

					self.Eboppos = (self.mouseTop > (self.nzHeight - ((self.nzHeight/2)/self.heightRatio)));

					self.Eloppos = (self.mouseLeft < 0+(((self.nzWidth/2)/self.widthRatio)));

					self.Eroppos = (self.mouseLeft > (self.nzWidth - (self.nzWidth/2)/self.widthRatio-(self.options.lensBorderSize*2)));  

				}



				// if the mouse position of the slider is one of the outerbounds, then hide  window and lens

				if (self.mouseLeft <= 0 || self.mouseTop < 0 || self.mouseLeft > self.nzWidth || self.mouseTop > self.nzHeight ) {				          

					self.setElements("hide");

					return;

				}

				//else continue with operations

				else {





					//lens options

					if(self.options.showLens) {

						//		self.showHideLens("show");

						//set background position of lens

						self.lensLeftPos = String(self.mouseLeft - self.zoomLens.width() / 2);

						self.lensTopPos = String(self.mouseTop - self.zoomLens.height() / 2);





					}

					//adjust the background position if the mouse is in one of the outer regions 



					//Top region

					if(self.Etoppos){

						self.lensTopPos = 0;

					}

					//Left Region

					if(self.Eloppos){

						self.windowLeftPos = 0;

						self.lensLeftPos = 0;

						self.tintpos=0;

					}     

					//Set bottom and right region for window mode

					if(self.options.zoomType == "window") {

						if(self.Eboppos){

							self.lensTopPos = Math.max( (self.nzHeight)-self.zoomLens.height()-(self.options.lensBorderSize*2), 0 );

						} 

						if(self.Eroppos){

							self.lensLeftPos = (self.nzWidth-(self.zoomLens.width())-(self.options.lensBorderSize*2));

						}  

					}  

					//Set bottom and right region for inner mode

					if(self.options.zoomType == "inner") {

						if(self.Eboppos){

							self.lensTopPos = Math.max( ((self.nzHeight)-(self.options.lensBorderSize*2)), 0 );

						} 

						if(self.Eroppos){

							self.lensLeftPos = (self.nzWidth-(self.nzWidth)-(self.options.lensBorderSize*2));

						}  



					}

					//if lens zoom

					if(self.options.zoomType == "lens") {  

						self.windowLeftPos = String(((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomLens.width() / 2) * (-1));   

						self.windowTopPos = String(((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomLens.height() / 2) * (-1));



						self.zoomLens.css({ backgroundPosition: self.windowLeftPos + 'px ' + self.windowTopPos + 'px' });



						if(self.changeBgSize){  



							if(self.nzHeight>self.nzWidth){  

								if(self.options.zoomType == "lens"){       

									self.zoomLens.css({ "background-size": self.largeWidth/self.newvalueheight + 'px ' + self.largeHeight/self.newvalueheight + 'px' });

								}   



								self.zoomWindow.css({ "background-size": self.largeWidth/self.newvalueheight + 'px ' + self.largeHeight/self.newvalueheight + 'px' });

							}

							else{     

								if(self.options.zoomType == "lens"){       

									self.zoomLens.css({ "background-size": self.largeWidth/self.newvaluewidth + 'px ' + self.largeHeight/self.newvaluewidth + 'px' });

								}   

								self.zoomWindow.css({ "background-size": self.largeWidth/self.newvaluewidth + 'px ' + self.largeHeight/self.newvaluewidth + 'px' });            

							}

							self.changeBgSize = false;

						}    



						self.setWindowPostition(e);  

					}

					//if tint zoom   

					if(self.options.tint && self.options.zoomType != "inner") {

						self.setTintPosition(e);



					}

					//set the css background position 

					if(self.options.zoomType == "window") {

						self.setWindowPostition(e);   

					}

					if(self.options.zoomType == "inner") {

						self.setWindowPostition(e);   

					}

					if(self.options.showLens) {



						if(self.fullwidth && self.options.zoomType != "lens"){

							self.lensLeftPos = 0;



						}

						self.zoomLens.css({ left: self.lensLeftPos + 'px', top: self.lensTopPos + 'px' })  

					}



				} //end else







			},

			showHideWindow: function(change) {

				var self = this;              

				if(change == "show"){      

					if(!self.isWindowActive){

						if(self.options.zoomWindowFadeIn){

							self.zoomWindow.stop(true, true, false).fadeIn(self.options.zoomWindowFadeIn);

						}

						else{self.zoomWindow.show();}

						self.isWindowActive = true;

					}            

				}

				if(change == "hide"){

					if(self.isWindowActive){

						if(self.options.zoomWindowFadeOut){

							self.zoomWindow.stop(true, true).fadeOut(self.options.zoomWindowFadeOut);

						}

						else{self.zoomWindow.hide();}

						self.isWindowActive = false;        

					}      

				}

			},

			showHideLens: function(change) {

				var self = this;              

				if(change == "show"){      

					if(!self.isLensActive){

						if(self.options.lensFadeIn){

							self.zoomLens.stop(true, true, false).fadeIn(self.options.lensFadeIn);

						}

						else{self.zoomLens.show();}

						self.isLensActive = true;

					}            

				}

				if(change == "hide"){

					if(self.isLensActive){

						if(self.options.lensFadeOut){

							self.zoomLens.stop(true, true).fadeOut(self.options.lensFadeOut);

						}

						else{self.zoomLens.hide();}

						self.isLensActive = false;        

					}      

				}

			},

			showHideTint: function(change) {

				var self = this;              

				if(change == "show"){      

					if(!self.isTintActive){



						if(self.options.zoomTintFadeIn){

							self.zoomTint.css({opacity:self.options.tintOpacity}).animate().stop(true, true).fadeIn("slow");

						}

						else{

							self.zoomTint.css({opacity:self.options.tintOpacity}).animate();

							self.zoomTint.show();





						}

						self.isTintActive = true;

					}            

				}

				if(change == "hide"){      

					if(self.isTintActive){ 



						if(self.options.zoomTintFadeOut){

							self.zoomTint.stop(true, true).fadeOut(self.options.zoomTintFadeOut);

						}

						else{self.zoomTint.hide();}

						self.isTintActive = false;        

					}      

				}

			},

			setLensPostition: function( e ) {





			},

			setWindowPostition: function( e ) {

				//return obj.slice( 0, count );

				var self = this;



				if(!isNaN(self.options.zoomWindowPosition)){



					switch (self.options.zoomWindowPosition) { 

					case 1: //done         

						self.windowOffsetTop = (self.options.zoomWindowOffety);//DONE - 1

						self.windowOffsetLeft =(+self.nzWidth); //DONE 1, 2, 3, 4, 16

						break;

					case 2:

						if(self.options.zoomWindowHeight > self.nzHeight){ //positive margin



							self.windowOffsetTop = ((self.options.zoomWindowHeight/2)-(self.nzHeight/2))*(-1);

							self.windowOffsetLeft =(self.nzWidth); //DONE 1, 2, 3, 4, 16

						}

						else{ //negative margin



						}

						break;

					case 3: //done        

						self.windowOffsetTop = (self.nzHeight - self.zoomWindow.height() - (self.options.borderSize*2)); //DONE 3,9

						self.windowOffsetLeft =(self.nzWidth); //DONE 1, 2, 3, 4, 16

						break;      

					case 4: //done  

						self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8

						self.windowOffsetLeft =(self.nzWidth); //DONE 1, 2, 3, 4, 16

						break;

					case 5: //done  

						self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8

						self.windowOffsetLeft =(self.nzWidth-self.zoomWindow.width()-(self.options.borderSize*2)); //DONE - 5,15

						break;

					case 6: 

						if(self.options.zoomWindowHeight > self.nzHeight){ //positive margin

							self.windowOffsetTop = (self.nzHeight);  //DONE - 4,5,6,7,8



							self.windowOffsetLeft =((self.options.zoomWindowWidth/2)-(self.nzWidth/2)+(self.options.borderSize*2))*(-1);  

						}

						else{ //negative margin



						}





						break;

					case 7: //done  

						self.windowOffsetTop = (self.nzHeight);  //DONE - 4,5,6,7,8

						self.windowOffsetLeft = 0; //DONE 7, 13

						break;

					case 8: //done  

						self.windowOffsetTop = (self.nzHeight); //DONE - 4,5,6,7,8

						self.windowOffsetLeft =(self.zoomWindow.width()+(self.options.borderSize*2) )* (-1);  //DONE 8,9,10,11,12

						break;

					case 9:  //done  

						self.windowOffsetTop = (self.nzHeight - self.zoomWindow.height() - (self.options.borderSize*2)); //DONE 3,9

						self.windowOffsetLeft =(self.zoomWindow.width()+(self.options.borderSize*2) )* (-1);  //DONE 8,9,10,11,12

						break;

					case 10: 

						if(self.options.zoomWindowHeight > self.nzHeight){ //positive margin



							self.windowOffsetTop = ((self.options.zoomWindowHeight/2)-(self.nzHeight/2))*(-1);

							self.windowOffsetLeft =(self.zoomWindow.width()+(self.options.borderSize*2) )* (-1);  //DONE 8,9,10,11,12

						}

						else{ //negative margin



						}

						break;

					case 11: 

						self.windowOffsetTop = (self.options.zoomWindowOffety);

						self.windowOffsetLeft =(self.zoomWindow.width()+(self.options.borderSize*2) )* (-1);  //DONE 8,9,10,11,12

						break;

					case 12: //done  

						self.windowOffsetTop = (self.zoomWindow.height()+(self.options.borderSize*2))*(-1); //DONE 12,13,14,15,16

						self.windowOffsetLeft =(self.zoomWindow.width()+(self.options.borderSize*2) )* (-1);  //DONE 8,9,10,11,12

						break;

					case 13: //done  

						self.windowOffsetTop = (self.zoomWindow.height()+(self.options.borderSize*2))*(-1); //DONE 12,13,14,15,16

						self.windowOffsetLeft =(0); //DONE 7, 13

						break;

					case 14: 

						if(self.options.zoomWindowHeight > self.nzHeight){ //positive margin

							self.windowOffsetTop = (self.zoomWindow.height()+(self.options.borderSize*2))*(-1); //DONE 12,13,14,15,16



							self.windowOffsetLeft =((self.options.zoomWindowWidth/2)-(self.nzWidth/2)+(self.options.borderSize*2))*(-1);  

						}

						else{ //negative margin



						}



						break;

					case 15://done   

						self.windowOffsetTop = (self.zoomWindow.height()+(self.options.borderSize*2))*(-1); //DONE 12,13,14,15,16

						self.windowOffsetLeft =(self.nzWidth-self.zoomWindow.width()-(self.options.borderSize*2)); //DONE - 5,15

						break;

					case 16:  //done  

						self.windowOffsetTop = (self.zoomWindow.height()+(self.options.borderSize*2))*(-1); //DONE 12,13,14,15,16

						self.windowOffsetLeft =(self.nzWidth); //DONE 1, 2, 3, 4, 16

						break;            

					default: //done  

						self.windowOffsetTop = (self.options.zoomWindowOffety);//DONE - 1

					self.windowOffsetLeft =(self.nzWidth); //DONE 1, 2, 3, 4, 16

					} 

				} //end isNAN

				else{

					//WE CAN POSITION IN A CLASS - ASSUME THAT ANY STRING PASSED IS

					self.externalContainer = $('#'+self.options.zoomWindowPosition);

					self.externalContainerWidth = self.externalContainer.width();

					self.externalContainerHeight = self.externalContainer.height();

					self.externalContainerOffset = self.externalContainer.offset();



					self.windowOffsetTop = self.externalContainerOffset.top;//DONE - 1

					self.windowOffsetLeft =self.externalContainerOffset.left; //DONE 1, 2, 3, 4, 16



				}

				self.isWindowSet = true;

				self.windowOffsetTop = self.windowOffsetTop + self.options.zoomWindowOffety;

				self.windowOffsetLeft = self.windowOffsetLeft + self.options.zoomWindowOffetx;



				self.zoomWindow.css({ top: self.windowOffsetTop});

				self.zoomWindow.css({ left: self.windowOffsetLeft});



				if(self.options.zoomType == "inner") {

					self.zoomWindow.css({ top: 0});

					self.zoomWindow.css({ left: 0});



				}   





				self.windowLeftPos = String(((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomWindow.width() / 2) * (-1));   

				self.windowTopPos = String(((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomWindow.height() / 2) * (-1));

				if(self.Etoppos){self.windowTopPos = 0;}

				if(self.Eloppos){self.windowLeftPos = 0;}     

				if(self.Eboppos){self.windowTopPos = (self.largeHeight/self.currentZoomLevel-self.zoomWindow.height())*(-1);  } 

				if(self.Eroppos){self.windowLeftPos = ((self.largeWidth/self.currentZoomLevel-self.zoomWindow.width())*(-1));}    



				//stops micro movements

				if(self.fullheight){

					self.windowTopPos = 0;



				}

				if(self.fullwidth){

					self.windowLeftPos = 0;



				}

				//set the css background position 





				if(self.options.zoomType == "window" || self.options.zoomType == "inner") {



					if(self.zoomLock == 1){

						//overrides for images not zoomable

						if(self.widthRatio <= 1){



							self.windowLeftPos = 0;

						}

						if(self.heightRatio <= 1){ 

							self.windowTopPos = 0;

						}

					}

					// adjust images less than the window height



					if(self.largeHeight < self.options.zoomWindowHeight){



						self.windowTopPos = 0;

					}

					if(self.largeWidth < self.options.zoomWindowWidth){

						self.windowLeftPos = 0;

					}       



					//set the zoomwindow background position

					if (self.options.easing){



						//     if(self.changeZoom){

						//           clearInterval(self.loop);

						//           self.changeZoom = false;

						//           self.loop = false;



						//            }

						//set the pos to 0 if not set

						if(!self.xp){self.xp = 0;}

						if(!self.yp){self.yp = 0;}  

						//if loop not already started, then run it 

						if (!self.loop){           

							self.loop = setInterval(function(){                

								//using zeno's paradox    



								self.xp += (self.windowLeftPos  - self.xp) / self.options.easingAmount; 

								self.yp += (self.windowTopPos  - self.yp) / self.options.easingAmount;

								if(self.scrollingLock){





									clearInterval(self.loop);

									self.xp = self.windowLeftPos;

									self.yp = self.windowTopPos            



									self.xp = ((e.pageX - self.nzOffset.left) * self.widthRatio - self.zoomWindow.width() / 2) * (-1);

									self.yp = (((e.pageY - self.nzOffset.top) * self.heightRatio - self.zoomWindow.height() / 2) * (-1));                         



									if(self.changeBgSize){    

										if(self.nzHeight>self.nzWidth){  

											if(self.options.zoomType == "lens"){      

												self.zoomLens.css({ "background-size": self.largeWidth/self.newvalueheight + 'px ' + self.largeHeight/self.newvalueheight + 'px' });

											}   

											self.zoomWindow.css({ "background-size": self.largeWidth/self.newvalueheight + 'px ' + self.largeHeight/self.newvalueheight + 'px' });

										}

										else{   

											if(self.options.zoomType != "lens"){      

												self.zoomLens.css({ "background-size": self.largeWidth/self.newvaluewidth + 'px ' + self.largeHeight/self.newvalueheight + 'px' });

											}            

											self.zoomWindow.css({ "background-size": self.largeWidth/self.newvaluewidth + 'px ' + self.largeHeight/self.newvaluewidth + 'px' });            



										}



										/*

             if(!self.bgxp){self.bgxp = self.largeWidth/self.newvalue;}

						if(!self.bgyp){self.bgyp = self.largeHeight/self.newvalue ;}  

                 if (!self.bgloop){   

                 	self.bgloop = setInterval(function(){   



                 self.bgxp += (self.largeWidth/self.newvalue  - self.bgxp) / self.options.easingAmount; 

								self.bgyp += (self.largeHeight/self.newvalue  - self.bgyp) / self.options.easingAmount;



           self.zoomWindow.css({ "background-size": self.bgxp + 'px ' + self.bgyp + 'px' });





                  }, 16);



                 }

										 */

										self.changeBgSize = false;

									}



									self.zoomWindow.css({ backgroundPosition: self.windowLeftPos + 'px ' + self.windowTopPos + 'px' });

									self.scrollingLock = false;

									self.loop = false;



								}

								else{

									if(self.changeBgSize){    

										if(self.nzHeight>self.nzWidth){ 

											if(self.options.zoomType == "lens"){      

												self.zoomLens.css({ "background-size": self.largeWidth/self.newvalueheight + 'px ' + self.largeHeight/self.newvalueheight + 'px' });

											}         

											self.zoomWindow.css({ "background-size": self.largeWidth/self.newvalueheight + 'px ' + self.largeHeight/self.newvalueheight + 'px' });

										}

										else{                 

											if(self.options.zoomType != "lens"){     

												self.zoomLens.css({ "background-size": self.largeWidth/self.newvaluewidth + 'px ' + self.largeHeight/self.newvaluewidth + 'px' });

											}      

											self.zoomWindow.css({ "background-size": self.largeWidth/self.newvaluewidth + 'px ' + self.largeHeight/self.newvaluewidth + 'px' });            

										}

										self.changeBgSize = false;

									}                   



									self.zoomWindow.css({ backgroundPosition: self.xp + 'px ' + self.yp + 'px' });

								}       

							}, 16);

						}

					}   

					else{    

						if(self.changeBgSize){  

							if(self.nzHeight>self.nzWidth){  

								if(self.options.zoomType == "lens"){      

									self.zoomLens.css({ "background-size": self.largeWidth/self.newvalueheight + 'px ' + self.largeHeight/self.newvalueheight + 'px' });

								} 



								self.zoomWindow.css({ "background-size": self.largeWidth/self.newvalueheight + 'px ' + self.largeHeight/self.newvalueheight + 'px' });

							}

							else{     

								if(self.options.zoomType == "lens"){      

									self.zoomLens.css({ "background-size": self.largeWidth/self.newvaluewidth + 'px ' + self.largeHeight/self.newvaluewidth + 'px' });

								} 

								if((self.largeHeight/self.newvaluewidth) < self.options.zoomWindowHeight){ 



									self.zoomWindow.css({ "background-size": self.largeWidth/self.newvaluewidth + 'px ' + self.largeHeight/self.newvaluewidth + 'px' });            

								}

								else{



									self.zoomWindow.css({ "background-size": self.largeWidth/self.newvalueheight + 'px ' + self.largeHeight/self.newvalueheight + 'px' });   

								}



							}

							self.changeBgSize = false;

						}     



						self.zoomWindow.css({ backgroundPosition: self.windowLeftPos + 'px ' + self.windowTopPos + 'px' });       

					}

				} 

			},

			setTintPosition: function(e){

				var self = this;

				self.nzOffset = self.$elem.offset();

				self.tintpos = String(((e.pageX - self.nzOffset.left)-(self.zoomLens.width() / 2)) * (-1)); 

				self.tintposy = String(((e.pageY - self.nzOffset.top) - self.zoomLens.height() / 2) * (-1));	

				if(self.Etoppos){

					self.tintposy = 0;

				}

				if(self.Eloppos){

					self.tintpos=0;

				}     

				if(self.Eboppos){

					self.tintposy = (self.nzHeight-self.zoomLens.height()-(self.options.lensBorderSize*2))*(-1);

				} 

				if(self.Eroppos){

					self.tintpos = ((self.nzWidth-self.zoomLens.width()-(self.options.lensBorderSize*2))*(-1));

				}    

				if(self.options.tint) {

					//stops micro movements

					if(self.fullheight){

						self.tintposy = 0;



					}

					if(self.fullwidth){ 

						self.tintpos = 0;



					}   

					self.zoomTintImage.css({'left': self.tintpos+'px'});

					self.zoomTintImage.css({'top': self.tintposy+'px'});

				}

			},



			swaptheimage: function(smallimage, largeimage){

				var self = this;

				var newImg = new Image(); 



				if(self.options.loadingIcon){

					self.spinner = $('<div style="background: url(\''+self.options.loadingIcon+'\') no-repeat center;height:'+self.nzHeight+'px;width:'+self.nzWidth+'px;z-index: 2000;position: absolute; background-position: center center;"></div>');

					self.$elem.after(self.spinner);

				}



				self.options.onImageSwap(self.$elem);



				newImg.onload = function() {

					self.largeWidth = newImg.width;

					self.largeHeight = newImg.height;

					self.zoomImage = largeimage;

                    if (typeof self.zoomWindow == 'undefined') return;

					self.zoomWindow.css({ "background-size": self.largeWidth + 'px ' + self.largeHeight + 'px' });

					self.zoomWindow.css({ "background-size": self.largeWidth + 'px ' + self.largeHeight + 'px' });





					self.swapAction(smallimage, largeimage);

					return;              

				}          

				newImg.src = largeimage; // this must be done AFTER setting onload



			},

			swapAction: function(smallimage, largeimage){





				var self = this;    



				var newImg2 = new Image(); 

				newImg2.onload = function() {

					//re-calculate values

					self.nzHeight = newImg2.height;

					self.nzWidth = newImg2.width;

					self.options.onImageSwapComplete(self.$elem);



					self.doneCallback();  

					return;      

				}          

				newImg2.src = smallimage; 



				//reset the zoomlevel to that initially set in options

				self.currentZoomLevel = self.options.zoomLevel;

				self.options.maxZoomLevel = false;



				//swaps the main image

				//self.$elem.attr("src",smallimage);

				//swaps the zoom image     

				if(self.options.zoomType == "lens") {

					self.zoomLens.css({ backgroundImage: "url('" + largeimage + "')" }); 

				}

				if(self.options.zoomType == "window") {

					self.zoomWindow.css({ backgroundImage: "url('" + largeimage + "')" }); 

				}

				if(self.options.zoomType == "inner") {

					self.zoomWindow.css({ backgroundImage: "url('" + largeimage + "')" }); 

				} 







				self.currentImage = largeimage;



				if(self.options.imageCrossfade){

					var oldImg = self.$elem;

					var newImg = oldImg.clone();         

					self.$elem.attr("src",smallimage)

					self.$elem.after(newImg);

					newImg.stop(true).fadeOut(self.options.imageCrossfade, function() {

						$(this).remove();         

					});



					//       				if(self.options.zoomType == "inner"){

					//remove any attributes on the cloned image so we can resize later

					self.$elem.width("auto").removeAttr("width");

					self.$elem.height("auto").removeAttr("height");

					//   }



					oldImg.fadeIn(self.options.imageCrossfade);



					if(self.options.tint && self.options.zoomType != "inner") {



						var oldImgTint = self.zoomTintImage;

						var newImgTint = oldImgTint.clone();         

						self.zoomTintImage.attr("src",largeimage)

						self.zoomTintImage.after(newImgTint);

						newImgTint.stop(true).fadeOut(self.options.imageCrossfade, function() {

							$(this).remove();         

						});







						oldImgTint.fadeIn(self.options.imageCrossfade);





						//self.zoomTintImage.attr("width",elem.data("image"));



						//resize the tint window

						self.zoomTint.css({ height: self.$elem.height()});

						self.zoomTint.css({ width: self.$elem.width()});

					}    



					self.zoomContainer.css("height", self.$elem.height());

					self.zoomContainer.css("width", self.$elem.width());



					if(self.options.zoomType == "inner"){ 

						if(!self.options.constrainType){

							self.zoomWrap.parent().css("height", self.$elem.height());

							self.zoomWrap.parent().css("width", self.$elem.width());



							self.zoomWindow.css("height", self.$elem.height());

							self.zoomWindow.css("width", self.$elem.width());

						}

					} 



					if(self.options.imageCrossfade){  

						self.zoomWrap.css("height", self.$elem.height());

						self.zoomWrap.css("width", self.$elem.width());

					} 

				}

				else{

					self.$elem.attr("src",smallimage); 

					if(self.options.tint) {

						self.zoomTintImage.attr("src",largeimage);

						//self.zoomTintImage.attr("width",elem.data("image"));

						self.zoomTintImage.attr("height",self.$elem.height());

						//self.zoomTintImage.attr('src') = elem.data("image");

						self.zoomTintImage.css({ height: self.$elem.height()}); 

						self.zoomTint.css({ height: self.$elem.height()});



					}

					self.zoomContainer.css("height", self.$elem.height());

					self.zoomContainer.css("width", self.$elem.width());



					if(self.options.imageCrossfade){  

						self.zoomWrap.css("height", self.$elem.height());

						self.zoomWrap.css("width", self.$elem.width());

					} 

				}              

				if(self.options.constrainType){     



					//This will contrain the image proportions

					if(self.options.constrainType == "height"){ 



						self.zoomContainer.css("height", self.options.constrainSize);

						self.zoomContainer.css("width", "auto");



						if(self.options.imageCrossfade){  

							self.zoomWrap.css("height", self.options.constrainSize);

							self.zoomWrap.css("width", "auto"); 

							self.constwidth = self.zoomWrap.width();





						}

						else{                  

							self.$elem.css("height", self.options.constrainSize);

							self.$elem.css("width", "auto");

							self.constwidth = self.$elem.width();

						} 



						if(self.options.zoomType == "inner"){



							self.zoomWrap.parent().css("height", self.options.constrainSize);

							self.zoomWrap.parent().css("width", self.constwidth);   

							self.zoomWindow.css("height", self.options.constrainSize);

							self.zoomWindow.css("width", self.constwidth);    

						}        

						if(self.options.tint){

							self.tintContainer.css("height", self.options.constrainSize);

							self.tintContainer.css("width", self.constwidth);

							self.zoomTint.css("height", self.options.constrainSize);

							self.zoomTint.css("width", self.constwidth);

							self.zoomTintImage.css("height", self.options.constrainSize);

							self.zoomTintImage.css("width", self.constwidth); 

						} 



					}

					if(self.options.constrainType == "width"){       

						self.zoomContainer.css("height", "auto");

						self.zoomContainer.css("width", self.options.constrainSize);



						if(self.options.imageCrossfade){

							self.zoomWrap.css("height", "auto");

							self.zoomWrap.css("width", self.options.constrainSize);

							self.constheight = self.zoomWrap.height();

						}

						else{            

							self.$elem.css("height", "auto");

							self.$elem.css("width", self.options.constrainSize); 

							self.constheight = self.$elem.height();              

						} 

						if(self.options.zoomType == "inner"){

							self.zoomWrap.parent().css("height", self.constheight);

							self.zoomWrap.parent().css("width", self.options.constrainSize);   

							self.zoomWindow.css("height", self.constheight);

							self.zoomWindow.css("width", self.options.constrainSize);    

						} 

						if(self.options.tint){

							self.tintContainer.css("height", self.constheight);

							self.tintContainer.css("width", self.options.constrainSize);

							self.zoomTint.css("height", self.constheight);

							self.zoomTint.css("width", self.options.constrainSize);

							self.zoomTintImage.css("height", self.constheight);

							self.zoomTintImage.css("width", self.options.constrainSize); 

						}   



					}        





				}



			},

			doneCallback: function(){



				var self = this;

				if(self.options.loadingIcon){

					self.spinner.hide();     

				}   



				self.nzOffset = self.$elem.offset();

				self.nzWidth = self.$elem.width();

				self.nzHeight = self.$elem.height();



				// reset the zoomlevel back to default

				self.currentZoomLevel = self.options.zoomLevel;



				//ratio of the large to small image

				self.widthRatio = self.largeWidth / self.nzWidth;

				self.heightRatio = self.largeHeight / self.nzHeight; 



				//NEED TO ADD THE LENS SIZE FOR ROUND

				// adjust images less than the window height

				if(self.options.zoomType == "window") {



					if(self.nzHeight < self.options.zoomWindowWidth/self.widthRatio){

						lensHeight = self.nzHeight;  



					}

					else{

						lensHeight = String((self.options.zoomWindowHeight/self.heightRatio))

					}



					if(self.options.zoomWindowWidth < self.options.zoomWindowWidth){

						lensWidth = self.nzWidth;

					}       

					else{

						lensWidth =  (self.options.zoomWindowWidth/self.widthRatio);

					}





					if(self.zoomLens){



						self.zoomLens.css('width', lensWidth);    

						self.zoomLens.css('height', lensHeight); 





					}

				}

			},

			getCurrentImage: function(){

				var self = this;  

				return self.zoomImage; 

			}, 

			getGalleryList: function(){

				var self = this;   

				//loop through the gallery options and set them in list for fancybox

				self.gallerylist = [];

				if (self.options.gallery){ 





					$('#'+self.options.gallery + ' a').each(function() {



						var img_src = '';

						if($(this).data("zoom-image")){

							img_src = $(this).data("zoom-image");

						}

						else if($(this).data("image")){

							img_src = $(this).data("image");

						}			

						//put the current image at the start

						if(img_src == self.zoomImage){

							self.gallerylist.unshift({

								href: ''+img_src+'',

								title: $(this).find('img').attr("title")

							});	

						}

						else{

							self.gallerylist.push({

								href: ''+img_src+'',

								title: $(this).find('img').attr("title")

							});

						}





					});

				}                                                       

				//if no gallery - return current image

				else{

					self.gallerylist.push({

						href: ''+self.zoomImage+'',

						title: $(this).find('img').attr("title")

					}); 

				}

				return self.gallerylist;



			},

			changeZoomLevel: function(value){

				var self = this;   



				//flag a zoom, so can adjust the easing during setPosition     

				self.scrollingLock = true;   



				//round to two decimal places

				self.newvalue = parseFloat(value).toFixed(2);

				newvalue = parseFloat(value).toFixed(2);









				//maxwidth & Maxheight of the image

				maxheightnewvalue = self.largeHeight/((self.options.zoomWindowHeight / self.nzHeight) * self.nzHeight);     

				maxwidthtnewvalue = self.largeWidth/((self.options.zoomWindowWidth / self.nzWidth) * self.nzWidth);   	









				//calculate new heightratio

				if(self.options.zoomType != "inner")

				{

					if(maxheightnewvalue <= newvalue){

						self.heightRatio = (self.largeHeight/maxheightnewvalue) / self.nzHeight;

						self.newvalueheight = maxheightnewvalue;

						self.fullheight = true;



					}

					else{

						self.heightRatio = (self.largeHeight/newvalue) / self.nzHeight; 

						self.newvalueheight = newvalue;

						self.fullheight = false;



					}





//					calculate new width ratio



					if(maxwidthtnewvalue <= newvalue){

						self.widthRatio = (self.largeWidth/maxwidthtnewvalue) / self.nzWidth;

						self.newvaluewidth = maxwidthtnewvalue;

						self.fullwidth = true;



					}

					else{

						self.widthRatio = (self.largeWidth/newvalue) / self.nzWidth; 

						self.newvaluewidth = newvalue;

						self.fullwidth = false;



					}

					if(self.options.zoomType == "lens"){

						if(maxheightnewvalue <= newvalue){

							self.fullwidth = true;

							self.newvaluewidth = maxheightnewvalue;



						} else{

							self.widthRatio = (self.largeWidth/newvalue) / self.nzWidth; 

							self.newvaluewidth = newvalue;



							self.fullwidth = false;

						}}

				}







				if(self.options.zoomType == "inner")

				{

					maxheightnewvalue = parseFloat(self.largeHeight/self.nzHeight).toFixed(2);     

					maxwidthtnewvalue = parseFloat(self.largeWidth/self.nzWidth).toFixed(2);      

					if(newvalue > maxheightnewvalue){

						newvalue = maxheightnewvalue;

					}

					if(newvalue > maxwidthtnewvalue){

						newvalue = maxwidthtnewvalue;

					}      





					if(maxheightnewvalue <= newvalue){





						self.heightRatio = (self.largeHeight/newvalue) / self.nzHeight; 

						if(newvalue > maxheightnewvalue){

							self.newvalueheight = maxheightnewvalue;

						}else{

							self.newvalueheight = newvalue;

						}

						self.fullheight = true;





					}

					else{







						self.heightRatio = (self.largeHeight/newvalue) / self.nzHeight; 



						if(newvalue > maxheightnewvalue){



							self.newvalueheight = maxheightnewvalue;

						}else{

							self.newvalueheight = newvalue;

						}

						self.fullheight = false;

					}









					if(maxwidthtnewvalue <= newvalue){   



						self.widthRatio = (self.largeWidth/newvalue) / self.nzWidth; 

						if(newvalue > maxwidthtnewvalue){



							self.newvaluewidth = maxwidthtnewvalue;

						}else{

							self.newvaluewidth = newvalue;

						}



						self.fullwidth = true;





					}

					else{  



						self.widthRatio = (self.largeWidth/newvalue) / self.nzWidth; 

						self.newvaluewidth = newvalue;

						self.fullwidth = false;

					}        





				} //end inner

				scrcontinue = false;



				if(self.options.zoomType == "inner"){



					if(self.nzWidth > self.nzHeight){

						if( self.newvaluewidth <= maxwidthtnewvalue){

							scrcontinue = true;

						}

						else{



							scrcontinue = false;

							self.fullheight = true;

							self.fullwidth = true;

						}

					}

					if(self.nzHeight > self.nzWidth){     

						if( self.newvaluewidth <= maxwidthtnewvalue){

							scrcontinue = true;

						}

						else{

							scrcontinue = false;  



							self.fullheight = true;

							self.fullwidth = true;

						}

					}

				}



				if(self.options.zoomType != "inner"){

					scrcontinue = true;

				}



				if(scrcontinue){







					self.zoomLock = 0;

					self.changeZoom = true;



					//if lens height is less than image height





					if(((self.options.zoomWindowHeight)/self.heightRatio) <= self.nzHeight){





						self.currentZoomLevel = self.newvalueheight; 

						if(self.options.zoomType != "lens" && self.options.zoomType != "inner") {

							self.changeBgSize = true;



							self.zoomLens.css({height: String((self.options.zoomWindowHeight)/self.heightRatio) + 'px' }) 

						}

						if(self.options.zoomType == "lens" || self.options.zoomType == "inner") {  

							self.changeBgSize = true;  

						}	





					} 









					if((self.options.zoomWindowWidth/self.widthRatio) <= self.nzWidth){







						if(self.options.zoomType != "inner"){

							if(self.newvaluewidth > self.newvalueheight)   {

								self.currentZoomLevel = self.newvaluewidth;                 



							}

						}



						if(self.options.zoomType != "lens" && self.options.zoomType != "inner") {

							self.changeBgSize = true;



							self.zoomLens.css({width: String((self.options.zoomWindowWidth)/self.widthRatio) + 'px' })

						}

						if(self.options.zoomType == "lens" || self.options.zoomType == "inner") {  

							self.changeBgSize = true;

						}	



					}

					if(self.options.zoomType == "inner"){

						self.changeBgSize = true;  



						if(self.nzWidth > self.nzHeight){

							self.currentZoomLevel = self.newvaluewidth;

						}

						if(self.nzHeight > self.nzWidth){

							self.currentZoomLevel = self.newvaluewidth;

						}

					}



				}      //under



				//sets the boundry change, called in setWindowPos

				self.setPosition(self.currentLoc);

				//

			},

			closeAll: function(){

				if(self.zoomWindow){self.zoomWindow.hide();}

				if(self.zoomLens){self.zoomLens.hide();}

				if(self.zoomTint){self.zoomTint.hide();}

			},

			changeState: function(value){

      	var self = this;

				if(value == 'enable'){self.options.zoomEnabled = true;}

				if(value == 'disable'){self.options.zoomEnabled = false;}



			}



	};









	$.fn.elevateZoom = function( options ) {

		return this.each(function() {

			var elevate = Object.create( ElevateZoom );



			elevate.init( options, this );



			$.data( this, 'elevateZoom', elevate );



		});

	};



	$.fn.elevateZoom.options = {

			zoomActivation: "hover", // Can also be click (PLACEHOLDER FOR NEXT VERSION)

      zoomEnabled: true, //false disables zoomwindow from showing

			preloading: 1, //by default, load all the images, if 0, then only load images after activated (PLACEHOLDER FOR NEXT VERSION)

			zoomLevel: 1, //default zoom level of image

			scrollZoom: false, //allow zoom on mousewheel, true to activate

			scrollZoomIncrement: 0.1,  //steps of the scrollzoom

			minZoomLevel: false,

			maxZoomLevel: false,

			easing: false,

			easingAmount: 12,

			lensSize: 200,

			zoomWindowWidth: 400,

			zoomWindowHeight: 400,

			zoomWindowOffetx: 0,

			zoomWindowOffety: 0,

			zoomWindowPosition: 1,

			zoomWindowBgColour: "#fff",

			lensFadeIn: false,

			lensFadeOut: false,

			debug: false,

			zoomWindowFadeIn: false,

			zoomWindowFadeOut: false,

			zoomWindowAlwaysShow: false,

			zoomTintFadeIn: false,

			zoomTintFadeOut: false,

			borderSize: 4,

			showLens: true,

			borderColour: "#888",

			lensBorderSize: 1,

			lensBorderColour: "#000",

			lensShape: "square", //can be "round"

			zoomType: "window", //window is default,  also "lens" available -

			containLensZoom: false,

			lensColour: "white", //colour of the lens background

			lensOpacity: 0.4, //opacity of the lens

			lenszoom: false,

			tint: false, //enable the tinting

			tintColour: "#333", //default tint color, can be anything, red, #ccc, rgb(0,0,0)

			tintOpacity: 0.4, //opacity of the tint

			gallery: false,

			galleryActiveClass: "zoomGalleryActive",

			imageCrossfade: false,

			constrainType: false,  //width or height

			constrainSize: false,  //in pixels the dimensions you want to constrain on

			loadingIcon: false, //http://www.example.com/spinner.gif

			cursor:"default", // user should set to what they want the cursor as, if they have set a click function

			responsive:true,

			onComplete: $.noop,

			onZoomedImageLoaded: function() {},

			onImageSwap: $.noop,

			onImageSwapComplete: $.noop,

            zoomContainer: 'body' // will be body

	};



})( jQuery, window, document );



/*!


 * fancyBox - jQuery Plugin


 * version: 2.1.5 (Fri, 14 Jun 2013)


 * requires jQuery v1.6 or later


 *


 * Examples at http://fancyapps.com/fancybox/


 * License: www.fancyapps.com/fancybox/#license


 *


 * Copyright 2012 Janis Skarnelis - janis@fancyapps.com


 *


 */





;(function (window, document, $, undefined) {


    "use strict";





    var H = $("html"),


        W = $(window),


        D = $(document),


        F = $.fancybox = function () {


            F.open.apply( this, arguments );


        },


        IE =  navigator.userAgent.match(/msie/i),


        didUpdate	= null,


        isTouch		= document.createTouch !== undefined,





        isQuery	= function(obj) {


            return obj && obj.hasOwnProperty && obj instanceof $;


        },


        isString = function(str) {


            return str && $.type(str) === "string";


        },


        isPercentage = function(str) {


            return isString(str) && str.indexOf('%') > 0;


        },


        isScrollable = function(el) {


            return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight)));


        },


        getScalar = function(orig, dim) {


            var value = parseInt(orig, 10) || 0;





            if (dim && isPercentage(orig)) {


                value = F.getViewport()[ dim ] / 100 * value;


            }





            return Math.ceil(value);


        },


        getValue = function(value, dim) {


            return getScalar(value, dim) + 'px';


        };





    $.extend(F, {


        // The current version of fancyBox


        version: '2.1.5',





        defaults: {


            padding : 15,


            margin  : 20,





            width     : 800,


            height    : 600,


            minWidth  : 100,


            minHeight : 100,


            maxWidth  : 9999,


            maxHeight : 9999,


            pixelRatio: 1, // Set to 2 for retina display support





            autoSize   : true,


            autoHeight : false,


            autoWidth  : false,





            autoResize  : true,


            autoCenter  : !isTouch,


            fitToView   : true,


            aspectRatio : false,


            topRatio    : 0.5,


            leftRatio   : 0.5,





            scrolling : 'auto', // 'auto', 'yes' or 'no'


            wrapCSS   : '',





            arrows     : true,


            closeBtn   : true,


            closeClick : false,


            nextClick  : false,


            mouseWheel : true,


            autoPlay   : false,


            playSpeed  : 3000,


            preload    : 3,


            modal      : false,


            loop       : true,





            ajax  : {


                dataType : 'html',


                headers  : { 'X-fancyBox': true }


            },


            iframe : {


                scrolling : 'auto',


                preload   : true


            },


            swf : {


                wmode: 'transparent',


                allowfullscreen   : 'true',


                allowscriptaccess : 'always'


            },





            keys  : {


                next : {


                    13 : 'left', // enter


                    34 : 'up',   // page down


                    39 : 'left', // right arrow


                    40 : 'up'    // down arrow


                },


                prev : {


                    8  : 'right',  // backspace


                    33 : 'down',   // page up


                    37 : 'right',  // left arrow


                    38 : 'down'    // up arrow


                },


                close  : [27], // escape key


                play   : [32], // space - start/stop slideshow


                toggle : [70]  // letter "f" - toggle fullscreen


            },





            direction : {


                next : 'left',


                prev : 'right'


            },





            scrollOutside  : true,





            // Override some properties


            index   : 0,


            type    : null,


            href    : null,


            content : null,


            title   : null,





            // HTML templates


            tpl: {


                wrap     : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',


                image    : '<img class="fancybox-image" src="{href}" alt="" />',


                iframe   : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>',


                error    : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',


                closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',


                next     : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',


                prev     : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>',


                loading  : '<div id="fancybox-loading"><div></div></div>'


            },





            // Properties for each animation type


            // Opening fancyBox


            openEffect  : 'fade', // 'elastic', 'fade' or 'none'


            openSpeed   : 250,


            openEasing  : 'swing',


            openOpacity : true,


            openMethod  : 'zoomIn',





            // Closing fancyBox


            closeEffect  : 'fade', // 'elastic', 'fade' or 'none'


            closeSpeed   : 250,


            closeEasing  : 'swing',


            closeOpacity : true,


            closeMethod  : 'zoomOut',





            // Changing next gallery item


            nextEffect : 'elastic', // 'elastic', 'fade' or 'none'


            nextSpeed  : 250,


            nextEasing : 'swing',


            nextMethod : 'changeIn',





            // Changing previous gallery item


            prevEffect : 'elastic', // 'elastic', 'fade' or 'none'


            prevSpeed  : 250,


            prevEasing : 'swing',


            prevMethod : 'changeOut',





            // Enable default helpers


            helpers : {


                overlay : true,


                title   : true


            },





            // Callbacks


            onCancel     : $.noop, // If canceling


            beforeLoad   : $.noop, // Before loading


            afterLoad    : $.noop, // After loading


            beforeShow   : $.noop, // Before changing in current item


            afterShow    : $.noop, // After opening


            beforeChange : $.noop, // Before changing gallery item


            beforeClose  : $.noop, // Before closing


            afterClose   : $.noop  // After closing


        },





        //Current state


        group    : {}, // Selected group


        opts     : {}, // Group options


        previous : null,  // Previous element


        coming   : null,  // Element being loaded


        current  : null,  // Currently loaded element


        isActive : false, // Is activated


        isOpen   : false, // Is currently open


        isOpened : false, // Have been fully opened at least once





        wrap  : null,


        skin  : null,


        outer : null,


        inner : null,





        player : {


            timer    : null,


            isActive : false


        },





        // Loaders


        ajaxLoad   : null,


        imgPreload : null,





        // Some collections


        transitions : {},


        helpers     : {},





        /*


         *	Static methods


         */





        open: function (group, opts) {


            if (!group) {


                return;


            }





            if (!$.isPlainObject(opts)) {


                opts = {};


            }





            // Close if already active


            if (false === F.close(true)) {


                return;


            }





            // Normalize group


            if (!$.isArray(group)) {


                group = isQuery(group) ? $(group).get() : [group];


            }





            // Recheck if the type of each element is `object` and set content type (image, ajax, etc)


            $.each(group, function(i, element) {


                var obj = {},


                    href,


                    title,


                    content,


                    type,


                    rez,


                    hrefParts,


                    selector;





                if ($.type(element) === "object") {


                    // Check if is DOM element


                    if (element.nodeType) {


                        element = $(element);


                    }





                    if (isQuery(element)) {


                        obj = {


                            href    : element.data('fancybox-href') || element.attr('href'),


                            title   : $('<div/>').text( element.data('fancybox-title') || element.attr('title') || '' ).html(),


                            isDom   : true,


                            element : element


                        };





                        if ($.metadata) {


                            $.extend(true, obj, element.metadata());


                        }





                    } else {


                        obj = element;


                    }


                }





                href  = opts.href  || obj.href || (isString(element) ? element : null);


                title = opts.title !== undefined ? opts.title : obj.title || '';





                content = opts.content || obj.content;


                type    = content ? 'html' : (opts.type  || obj.type);





                if (!type && obj.isDom) {


                    type = element.data('fancybox-type');





                    if (!type) {


                        rez  = element.prop('class').match(/fancybox\.(\w+)/);


                        type = rez ? rez[1] : null;


                    }


                }





                if (isString(href)) {


                    // Try to guess the content type


                    if (!type) {


                        if (F.isImage(href)) {


                            type = 'image';





                        } else if (F.isSWF(href)) {


                            type = 'swf';





                        } else if (href.charAt(0) === '#') {


                            type = 'inline';





                        } else if (isString(element)) {


                            type    = 'html';


                            content = element;


                        }


                    }





                    // Split url into two pieces with source url and content selector, e.g,


                    // "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id"


                    if (type === 'ajax') {


                        hrefParts = href.split(/\s+/, 2);


                        href      = hrefParts.shift();


                        selector  = hrefParts.shift();


                    }


                }





                if (!content) {


                    if (type === 'inline') {


                        if (href) {


                            content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7





                        } else if (obj.isDom) {


                            content = element;


                        }





                    } else if (type === 'html') {


                        content = href;





                    } else if (!type && !href && obj.isDom) {


                        type    = 'inline';


                        content = element;


                    }


                }





                $.extend(obj, {


                    href     : href,


                    type     : type,


                    content  : content,


                    title    : title,


                    selector : selector


                });





                group[ i ] = obj;


            });





            // Extend the defaults


            F.opts = $.extend(true, {}, F.defaults, opts);





            // All options are merged recursive except keys


            if (opts.keys !== undefined) {


                F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false;


            }





            F.group = group;





            return F._start(F.opts.index);


        },





        // Cancel image loading or abort ajax request


        cancel: function () {


            var coming = F.coming;





            if (coming && false === F.trigger('onCancel')) {


                return;


            }





            F.hideLoading();





            if (!coming) {


                return;


            }





            if (F.ajaxLoad) {


                F.ajaxLoad.abort();


            }





            F.ajaxLoad = null;





            if (F.imgPreload) {


                F.imgPreload.onload = F.imgPreload.onerror = null;


            }





            if (coming.wrap) {


                coming.wrap.stop(true, true).trigger('onReset').remove();


            }





            F.coming = null;





            // If the first item has been canceled, then clear everything


            if (!F.current) {


                F._afterZoomOut( coming );


            }


        },





        // Start closing animation if is open; remove immediately if opening/closing


        close: function (event) {


            F.cancel();





            if (false === F.trigger('beforeClose')) {


                return;


            }





            F.unbindEvents();





            if (!F.isActive) {


                return;


            }





            if (!F.isOpen || event === true) {


                $('.fancybox-wrap').stop(true).trigger('onReset').remove();





                F._afterZoomOut();





            } else {


                F.isOpen = F.isOpened = false;


                F.isClosing = true;





                $('.fancybox-item, .fancybox-nav').remove();





                F.wrap.stop(true, true).removeClass('fancybox-opened');





                F.transitions[ F.current.closeMethod ]();


            }


        },





        // Manage slideshow:


        //   $.fancybox.play(); - toggle slideshow


        //   $.fancybox.play( true ); - start


        //   $.fancybox.play( false ); - stop


        play: function ( action ) {


            var clear = function () {


                    clearTimeout(F.player.timer);


                },


                set = function () {


                    clear();





                    if (F.current && F.player.isActive) {


                        F.player.timer = setTimeout(F.next, F.current.playSpeed);


                    }


                },


                stop = function () {


                    clear();





                    D.unbind('.player');





                    F.player.isActive = false;





                    F.trigger('onPlayEnd');


                },


                start = function () {


                    if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {


                        F.player.isActive = true;





                        D.bind({


                            'onCancel.player beforeClose.player' : stop,


                            'onUpdate.player'   : set,


                            'beforeLoad.player' : clear


                        });





                        set();





                        F.trigger('onPlayStart');


                    }


                };





            if (action === true || (!F.player.isActive && action !== false)) {


                start();


            } else {


                stop();


            }


        },





        // Navigate to next gallery item


        next: function ( direction ) {


            var current = F.current;





            if (current) {


                if (!isString(direction)) {


                    direction = current.direction.next;


                }





                F.jumpto(current.index + 1, direction, 'next');


            }


        },





        // Navigate to previous gallery item


        prev: function ( direction ) {


            var current = F.current;





            if (current) {


                if (!isString(direction)) {


                    direction = current.direction.prev;


                }





                F.jumpto(current.index - 1, direction, 'prev');


            }


        },





        // Navigate to gallery item by index


        jumpto: function ( index, direction, router ) {


            var current = F.current;





            if (!current) {


                return;


            }





            index = getScalar(index);





            F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ];


            F.router    = router || 'jumpto';





            if (current.loop) {


                if (index < 0) {


                    index = current.group.length + (index % current.group.length);


                }





                index = index % current.group.length;


            }





            if (current.group[ index ] !== undefined) {


                F.cancel();





                F._start(index);


            }


        },





        // Center inside viewport and toggle position type to fixed or absolute if needed


        reposition: function (e, onlyAbsolute) {


            var current = F.current,


                wrap    = current ? current.wrap : null,


                pos;





            if (wrap) {


                pos = F._getPosition(onlyAbsolute);





                if (e && e.type === 'scroll') {


                    delete pos.position;





                    wrap.stop(true, true).animate(pos, 200);





                } else {


                    wrap.css(pos);





                    current.pos = $.extend({}, current.dim, pos);


                }


            }


        },





        update: function (e) {


            var type = (e && e.originalEvent && e.originalEvent.type),


                anyway = !type || type === 'orientationchange';





            if (anyway) {


                clearTimeout(didUpdate);





                didUpdate = null;


            }





            if (!F.isOpen || didUpdate) {


                return;


            }





            didUpdate = setTimeout(function() {


                var current = F.current;





                if (!current || F.isClosing) {


                    return;


                }





                F.wrap.removeClass('fancybox-tmp');





                if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) {


                    F._setDimension();


                }





                if (!(type === 'scroll' && current.canShrink)) {


                    F.reposition(e);


                }





                F.trigger('onUpdate');





                didUpdate = null;





            }, (anyway && !isTouch ? 0 : 300));


        },





        // Shrink content to fit inside viewport or restore if resized


        toggle: function ( action ) {


            if (F.isOpen) {


                F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView;





                // Help browser to restore document dimensions


                if (isTouch) {


                    F.wrap.removeAttr('style').addClass('fancybox-tmp');





                    F.trigger('onUpdate');


                }





                F.update();


            }


        },





        hideLoading: function () {


            D.unbind('.loading');





            $('#fancybox-loading').remove();


        },





        showLoading: function () {


            var el, viewport;





            F.hideLoading();





            el = $(F.opts.tpl.loading).click(F.cancel).appendTo('body');





            // If user will press the escape-button, the request will be canceled


            D.bind('keydown.loading', function(e) {


                if ((e.which || e.keyCode) === 27) {


                    e.preventDefault();





                    F.cancel();


                }


            });





            if (!F.defaults.fixed) {


                viewport = F.getViewport();





                el.css({


                    position : 'absolute',


                    top  : (viewport.h * 0.5) + viewport.y,


                    left : (viewport.w * 0.5) + viewport.x


                });


            }





            F.trigger('onLoading');


        },





        getViewport: function () {


            var locked = (F.current && F.current.locked) || false,


                rez    = {


                    x: W.scrollLeft(),


                    y: W.scrollTop()


                };





            if (locked && locked.length) {


                rez.w = locked[0].clientWidth;


                rez.h = locked[0].clientHeight;





            } else {


                // See http://bugs.jquery.com/ticket/6724


                rez.w = isTouch && window.innerWidth  ? window.innerWidth  : W.width();


                rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height();


            }





            return rez;


        },





        // Unbind the keyboard / clicking actions


        unbindEvents: function () {


            if (F.wrap && isQuery(F.wrap)) {


                F.wrap.unbind('.fb');


            }





            D.unbind('.fb');


            W.unbind('.fb');


        },





        bindEvents: function () {


            var current = F.current,


                keys;





            if (!current) {


                return;


            }





            // Changing document height on iOS devices triggers a 'resize' event,


            // that can change document height... repeating infinitely


            W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update);





            keys = current.keys;





            if (keys) {


                D.bind('keydown.fb', function (e) {


                    var code   = e.which || e.keyCode,


                        target = e.target || e.srcElement;





                    // Skip esc key if loading, because showLoading will cancel preloading


                    if (code === 27 && F.coming) {


                        return false;


                    }





                    // Ignore key combinations and key events within form elements


                    if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) {


                        $.each(keys, function(i, val) {


                            if (current.group.length > 1 && val[ code ] !== undefined) {


                                F[ i ]( val[ code ] );





                                e.preventDefault();


                                return false;


                            }





                            if ($.inArray(code, val) > -1) {


                                F[ i ] ();





                                e.preventDefault();


                                return false;


                            }


                        });


                    }


                });


            }





            if ($.fn.mousewheel && current.mouseWheel) {


                F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) {


                    var target = e.target || null,


                        parent = $(target),


                        canScroll = false;





                    while (parent.length) {


                        if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) {


                            break;


                        }





                        canScroll = isScrollable( parent[0] );


                        parent    = $(parent).parent();


                    }





                    if (delta !== 0 && !canScroll) {


                        if (F.group.length > 1 && !current.canShrink) {


                            if (deltaY > 0 || deltaX > 0) {


                                F.prev( deltaY > 0 ? 'down' : 'left' );





                            } else if (deltaY < 0 || deltaX < 0) {


                                F.next( deltaY < 0 ? 'up' : 'right' );


                            }





                            e.preventDefault();


                        }


                    }


                });


            }


        },





        trigger: function (event, o) {


            var ret, obj = o || F.coming || F.current;





            if (obj) {


                if ($.isFunction( obj[event] )) {


                    ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1));


                }





                if (ret === false) {


                    return false;


                }





                if (obj.helpers) {


                    $.each(obj.helpers, function (helper, opts) {


                        if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) {


                            F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj);


                        }


                    });


                }


            }





            D.trigger(event);


        },





        isImage: function (str) {


            return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);


        },





        isSWF: function (str) {


            return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i);


        },





        _start: function (index) {


            var coming = {},


                obj,


                href,


                type,


                margin,


                padding;





            index = getScalar( index );


            obj   = F.group[ index ] || null;





            if (!obj) {


                return false;


            }





            coming = $.extend(true, {}, F.opts, obj);





            // Convert margin and padding properties to array - top, right, bottom, left


            margin  = coming.margin;


            padding = coming.padding;





            if ($.type(margin) === 'number') {


                coming.margin = [margin, margin, margin, margin];


            }





            if ($.type(padding) === 'number') {


                coming.padding = [padding, padding, padding, padding];


            }





            // 'modal' propery is just a shortcut


            if (coming.modal) {


                $.extend(true, coming, {


                    closeBtn   : false,


                    closeClick : false,


                    nextClick  : false,


                    arrows     : false,


                    mouseWheel : false,


                    keys       : null,


                    helpers: {


                        overlay : {


                            closeClick : false


                        }


                    }


                });


            }





            // 'autoSize' property is a shortcut, too


            if (coming.autoSize) {


                coming.autoWidth = coming.autoHeight = true;


            }





            if (coming.width === 'auto') {


                coming.autoWidth = true;


            }





            if (coming.height === 'auto') {


                coming.autoHeight = true;


            }





            /*


             * Add reference to the group, so it`s possible to access from callbacks, example:


             * afterLoad : function() {


             *     this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');


             * }


             */





            coming.group  = F.group;


            coming.index  = index;





            // Give a chance for callback or helpers to update coming item (type, title, etc)


            F.coming = coming;





            if (false === F.trigger('beforeLoad')) {


                F.coming = null;





                return;


            }





            type = coming.type;


            href = coming.href;





            if (!type) {


                F.coming = null;





                //If we can not determine content type then drop silently or display next/prev item if looping through gallery


                if (F.current && F.router && F.router !== 'jumpto') {


                    F.current.index = index;





                    return F[ F.router ]( F.direction );


                }





                return false;


            }





            F.isActive = true;





            if (type === 'image' || type === 'swf') {


                coming.autoHeight = coming.autoWidth = false;


                coming.scrolling  = 'visible';


            }





            if (type === 'image') {


                coming.aspectRatio = true;


            }





            if (type === 'iframe' && isTouch) {


                coming.scrolling = 'scroll';


            }





            // Build the neccessary markup


            coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' );





            $.extend(coming, {


                skin  : $('.fancybox-skin',  coming.wrap),


                outer : $('.fancybox-outer', coming.wrap),


                inner : $('.fancybox-inner', coming.wrap)


            });





            $.each(["Top", "Right", "Bottom", "Left"], function(i, v) {


                coming.skin.css('padding' + v, getValue(coming.padding[ i ]));


            });





            F.trigger('onReady');





            // Check before try to load; 'inline' and 'html' types need content, others - href


            if (type === 'inline' || type === 'html') {


                if (!coming.content || !coming.content.length) {


                    return F._error( 'content' );


                }





            } else if (!href) {


                return F._error( 'href' );


            }





            if (type === 'image') {


                F._loadImage();





            } else if (type === 'ajax') {


                F._loadAjax();





            } else if (type === 'iframe') {


                F._loadIframe();





            } else {


                F._afterLoad();


            }


        },





        _error: function ( type ) {


            $.extend(F.coming, {


                type       : 'html',


                autoWidth  : true,


                autoHeight : true,


                minWidth   : 0,


                minHeight  : 0,


                scrolling  : 'no',


                hasError   : type,


                content    : F.coming.tpl.error


            });





            F._afterLoad();


        },





        _loadImage: function () {


            // Reset preload image so it is later possible to check "complete" property


            var img = F.imgPreload = new Image();





            img.onload = function () {


                this.onload = this.onerror = null;





                F.coming.width  = this.width / F.opts.pixelRatio;


                F.coming.height = this.height / F.opts.pixelRatio;





                F._afterLoad();


            };





            img.onerror = function () {


                this.onload = this.onerror = null;





                F._error( 'image' );


            };





            img.src = F.coming.href;





            if (img.complete !== true) {


                F.showLoading();


            }


        },





        _loadAjax: function () {


            var coming = F.coming;





            F.showLoading();





            F.ajaxLoad = $.ajax($.extend({}, coming.ajax, {


                url: coming.href,


                error: function (jqXHR, textStatus) {


                    if (F.coming && textStatus !== 'abort') {


                        F._error( 'ajax', jqXHR );





                    } else {


                        F.hideLoading();


                    }


                },


                success: function (data, textStatus) {


                    if (textStatus === 'success') {


                        coming.content = data;





                        F._afterLoad();


                    }


                }


            }));


        },





        _loadIframe: function() {


            var coming = F.coming,


                iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime()))


                    .attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling)


                    .attr('src', coming.href);





            // This helps IE


            $(coming.wrap).bind('onReset', function () {


                try {


                    $(this).find('iframe').hide().attr('src', '//about:blank').end().empty();


                } catch (e) {}


            });





            if (coming.iframe.preload) {


                F.showLoading();





                iframe.one('load', function() {


                    $(this).data('ready', 1);





                    // iOS will lose scrolling if we resize


                    if (!isTouch) {


                        $(this).bind('load.fb', F.update);


                    }





                    // Without this trick:


                    //   - iframe won't scroll on iOS devices


                    //   - IE7 sometimes displays empty iframe


                    $(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show();





                    F._afterLoad();


                });


            }





            coming.content = iframe.appendTo( coming.inner );





            if (!coming.iframe.preload) {


                F._afterLoad();


            }


        },





        _preloadImages: function() {


            var group   = F.group,


                current = F.current,


                len     = group.length,


                cnt     = current.preload ? Math.min(current.preload, len - 1) : 0,


                item,


                i;





            for (i = 1; i <= cnt; i += 1) {


                item = group[ (current.index + i ) % len ];





                if (item.type === 'image' && item.href) {


                    new Image().src = item.href;


                }


            }


        },





        _afterLoad: function () {


            var coming   = F.coming,


                previous = F.current,


                placeholder = 'fancybox-placeholder',


                current,


                content,


                type,


                scrolling,


                href,


                embed;





            F.hideLoading();





            if (!coming || F.isActive === false) {


                return;


            }





            if (false === F.trigger('afterLoad', coming, previous)) {


                coming.wrap.stop(true).trigger('onReset').remove();





                F.coming = null;





                return;


            }





            if (previous) {


                F.trigger('beforeChange', previous);





                previous.wrap.stop(true).removeClass('fancybox-opened')


                    .find('.fancybox-item, .fancybox-nav')


                    .remove();


            }





            F.unbindEvents();





            current   = coming;


            content   = coming.content;


            type      = coming.type;


            scrolling = coming.scrolling;





            $.extend(F, {


                wrap  : current.wrap,


                skin  : current.skin,


                outer : current.outer,


                inner : current.inner,


                current  : current,


                previous : previous


            });





            href = current.href;





            switch (type) {


                case 'inline':


                case 'ajax':


                case 'html':


                    if (current.selector) {


                        content = $('<div>').html(content).find(current.selector);





                    } else if (isQuery(content)) {


                        if (!content.data(placeholder)) {


                            content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() );


                        }





                        content = content.show().detach();





                        current.wrap.bind('onReset', function () {


                            if ($(this).find(content).length) {


                                content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false);


                            }


                        });


                    }


                    break;





                case 'image':


                    content = current.tpl.image.replace(/\{href\}/g, href);


                    break;





                case 'swf':


                    content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>';


                    embed   = '';





                    $.each(current.swf, function(name, val) {


                        content += '<param name="' + name + '" value="' + val + '"></param>';


                        embed   += ' ' + name + '="' + val + '"';


                    });





                    content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>';


                    break;


            }





            if (!(isQuery(content) && content.parent().is(current.inner))) {


                current.inner.append( content );


            }





            // Give a chance for helpers or callbacks to update elements


            F.trigger('beforeShow');





            // Set scrolling before calculating dimensions


            current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));





            // Set initial dimensions and start position


            F._setDimension();





            F.reposition();





            F.isOpen = false;


            F.coming = null;





            F.bindEvents();





            if (!F.isOpened) {


                $('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove();





            } else if (previous.prevMethod) {


                F.transitions[ previous.prevMethod ]();


            }





            F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ]();





            F._preloadImages();


        },





        _setDimension: function () {


            var viewport   = F.getViewport(),


                steps      = 0,


                canShrink  = false,


                canExpand  = false,


                wrap       = F.wrap,


                skin       = F.skin,


                inner      = F.inner,


                current    = F.current,


                width      = current.width,


                height     = current.height,


                minWidth   = current.minWidth,


                minHeight  = current.minHeight,


                maxWidth   = current.maxWidth,


                maxHeight  = current.maxHeight,


                scrolling  = current.scrolling,


                scrollOut  = current.scrollOutside ? current.scrollbarWidth : 0,


                margin     = current.margin,


                wMargin    = getScalar(margin[1] + margin[3]),


                hMargin    = getScalar(margin[0] + margin[2]),


                wPadding,


                hPadding,


                wSpace,


                hSpace,


                origWidth,


                origHeight,


                origMaxWidth,


                origMaxHeight,


                ratio,


                width_,


                height_,


                maxWidth_,


                maxHeight_,


                iframe,


                body;





            // Reset dimensions so we could re-check actual size


            wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp');





            wPadding = getScalar(skin.outerWidth(true)  - skin.width());


            hPadding = getScalar(skin.outerHeight(true) - skin.height());





            // Any space between content and viewport (margin, padding, border, title)


            wSpace = wMargin + wPadding;


            hSpace = hMargin + hPadding;





            origWidth  = isPercentage(width)  ? (viewport.w - wSpace) * getScalar(width)  / 100 : width;


            origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height;





            if (current.type === 'iframe') {


                iframe = current.content;





                if (current.autoHeight && iframe && iframe.data('ready') === 1) {


                    try {


                        if (iframe[0].contentWindow.document.location) {


                            inner.width( origWidth ).height(9999);





                            body = iframe.contents().find('body');





                            if (scrollOut) {


                                body.css('overflow-x', 'hidden');


                            }





                            origHeight = body.outerHeight(true);


                        }





                    } catch (e) {}


                }





            } else if (current.autoWidth || current.autoHeight) {


                inner.addClass( 'fancybox-tmp' );





                // Set width or height in case we need to calculate only one dimension


                if (!current.autoWidth) {


                    inner.width( origWidth );


                }





                if (!current.autoHeight) {


                    inner.height( origHeight );


                }





                if (current.autoWidth) {


                    origWidth = inner.width();


                }





                if (current.autoHeight) {


                    origHeight = inner.height();


                }





                inner.removeClass( 'fancybox-tmp' );


            }





            width  = getScalar( origWidth );


            height = getScalar( origHeight );





            ratio  = origWidth / origHeight;





            // Calculations for the content


            minWidth  = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth);


            maxWidth  = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth);





            minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight);


            maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight);





            // These will be used to determine if wrap can fit in the viewport


            origMaxWidth  = maxWidth;


            origMaxHeight = maxHeight;





            if (current.fitToView) {


                maxWidth  = Math.min(viewport.w - wSpace, maxWidth);


                maxHeight = Math.min(viewport.h - hSpace, maxHeight);


            }





            maxWidth_  = viewport.w - wMargin;


            maxHeight_ = viewport.h - hMargin;





            if (current.aspectRatio) {


                if (width > maxWidth) {


                    width  = maxWidth;


                    height = getScalar(width / ratio);


                }





                if (height > maxHeight) {


                    height = maxHeight;


                    width  = getScalar(height * ratio);


                }





                if (width < minWidth) {


                    width  = minWidth;


                    height = getScalar(width / ratio);


                }





                if (height < minHeight) {


                    height = minHeight;


                    width  = getScalar(height * ratio);


                }





            } else {


                width = Math.max(minWidth, Math.min(width, maxWidth));





                if (current.autoHeight && current.type !== 'iframe') {


                    inner.width( width );





                    height = inner.height();


                }





                height = Math.max(minHeight, Math.min(height, maxHeight));


            }





            // Try to fit inside viewport (including the title)


            if (current.fitToView) {


                inner.width( width ).height( height );





                wrap.width( width + wPadding );





                // Real wrap dimensions


                width_  = wrap.width();


                height_ = wrap.height();





                if (current.aspectRatio) {


                    while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {


                        if (steps++ > 19) {


                            break;


                        }





                        height = Math.max(minHeight, Math.min(maxHeight, height - 10));


                        width  = getScalar(height * ratio);





                        if (width < minWidth) {


                            width  = minWidth;


                            height = getScalar(width / ratio);


                        }





                        if (width > maxWidth) {


                            width  = maxWidth;


                            height = getScalar(width / ratio);


                        }





                        inner.width( width ).height( height );





                        wrap.width( width + wPadding );





                        width_  = wrap.width();


                        height_ = wrap.height();


                    }





                } else {


                    width  = Math.max(minWidth,  Math.min(width,  width  - (width_  - maxWidth_)));


                    height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_)));


                }


            }





            if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) {


                width += scrollOut;


            }





            inner.width( width ).height( height );





            wrap.width( width + wPadding );





            width_  = wrap.width();


            height_ = wrap.height();





            canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;


            canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight));





            $.extend(current, {


                dim : {


                    width	: getValue( width_ ),


                    height	: getValue( height_ )


                },


                origWidth  : origWidth,


                origHeight : origHeight,


                canShrink  : canShrink,


                canExpand  : canExpand,


                wPadding   : wPadding,


                hPadding   : hPadding,


                wrapSpace  : height_ - skin.outerHeight(true),


                skinSpace  : skin.height() - height


            });





            if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {


                inner.height('auto');


            }


        },





        _getPosition: function (onlyAbsolute) {


            var current  = F.current,


                viewport = F.getViewport(),


                margin   = current.margin,


                width    = F.wrap.width()  + margin[1] + margin[3],


                height   = F.wrap.height() + margin[0] + margin[2],


                rez      = {


                    position: 'absolute',


                    top  : margin[0],


                    left : margin[3]


                };





            if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {


                rez.position = 'fixed';





            } else if (!current.locked) {


                rez.top  += viewport.y;


                rez.left += viewport.x;


            }





            rez.top  = getValue(Math.max(rez.top,  rez.top  + ((viewport.h - height) * current.topRatio)));


            rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width)  * current.leftRatio)));





            return rez;


        },





        _afterZoomIn: function () {


            var current = F.current;





            if (!current) {


                return;


            }





            F.isOpen = F.isOpened = true;





            F.wrap.css('overflow', 'visible').addClass('fancybox-opened').hide().show(0);





            F.update();





            // Assign a click event


            if ( current.closeClick || (current.nextClick && F.group.length > 1) ) {


                F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {


                    if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {


                        e.preventDefault();





                        F[ current.closeClick ? 'close' : 'next' ]();


                    }


                });


            }





            // Create a close button


            if (current.closeBtn) {


                $(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) {


                    e.preventDefault();





                    F.close();


                });


            }





            // Create navigation arrows


            if (current.arrows && F.group.length > 1) {


                if (current.loop || current.index > 0) {


                    $(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev);


                }





                if (current.loop || current.index < F.group.length - 1) {


                    $(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next);


                }


            }





            F.trigger('afterShow');





            // Stop the slideshow if this is the last item


            if (!current.loop && current.index === current.group.length - 1) {





                F.play( false );





            } else if (F.opts.autoPlay && !F.player.isActive) {


                F.opts.autoPlay = false;





                F.play(true);


            }


        },





        _afterZoomOut: function ( obj ) {


            obj = obj || F.current;





            $('.fancybox-wrap').trigger('onReset').remove();





            $.extend(F, {


                group  : {},


                opts   : {},


                router : false,


                current   : null,


                isActive  : false,


                isOpened  : false,


                isOpen    : false,


                isClosing : false,


                wrap   : null,


                skin   : null,


                outer  : null,


                inner  : null


            });





            F.trigger('afterClose', obj);


        }


    });





    /*


     *	Default transitions


     */





    F.transitions = {


        getOrigPosition: function () {


            var current  = F.current,


                element  = current.element,


                orig     = current.orig,


                pos      = {},


                width    = 50,


                height   = 50,


                hPadding = current.hPadding,


                wPadding = current.wPadding,


                viewport = F.getViewport();





            if (!orig && current.isDom && element.is(':visible')) {


                orig = element.find('img:first');





                if (!orig.length) {


                    orig = element;


                }


            }





            if (isQuery(orig)) {


                pos = orig.offset();





                if (orig.is('img')) {


                    width  = orig.outerWidth();


                    height = orig.outerHeight();


                }





            } else {


                pos.top  = viewport.y + (viewport.h - height) * current.topRatio;


                pos.left = viewport.x + (viewport.w - width)  * current.leftRatio;


            }





            if (F.wrap.css('position') === 'fixed' || current.locked) {


                pos.top  -= viewport.y;


                pos.left -= viewport.x;


            }





            pos = {


                top     : getValue(pos.top  - hPadding * current.topRatio),


                left    : getValue(pos.left - wPadding * current.leftRatio),


                width   : getValue(width  + wPadding),


                height  : getValue(height + hPadding)


            };





            return pos;


        },





        step: function (now, fx) {


            var ratio,


                padding,


                value,


                prop       = fx.prop,


                current    = F.current,


                wrapSpace  = current.wrapSpace,


                skinSpace  = current.skinSpace;





            if (prop === 'width' || prop === 'height') {


                ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start);





                if (F.isClosing) {


                    ratio = 1 - ratio;


                }





                padding = prop === 'width' ? current.wPadding : current.hPadding;


                value   = now - padding;





                F.skin[ prop ](  getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) ) );


                F.inner[ prop ]( getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) );


            }


        },





        zoomIn: function () {


            var current  = F.current,


                startPos = current.pos,


                effect   = current.openEffect,


                elastic  = effect === 'elastic',


                endPos   = $.extend({opacity : 1}, startPos);





            // Remove "position" property that breaks older IE


            delete endPos.position;





            if (elastic) {


                startPos = this.getOrigPosition();





                if (current.openOpacity) {


                    startPos.opacity = 0.1;


                }





            } else if (effect === 'fade') {


                startPos.opacity = 0.1;


            }





            F.wrap.css(startPos).animate(endPos, {


                duration : effect === 'none' ? 0 : current.openSpeed,


                easing   : current.openEasing,


                step     : elastic ? this.step : null,


                complete : F._afterZoomIn


            });


        },





        zoomOut: function () {


            var current  = F.current,


                effect   = current.closeEffect,


                elastic  = effect === 'elastic',


                endPos   = {opacity : 0.1};





            if (elastic) {


                endPos = this.getOrigPosition();





                if (current.closeOpacity) {


                    endPos.opacity = 0.1;


                }


            }





            F.wrap.animate(endPos, {


                duration : effect === 'none' ? 0 : current.closeSpeed,


                easing   : current.closeEasing,


                step     : elastic ? this.step : null,


                complete : F._afterZoomOut


            });


        },





        changeIn: function () {


            var current   = F.current,


                effect    = current.nextEffect,


                startPos  = current.pos,


                endPos    = { opacity : 1 },


                direction = F.direction,


                distance  = 200,


                field;





            startPos.opacity = 0.1;





            if (effect === 'elastic') {


                field = direction === 'down' || direction === 'up' ? 'top' : 'left';





                if (direction === 'down' || direction === 'right') {


                    startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance);


                    endPos[ field ]   = '+=' + distance + 'px';





                } else {


                    startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance);


                    endPos[ field ]   = '-=' + distance + 'px';


                }


            }





            // Workaround for http://bugs.jquery.com/ticket/12273


            if (effect === 'none') {


                F._afterZoomIn();





            } else {


                F.wrap.css(startPos).animate(endPos, {


                    duration : current.nextSpeed,


                    easing   : current.nextEasing,


                    complete : F._afterZoomIn


                });


            }


        },





        changeOut: function () {


            var previous  = F.previous,


                effect    = previous.prevEffect,


                endPos    = { opacity : 0.1 },


                direction = F.direction,


                distance  = 200;





            if (effect === 'elastic') {


                endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px';


            }





            previous.wrap.animate(endPos, {


                duration : effect === 'none' ? 0 : previous.prevSpeed,


                easing   : previous.prevEasing,


                complete : function () {


                    $(this).trigger('onReset').remove();


                }


            });


        }


    };





    /*


     *	Overlay helper


     */





    F.helpers.overlay = {


        defaults : {


            closeClick : true,      // if true, fancyBox will be closed when user clicks on the overlay


            speedOut   : 200,       // duration of fadeOut animation


            showEarly  : true,      // indicates if should be opened immediately or wait until the content is ready


            css        : {},        // custom CSS properties


            locked     : !isTouch,  // if true, the content will be locked into overlay


            fixed      : true       // if false, the overlay CSS position property will not be set to "fixed"


        },





        overlay : null,      // current handle


        fixed   : false,     // indicates if the overlay has position "fixed"


        el      : $('html'), // element that contains "the lock"





        // Public methods


        create : function(opts) {


            var parent;





            opts = $.extend({}, this.defaults, opts);





            if (this.overlay) {


                this.close();


            }





            parent = F.coming ? F.coming.parent : opts.parent;





            this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( parent && parent.length ? parent : 'body' );


            this.fixed   = false;





            if (opts.fixed && F.defaults.fixed) {


                this.overlay.addClass('fancybox-overlay-fixed');





                this.fixed = true;


            }


        },





        open : function(opts) {


            var that = this;





            opts = $.extend({}, this.defaults, opts);





            if (this.overlay) {


                this.overlay.unbind('.overlay').width('auto').height('auto');





            } else {


                this.create(opts);


            }





            if (!this.fixed) {


                W.bind('resize.overlay', $.proxy( this.update, this) );





                this.update();


            }





            if (opts.closeClick) {


                this.overlay.bind('click.overlay', function(e) {


                    if ($(e.target).hasClass('fancybox-overlay')) {


                        if (F.isActive) {


                            F.close();


                        } else {


                            that.close();


                        }





                        return false;


                    }


                });


            }





            this.overlay.css( opts.css ).show();


        },





        close : function() {


            W.unbind('resize.overlay');





            if (this.el.hasClass('fancybox-lock')) {


                $('.fancybox-margin').removeClass('fancybox-margin');





                this.el.removeClass('fancybox-lock');





                W.scrollTop( this.scrollV ).scrollLeft( this.scrollH );


            }





            $('.fancybox-overlay').remove().hide();





            $.extend(this, {


                overlay : null,


                fixed   : false


            });


        },





        // Private, callbacks





        update : function () {


            var width = '100%', offsetWidth;





            // Reset width/height so it will not mess


            this.overlay.width(width).height('100%');





            // jQuery does not return reliable result for IE


            if (IE) {


                offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);





                if (D.width() > offsetWidth) {


                    width = D.width();


                }





            } else if (D.width() > W.width()) {


                width = D.width();


            }





            this.overlay.width(width).height(D.height());


        },





        // This is where we can manipulate DOM, because later it would cause iframes to reload


        onReady : function (opts, obj) {


            var overlay = this.overlay;





            $('.fancybox-overlay').stop(true, true);





            if (!overlay) {


                this.create(opts);


            }





            if (opts.locked && this.fixed && obj.fixed) {


                obj.locked = this.overlay.append( obj.wrap );


                obj.fixed  = false;


            }





            if (opts.showEarly === true) {


                this.beforeShow.apply(this, arguments);


            }


        },





        beforeShow : function(opts, obj) {


            if (obj.locked && !this.el.hasClass('fancybox-lock')) {


                if (this.fixPosition !== false) {


                    $('*:not(object)').filter(function(){


                        return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") );


                    }).addClass('fancybox-margin');


                }





                this.el.addClass('fancybox-margin');





                this.scrollV = W.scrollTop();


                this.scrollH = W.scrollLeft();





                this.el.addClass('fancybox-lock');





                W.scrollTop( this.scrollV ).scrollLeft( this.scrollH );


            }





            this.open(opts);


        },





        onUpdate : function() {


            if (!this.fixed) {


                this.update();


            }


        },





        afterClose: function (opts) {


            // Remove overlay if exists and fancyBox is not opening


            // (e.g., it is not being open using afterClose callback)


            if (this.overlay && !F.coming) {


                this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this ));


            }


        }


    };





    /*


     *	Title helper


     */





    F.helpers.title = {


        defaults : {


            type     : 'float', // 'float', 'inside', 'outside' or 'over',


            position : 'bottom' // 'top' or 'bottom'


        },





        beforeShow: function (opts) {


            var current = F.current,


                text    = current.title,


                type    = opts.type,


                title,


                target;





            if ($.isFunction(text)) {


                text = text.call(current.element, current);


            }





            if (!isString(text) || $.trim(text) === '') {


                return;


            }





            title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">' + text + '</div>');





            switch (type) {


                case 'inside':


                    target = F.skin;


                    break;





                case 'outside':


                    target = F.wrap;


                    break;





                case 'over':


                    target = F.inner;


                    break;





                default: // 'float'


                    target = F.skin;





                    title.appendTo('body');





                    if (IE) {


                        title.width( title.width() );


                    }





                    title.wrapInner('<span class="child"></span>');





                    //Increase bottom margin so this title will also fit into viewport


                    F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) );


                    break;


            }





            title[ (opts.position === 'top' ? 'prependTo'  : 'appendTo') ](target);


        }


    };





    // jQuery plugin initialization


    $.fn.fancybox = function (options) {


        var index,


            that     = $(this),


            selector = this.selector || '',


            run      = function(e) {


                var what = $(this).blur(), idx = index, relType, relVal;





                if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) {


                    relType = options.groupAttr || 'data-fancybox-group';


                    relVal  = what.attr(relType);





                    if (!relVal) {


                        relType = 'rel';


                        relVal  = what.get(0)[ relType ];


                    }





                    if (relVal && relVal !== '' && relVal !== 'nofollow') {


                        what = selector.length ? $(selector) : that;


                        what = what.filter('[' + relType + '="' + relVal + '"]');


                        idx  = what.index(this);


                    }





                    options.index = idx;





                    // Stop an event from bubbling if everything is fine


                    if (F.open(what, options) !== false) {


                        e.preventDefault();


                    }


                }


            };





        options = options || {};


        index   = options.index || 0;





        if (!selector || options.live === false) {


            that.unbind('click.fb-start').bind('click.fb-start', run);





        } else {


            D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run);


        }





        this.filter('[data-fancybox-start=1]').trigger('click');





        return this;


    };





    // Tests that need a body at doc ready


    D.ready(function() {


        var w1, w2;





        if ( $.scrollbarWidth === undefined ) {


            // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth


            $.scrollbarWidth = function() {


                var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'),


                    child  = parent.children(),


                    width  = child.innerWidth() - child.height( 99 ).innerWidth();





                parent.remove();





                return width;


            };


        }





        if ( $.support.fixedPosition === undefined ) {


            $.support.fixedPosition = (function() {


                var elem  = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'),


                    fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 );





                elem.remove();





                return fixed;


            }());


        }





        $.extend(F.defaults, {


            scrollbarWidth : $.scrollbarWidth(),


            fixed  : $.support.fixedPosition,


            parent : $('body')


        });





        //Get real width of page scroll-bar


        w1 = $(window).width();





        H.addClass('fancybox-lock-test');





        w2 = $(window).width();





        H.removeClass('fancybox-lock-test');





        $("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head");


    });





}(window, document, jQuery));



//** jQuery Scroll to Top Control script- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com.


//** Available/ usage terms at http://www.dynamicdrive.com (March 30th, 09')


//** v1.1 (April 7th, 09'):


//** 1) Adds ability to scroll to an absolute position (from top of page) or specific element on the page instead.


//** 2) Fixes scroll animation not working in Opera. 








var scrolltotop={


	//startline: Integer. Number of pixels from top of doc scrollbar is scrolled before showing control


	//scrollto: Keyword (Integer, or "Scroll_to_Element_ID"). How far to scroll document up when control is clicked on (0=top).


	setting: {startline:100, scrollto: 0, scrollduration:1000, fadeduration:[500, 100]},


	controlHTML: '<img src="assets/img/up.png" style="width:40px; height:40px" />', //HTML for control, which is auto wrapped in DIV w/ ID="topcontrol"


	controlattrs: {offsetx:10, offsety:10}, //offset of control relative to right/ bottom of window corner


	anchorkeyword: '#top', //Enter href value of HTML anchors on the page that should also act as "Scroll Up" links





	state: {isvisible:false, shouldvisible:false},





	scrollup:function(){


		if (!this.cssfixedsupport) //if control is positioned using JavaScript


			this.$control.css({opacity:0}); //hide control immediately after clicking it


		var dest=isNaN(this.setting.scrollto)? this.setting.scrollto : parseInt(this.setting.scrollto);


		if (typeof dest=="string" && jQuery('#'+dest).length==1) //check element set by string exists


			dest=jQuery('#'+dest).offset().top;


		else


			dest=0;


		this.$body.animate({scrollTop: dest}, this.setting.scrollduration);


	},





	keepfixed:function(){


		var $window=jQuery(window);


		var controlx=$window.scrollLeft() + $window.width() - this.$control.width() - this.controlattrs.offsetx;


		var controly=$window.scrollTop() + $window.height() - this.$control.height() - this.controlattrs.offsety;


		this.$control.css({left:controlx+'px', top:controly+'px'})


	},





	togglecontrol:function(){


		var scrolltop=jQuery(window).scrollTop();


		if (!this.cssfixedsupport)


			this.keepfixed();


		this.state.shouldvisible=(scrolltop>=this.setting.startline)? true : false;


		if (this.state.shouldvisible && !this.state.isvisible){


			this.$control.stop().animate({opacity:1}, this.setting.fadeduration[0]);


			this.state.isvisible=true


		}


		else if (this.state.shouldvisible==false && this.state.isvisible){


			this.$control.stop().animate({opacity:0}, this.setting.fadeduration[1]);


			this.state.isvisible=false


		}


	},


	


	init:function(){


		jQuery(document).ready(function($){


			var mainobj=scrolltotop;


			var iebrws=document.all;


			mainobj.cssfixedsupport=!iebrws || iebrws && document.compatMode=="CSS1Compat" && window.XMLHttpRequest //not IE or IE7+ browsers in standards mode


			mainobj.$body=(window.opera)? (document.compatMode=="CSS1Compat"? $('html') : $('body')) : $('html,body');


			mainobj.$control=$('<div id="topcontrol">'+mainobj.controlHTML+'</div>')


				.css({position:mainobj.cssfixedsupport? 'fixed' : 'absolute', bottom:mainobj.controlattrs.offsety, opacity:0, cursor:'pointer'})


				.attr({title:''})


				.click(function(){mainobj.scrollup(); return false})


				.appendTo('body');


			if (document.all && !window.XMLHttpRequest && mainobj.$control.text()!='') //loose check for IE6 and below, plus whether control contains any text


				mainobj.$control.css({width:mainobj.$control.width()}); //IE6- seems to require an explicit width on a DIV containing text


			mainobj.togglecontrol();


			$('a[href="' + mainobj.anchorkeyword +'"]').click(function(){


				mainobj.scrollup();


				return false


			});


			$(window).bind('scroll resize', function(e){


				mainobj.togglecontrol();


			});


		})


	}


};





//scrolltotop.init()



/**


* jquery.matchHeight.js master


* http://brm.io/jquery-match-height/


* License: MIT


*/





;(function($) {


    /*


    *  internal


    */





    var _previousResizeWidth = -1,


        _updateTimeout = -1;





    /*


    *  _parse


    *  value parse utility function


    */





    var _parse = function(value) {


        // parse value and convert NaN to 0


        return parseFloat(value) || 0;


    };





    /*


    *  _rows


    *  utility function returns array of jQuery selections representing each row


    *  (as displayed after float wrapping applied by browser)


    */





    var _rows = function(elements) {


        var tolerance = 1,


            $elements = $(elements),


            lastTop = null,


            rows = [];





        // group elements by their top position


        $elements.each(function(){


            var $that = $(this),


                top = $that.offset().top - _parse($that.css('margin-top')),


                lastRow = rows.length > 0 ? rows[rows.length - 1] : null;





            if (lastRow === null) {


                // first item on the row, so just push it


                rows.push($that);


            } else {


                // if the row top is the same, add to the row group


                if (Math.floor(Math.abs(lastTop - top)) <= tolerance) {


                    rows[rows.length - 1] = lastRow.add($that);


                } else {


                    // otherwise start a new row group


                    rows.push($that);


                }


            }





            // keep track of the last row top


            lastTop = top;


        });





        return rows;


    };





    /*


    *  _parseOptions


    *  handle plugin options


    */





    var _parseOptions = function(options) {


        var opts = {


            byRow: true,


            property: 'height',


            target: null,


            remove: false


        };





        if (typeof options === 'object') {


            return $.extend(opts, options);


        }





        if (typeof options === 'boolean') {


            opts.byRow = options;


        } else if (options === 'remove') {


            opts.remove = true;


        }





        return opts;


    };





    /*


    *  matchHeight


    *  plugin definition


    */





    var matchHeight = $.fn.matchHeight = function(options) {


        var opts = _parseOptions(options);





        // handle remove


        if (opts.remove) {


            var that = this;





            // remove fixed height from all selected elements


            this.css(opts.property, '');





            // remove selected elements from all groups


            $.each(matchHeight._groups, function(key, group) {


                group.elements = group.elements.not(that);


            });





            // TODO: cleanup empty groups





            return this;


        }





        if (this.length <= 1 && !opts.target) {


            return this;


        }





        // keep track of this group so we can re-apply later on load and resize events


        matchHeight._groups.push({


            elements: this,


            options: opts


        });





        // match each element's height to the tallest element in the selection


        matchHeight._apply(this, opts);





        return this;


    };





    /*


    *  plugin global options


    */





    matchHeight._groups = [];


    matchHeight._throttle = 80;


    matchHeight._maintainScroll = false;


    matchHeight._beforeUpdate = null;


    matchHeight._afterUpdate = null;





    /*


    *  matchHeight._apply


    *  apply matchHeight to given elements


    */





    matchHeight._apply = function(elements, options) {


        var opts = _parseOptions(options),


            $elements = $(elements),


            rows = [$elements];





        // take note of scroll position


        var scrollTop = $(window).scrollTop(),


            htmlHeight = $('html').outerHeight(true);





        // get hidden parents


        var $hiddenParents = $elements.parents().filter(':hidden');





        // cache the original inline style


        $hiddenParents.each(function() {


            var $that = $(this);


            $that.data('style-cache', $that.attr('style'));


        });





        // temporarily must force hidden parents visible


        $hiddenParents.css('display', 'block');





        // get rows if using byRow, otherwise assume one row


        if (opts.byRow && !opts.target) {





            // must first force an arbitrary equal height so floating elements break evenly


            $elements.each(function() {


                var $that = $(this),


                    display = $that.css('display') === 'inline-block' ? 'inline-block' : 'block';





                // cache the original inline style


                $that.data('style-cache', $that.attr('style'));





                $that.css({


                    'display': display,


                    'padding-top': '0',


                    'padding-bottom': '0',


                    'margin-top': '0',


                    'margin-bottom': '0',


                    'border-top-width': '0',


                    'border-bottom-width': '0',


                    'height': '100px'


                });


            });





            // get the array of rows (based on element top position)


            rows = _rows($elements);





            // revert original inline styles


            $elements.each(function() {


                var $that = $(this);


                $that.attr('style', $that.data('style-cache') || '');


            });


        }





        $.each(rows, function(key, row) {


            var $row = $(row),


                targetHeight = 0;





            if (!opts.target) {


                // skip apply to rows with only one item


                if (opts.byRow && $row.length <= 1) {


                    $row.css(opts.property, '');


                    return;


                }





                // iterate the row and find the max height


                $row.each(function(){


                    var $that = $(this),


                        display = $that.css('display') === 'inline-block' ? 'inline-block' : 'block';





                    // ensure we get the correct actual height (and not a previously set height value)


                    var css = { 'display': display };


                    css[opts.property] = '';


                    $that.css(css);





                    // find the max height (including padding, but not margin)


                    if ($that.outerHeight(false) > targetHeight) {


                        targetHeight = $that.outerHeight(false);


                    }





                    // revert display block


                    $that.css('display', '');


                });


            } else {


                // if target set, use the height of the target element


                targetHeight = opts.target.outerHeight(false);


            }





            // iterate the row and apply the height to all elements


            $row.each(function(){


                var $that = $(this),


                    verticalPadding = 0;





                // don't apply to a target


                if (opts.target && $that.is(opts.target)) {


                    return;


                }





                // handle padding and border correctly (required when not using border-box)


                if ($that.css('box-sizing') !== 'border-box') {


                    verticalPadding += _parse($that.css('border-top-width')) + _parse($that.css('border-bottom-width'));


                    verticalPadding += _parse($that.css('padding-top')) + _parse($that.css('padding-bottom'));


                }





                // set the height (accounting for padding and border)


                $that.css(opts.property, targetHeight - verticalPadding);


            });


        });





        // revert hidden parents


        $hiddenParents.each(function() {


            var $that = $(this);


            $that.attr('style', $that.data('style-cache') || null);


        });





        // restore scroll position if enabled


        if (matchHeight._maintainScroll) {


            $(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true));


        }





        return this;


    };





    /*


    *  matchHeight._applyDataApi


    *  applies matchHeight to all elements with a data-match-height attribute


    */





    matchHeight._applyDataApi = function() {


        var groups = {};





        // generate groups by their groupId set by elements using data-match-height


        $('[data-match-height], [data-mh]').each(function() {


            var $this = $(this),


                groupId = $this.attr('data-mh') || $this.attr('data-match-height');





            if (groupId in groups) {


                groups[groupId] = groups[groupId].add($this);


            } else {


                groups[groupId] = $this;


            }


        });





        // apply matchHeight to each group


        $.each(groups, function() {


            this.matchHeight(true);


        });


    };





    /*


    *  matchHeight._update


    *  updates matchHeight on all current groups with their correct options


    */





    var _update = function(event) {


        if (matchHeight._beforeUpdate) {


            matchHeight._beforeUpdate(event, matchHeight._groups);


        }





        $.each(matchHeight._groups, function() {


            matchHeight._apply(this.elements, this.options);


        });





        if (matchHeight._afterUpdate) {


            matchHeight._afterUpdate(event, matchHeight._groups);


        }


    };





    matchHeight._update = function(throttle, event) {


        // prevent update if fired from a resize event


        // where the viewport width hasn't actually changed


        // fixes an event looping bug in IE8


        if (event && event.type === 'resize') {


            var windowWidth = $(window).width();


            if (windowWidth === _previousResizeWidth) {


                return;


            }


            _previousResizeWidth = windowWidth;


        }





        // throttle updates


        if (!throttle) {


            _update(event);


        } else if (_updateTimeout === -1) {


            _updateTimeout = setTimeout(function() {


                _update(event);


                _updateTimeout = -1;


            }, matchHeight._throttle);


        }


    };





    /*


    *  bind events


    */





    // apply on DOM ready event


    $(matchHeight._applyDataApi);





    // update heights on load and resize events


    $(window).bind('load', function(event) {


        matchHeight._update(false, event);


    });





    // throttled update heights on resize events


    $(window).bind('resize orientationchange', function(event) {


        matchHeight._update(true, event);


    });





})(jQuery);






/* Modernizr (Custom Build) | MIT & BSD

 * Build: http://modernizr.com/download/#-csstransforms3d-csstransitions-touch-shiv-load-cssclasses-prefixed-teststyles-testprops-testallprops-prefixes-domprefixes-mq-respond

 */

;window.Modernizr=function(e,t,n){function C(e){f.cssText=e}function k(e,t){return C(h.join(e+";")+(t||""))}function L(e,t){return typeof e===t}function A(e,t){return!!~(""+e).indexOf(t)}function O(e,t){for(var r in e){var i=e[r];if(!A(i,"-")&&f[i]!==n)return t=="pfx"?i:!0}return!1}function M(e,t,r){for(var i in e){var s=t[e[i]];if(s!==n)return r===!1?e[i]:L(s,"function")?s.bind(r||t):s}return!1}function _(e,t,n){var r=e.charAt(0).toUpperCase()+e.slice(1),i=(e+" "+d.join(r+" ")+r).split(" ");return L(t,"string")||L(t,"undefined")?O(i,t):(i=(e+" "+v.join(r+" ")+r).split(" "),M(i,t,n))}var r="2.8.3",i={},s=!0,o=t.documentElement,u="modernizr",a=t.createElement(u),f=a.style,l,c={}.toString,h=" -webkit- -moz- -o- -ms- ".split(" "),p="Webkit Moz O ms",d=p.split(" "),v=p.toLowerCase().split(" "),m={},g={},y={},b=[],w=b.slice,E,S=function(e,n,r,i){var s,a,f,l,c=t.createElement("div"),h=t.body,p=h||t.createElement("body");if(parseInt(r,10))while(r--)f=t.createElement("div"),f.id=i?i[r]:u+(r+1),c.appendChild(f);return s=["&#173;",'<style id="s',u,'">',e,"</style>"].join(""),c.id=u,(h?c:p).innerHTML+=s,p.appendChild(c),h||(p.style.background="",p.style.overflow="hidden",l=o.style.overflow,o.style.overflow="hidden",o.appendChild(p)),a=n(c,e),h?c.parentNode.removeChild(c):(p.parentNode.removeChild(p),o.style.overflow=l),!!a},x=function(t){var n=e.matchMedia||e.msMatchMedia;if(n)return n(t)&&n(t).matches||!1;var r;return S("@media "+t+" { #"+u+" { position: absolute; } }",function(t){r=(e.getComputedStyle?getComputedStyle(t,null):t.currentStyle)["position"]=="absolute"}),r},T={}.hasOwnProperty,N;!L(T,"undefined")&&!L(T.call,"undefined")?N=function(e,t){return T.call(e,t)}:N=function(e,t){return t in e&&L(e.constructor.prototype[t],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError;var r=w.call(arguments,1),i=function(){if(this instanceof i){var e=function(){};e.prototype=n.prototype;var s=new e,o=n.apply(s,r.concat(w.call(arguments)));return Object(o)===o?o:s}return n.apply(t,r.concat(w.call(arguments)))};return i}),m.touch=function(){var n;return"ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch?n=!0:S(["@media (",h.join("touch-enabled),("),u,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(e){n=e.offsetTop===9}),n},m.csstransforms3d=function(){var e=!!_("perspective");return e&&"webkitPerspective"in o.style&&S("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(t,n){e=t.offsetLeft===9&&t.offsetHeight===3}),e},m.csstransitions=function(){return _("transition")};for(var D in m)N(m,D)&&(E=D.toLowerCase(),i[E]=m[D](),b.push((i[E]?"":"no-")+E));return i.addTest=function(e,t){if(typeof e=="object")for(var r in e)N(e,r)&&i.addTest(r,e[r]);else{e=e.toLowerCase();if(i[e]!==n)return i;t=typeof t=="function"?t():t,typeof s!="undefined"&&s&&(o.className+=" "+(t?"":"no-")+e),i[e]=t}return i},C(""),a=l=null,function(e,t){function c(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function h(){var e=y.elements;return typeof e=="string"?e.split(" "):e}function p(e){var t=f[e[u]];return t||(t={},a++,e[u]=a,f[a]=t),t}function d(e,n,r){n||(n=t);if(l)return n.createElement(e);r||(r=p(n));var o;return r.cache[e]?o=r.cache[e].cloneNode():s.test(e)?o=(r.cache[e]=r.createElem(e)).cloneNode():o=r.createElem(e),o.canHaveChildren&&!i.test(e)&&!o.tagUrn?r.frag.appendChild(o):o}function v(e,n){e||(e=t);if(l)return e.createDocumentFragment();n=n||p(e);var r=n.frag.cloneNode(),i=0,s=h(),o=s.length;for(;i<o;i++)r.createElement(s[i]);return r}function m(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return y.shivMethods?d(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/[\w\-]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(y,t.frag)}function g(e){e||(e=t);var n=p(e);return y.shivCSS&&!o&&!n.hasCSS&&(n.hasCSS=!!c(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||m(e,n),e}var n="3.7.0",r=e.html5||{},i=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,s=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,o,u="_html5shiv",a=0,f={},l;(function(){try{var e=t.createElement("a");e.innerHTML="<xyz></xyz>",o="hidden"in e,l=e.childNodes.length==1||function(){t.createElement("a");var e=t.createDocumentFragment();return typeof e.cloneNode=="undefined"||typeof e.createDocumentFragment=="undefined"||typeof e.createElement=="undefined"}()}catch(n){o=!0,l=!0}})();var y={elements:r.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:n,shivCSS:r.shivCSS!==!1,supportsUnknownElements:l,shivMethods:r.shivMethods!==!1,type:"default",shivDocument:g,createElement:d,createDocumentFragment:v};e.html5=y,g(t)}(this,t),i._version=r,i._prefixes=h,i._domPrefixes=v,i._cssomPrefixes=d,i.mq=x,i.testProp=function(e){return O([e])},i.testAllProps=_,i.testStyles=S,i.prefixed=function(e,t,n){return t?_(e,t,n):_(e,"pfx")},o.className=o.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(s?" js "+b.join(" "):""),i}(this,this.document),function(e,t,n){function r(e){return"[object Function]"==d.call(e)}function i(e){return"string"==typeof e}function s(){}function o(e){return!e||"loaded"==e||"complete"==e||"uninitialized"==e}function u(){var e=v.shift();m=1,e?e.t?h(function(){("c"==e.t?k.injectCss:k.injectJs)(e.s,0,e.a,e.x,e.e,1)},0):(e(),u()):m=0}function a(e,n,r,i,s,a,f){function l(t){if(!d&&o(c.readyState)&&(w.r=d=1,!m&&u(),c.onload=c.onreadystatechange=null,t)){"img"!=e&&h(function(){b.removeChild(c)},50);for(var r in T[n])T[n].hasOwnProperty(r)&&T[n][r].onload()}}var f=f||k.errorTimeout,c=t.createElement(e),d=0,g=0,w={t:r,s:n,e:s,a:a,x:f};1===T[n]&&(g=1,T[n]=[]),"object"==e?c.data=n:(c.src=n,c.type=e),c.width=c.height="0",c.onerror=c.onload=c.onreadystatechange=function(){l.call(this,g)},v.splice(i,0,w),"img"!=e&&(g||2===T[n]?(b.insertBefore(c,y?null:p),h(l,f)):T[n].push(c))}function f(e,t,n,r,s){return m=0,t=t||"j",i(e)?a("c"==t?E:w,e,t,this.i++,n,r,s):(v.splice(this.i++,0,e),1==v.length&&u()),this}function l(){var e=k;return e.loader={load:f,i:0},e}var c=t.documentElement,h=e.setTimeout,p=t.getElementsByTagName("script")[0],d={}.toString,v=[],m=0,g="MozAppearance"in c.style,y=g&&!!t.createRange().compareNode,b=y?c:p.parentNode,c=e.opera&&"[object Opera]"==d.call(e.opera),c=!!t.attachEvent&&!c,w=g?"object":c?"script":"img",E=c?"script":w,S=Array.isArray||function(e){return"[object Array]"==d.call(e)},x=[],T={},N={timeout:function(e,t){return t.length&&(e.timeout=t[0]),e}},C,k;k=function(e){function t(e){var e=e.split("!"),t=x.length,n=e.pop(),r=e.length,n={url:n,origUrl:n,prefixes:e},i,s,o;for(s=0;s<r;s++)o=e[s].split("="),(i=N[o.shift()])&&(n=i(n,o));for(s=0;s<t;s++)n=x[s](n);return n}function o(e,i,s,o,u){var a=t(e),f=a.autoCallback;a.url.split(".").pop().split("?").shift(),a.bypass||(i&&(i=r(i)?i:i[e]||i[o]||i[e.split("/").pop().split("?")[0]]),a.instead?a.instead(e,i,s,o,u):(T[a.url]?a.noexec=!0:T[a.url]=1,s.load(a.url,a.forceCSS||!a.forceJS&&"css"==a.url.split(".").pop().split("?").shift()?"c":n,a.noexec,a.attrs,a.timeout),(r(i)||r(f))&&s.load(function(){l(),i&&i(a.origUrl,u,o),f&&f(a.origUrl,u,o),T[a.url]=2})))}function u(e,t){function n(e,n){if(e){if(i(e))n||(f=function(){var e=[].slice.call(arguments);l.apply(this,e),c()}),o(e,f,t,0,u);else if(Object(e)===e)for(p in h=function(){var t=0,n;for(n in e)e.hasOwnProperty(n)&&t++;return t}(),e)e.hasOwnProperty(p)&&(!n&&!--h&&(r(f)?f=function(){var e=[].slice.call(arguments);l.apply(this,e),c()}:f[p]=function(e){return function(){var t=[].slice.call(arguments);e&&e.apply(this,t),c()}}(l[p])),o(e[p],f,t,p,u))}else!n&&c()}var u=!!e.test,a=e.load||e.both,f=e.callback||s,l=f,c=e.complete||s,h,p;n(u?e.yep:e.nope,!!a),a&&n(a)}var a,f,c=this.yepnope.loader;if(i(e))o(e,0,c,0);else if(S(e))for(a=0;a<e.length;a++)f=e[a],i(f)?o(f,0,c,0):S(f)?k(f):Object(f)===f&&u(f,c);else Object(e)===e&&u(e,c)},k.addPrefix=function(e,t){N[e]=t},k.addFilter=function(e){x.push(e)},k.errorTimeout=1e4,null==t.readyState&&t.addEventListener&&(t.readyState="loading",t.addEventListener("DOMContentLoaded",C=function(){t.removeEventListener("DOMContentLoaded",C,0),t.readyState="complete"},0)),e.yepnope=l(),e.yepnope.executeStack=u,e.yepnope.injectJs=function(e,n,r,i,a,f){var l=t.createElement("script"),c,d,i=i||k.errorTimeout;l.src=e;for(d in r)l.setAttribute(d,r[d]);n=f?u:n||s,l.onreadystatechange=l.onload=function(){!c&&o(l.readyState)&&(c=1,n(),l.onload=l.onreadystatechange=null)},h(function(){c||(c=1,n(1))},i),a?l.onload():p.parentNode.insertBefore(l,p)},e.yepnope.injectCss=function(e,n,r,i,o,a){var i=t.createElement("link"),f,n=a?u:n||s;i.href=e,i.rel="stylesheet",i.type="text/css";for(f in r)i.setAttribute(f,r[f]);o||(p.parentNode.insertBefore(i,p),h(n,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};



/**


 * jquery.flipshow.js v1.0.0


 * http://www.codrops.com


 *


 * Licensed under the MIT license.


 * http://www.opensource.org/licenses/mit-license.php


 *


 * Copyright 2013, Codrops


 * http://www.codrops.com


 */


;( function( $, window, undefined ) {





	'use strict';





	// ======================= imagesLoaded Plugin ===============================


	// https://github.com/desandro/imagesloaded





	// $('#my-container').imagesLoaded(myFunction)


	// execute a callback when all images have loaded.


	// needed because .load() doesn't work on cached images





	// callback function gets image collection as argument


	//  this is the container





	// original: mit license. paul irish. 2010.


	// contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou





	// blank image data-uri bypasses webkit log warning (thx doug jones)


	// blank image data-uri bypasses webkit log warning (thx doug jones)


	var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';





	$.fn.imagesLoaded = function( callback ) {


		var $this = this,


			deferred = $.isFunction($.Deferred) ? $.Deferred() : 0,


			hasNotify = $.isFunction(deferred.notify),


			$images = $this.find('img').add( $this.filter('img') ),


			loaded = [],


			proper = [],


			broken = [];





		// Register deferred callbacks


		if ($.isPlainObject(callback)) {


			$.each(callback, function (key, value) {


				if (key === 'callback') {


					callback = value;


				} else if (deferred) {


					deferred[key](value);


				}


			});


		}





		function doneLoading() {


			var $proper = $(proper),


				$broken = $(broken);





			if ( deferred ) {


				if ( broken.length ) {


					deferred.reject( $images, $proper, $broken );


				} else {


					deferred.resolve( $images );


				}


			}





			if ( $.isFunction( callback ) ) {


				callback.call( $this, $images, $proper, $broken );


			}


		}





		function imgLoadedHandler( event ) {


			imgLoaded( event.target, event.type === 'error' );


		}





		function imgLoaded( img, isBroken ) {


			// don't proceed if BLANK image, or image is already loaded


			if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) {


				return;


			}





			// store element in loaded images array


			loaded.push( img );





			// keep track of broken and properly loaded images


			if ( isBroken ) {


				broken.push( img );


			} else {


				proper.push( img );


			}





			// cache image and its state for future calls


			$.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } );





			// trigger deferred progress method if present


			if ( hasNotify ) {


				deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] );


			}





			// call doneLoading and clean listeners if all images are loaded


			if ( $images.length === loaded.length ) {


				setTimeout( doneLoading );


				$images.unbind( '.imagesLoaded', imgLoadedHandler );


			}


		}





		// if no images, trigger immediately


		if ( !$images.length ) {


			doneLoading();


		} else {


			$images.bind( 'load.imagesLoaded error.imagesLoaded', imgLoadedHandler )


			.each( function( i, el ) {


				var src = el.src;





				// find out if this image has been already checked for status


				// if it was, and src has not changed, call imgLoaded on it


				var cached = $.data( el, 'imagesLoaded' );


				if ( cached && cached.src === src ) {


					imgLoaded( el, cached.isBroken );


					return;


				}





				// if complete is true and browser supports natural sizes, try


				// to check for image status manually


				if ( el.complete && el.naturalWidth !== undefined ) {


					imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 );


					return;


				}





				// cached images don't fire load sometimes, so we reset src, but only when


				// dealing with IE, or image is complete (loaded) and failed manual check


				// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f


				if ( el.readyState || el.complete ) {


					el.src = BLANK;


					el.src = src;


				}


			});


		}





		return deferred ? deferred.promise( $this ) : $this;


	};





	// global


	var Modernizr = window.Modernizr;





	$.Flipshow = function( options, element ) {


		this.$el = $( element );


		this._init( options );


	};





	// the options


	$.Flipshow.defaults = {


		// default transition speed (ms)


		speed : 700,


		// default transition easing


		easing : 'ease-out'


	};





	$.Flipshow.prototype = {


		_init : function( options ) {





			// options


			this.options = $.extend( true, {}, $.Flipshow.defaults, options );


			// support for CSS Transitions & 3D transforms


			this.support = Modernizr.csstransitions && Modernizr.csstransforms3d && !(/MSIE (\d+\.\d+);/.test(navigator.userAgent));


			// transition end event name and transform name


			var transEndEventNames = {


					'WebkitTransition' : 'webkitTransitionEnd',


					'MozTransition' : 'transitionend',


					'OTransition' : 'oTransitionEnd',


					'msTransition' : 'MSTransitionEnd',


					'transition' : 'transitionend'


				},


				transformNames = {


					'WebkitTransform' : '-webkit-transform',


					'MozTransform' : '-moz-transform',


					'OTransform' : '-o-transform',


					'msTransform' : '-ms-transform',


					'transform' : 'transform'


				};





			if( this.support ) {


				this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ] + '.cbpFWSlider';


				this.transformName = transformNames[ Modernizr.prefixed( 'transform' ) ];


			}


			this.transitionProperties = this.transformName + ' ' + this.options.speed + 'ms ' + this.options.easing;





			// the list of items


			this.$listItems = this.$el.children( 'ul.fc-slides' );


			// the items


			this.$items = this.$listItems.children( 'li' ).hide();


			// total number of items


			this.itemsCount = this.$items.length;


			// current item´s index


			this.current = 0;


			this.$listItems.imagesLoaded( $.proxy( function() {


				// show first item


				this.$items.eq( this.current ).show();


				// add navigation and flipping structure


				if( this.itemsCount > 0 ) {


					this._addNav();


					if( this.support ) {


						this._layout();


					}


				}


			}, this ) );





		},


		_addNav : function() {





			var self = this,


				$navLeft = $( '<div class="fc-left"><span></span><span></span><span></span><i class="fa fa-arrow-left"></i></div>' ),


				$navRight = $( '<div class="fc-right"><span></span><span></span><span></span><i class="fa fa-arrow-right"></i></div>' );





			$( '<nav></nav>' ).append( $navLeft, $navRight ).appendTo( this.$el );





			$navLeft.find( 'span' ).on( 'click.flipshow touchstart.flipshow', function() {


				self._navigate( $( this ), 'left' );


			} );





			$navRight.find( 'span' ).on( 'click.flipshow touchstart.flipshow', function() {


				self._navigate( $( this ), 'right' );


			} );





		},


		_layout : function( $current, $next ) {





			this.$flipFront = $( '<div class="fc-front"><div></div></div>' );


			this.$frontContent = this.$flipFront.children( 'div:first' );


			this.$flipBack = $( '<div class="fc-back"><div></div></div>' );


			this.$backContent = this.$flipBack.children( 'div:first' );


			this.$flipEl = $( '<div class="fc-flip"></div>' ).append( this.$flipFront, this.$flipBack ).hide().appendTo( this.$el );





		},


		_navigate : function( $nav, dir ) {





			if( this.isAnimating && this.support ) {


				return false;


			}


			this.isAnimating = true;





			var $currentItem = this.$items.eq( this.current ).hide();





			if( dir === 'right' ) {


				this.current < this.itemsCount - 1 ? ++this.current : this.current = 0;


			}


			else if( dir === 'left' ) {


				this.current > 0 ? --this.current : this.current = this.itemsCount - 1;


			}





			var $nextItem = this.$items.eq( this.current );





			if( this.support ) {


				this._flip( $currentItem, $nextItem, dir, $nav.index() );


			}


			else {


				$nextItem.show();


			}





		},


		_flip : function( $currentItem, $nextItem, dir, angle ) {





			var transformProperties = '',


				// overlays


				$overlayLight = $( '<div class="fc-overlay-light"></div>' ),


				$overlayDark = $( '<div class="fc-overlay-dark"></div>' );





            if (typeof this.$flipEl == 'undefined')


                return;





			this.$flipEl.css( 'transition', this.transitionProperties );





			this.$flipFront.find( 'div.fc-overlay-light, div.fc-overlay-dark' ).remove();


			this.$flipBack.find( 'div.fc-overlay-light, div.fc-overlay-dark' ).remove();





			if( dir === 'right' ) {


				this.$flipFront.append( $overlayLight );


				this.$flipBack.append( $overlayDark );


				$overlayDark.css( 'opacity', 1 );


			}


			else if( dir === 'left' ) {


				this.$flipFront.append( $overlayDark );


				this.$flipBack.append( $overlayLight );


				$overlayLight.css( 'opacity', 1 );


			}


			var overlayStyle = { transition : 'opacity ' + ( this.options.speed / 1.3 ) + 'ms' };


			$overlayLight.css( overlayStyle );


			$overlayDark.css( overlayStyle );





			switch( angle ) {


				case 0 :


					transformProperties = dir === 'left' ? 'rotate3d(-1,1,0,-179deg) rotate3d(-1,1,0,-1deg)' : 'rotate3d(1,1,0,180deg)';


					break;


				case 1 :


					transformProperties = dir === 'left' ? 'rotate3d(0,1,0,-179deg) rotate3d(0,1,0,-1deg)' : 'rotate3d(0,1,0,180deg)';


					break;


				case 2 :


					transformProperties = dir === 'left' ? 'rotate3d(1,1,0,-179deg) rotate3d(1,1,0,-1deg)' : 'rotate3d(-1,1,0,179deg) rotate3d(-1,1,0,1deg)';


					break;


			}





			this.$flipBack.css( 'transform', transformProperties );





			this.$frontContent.empty().html( $currentItem.html() );


			this.$backContent.empty().html( $nextItem.html() );


			this.$flipEl.show();





			var self = this;


			setTimeout( function() {





				self.$flipEl.css( 'transform', transformProperties );


				$overlayLight.css( 'opacity', dir === 'right' ? 1 : 0 );


				$overlayDark.css( 'opacity', dir === 'right' ? 0 : 1 );


				self.$flipEl.on( self.transEndEventName, function( event ) {


					if( event.target.className === 'fc-overlay-light' || event.target.className === 'fc-overlay-dark' ) return;


					self._ontransitionend( $nextItem );


				} );





			}, 25 );





		},


		_ontransitionend : function( $nextItem ) {


			$nextItem.show();


			this.$flipEl.off( this.transEndEventName ).css( {


				transition : 'none',


				transform : 'none'


			} ).hide();


			this.isAnimating = false;


		}


	};





	var logError = function( message ) {


		if ( window.console ) {


			window.console.error( message );


		}


	};





	$.fn.flipshow = function( options ) {


		if ( typeof options === 'string' ) {


			var args = Array.prototype.slice.call( arguments, 1 );


			this.each(function() {


				var instance = $.data( this, 'flipshow' );


				if ( !instance ) {


					logError( "cannot call methods on flipshow prior to initialization; " +


					"attempted to call method '" + options + "'" );


					return;


				}


				if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {


					logError( "no such method '" + options + "' for flipshow instance" );


					return;


				}


				instance[ options ].apply( instance, args );


			});


		}


		else {


			this.each(function() {


				var instance = $.data( this, 'flipshow' );


				if ( instance ) {


					instance._init();


				}


				else {


					instance = $.data( this, 'flipshow', new $.Flipshow( options, this ) );


				}


			});


		}


		return this;


	};





} )( jQuery, window );



/*! Magnific Popup - v1.1.0 - 2016-02-20

* http://dimsemenov.com/plugins/magnific-popup/

* Copyright (c) 2016 Dmitry Semenov; */

;(function (factory) { 

if (typeof define === 'function' && define.amd) { 

 // AMD. Register as an anonymous module. 

 define(['jquery'], factory); 

 } else if (typeof exports === 'object') { 

 // Node/CommonJS 

 factory(require('jquery')); 

 } else { 

 // Browser globals 

 factory(window.jQuery || window.Zepto); 

 } 

 }(function($) { 



/*>>core*/

/**

 * 

 * Magnific Popup Core JS file

 * 

 */





/**

 * Private static constants

 */

var CLOSE_EVENT = 'Close',

	BEFORE_CLOSE_EVENT = 'BeforeClose',

	AFTER_CLOSE_EVENT = 'AfterClose',

	BEFORE_APPEND_EVENT = 'BeforeAppend',

	MARKUP_PARSE_EVENT = 'MarkupParse',

	OPEN_EVENT = 'Open',

	CHANGE_EVENT = 'Change',

	NS = 'mfp',

	EVENT_NS = '.' + NS,

	READY_CLASS = 'mfp-ready',

	REMOVING_CLASS = 'mfp-removing',

	PREVENT_CLOSE_CLASS = 'mfp-prevent-close';





/**

 * Private vars 

 */

/*jshint -W079 */

var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this'

	MagnificPopup = function(){},

	_isJQ = !!(window.jQuery),

	_prevStatus,

	_window = $(window),

	_document,

	_prevContentType,

	_wrapClasses,

	_currPopupType;





/**

 * Private functions

 */

var _mfpOn = function(name, f) {

		mfp.ev.on(NS + name + EVENT_NS, f);

	},

	_getEl = function(className, appendTo, html, raw) {

		var el = document.createElement('div');

		el.className = 'mfp-'+className;

		if(html) {

			el.innerHTML = html;

		}

		if(!raw) {

			el = $(el);

			if(appendTo) {

				el.appendTo(appendTo);

			}

		} else if(appendTo) {

			appendTo.appendChild(el);

		}

		return el;

	},

	_mfpTrigger = function(e, data) {

		mfp.ev.triggerHandler(NS + e, data);



		if(mfp.st.callbacks) {

			// converts "mfpEventName" to "eventName" callback and triggers it if it's present

			e = e.charAt(0).toLowerCase() + e.slice(1);

			if(mfp.st.callbacks[e]) {

				mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]);

			}

		}

	},

	_getCloseBtn = function(type) {

		if(type !== _currPopupType || !mfp.currTemplate.closeBtn) {

			mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) );

			_currPopupType = type;

		}

		return mfp.currTemplate.closeBtn;

	},

	// Initialize Magnific Popup only when called at least once

	_checkInstance = function() {

		if(!$.magnificPopup.instance) {

			/*jshint -W020 */

			mfp = new MagnificPopup();

			mfp.init();

			$.magnificPopup.instance = mfp;

		}

	},

	// CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr

	supportsTransitions = function() {

		var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist

			v = ['ms','O','Moz','Webkit']; // 'v' for vendor



		if( s['transition'] !== undefined ) {

			return true; 

		}

			

		while( v.length ) {

			if( v.pop() + 'Transition' in s ) {

				return true;

			}

		}

				

		return false;

	};







/**

 * Public functions

 */

MagnificPopup.prototype = {



	constructor: MagnificPopup,



	/**

	 * Initializes Magnific Popup plugin. 

	 * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed

	 */

	init: function() {

		var appVersion = navigator.appVersion;

		mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener;

		mfp.isAndroid = (/android/gi).test(appVersion);

		mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);

		mfp.supportsTransition = supportsTransitions();



		// We disable fixed positioned lightbox on devices that don't handle it nicely.

		// If you know a better way of detecting this - let me know.

		mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );

		_document = $(document);



		mfp.popupsCache = {};

	},



	/**

	 * Opens popup

	 * @param  data [description]

	 */

	open: function(data) {



		var i;



		if(data.isObj === false) { 

			// convert jQuery collection to array to avoid conflicts later

			mfp.items = data.items.toArray();



			mfp.index = 0;

			var items = data.items,

				item;

			for(i = 0; i < items.length; i++) {

				item = items[i];

				if(item.parsed) {

					item = item.el[0];

				}

				if(item === data.el[0]) {

					mfp.index = i;

					break;

				}

			}

		} else {

			mfp.items = $.isArray(data.items) ? data.items : [data.items];

			mfp.index = data.index || 0;

		}



		// if popup is already opened - we just update the content

		if(mfp.isOpen) {

			mfp.updateItemHTML();

			return;

		}

		

		mfp.types = []; 

		_wrapClasses = '';

		if(data.mainEl && data.mainEl.length) {

			mfp.ev = data.mainEl.eq(0);

		} else {

			mfp.ev = _document;

		}



		if(data.key) {

			if(!mfp.popupsCache[data.key]) {

				mfp.popupsCache[data.key] = {};

			}

			mfp.currTemplate = mfp.popupsCache[data.key];

		} else {

			mfp.currTemplate = {};

		}







		mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data ); 

		mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;



		if(mfp.st.modal) {

			mfp.st.closeOnContentClick = false;

			mfp.st.closeOnBgClick = false;

			mfp.st.showCloseBtn = false;

			mfp.st.enableEscapeKey = false;

		}

		



		// Building markup

		// main containers are created only once

		if(!mfp.bgOverlay) {



			// Dark overlay

			mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {

				mfp.close();

			});



			mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) {

				if(mfp._checkIfClose(e.target)) {

					mfp.close();

				}

			});



			mfp.container = _getEl('container', mfp.wrap);

		}



		mfp.contentContainer = _getEl('content');

		if(mfp.st.preloader) {

			mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);

		}





		// Initializing modules

		var modules = $.magnificPopup.modules;

		for(i = 0; i < modules.length; i++) {

			var n = modules[i];

			n = n.charAt(0).toUpperCase() + n.slice(1);

			mfp['init'+n].call(mfp);

		}

		_mfpTrigger('BeforeOpen');





		if(mfp.st.showCloseBtn) {

			// Close button

			if(!mfp.st.closeBtnInside) {

				mfp.wrap.append( _getCloseBtn() );

			} else {

				_mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {

					values.close_replaceWith = _getCloseBtn(item.type);

				});

				_wrapClasses += ' mfp-close-btn-in';

			}

		}



		if(mfp.st.alignTop) {

			_wrapClasses += ' mfp-align-top';

		}



	



		if(mfp.fixedContentPos) {

			mfp.wrap.css({

				overflow: mfp.st.overflowY,

				overflowX: 'hidden',

				overflowY: mfp.st.overflowY

			});

		} else {

			mfp.wrap.css({ 

				top: _window.scrollTop(),

				position: 'absolute'

			});

		}

		if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {

			mfp.bgOverlay.css({

				height: _document.height(),

				position: 'absolute'

			});

		}



		



		if(mfp.st.enableEscapeKey) {

			// Close on ESC key

			_document.on('keyup' + EVENT_NS, function(e) {

				if(e.keyCode === 27) {

					mfp.close();

				}

			});

		}



		_window.on('resize' + EVENT_NS, function() {

			mfp.updateSize();

		});





		if(!mfp.st.closeOnContentClick) {

			_wrapClasses += ' mfp-auto-cursor';

		}

		

		if(_wrapClasses)

			mfp.wrap.addClass(_wrapClasses);





		// this triggers recalculation of layout, so we get it once to not to trigger twice

		var windowHeight = mfp.wH = _window.height();



		

		var windowStyles = {};



		if( mfp.fixedContentPos ) {

            if(mfp._hasScrollBar(windowHeight)){

                var s = mfp._getScrollbarSize();

                if(s) {

                    if ($('html').hasClass('browser-rtl'))

                        windowStyles.marginLeft = s;

                    else

                        windowStyles.marginRight = s;

                }

            }

        }



		if(mfp.fixedContentPos) {

			if(!mfp.isIE7) {

				windowStyles.overflow = 'hidden';

			} else {

				// ie7 double-scroll bug

				$('body, html').css('overflow', 'hidden');

			}

		}



		

		

		var classesToadd = mfp.st.mainClass;

		if(mfp.isIE7) {

			classesToadd += ' mfp-ie7';

		}

		if(classesToadd) {

			mfp._addClassToMFP( classesToadd );

		}



		// add content

		mfp.updateItemHTML();



		_mfpTrigger('BuildControls');



		// remove scrollbar, add margin e.t.c

		$('html').css(windowStyles);

		

		// add everything to DOM

		mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) );



		// Save last focused element

		mfp._lastFocusedEl = document.activeElement;

		

		// Wait for next cycle to allow CSS transition

		setTimeout(function() {

			

			if(mfp.content) {

				mfp._addClassToMFP(READY_CLASS);

				mfp._setFocus();

			} else {

				// if content is not defined (not loaded e.t.c) we add class only for BG

				mfp.bgOverlay.addClass(READY_CLASS);

			}

			

			// Trap the focus in popup

			_document.on('focusin' + EVENT_NS, mfp._onFocusIn);



		}, 16);



		mfp.isOpen = true;

		mfp.updateSize(windowHeight);

		_mfpTrigger(OPEN_EVENT);



		return data;

	},



	/**

	 * Closes the popup

	 */

	close: function() {

		if(!mfp.isOpen) return;

		_mfpTrigger(BEFORE_CLOSE_EVENT);



		mfp.isOpen = false;

		// for CSS3 animation

		if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition )  {

			mfp._addClassToMFP(REMOVING_CLASS);

			setTimeout(function() {

				mfp._close();

			}, mfp.st.removalDelay);

		} else {

			mfp._close();

		}

	},



	/**

	 * Helper for close() function

	 */

	_close: function() {

		_mfpTrigger(CLOSE_EVENT);



		var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';



		mfp.bgOverlay.detach();

		mfp.wrap.detach();

		mfp.container.empty();



		if(mfp.st.mainClass) {

			classesToRemove += mfp.st.mainClass + ' ';

		}



		mfp._removeClassFromMFP(classesToRemove);



		if(mfp.fixedContentPos) {

            var windowStyles;

            if ($('html').hasClass('browser-rtl'))

                windowStyles = {marginLeft: ''};

            else

                windowStyles = {marginRight: ''};

			if(mfp.isIE7) {

				$('body, html').css('overflow', '');

			} else {

				windowStyles.overflow = '';

			}

			$('html').css(windowStyles);

		}

		

		_document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);

		mfp.ev.off(EVENT_NS);



		// clean up DOM elements that aren't removed

		mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');

		mfp.bgOverlay.attr('class', 'mfp-bg');

		mfp.container.attr('class', 'mfp-container');



		// remove close button from target element

		if(mfp.st.showCloseBtn &&

		(!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {

			if(mfp.currTemplate.closeBtn)

				mfp.currTemplate.closeBtn.detach();

		}





		if(mfp.st.autoFocusLast && mfp._lastFocusedEl) {

			$(mfp._lastFocusedEl).focus(); // put tab focus back

		}

		mfp.currItem = null;	

		mfp.content = null;

		mfp.currTemplate = null;

		mfp.prevHeight = 0;



		_mfpTrigger(AFTER_CLOSE_EVENT);

	},

	

	updateSize: function(winHeight) {



		if(mfp.isIOS) {

			// fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2

			var zoomLevel = document.documentElement.clientWidth / window.innerWidth;

			var height = window.innerHeight * zoomLevel;

			mfp.wrap.css('height', height);

			mfp.wH = height;

		} else {

			mfp.wH = winHeight || _window.height();

		}

		// Fixes #84: popup incorrectly positioned with position:relative on body

		if(!mfp.fixedContentPos) {

			mfp.wrap.css('height', mfp.wH);

		}



		_mfpTrigger('Resize');



	},



	/**

	 * Set content of popup based on current index

	 */

	updateItemHTML: function() {

		var item = mfp.items[mfp.index];



		// Detach and perform modifications

		mfp.contentContainer.detach();



		if(mfp.content)

			mfp.content.detach();



		if(!item.parsed) {

			item = mfp.parseEl( mfp.index );

		}



		var type = item.type;



		_mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);

		// BeforeChange event works like so:

		// _mfpOn('BeforeChange', function(e, prevType, newType) { });



		mfp.currItem = item;



		if(!mfp.currTemplate[type]) {

			var markup = mfp.st[type] ? mfp.st[type].markup : false;



			// allows to modify markup

			_mfpTrigger('FirstMarkupParse', markup);



			if(markup) {

				mfp.currTemplate[type] = $(markup);

			} else {

				// if there is no markup found we just define that template is parsed

				mfp.currTemplate[type] = true;

			}

		}



		if(_prevContentType && _prevContentType !== item.type) {

			mfp.container.removeClass('mfp-'+_prevContentType+'-holder');

		}



		var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);

		mfp.appendContent(newContent, type);



		item.preloaded = true;



		_mfpTrigger(CHANGE_EVENT, item);

		_prevContentType = item.type;



		// Append container back after its content changed

		mfp.container.prepend(mfp.contentContainer);



		_mfpTrigger('AfterChange');

	},





	/**

	 * Set HTML content of popup

	 */

	appendContent: function(newContent, type) {

		mfp.content = newContent;



		if(newContent) {

			if(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&

				mfp.currTemplate[type] === true) {

				// if there is no markup, we just append close button element inside

				if(!mfp.content.find('.mfp-close').length) {

					mfp.content.append(_getCloseBtn());

				}

			} else {

				mfp.content = newContent;

			}

		} else {

			mfp.content = '';

		}



		_mfpTrigger(BEFORE_APPEND_EVENT);

		mfp.container.addClass('mfp-'+type+'-holder');



		mfp.contentContainer.append(mfp.content);

	},





	/**

	 * Creates Magnific Popup data object based on given data

	 * @param  {int} index Index of item to parse

	 */

	parseEl: function(index) {

		var item = mfp.items[index],

			type;



		if(item.tagName) {

			item = { el: $(item) };

		} else {

			type = item.type;

			item = { data: item, src: item.src };

		}



		if(item.el) {

			var types = mfp.types;



			// check for 'mfp-TYPE' class

			for(var i = 0; i < types.length; i++) {

				if( item.el.hasClass('mfp-'+types[i]) ) {

					type = types[i];

					break;

				}

			}



			item.src = item.el.attr('data-mfp-src');

			if(!item.src) {

				item.src = item.el.attr('href');

			}

		}



		item.type = type || mfp.st.type || 'inline';

		item.index = index;

		item.parsed = true;

		mfp.items[index] = item;

		_mfpTrigger('ElementParse', item);



		return mfp.items[index];

	},





	/**

	 * Initializes single popup or a group of popups

	 */

	addGroup: function(el, options) {

		var eHandler = function(e) {

			e.mfpEl = this;

			mfp._openClick(e, el, options);

		};



		if(!options) {

			options = {};

		}



		var eName = 'click.magnificPopup';

		options.mainEl = el;



		if(options.items) {

			options.isObj = true;

			el.off(eName).on(eName, eHandler);

		} else {

			options.isObj = false;

			if(options.delegate) {

				el.off(eName).on(eName, options.delegate , eHandler);

			} else {

				options.items = el;

				el.off(eName).on(eName, eHandler);

			}

		}

	},

	_openClick: function(e, el, options) {

		var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;





		if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) {

			return;

		}



		var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;



		if(disableOn) {

			if($.isFunction(disableOn)) {

				if( !disableOn.call(mfp) ) {

					return true;

				}

			} else { // else it's number

				if( _window.width() < disableOn ) {

					return true;

				}

			}

		}



		if(e.type) {

			e.preventDefault();



			// This will prevent popup from closing if element is inside and popup is already opened

			if(mfp.isOpen) {

				e.stopPropagation();

			}

		}



		options.el = $(e.mfpEl);

		if(options.delegate) {

			options.items = el.find(options.delegate);

		}

		mfp.open(options);

	},





	/**

	 * Updates text on preloader

	 */

	updateStatus: function(status, text) {



		if(mfp.preloader) {

			if(_prevStatus !== status) {

				mfp.container.removeClass('mfp-s-'+_prevStatus);

			}



			if(!text && status === 'loading') {

				text = mfp.st.tLoading;

			}



			var data = {

				status: status,

				text: text

			};

			// allows to modify status

			_mfpTrigger('UpdateStatus', data);



			status = data.status;

			text = data.text;



			mfp.preloader.html(text);



			mfp.preloader.find('a').on('click', function(e) {

				e.stopImmediatePropagation();

			});



			mfp.container.addClass('mfp-s-'+status);

			_prevStatus = status;

		}

	},





	/*

		"Private" helpers that aren't private at all

	 */

	// Check to close popup or not

	// "target" is an element that was clicked

	_checkIfClose: function(target) {



		if($(target).hasClass(PREVENT_CLOSE_CLASS)) {

			return;

		}



		var closeOnContent = mfp.st.closeOnContentClick;

		var closeOnBg = mfp.st.closeOnBgClick;



		if(closeOnContent && closeOnBg) {

			return true;

		} else {



			// We close the popup if click is on close button or on preloader. Or if there is no content.

			if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {

				return true;

			}



			// if click is outside the content

			if(  (target !== mfp.content[0] && !$.contains(mfp.content[0], target))  ) {

				if(closeOnBg) {

					// last check, if the clicked element is in DOM, (in case it's removed onclick)

					if( $.contains(document, target) ) {

						return true;

					}

				}

			} else if(closeOnContent) {

				return true;

			}



		}

		return false;

	},

	_addClassToMFP: function(cName) {

		mfp.bgOverlay.addClass(cName);

		mfp.wrap.addClass(cName);

	},

	_removeClassFromMFP: function(cName) {

		this.bgOverlay.removeClass(cName);

		mfp.wrap.removeClass(cName);

	},

	_hasScrollBar: function(winHeight) {

		return (  (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );

	},

	_setFocus: function() {

		(mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();

	},

	_onFocusIn: function(e) {

		if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {

			mfp._setFocus();

			return false;

		}

	},

	_parseMarkup: function(template, values, item) {

		var arr;

		if(item.data) {

			values = $.extend(item.data, values);

		}

		_mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );



		$.each(values, function(key, value) {

			if(value === undefined || value === false) {

				return true;

			}

			arr = key.split('_');

			if(arr.length > 1) {

				var el = template.find(EVENT_NS + '-'+arr[0]);



				if(el.length > 0) {

					var attr = arr[1];

					if(attr === 'replaceWith') {

						if(el[0] !== value[0]) {

							el.replaceWith(value);

						}

					} else if(attr === 'img') {

						if(el.is('img')) {

							el.attr('src', value);

						} else {

							el.replaceWith( $('<img>').attr('src', value).attr('class', el.attr('class')) );

						}

					} else {

						el.attr(arr[1], value);

					}

				}



			} else {

				template.find(EVENT_NS + '-'+key).html(value);

			}

		});

	},



	_getScrollbarSize: function() {

		// thx David

		if(mfp.scrollbarSize === undefined) {

			var scrollDiv = document.createElement("div");

			scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';

			document.body.appendChild(scrollDiv);

			mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;

			document.body.removeChild(scrollDiv);

		}

		return mfp.scrollbarSize;

	}



}; /* MagnificPopup core prototype end */









/**

 * Public static functions

 */

$.magnificPopup = {

	instance: null,

	proto: MagnificPopup.prototype,

	modules: [],



	open: function(options, index) {

		_checkInstance();



		if(!options) {

			options = {};

		} else {

			options = $.extend(true, {}, options);

		}



		options.isObj = true;

		options.index = index || 0;

		return this.instance.open(options);

	},



	close: function() {

		return $.magnificPopup.instance && $.magnificPopup.instance.close();

	},



	registerModule: function(name, module) {

		if(module.options) {

			$.magnificPopup.defaults[name] = module.options;

		}

		$.extend(this.proto, module.proto);

		this.modules.push(name);

	},



	defaults: {



		// Info about options is in docs:

		// http://dimsemenov.com/plugins/magnific-popup/documentation.html#options



		disableOn: 0,



		key: null,



		midClick: false,



		mainClass: '',



		preloader: true,



		focus: '', // CSS selector of input to focus after popup is opened



		closeOnContentClick: false,



		closeOnBgClick: true,



		closeBtnInside: true,



		showCloseBtn: true,



		enableEscapeKey: true,



		modal: false,



		alignTop: false,



		removalDelay: 0,



		prependTo: null,



		fixedContentPos: 'auto',



		fixedBgPos: 'auto',



		overflowY: 'auto',



		closeMarkup: '<button title="%title%" type="button" class="mfp-close">&#215;</button>',



		tClose: 'Close (Esc)',



		tLoading: 'Loading...',



		autoFocusLast: true



	}

};







$.fn.magnificPopup = function(options) {

	_checkInstance();



	var jqEl = $(this);



	// We call some API method of first param is a string

	if (typeof options === "string" ) {



		if(options === 'open') {

			var items,

				itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,

				index = parseInt(arguments[1], 10) || 0;



			if(itemOpts.items) {

				items = itemOpts.items[index];

			} else {

				items = jqEl;

				if(itemOpts.delegate) {

					items = items.find(itemOpts.delegate);

				}

				items = items.eq( index );

			}

			mfp._openClick({mfpEl:items}, jqEl, itemOpts);

		} else {

			if(mfp.isOpen)

				mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));

		}



	} else {

		// clone options obj

		options = $.extend(true, {}, options);



		/*

		 * As Zepto doesn't support .data() method for objects

		 * and it works only in normal browsers

		 * we assign "options" object directly to the DOM element. FTW!

		 */

		if(_isJQ) {

			jqEl.data('magnificPopup', options);

		} else {

			jqEl[0].magnificPopup = options;

		}



		mfp.addGroup(jqEl, options);



	}

	return jqEl;

};



/*>>core*/



/*>>inline*/



var INLINE_NS = 'inline',

	_hiddenClass,

	_inlinePlaceholder,

	_lastInlineElement,

	_putInlineElementsBack = function() {

		if(_lastInlineElement) {

			_inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();

			_lastInlineElement = null;

		}

	};



$.magnificPopup.registerModule(INLINE_NS, {

	options: {

		hiddenClass: 'hide', // will be appended with `mfp-` prefix

		markup: '',

		tNotFound: 'Content not found'

	},

	proto: {



		initInline: function() {

			mfp.types.push(INLINE_NS);



			_mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {

				_putInlineElementsBack();

			});

		},



		getInline: function(item, template) {



			_putInlineElementsBack();



			if(item.src) {

				var inlineSt = mfp.st.inline,

					el = $(item.src);



				if(el.length) {



					// If target element has parent - we replace it with placeholder and put it back after popup is closed

					var parent = el[0].parentNode;

					if(parent && parent.tagName) {

						if(!_inlinePlaceholder) {

							_hiddenClass = inlineSt.hiddenClass;

							_inlinePlaceholder = _getEl(_hiddenClass);

							_hiddenClass = 'mfp-'+_hiddenClass;

						}

						// replace target inline element with placeholder

						_lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);

					}



					mfp.updateStatus('ready');

				} else {

					mfp.updateStatus('error', inlineSt.tNotFound);

					el = $('<div>');

				}



				item.inlineElement = el;

				return el;

			}



			mfp.updateStatus('ready');

			mfp._parseMarkup(template, {}, item);

			return template;

		}

	}

});



/*>>inline*/



/*>>ajax*/

var AJAX_NS = 'ajax',

	_ajaxCur,

	_removeAjaxCursor = function() {

		if(_ajaxCur) {

			$(document.body).removeClass(_ajaxCur);

		}

	},

	_destroyAjaxRequest = function() {

		_removeAjaxCursor();

		if(mfp.req) {

			mfp.req.abort();

		}

	};



$.magnificPopup.registerModule(AJAX_NS, {



	options: {

		settings: null,

		cursor: 'mfp-ajax-cur',

		tError: '<a href="%url%">The content</a> could not be loaded.'

	},



	proto: {

		initAjax: function() {

			mfp.types.push(AJAX_NS);

			_ajaxCur = mfp.st.ajax.cursor;



			_mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);

			_mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);

		},

		getAjax: function(item) {



			if(_ajaxCur) {

				$(document.body).addClass(_ajaxCur);

			}



			mfp.updateStatus('loading');



			var opts = $.extend({

				url: item.src,

				success: function(data, textStatus, jqXHR) {

					var temp = {

						data:data,

						xhr:jqXHR

					};



					_mfpTrigger('ParseAjax', temp);



					mfp.appendContent( $(temp.data), AJAX_NS );



					item.finished = true;



					_removeAjaxCursor();



					mfp._setFocus();



					setTimeout(function() {

						mfp.wrap.addClass(READY_CLASS);

					}, 16);



					mfp.updateStatus('ready');



					_mfpTrigger('AjaxContentAdded');

				},

				error: function() {

					_removeAjaxCursor();

					item.finished = item.loadError = true;

					mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src));

				}

			}, mfp.st.ajax.settings);



			mfp.req = $.ajax(opts);



			return '';

		}

	}

});



/*>>ajax*/



/*>>image*/

var _imgInterval,

	_getTitle = function(item) {

		if(item.data && item.data.title !== undefined)

			return item.data.title;



		var src = mfp.st.image.titleSrc;



		if(src) {

			if($.isFunction(src)) {

				return src.call(mfp, item);

			} else if(item.el) {

				return item.el.attr(src) || '';

			}

		}

		return '';

	};



$.magnificPopup.registerModule('image', {



	options: {

		markup: '<div class="mfp-figure">'+

					'<div class="mfp-close"></div>'+

					'<figure>'+

						'<div class="mfp-img"></div>'+

						'<figcaption>'+

							'<div class="mfp-bottom-bar">'+

								'<div class="mfp-title"></div>'+

								'<div class="mfp-counter"></div>'+

							'</div>'+

						'</figcaption>'+

					'</figure>'+

				'</div>',

		cursor: 'mfp-zoom-out-cur',

		titleSrc: 'title',

		verticalFit: true,

		tError: '<a href="%url%">The image</a> could not be loaded.'

	},



	proto: {

		initImage: function() {

			var imgSt = mfp.st.image,

				ns = '.image';



			mfp.types.push('image');



			_mfpOn(OPEN_EVENT+ns, function() {

				if(mfp.currItem.type === 'image' && imgSt.cursor) {

					$(document.body).addClass(imgSt.cursor);

				}

			});



			_mfpOn(CLOSE_EVENT+ns, function() {

				if(imgSt.cursor) {

					$(document.body).removeClass(imgSt.cursor);

				}

				_window.off('resize' + EVENT_NS);

			});



			_mfpOn('Resize'+ns, mfp.resizeImage);

			if(mfp.isLowIE) {

				_mfpOn('AfterChange', mfp.resizeImage);

			}

		},

		resizeImage: function() {

			var item = mfp.currItem;

			if(!item || !item.img) return;



			if(mfp.st.image.verticalFit) {

				var decr = 0;

				// fix box-sizing in ie7/8

				if(mfp.isLowIE) {

					decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);

				}

				item.img.css('max-height', mfp.wH-decr);

			}

		},

		_onImageHasSize: function(item) {

			if(item.img) {



				item.hasSize = true;



				if(_imgInterval) {

					clearInterval(_imgInterval);

				}



				item.isCheckingImgSize = false;



				_mfpTrigger('ImageHasSize', item);



				if(item.imgHidden) {

					if(mfp.content)

						mfp.content.removeClass('mfp-loading');



					item.imgHidden = false;

				}



			}

		},



		/**

		 * Function that loops until the image has size to display elements that rely on it asap

		 */

		findImageSize: function(item) {



			var counter = 0,

				img = item.img[0],

				mfpSetInterval = function(delay) {



					if(_imgInterval) {

						clearInterval(_imgInterval);

					}

					// decelerating interval that checks for size of an image

					_imgInterval = setInterval(function() {

						if(img.naturalWidth > 0) {

							mfp._onImageHasSize(item);

							return;

						}



						if(counter > 200) {

							clearInterval(_imgInterval);

						}



						counter++;

						if(counter === 3) {

							mfpSetInterval(10);

						} else if(counter === 40) {

							mfpSetInterval(50);

						} else if(counter === 100) {

							mfpSetInterval(500);

						}

					}, delay);

				};



			mfpSetInterval(1);

		},



		getImage: function(item, template) {



			var guard = 0,



				// image load complete handler

				onLoadComplete = function() {

					if(item) {

						if (item.img[0].complete) {

							item.img.off('.mfploader');



							if(item === mfp.currItem){

								mfp._onImageHasSize(item);



								mfp.updateStatus('ready');

							}



							item.hasSize = true;

							item.loaded = true;



							_mfpTrigger('ImageLoadComplete');



						}

						else {

							// if image complete check fails 200 times (20 sec), we assume that there was an error.

							guard++;

							if(guard < 200) {

								setTimeout(onLoadComplete,100);

							} else {

								onLoadError();

							}

						}

					}

				},



				// image error handler

				onLoadError = function() {

					if(item) {

						item.img.off('.mfploader');

						if(item === mfp.currItem){

							mfp._onImageHasSize(item);

							mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );

						}



						item.hasSize = true;

						item.loaded = true;

						item.loadError = true;

					}

				},

				imgSt = mfp.st.image;





			var el = template.find('.mfp-img');

			if(el.length) {

				var img = document.createElement('img');

				img.className = 'mfp-img';

				if(item.el && item.el.find('img').length) {

					img.alt = item.el.find('img').attr('alt');

				}

				item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);

				img.src = item.src;



				// without clone() "error" event is not firing when IMG is replaced by new IMG

				// TODO: find a way to avoid such cloning

				if(el.is('img')) {

					item.img = item.img.clone();

				}



				img = item.img[0];

				if(img.naturalWidth > 0) {

					item.hasSize = true;

				} else if(!img.width) {

					item.hasSize = false;

				}

			}



			mfp._parseMarkup(template, {

				title: _getTitle(item),

				img_replaceWith: item.img

			}, item);



			mfp.resizeImage();



			if(item.hasSize) {

				if(_imgInterval) clearInterval(_imgInterval);



				if(item.loadError) {

					template.addClass('mfp-loading');

					mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );

				} else {

					template.removeClass('mfp-loading');

					mfp.updateStatus('ready');

				}

				return template;

			}



			mfp.updateStatus('loading');

			item.loading = true;



			if(!item.hasSize) {

				item.imgHidden = true;

				template.addClass('mfp-loading');

				mfp.findImageSize(item);

			}



			return template;

		}

	}

});



/*>>image*/



/*>>zoom*/

var hasMozTransform,

	getHasMozTransform = function() {

		if(hasMozTransform === undefined) {

			hasMozTransform = document.createElement('p').style.MozTransform !== undefined;

		}

		return hasMozTransform;

	};



$.magnificPopup.registerModule('zoom', {



	options: {

		enabled: false,

		easing: 'ease-in-out',

		duration: 300,

		opener: function(element) {

			return element.is('img') ? element : element.find('img');

		}

	},



	proto: {



		initZoom: function() {

			var zoomSt = mfp.st.zoom,

				ns = '.zoom',

				image;



			if(!zoomSt.enabled || !mfp.supportsTransition) {

				return;

			}



			var duration = zoomSt.duration,

				getElToAnimate = function(image) {

					var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),

						transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,

						cssObj = {

							position: 'fixed',

							zIndex: 9999,

							left: 0,

							top: 0,

							'-webkit-backface-visibility': 'hidden'

						},

						t = 'transition';



					cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;



					newImg.css(cssObj);

					return newImg;

				},

				showMainContent = function() {

					mfp.content.css('visibility', 'visible');

				},

				openTimeout,

				animatedImg;



			_mfpOn('BuildControls'+ns, function() {

				if(mfp._allowZoom()) {



					clearTimeout(openTimeout);

					mfp.content.css('visibility', 'hidden');



					// Basically, all code below does is clones existing image, puts in on top of the current one and animated it



					image = mfp._getItemToZoom();



					if(!image) {

						showMainContent();

						return;

					}



					animatedImg = getElToAnimate(image);



					animatedImg.css( mfp._getOffset() );



					mfp.wrap.append(animatedImg);



					openTimeout = setTimeout(function() {

						animatedImg.css( mfp._getOffset( true ) );

						openTimeout = setTimeout(function() {



							showMainContent();



							setTimeout(function() {

								animatedImg.remove();

								image = animatedImg = null;

								_mfpTrigger('ZoomAnimationEnded');

							}, 16); // avoid blink when switching images



						}, duration); // this timeout equals animation duration



					}, 16); // by adding this timeout we avoid short glitch at the beginning of animation





					// Lots of timeouts...

				}

			});

			_mfpOn(BEFORE_CLOSE_EVENT+ns, function() {

				if(mfp._allowZoom()) {



					clearTimeout(openTimeout);



					mfp.st.removalDelay = duration;



					if(!image) {

						image = mfp._getItemToZoom();

						if(!image) {

							return;

						}

						animatedImg = getElToAnimate(image);

					}



					animatedImg.css( mfp._getOffset(true) );

					mfp.wrap.append(animatedImg);

					mfp.content.css('visibility', 'hidden');



					setTimeout(function() {

						animatedImg.css( mfp._getOffset() );

					}, 16);

				}



			});



			_mfpOn(CLOSE_EVENT+ns, function() {

				if(mfp._allowZoom()) {

					showMainContent();

					if(animatedImg) {

						animatedImg.remove();

					}

					image = null;

				}

			});

		},



		_allowZoom: function() {

			return mfp.currItem.type === 'image';

		},



		_getItemToZoom: function() {

			if(mfp.currItem.hasSize) {

				return mfp.currItem.img;

			} else {

				return false;

			}

		},



		// Get element postion relative to viewport

		_getOffset: function(isLarge) {

			var el;

			if(isLarge) {

				el = mfp.currItem.img;

			} else {

				el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);

			}



			var offset = el.offset();

			var paddingTop = parseInt(el.css('padding-top'),10);

			var paddingBottom = parseInt(el.css('padding-bottom'),10);

			offset.top -= ( $(window).scrollTop() - paddingTop );





			/*



			Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.



			 */

			var obj = {

				width: el.width(),

				// fix Zepto height+padding issue

				height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop

			};



			// I hate to do this, but there is no another option

			if( getHasMozTransform() ) {

				obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';

			} else {

				obj.left = offset.left;

				obj.top = offset.top;

			}

			return obj;

		}



	}

});







/*>>zoom*/



/*>>iframe*/



var IFRAME_NS = 'iframe',

	_emptyPage = '//about:blank',



	_fixIframeBugs = function(isShowing) {

		if(mfp.currTemplate[IFRAME_NS]) {

			var el = mfp.currTemplate[IFRAME_NS].find('iframe');

			if(el.length) {

				// reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug

				if(!isShowing) {

					el[0].src = _emptyPage;

				}



				// IE8 black screen bug fix

				if(mfp.isIE8) {

					el.css('display', isShowing ? 'block' : 'none');

				}

			}

		}

	};



$.magnificPopup.registerModule(IFRAME_NS, {



	options: {

		markup: '<div class="mfp-iframe-scaler">'+

					'<div class="mfp-close"></div>'+

					'<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+

				'</div>',



		srcAction: 'iframe_src',



		// we don't care and support only one default type of URL by default

		patterns: {

			youtube: {

				index: 'youtube.com',

				id: 'v=',

				src: '//www.youtube.com/embed/%id%?autoplay=1'

			},

			vimeo: {

				index: 'vimeo.com/',

				id: '/',

				src: '//player.vimeo.com/video/%id%?autoplay=1'

			},

			gmaps: {

				index: '//maps.google.',

				src: '%id%&output=embed'

			}

		}

	},



	proto: {

		initIframe: function() {

			mfp.types.push(IFRAME_NS);



			_mfpOn('BeforeChange', function(e, prevType, newType) {

				if(prevType !== newType) {

					if(prevType === IFRAME_NS) {

						_fixIframeBugs(); // iframe if removed

					} else if(newType === IFRAME_NS) {

						_fixIframeBugs(true); // iframe is showing

					}

				}// else {

					// iframe source is switched, don't do anything

				//}

			});



			_mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {

				_fixIframeBugs();

			});

		},



		getIframe: function(item, template) {

			var embedSrc = item.src;

			var iframeSt = mfp.st.iframe;



			$.each(iframeSt.patterns, function() {

				if(embedSrc.indexOf( this.index ) > -1) {

					if(this.id) {

						if(typeof this.id === 'string') {

							embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);

						} else {

							embedSrc = this.id.call( this, embedSrc );

						}

					}

					embedSrc = this.src.replace('%id%', embedSrc );

					return false; // break;

				}

			});



			var dataObj = {};

			if(iframeSt.srcAction) {

				dataObj[iframeSt.srcAction] = embedSrc;

			}

			mfp._parseMarkup(template, dataObj, item);



			mfp.updateStatus('ready');



			return template;

		}

	}

});







/*>>iframe*/



/*>>gallery*/

/**

 * Get looped index depending on number of slides

 */

var _getLoopedId = function(index) {

		var numSlides = mfp.items.length;

		if(index > numSlides - 1) {

			return index - numSlides;

		} else  if(index < 0) {

			return numSlides + index;

		}

		return index;

	},

	_replaceCurrTotal = function(text, curr, total) {

		return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);

	};



$.magnificPopup.registerModule('gallery', {



	options: {

		enabled: false,

		arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>',

		preload: [0,2],

		navigateByImgClick: true,

		arrows: true,



		tPrev: 'Previous (Left arrow key)',

		tNext: 'Next (Right arrow key)',

		tCounter: '%curr% of %total%'

	},



	proto: {

		initGallery: function() {



			var gSt = mfp.st.gallery,

				ns = '.mfp-gallery';



			mfp.direction = true; // true - next, false - prev



			if(!gSt || !gSt.enabled ) return false;



			_wrapClasses += ' mfp-gallery';



			_mfpOn(OPEN_EVENT+ns, function() {



				if(gSt.navigateByImgClick) {

					mfp.wrap.on('click'+ns, '.mfp-img', function() {

						if(mfp.items.length > 1) {

							mfp.next();

							return false;

						}

					});

				}



				_document.on('keydown'+ns, function(e) {

					if (e.keyCode === 37) {

						mfp.prev();

					} else if (e.keyCode === 39) {

						mfp.next();

					}

				});

			});



			_mfpOn('UpdateStatus'+ns, function(e, data) {

				if(data.text) {

					data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);

				}

			});



			_mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {

				var l = mfp.items.length;

				values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';

			});



			_mfpOn('BuildControls' + ns, function() {

				if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {

					var markup = gSt.arrowMarkup,

						arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS),

						arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS);



					arrowLeft.click(function() {

						mfp.prev();

					});

					arrowRight.click(function() {

						mfp.next();

					});



					mfp.container.append(arrowLeft.add(arrowRight));

				}

			});



			_mfpOn(CHANGE_EVENT+ns, function() {

				if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);



				mfp._preloadTimeout = setTimeout(function() {

					mfp.preloadNearbyImages();

					mfp._preloadTimeout = null;

				}, 16);

			});





			_mfpOn(CLOSE_EVENT+ns, function() {

				_document.off(ns);

				mfp.wrap.off('click'+ns);

				mfp.arrowRight = mfp.arrowLeft = null;

			});



		},

		next: function() {

			mfp.direction = true;

			mfp.index = _getLoopedId(mfp.index + 1);

			mfp.updateItemHTML();

		},

		prev: function() {

			mfp.direction = false;

			mfp.index = _getLoopedId(mfp.index - 1);

			mfp.updateItemHTML();

		},

		goTo: function(newIndex) {

			mfp.direction = (newIndex >= mfp.index);

			mfp.index = newIndex;

			mfp.updateItemHTML();

		},

		preloadNearbyImages: function() {

			var p = mfp.st.gallery.preload,

				preloadBefore = Math.min(p[0], mfp.items.length),

				preloadAfter = Math.min(p[1], mfp.items.length),

				i;



			for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {

				mfp._preloadItem(mfp.index+i);

			}

			for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {

				mfp._preloadItem(mfp.index-i);

			}

		},

		_preloadItem: function(index) {

			index = _getLoopedId(index);



			if(mfp.items[index].preloaded) {

				return;

			}



			var item = mfp.items[index];

			if(!item.parsed) {

				item = mfp.parseEl( index );

			}



			_mfpTrigger('LazyLoad', item);



			if(item.type === 'image') {

				item.img = $('<img class="mfp-img" />').on('load.mfploader', function() {

					item.hasSize = true;

				}).on('error.mfploader', function() {

					item.hasSize = true;

					item.loadError = true;

					_mfpTrigger('LazyLoadError', item);

				}).attr('src', item.src);

			}





			item.preloaded = true;

		}

	}

});



/*>>gallery*/



/*>>retina*/



var RETINA_NS = 'retina';



$.magnificPopup.registerModule(RETINA_NS, {

	options: {

		replaceSrc: function(item) {

			return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; });

		},

		ratio: 1 // Function or number.  Set to 1 to disable.

	},

	proto: {

		initRetina: function() {

			if(window.devicePixelRatio > 1) {



				var st = mfp.st.retina,

					ratio = st.ratio;



				ratio = !isNaN(ratio) ? ratio : ratio();



				if(ratio > 1) {

					_mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {

						item.img.css({

							'max-width': item.img[0].naturalWidth / ratio,

							'width': '100%'

						});

					});

					_mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {

						item.src = st.replaceSrc(item, ratio);

					});

				}

			}



		}

	}

});



/*>>retina*/

 _checkInstance(); }));



/*!


 *         ,/


 *       ,'/


 *     ,' /


 *   ,'  /_____,


 * .'____    ,'


 *      /  ,'


 *     / ,'


 *    /,'


 *   /'


 *


 * Selectric ϟ v1.9.6 (Mar 24 2016) - http://lcdsantos.github.io/jQuery-Selectric/


 *


 * Copyright (c) 2016 Leonardo Santos; MIT License


 *


 */





(function(factory) {


    /* istanbul ignore next */


    if (typeof define === 'function' && define.amd) {


        define(['jquery'], factory);


    } else if (typeof module === 'object' && module.exports) {


        // Node/CommonJS


        module.exports = function( root, jQuery ) {


            if ( jQuery === undefined ) {


                if ( typeof window !== 'undefined' ) {


                    jQuery = require('jquery');


                }


                else {


                    jQuery = require('jquery')(root);


                }


            }


            factory(jQuery);


            return jQuery;


        };


    } else {


        // Browser globals


        factory(jQuery);


    }


}(function($) {





    'use strict';





    var pluginName = 'selectric',


        classList = 'Input Items Open Disabled TempShow HideSelect Wrapper Hover Responsive Above Scroll Group GroupLabel',


        bindSufix = '.sl',


        defaults = {


            onChange: function(elm) { $(elm).change(); },


            maxHeight: 300,


            keySearchTimeout: 500,


            arrowButtonMarkup: '<b class="button">&#x25be;</b>',


            disableOnMobile: true,


            openOnHover: false,


            hoverIntentTimeout: 500,


            expandToItemText: false,


            responsive: false,


            preventWindowScroll: true,


            inheritOriginalWidth: false,


            allowWrap: true,


            customClass: {


                prefix: pluginName,


                camelCase: false


            },


            optionsItemBuilder: '{text}', // function(itemData, element, index)


            labelBuilder: '{text}' // function(currItem)


        },


        hooks = {


            add: function(callbackName, hookName, fn) {


                if ( !this[callbackName] )


                    this[callbackName] = {};





                this[callbackName][hookName] = fn;


            },


            remove: function(callbackName, hookName) {


                delete this[callbackName][hookName];


            }


        },


        _utils = {


            // Replace diacritics


            replaceDiacritics: function(s) {


                // /[\340-\346]/g, // a


                // /[\350-\353]/g, // e


                // /[\354-\357]/g, // i


                // /[\362-\370]/g, // o


                // /[\371-\374]/g, // u


                // /[\361]/g,      // n


                // /[\347]/g,      // c


                // /[\377]/g       // y


                var d = '40-46 50-53 54-57 62-70 71-74 61 47 77'.replace(/\d+/g, '\\3$&').split(' '),


                    k = d.length;





                while (k--)


                    s = s.toLowerCase().replace(RegExp('[' + d[k] + ']', 'g'), 'aeiouncy'.charAt(k));





                return s;


            },


            // https://gist.github.com/atesgoral/984375


            format: function(f) {var a=arguments;return(""+f).replace(/{(\d+|(\w+))}/g,function(s,i,p) {return p&&a[1]?a[1][p]:a[i]})},


            nextEnabledItem: function(selectItems, selected) {


                while ( selectItems[ selected = (selected + 1) % selectItems.length ].disabled ) {}


                return selected;


            },


            previousEnabledItem: function(selectItems, selected) {


                while ( selectItems[ selected = (selected > 0 ? selected : selectItems.length) - 1 ].disabled ) {}


                return selected;


            },


            toDash: function(str) {


                return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();


            },


            triggerCallback: function(fn, scope) {


                var elm = scope.element,


                    func = scope.options['on' + fn];





                if ( $.isFunction(func) )


                    func.call(elm, elm, scope);





                if ( hooks[fn] ) {


                    $.each(hooks[fn], function() {


                        this.call(elm, elm, scope);


                    });


                }





                $(elm).trigger(pluginName + '-' + _utils.toDash(fn), scope);


            }


        },


        $doc = $(document),


        $win = $(window),


        Selectric = function(element, opts) {


            var _this = this,


                $original = $(element),


                $input, $items, $itemsScroll, $wrapper, $label, $outerWrapper, $li,


                isOpen = false,


                isEnabled = false,


                selected,


                currValue,


                itemsHeight,


                itemsInnerHeight,


                finalWidth,


                optionsLength,


                eventTriggers,


                isMobile = /android|ip(hone|od|ad)/i.test(navigator.userAgent),


                tabindex = $original.prop('tabindex'),


                labelBuilder;





            function _init(opts) {


                _this.options = $.extend(true, {}, defaults, _this.options, opts);


                _this.classes = {};


                _this.element = element;





                _utils.triggerCallback('BeforeInit', _this);





                // Disable on mobile browsers


                if ( _this.options.disableOnMobile && isMobile ) {


                    _this.disableOnMobile = true;


                    return;


                }





                // Preserve data


                _destroy(true);





                // Generate classNames for elements


                var customClass   = _this.options.customClass,


                    postfixes     = classList.split(' '),


                    originalWidth = $original.width();





                $.each(postfixes, function(i, currClass) {


                    var c = customClass.prefix + currClass;


                    _this.classes[currClass.toLowerCase()] = customClass.camelCase ? c : _utils.toDash(c);


                });





                $input        = $('<input/>', { 'class': _this.classes.input, 'readonly': isMobile });


                $items        = $('<div/>',   { 'class': _this.classes.items, 'tabindex': -1 });


                $itemsScroll  = $('<div/>',   { 'class': _this.classes.scroll });


                $wrapper      = $('<div/>',   { 'class': customClass.prefix, 'html': _this.options.arrowButtonMarkup });


                $label        = $('<p class="label"/>');


                $outerWrapper = $original.wrap('<div>').parent().append($wrapper.prepend($label), $items, $input);





                eventTriggers = {


                    open    : _open,


                    close   : _close,


                    destroy : _destroy,


                    refresh : _refresh,


                    init    : _init


                };





                $original.on(eventTriggers).wrap('<div class="' + _this.classes.hideselect + '">');


                $.extend(_this, eventTriggers);





                labelBuilder = _this.options.labelBuilder;





                if ( _this.options.inheritOriginalWidth && originalWidth > 0 )


                    $outerWrapper.width(originalWidth);





                _populate();


            }





            // Generate options markup and event binds


            function _populate() {


                _this.items = [];





                var $options = $original.children(),


                    _$li = '<ul>',


                    $justOptions = $original.find('option'),


                    selectedIndex = $justOptions.index($justOptions.filter(':selected')),


                    currIndex = 0;





                currValue = (selected = ~selectedIndex ? selectedIndex : 0);





                if ( optionsLength = $options.length ) {


                    // Build options markup


                    $options.each(function() {


                        var $elm = $(this);





                        if ( $elm.is('optgroup') ) {


                            var groupDisabled = $elm.prop('disabled'),


                                $children = $elm.children();





                            _$li += _utils.format('<ul class="{1}"><li class="{2}">{3}</li>',


                                $.trim([_this.classes.group, groupDisabled ? 'disabled' : '', $elm.prop('class')].join(' ')),


                                _this.classes.grouplabel,


                                $elm.prop('label')


                            );





                            if ( groupDisabled ) {


                                $children.prop('disabled', true);


                            }





                            $children.each(buildOption);





                            _$li += '</ul>';


                        } else {


                            buildOption.call($elm);


                        }





                        function buildOption() {


                            var $elm = $(this),


                                optionText = $elm.html(),


                                selectDisabled = $elm.prop('disabled'),


                                itemBuilder = _this.options.optionsItemBuilder;





                            _this.items[currIndex] = {


                                element  : $elm,


                                value    : $elm.val(),


                                text     : optionText,


                                slug     : _utils.replaceDiacritics(optionText),


                                disabled : selectDisabled


                            };





                            _$li += _utils.format('<li data-index="{1}" class="{2}">{3}</li>',


                                currIndex,


                                $.trim([currIndex == currValue ? 'selected' : '', currIndex == optionsLength - 1 ? 'last' : '', selectDisabled ? 'disabled' : ''].join(' ')),


                                $.isFunction(itemBuilder) ? itemBuilder(_this.items[currIndex], $elm, currIndex) : _utils.format(itemBuilder, _this.items[currIndex])


                            );





                            currIndex++;


                        }


                    });





                    $items.append( $itemsScroll.html(_$li + '</ul>') );





                    $label.html(


                        $.isFunction(labelBuilder) ? labelBuilder(_this.items[currValue]) : _utils.format(labelBuilder, _this.items[currValue])


                    )


                }





                $wrapper.add($original).add($outerWrapper).add($input).off(bindSufix);





                $outerWrapper.prop('class', [


                    _this.classes.wrapper,


                    $original.prop('class').replace(/\S+/g, _this.options.customClass.prefix + '-$&'),


                    _this.options.responsive ? _this.classes.responsive : ''


                ].join(' '));





                if ( !$original.prop('disabled') ) {


                    isEnabled = true;





                    // Not disabled, so... Removing disabled class and bind hover


                    $outerWrapper.removeClass(_this.classes.disabled).on('mouseenter' + bindSufix + ' mouseleave' + bindSufix, function(e) {


                        $(this).toggleClass(_this.classes.hover);





                        // Delay close effect when openOnHover is true


                        if ( _this.options.openOnHover ) {


                            clearTimeout(_this.closeTimer);


                            e.type == 'mouseleave' ? _this.closeTimer = setTimeout(_close, _this.options.hoverIntentTimeout) : _open();


                        }


                    });





                    // Toggle open/close


                    $wrapper.on('click' + bindSufix, function(e) {


                        isOpen ? _close() : _open(e);


                    });





                    $input


                        .prop({


                            tabindex: tabindex,


                            disabled: false


                        })


                        .on('keypress' + bindSufix, _handleSystemKeys)


                        .on('keydown' + bindSufix, function(e) {


                            _handleSystemKeys(e);





                            // Clear search


                            clearTimeout(_this.resetStr);


                            _this.resetStr = setTimeout(function() {


                                $input.val('');


                            }, _this.options.keySearchTimeout);





                            var key = e.keyCode || e.which;





                            // If it's a directional key


                            // 37 => Left


                            // 38 => Up


                            // 39 => Right


                            // 40 => Down


                            if ( key > 36 && key < 41 ) {


                                if ( !_this.options.allowWrap ) {


                                    if ( (key < 39 && selected == 0) || (key > 38 && (selected + 1) == _this.items.length) ) {


                                        return;


                                    }


                                }





                                _select(_utils[(key < 39 ? 'previous' : 'next') + 'EnabledItem'](_this.items, selected));


                            }


                        })


                        .on('focusin' + bindSufix, function(e) {


                            isOpen || _open(e);


                        })


                        .on('oninput' in $input[0] ? 'input' : 'keyup', function() {


                            if ( $input.val().length ) {


                                // Search in select options


                                $.each(_this.items, function(i, elm) {


                                    if ( RegExp('^' + $input.val(), 'i').test(elm.slug) && !elm.disabled ) {


                                        _select(i);


                                        return false;


                                    }


                                });


                            }


                        });





                    $original.prop('tabindex', false);





                    // Remove styles from items box


                    // Fix incorrect height when refreshed is triggered with fewer options


                    $li = $('li', $items.removeAttr('style')).on({


                        // Prevent <input> blur on Chrome


                        mousedown: function(e) {


                            e.preventDefault();


                            e.stopPropagation();


                        },


                        click: function() {


                            // The second parameter is to close the box after click


                            _select($(this).data('index'), true);





                            // Chrome doesn't close options box if select is wrapped with a label


                            // We need to 'return false' to avoid that


                            return false;


                        }


                    }).filter('[data-index]');


                } else {


                    $outerWrapper.addClass(_this.classes.disabled);


                    $input.prop('disabled', true);


                }





                _utils.triggerCallback('Init', _this);


            }





            function _refresh() {


                _utils.triggerCallback('Refresh', _this);


                _populate();


            }





            // Behavior when system keys is pressed


            function _handleSystemKeys(e) {


                var key = e.keyCode || e.which;





                if ( key == 13 ) {


                    e.preventDefault();


                }





                // Tab / Enter / ESC


                if ( /^(9|13|27)$/.test(key) ) {


                    e.stopPropagation();


                    _select(selected, true);


                }


            }





            // Set options box width/height


            function _calculateOptionsDimensions() {


                // Calculate options box height


                // Set a temporary class on the hidden parent of the element


                var hiddenChildren = $items.closest(':visible').children(':hidden').addClass(_this.classes.tempshow),


                    maxHeight = _this.options.maxHeight,


                    itemsWidth = $items.outerWidth(),


                    wrapperWidth = $wrapper.outerWidth() - (itemsWidth - $items.width());





                // Set the dimensions, minimum is wrapper width, expand for long items if option is true


                if ( !_this.options.expandToItemText || wrapperWidth > itemsWidth )


                    finalWidth = wrapperWidth;


                else {


                    // Make sure the scrollbar width is included


                    $items.css('overflow', 'scroll');





                    // Set a really long width for $outerWrapper


                    $outerWrapper.width(9e4);


                    finalWidth = $items.width();


                    // Set scroll bar to auto


                    $items.css('overflow', '');


                    $outerWrapper.width('');


                }





                $items.width(finalWidth).height() > maxHeight && $items.height(maxHeight);





                // Remove the temporary class


                hiddenChildren.removeClass(_this.classes.tempshow);


            }





            // Open the select options box


            function _open(e) {


                _utils.triggerCallback('BeforeOpen', _this);





                if ( e ) {


                    e.preventDefault();


                    e.stopPropagation();


                }





                if ( isEnabled ) {


                    _calculateOptionsDimensions();





                    // Find any other opened instances of select and close it


                    $('.' + _this.classes.hideselect, '.' + _this.classes.open).children()[pluginName]('close');





                    isOpen = true;


                    itemsHeight = $items.outerHeight();


                    itemsInnerHeight = $items.height();





                    // Toggle options box visibility


                    $outerWrapper.addClass(_this.classes.open);





                    // Give dummy input focus


                    $input.val('');


                    e && e.type !== 'focusin' && $input.focus();





                    $doc.on('click' + bindSufix, _close).on('scroll' + bindSufix, _isInViewport);


                    _isInViewport();





                    // Prevent window scroll when using mouse wheel inside items box


                    if ( _this.options.preventWindowScroll ) {


                        $doc.on('mousewheel' + bindSufix + ' DOMMouseScroll' + bindSufix, '.' + _this.classes.scroll, function(e) {


                            var orgEvent = e.originalEvent,


                                scrollTop = $(this).scrollTop(),


                                deltaY = 0;





                            if ( 'detail'      in orgEvent ) { deltaY = orgEvent.detail * -1; }


                            if ( 'wheelDelta'  in orgEvent ) { deltaY = orgEvent.wheelDelta;  }


                            if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }


                            if ( 'deltaY'      in orgEvent ) { deltaY = orgEvent.deltaY * -1; }





                            if ( scrollTop == (this.scrollHeight - itemsInnerHeight) && deltaY < 0 || scrollTop == 0 && deltaY > 0 ) {


                                e.preventDefault();


                            }


                        });


                    }





                    _detectItemVisibility(selected);





                    _utils.triggerCallback('Open', _this);


                }


            }





            // Detect is the options box is inside the window


            function _isInViewport() {


                var scrollTop = $win.scrollTop();


                var winHeight = $win.height();


                var uiPosX = $outerWrapper.offset().top;


                var uiHeight = $outerWrapper.outerHeight();





                var fitsDown = (uiPosX + uiHeight + itemsHeight) <= (scrollTop + winHeight);


                var fitsAbove = (uiPosX - itemsHeight) > scrollTop;





                // If it does not fit below, only render it


                // above it fit's there.


                // It's acceptable that the user needs to


                // scroll the viewport to see the cut off UI


                var renderAbove = !fitsDown && fitsAbove;





                $outerWrapper.toggleClass(_this.classes.above, renderAbove);


            }





            // Close the select options box


            function _close() {


                _utils.triggerCallback('BeforeClose', _this);





                if ( currValue != selected ) {


                    _utils.triggerCallback('BeforeChange', _this);





                    var text = _this.items[selected].text;





                    // Apply changed value to original select


                    $original


                        .prop('selectedIndex', currValue = selected)


                        .data('value', text);





                    // Change label text


                    $label.html(


                        $.isFunction(labelBuilder) ? labelBuilder(_this.items[selected]) : _utils.format(labelBuilder, _this.items[selected])


                    )





                    _utils.triggerCallback('Change', _this);


                }





                // Remove custom events on document


                $doc.off(bindSufix);





                // Remove visible class to hide options box


                $outerWrapper.removeClass(_this.classes.open);





                isOpen = false;





                _utils.triggerCallback('Close', _this);


            }





            // Select option


            function _select(index, close) {


                // Parameter index is required


                if ( index == undefined ) {


                    return;


                }





                // If element is disabled, can't select it


                if ( !_this.items[index].disabled ) {


                    // If 'close' is false (default), the options box won't close after


                    // each selected item, this is necessary for keyboard navigation


                    $li


                        .removeClass('selected')


                        .eq(selected = index)


                        .addClass('selected');





                    _detectItemVisibility(index);


                    close && _close();


                }


            }





            // Detect if currently selected option is visible and scroll the options box to show it


            function _detectItemVisibility(index) {


                var liHeight = $li.eq(index).outerHeight(),


                    liTop = $li[index].offsetTop,


                    itemsScrollTop = $itemsScroll.scrollTop(),


                    scrollT = liTop + liHeight * 2;





                $itemsScroll.scrollTop(


                    scrollT > itemsScrollTop + itemsHeight ? scrollT - itemsHeight :


                        liTop - liHeight < itemsScrollTop ? liTop - liHeight :


                            itemsScrollTop


                );


            }





            // Unbind and remove


            function _destroy(preserveData) {


                if ( isEnabled ) {


                    $items.add($wrapper).add($input).remove();


                    !preserveData && $original.removeData(pluginName).removeData('value');


                    $original.prop('tabindex', tabindex).off(bindSufix).off(eventTriggers).unwrap().unwrap();


                    isEnabled = false;


                }


            }





            _init(opts);


        };





    // A really lightweight plugin wrapper around the constructor,


    // preventing against multiple instantiations


    $.fn[pluginName] = function(args) {


        return this.each(function() {


            var data = $.data(this, pluginName);





            if ( data && !data.disableOnMobile )


                (''+args === args && data[args]) ? data[args]() : data.init(args);


            else


                $.data(this, pluginName, new Selectric(this, args));


        });


    };





    $.fn[pluginName].hooks = hooks;





}));
