text: /*! bigSlide - v0.11.0 - 2016-04-13
  * http://ascott1.github.io/bigSlide.js/
  * Copyright (c) 2016 Adam D. Scott; Licensed MIT */
  (function (factory) {
    'use strict';
    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($) {
    'use strict';
  
    // where inlineCSS is the string value of an element's style attribute
    // and toRemove is a string of space-separated CSS properties,
    // _cleanInlineCSS removes the CSS declaration for each property in toRemove from inlineCSS
    // and returns the resulting string
    function _cleanInlineCSS(inlineCSS, toRemove){
      var inlineCSSArray  = inlineCSS.split(';');
      var toRemoveArray   = toRemove.split(' ');
  
      var cleaned         = '';
      var keep;
  
      for (var i = 0, j = inlineCSSArray.length; i < j; i++) {
        keep = true;
        for (var a = 0, b = toRemoveArray.length; a < b; a++) {
          if (inlineCSSArray[i] === '' || inlineCSSArray[i].indexOf(toRemoveArray[a]) !== -1) {
            keep = false;
          }
        }
        if(keep) {cleaned += inlineCSSArray[i] + '; ';}
      }
  
      return cleaned;
    }
  
  
    $.fn.bigSlide = function(options) {
      // store the menuLink in a way that is globally accessible
      var menuLink = this;
  
      // plugin settings
      var settings = $.extend({
        'menu': ('#menu'),
        'push': ('.push-wrapper'),
        'shrink': ('.shrink'),
        'hiddenThin': ('.hiddenThin'),
        'side': 'right',
        'menuWidth': '250px',
        'semiOpenMenuWidth': '4em',
        'speed': '300',
        'state': 'closed',
        'activeBtn': 'active',
        'easyClose': true,
        'saveState': false,
        'semiOpenStatus': false,
        'semiOpenScreenWidth': 230,
        'beforeOpen': function () {},
        'afterOpen': function() {},
        'beforeClose': function() {},
        'afterClose': function() {}
      }, options);
  
      // CSS properties set by bigSlide.js on all implicated DOM elements
      var baseCSSDictionary = 'transition -o-transition -ms-transition -moz-transitions webkit-transition ' + settings.side;
  
      var model = {
        //CSS properties set by bigSlide.js on this.$menu
        menuCSSDictionary: baseCSSDictionary + ' position top bottom height width',
        //CSS properties set by bigSlide.js on this.$push
        pushCSSDictionary: baseCSSDictionary,
        // store the menu's state in the model
        'state': settings.state
      };
  
      // talk back and forth between the view and state
      var controller = {
        init: function(){
          view.init();
        },
  
        // remove bigSlide behavior from the menu
        _destroy: function(){
          view._destroy();
  
          delete menuLink.bigSlideAPI;
  
          // return a reference to the DOM selection bigSlide.js was called on
          // so that the destroy method is chainable
          return menuLink;
        },
  
        // update the menu's state
        changeState: function(){
          if (model.state === 'closed') {
            model.state = 'open'
          } else {
            model.state = 'closed'
          }
        },
  
        // set the menu's state
        setState: function(state){
          model.state = state;
        },
  
        // check the menu's state
        getState: function(){
          return model.state;
        }
      };
  
      // the view contains all of the visual interactions
      var view = {
        init: function(){
          // cache DOM values
          this.$menu = $(settings.menu);
          this.$push = $(settings.push);
          this.$shrink = $(settings.shrink);
          this.$hiddenThin = $(settings.hiddenThin);
          this.width = settings.menuWidth;
          this.semiOpenMenuWidth = settings.semiOpenMenuWidth;
  
          // CSS for how the menu will be positioned off screen
          var positionOffScreen = {
            'position': 'fixed',
            'top': '0',
            'bottom': '0',
            'height': '100%'
          };
  
          // css for the sliding animation
          var animateSlide = {
            '-webkit-transition': settings.side + ' ' + settings.speed + 'ms ease',
            '-moz-transition': settings.side + ' ' + settings.speed + 'ms ease',
            '-ms-transition': settings.side + ' ' + settings.speed + 'ms ease',
            '-o-transition': settings.side + ' ' + settings.speed + 'ms ease',
            'transition': settings.side + ' ' + settings.speed + 'ms ease'
          };
  
          // css for the shrink animation
          var animateShrink = {
            '-webkit-transition': 'all ' + settings.speed + 'ms ease',
            '-moz-transition': 'all ' + settings.speed + 'ms ease',
            '-ms-transition': 'all ' + settings.speed + 'ms ease',
            '-o-transition': 'all ' + settings.speed + 'ms ease',
            'transition': 'all ' + settings.speed + 'ms ease'
          };
  
          // we want to add the css sliding animation when the page is loaded (on the first menu link click)
          var animationApplied = false;
  
          // manually add the settings values
          positionOffScreen[settings.side] = '-' + settings.menuWidth;
          positionOffScreen.width = settings.menuWidth;
  
          // get the initial state based on the last saved state or on the state option
          var initialState = 'closed';
          if (settings.saveState) {
            initialState = localStorage.getItem('bigSlide-savedState');
            if (!initialState) initialState = settings.state;
          } else {
            initialState = settings.state;
          }
  
          // set the initial state on the controller
          controller.setState(initialState);
  
          // add the css values to position things offscreen or inscreen depending on the initial state value
          this.$menu.css(positionOffScreen);
  
          var initialScreenWidth = $(window).width();
          if (initialState === 'closed') {
            if (settings.semiOpenStatus && initialScreenWidth > settings.semiOpenScreenWidth) {
              this.$hiddenThin.hide();
              this.$menu.css(settings.side, '0');
              this.$menu.css('width', this.semiOpenMenuWidth);
              this.$push.css(settings.side, this.semiOpenMenuWidth);
              this.$shrink.css({
                'width': 'calc(100% - ' + this.semiOpenMenuWidth + ')'
              });
              this.$menu.addClass('semiOpen');
            } else {
              this.$push.css(settings.side, '0');
            }
          } else if (initialState === 'open') {
            this.$menu.css(settings.side, '0');
            this.$push.css(settings.side, this.width);
            this.$shrink.css({
              'width': 'calc(100% - ' + this.width + ')'
            });
            menuLink.addClass(settings.activeBtn);
          }
  
          var that = this;
  
          // register a click listener for desktop & touchstart for mobile
          menuLink.on('click.bigSlide touchstart.bigSlide', function(e) {
            // add the animation css if not present
            if (!animationApplied) {
              that.$menu.css(animateSlide);
              that.$push.css(animateSlide);
              that.$shrink.css(animateShrink);
              animationApplied = true;
            }
  
            e.preventDefault();
            if (controller.getState() === 'open') {
              view.toggleClose();
            } else {
              view.toggleOpen();
            }
          });
  
          // register a window resize listener for tracking the semi open status states
          // This could be more efficently or even there are people that could consider it unnecessary. We can think about it
          if (settings.semiOpenStatus) {
              $(window).resize(function() {
                  var screenWidth = $(window).width();
                  if (screenWidth > settings.semiOpenScreenWidth) {
                      if (controller.getState() === 'closed') {
                          that.$hiddenThin.hide();
                          that.$menu.css({ width: that.semiOpenMenuWidth});
                          that.$menu.css(settings.side, '0');
                          that.$push.css(settings.side, that.semiOpenMenuWidth);
                          that.$shrink.css({
                            'width': 'calc(100% - ' + that.semiOpenMenuWidth + ')'
                          });
                          that.$menu.addClass('semiOpen');
                      }
                  } else {
                      that.$menu.removeClass('semiOpen');
                      if (controller.getState() === 'closed') {
                          that.$menu.css(settings.side, '-' + that.width).css({width: that.width});
                          that.$push.css(settings.side, '0');
                          that.$shrink.css('width', '100%');
                          that.$hiddenThin.show();
                      }
                  }
              });
          }
  
          // this makes my eyes bleed, but adding it back in as it's a highly requested feature
          if (settings.easyClose) {
            $(document).on('click.bigSlide', function(e) {
             if (!$(e.target).parents().andSelf().is(menuLink) && !$(e.target).closest(settings.menu).length && controller.getState() === 'open')  {
               view.toggleClose();
             }
            });
          }
        },
  
        _destroy: function(){
          //remove inline styles generated by bigSlide.js while preserving any other inline styles
          this.$menu.each(function(){
            var $this = $(this);
            $this.attr( 'style', _cleanInlineCSS($this.attr('style'), model.menuCSSDictionary).trim() );
          });
  
          this.$push.each(function(){
            var $this = $(this);
            $this.attr( 'style', _cleanInlineCSS($this.attr('style'), model.pushCSSDictionary).trim() );
          });
  
          this.$shrink.each(function(){
            var $this = $(this);
            $this.attr( 'style', _cleanInlineCSS($this.attr('style'), model.pushCSSDictionary).trim() );
          });
  
          //remove active class and unbind bigSlide event handlers
          menuLink
            .removeClass(settings.activeBtn)
            .off('click.bigSlide touchstart.bigSlide');
  
          //release DOM references to avoid memory leaks
          this.$menu = null;
          this.$push = null;
          this.$shrink = null;
  
          //remove the local storage state
          localStorage.removeItem('bigSlide-savedState');
        },
  
        // toggle the menu open
        toggleOpen: function() {
          settings.beforeOpen();
          controller.changeState();
          view.applyOpenStyles();
          menuLink.addClass(settings.activeBtn);
          settings.afterOpen();
  
          // save the state
          if (settings.saveState) {
            localStorage.setItem('bigSlide-savedState', 'open');
          }
        },
  
        // toggle the menu closed
        toggleClose: function() {
          settings.beforeClose();
          controller.changeState();
          view.applyClosedStyles();
          menuLink.removeClass(settings.activeBtn);
          settings.afterClose();
  
          // save the state
          if (settings.saveState) {
            localStorage.setItem('bigSlide-savedState', 'closed');
          }
        },
  
        applyOpenStyles: function() {
          var screenWidth = $(window).width();
          if (settings.semiOpenStatus && screenWidth > settings.semiOpenScreenWidth) {
            this.$hiddenThin.show();
            this.$menu.animate({ width: this.width}, {duration: Math.abs(settings.speed - 100), easing: 'linear'});
            this.$push.css(settings.side, this.width);
            this.$shrink.css({
              'width': 'calc(100% - ' + this.width + ')'
            });
            this.$menu.removeClass('semiOpen');
          } else {
            this.$menu.css(settings.side, '0');
            this.$push.css(settings.side, this.width);
            this.$shrink.css({
              'width': 'calc(100% - ' + this.width + ')'
            });
          }
        },
  
        applyClosedStyles: function() {
          var screenWidth = $(window).width();
          if (settings.semiOpenStatus && screenWidth > settings.semiOpenScreenWidth) {
            this.$hiddenThin.hide();
            this.$menu.animate({ width: this.semiOpenMenuWidth}, {duration: Math.abs(settings.speed - 100), easing: 'linear'});
            this.$push.css(settings.side, this.semiOpenMenuWidth);
            this.$shrink.css({
              'width': 'calc(100% - ' + this.semiOpenMenuWidth + ')'
            });
            this.$menu.addClass('semiOpen');
          } else {
            this.$menu.css(settings.side, '-' + this.width);
            this.$push.css(settings.side, '0');
            this.$shrink.css('width', '100%');
          }
        }
  
      }
  
      controller.init();
  
      this.bigSlideAPI = {
        settings: settings,
        model: model,
        controller: controller,
        view: view,
        destroy: controller._destroy
      };
  
      return this;
    };
  
  }));
  