text: /**
   * @class mUtil  Metronic base utilize class that privides helper functions
   */
  
  var mUtil = function() {
      var resizeHandlers = [];
  
      /** @type {object} breakpoints The device width breakpoints **/
      var breakpoints = {        
          sm: 544, // Small screen / phone           
          md: 768, // Medium screen / tablet            
          lg: 992, // Large screen / desktop        
          xl: 1200 // Extra large screen / wide desktop
      };
  
      /** @type {object} colors State colors **/
      var colors = {
          brand:      '#716aca',
          metal:      '#c4c5d6',
          light:      '#ffffff',
          accent:     '#00c5dc',
          primary:    '#5867dd',
          success:    '#34bfa3',
          info:       '#36a3f7',
          warning:    '#ffb822',
          danger:     '#f4516c'
      };
  
      /**
      * Handle window resize event with some 
      * delay to attach event handlers upon resize complete 
      */
      var _windowResizeHandler = function() {
          var resize;
          var _runResizeHandlers = function() {
              // reinitialize other subscribed elements
              for (var i = 0; i < resizeHandlers.length; i++) {
                  var each = resizeHandlers[i];
                  each.call();
              }
          };
  
          jQuery(window).resize(function() {
              if (resize) {
                  clearTimeout(resize);
              }
              resize = setTimeout(function() {
                  _runResizeHandlers();
              }, 250); // wait 50ms until window resize finishes.
          });
      };
  
      return {
          /**
          * Class main initializer.
          * @param {object} options.
          * @returns null
          */
          //main function to initiate the theme
          init: function(options) {
              if (options && options.breakpoints) {
                  breakpoints = options.breakpoints;
              }
  
              if (options && options.colors) {
                  colors = options.colors;
              }
  
              _windowResizeHandler();
          },
  
          /**
          * Adds window resize event handler.
          * @param {function} callback function.
          */
          addResizeHandler: function(callback) {
              resizeHandlers.push(callback);
          },
  
          /**
          * Trigger window resize handlers.
          */
          runResizeHandlers: function() {
              _runResizeHandlers();
          },        
  
          /**
          * Get GET parameter value from URL.
          * @param {string} paramName Parameter name.
          * @returns {string}  
          */
          getURLParam: function(paramName) {
              var searchString = window.location.search.substring(1),
                  i, val, params = searchString.split("&");
  
              for (i = 0; i < params.length; i++) {
                  val = params[i].split("=");
                  if (val[0] == paramName) {
                      return unescape(val[1]);
                  }
              }
  
              return null;
          },
  
          /**
          * Checks whether current device is mobile touch.
          * @returns {boolean}  
          */
          isMobileDevice: function() {
              return (this.getViewPort().width < this.getBreakpoint('lg') ? true : false);
          },
  
          /**
          * Checks whether current device is desktop.
          * @returns {boolean}  
          */
          isDesktopDevice: function() {
              return mUtil.isMobileDevice() ? false : true;
          },
  
          /**
          * Gets browser window viewport size. Ref: http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
          * @returns {object}  
          */
          getViewPort: function() {
              var e = window,
                  a = 'inner';
              if (!('innerWidth' in window)) {
                  a = 'client';
                  e = document.documentElement || document.body;
              }
  
              return {
                  width: e[a + 'Width'],
                  height: e[a + 'Height']
              };
          },
  
          /**
          * Checks whether given device mode is currently activated.
          * @param {string} mode Responsive mode name(e.g: desktop, desktop-and-tablet, tablet, tablet-and-mobile, mobile)
          * @returns {boolean}  
          */
          isInResponsiveRange: function(mode) {
              var breakpoint = this.getViewPort().width;
  
              if (mode == 'general') {
                  return true;
              } else if (mode == 'desktop' && breakpoint >= (this.getBreakpoint('lg') + 1)) {
                  return true;
              } else if (mode == 'tablet' && (breakpoint >= (this.getBreakpoint('md') + 1) && breakpoint < this.getBreakpoint('lg'))) {
                  return true;
              } else if (mode == 'mobile' && breakpoint <= this.getBreakpoint('md')) {
                  return true;
              } else if (mode == 'desktop-and-tablet' && breakpoint >= (this.getBreakpoint('md') + 1)) {
                  return true;
              } else if (mode == 'tablet-and-mobile' && breakpoint <= this.getBreakpoint('lg')) {
                  return true;
              } else if (mode == 'minimal-desktop-and-below' && breakpoint <= this.getBreakpoint('xl')) {
                  return true;
              }
  
              return false;
          },
  
          /**
          * Generates unique ID for give prefix.
          * @param {string} prefix Prefix for generated ID
          * @returns {boolean}  
          */
          getUniqueID: function(prefix) {
              return prefix + Math.floor(Math.random() * (new Date()).getTime());
          },
  
          /**
          * Gets window width for give breakpoint mode.
          * @param {string} mode Responsive mode name(e.g: xl, lg, md, sm)
          * @returns {number}  
          */
          getBreakpoint: function(mode) {
              if ($.inArray(mode, breakpoints)) {
                  return breakpoints[mode];
              }
          },
  
          /**
          * Checks whether object has property matchs given key path.
          * @param {object} obj Object contains values paired with given key path
          * @param {string} keys Keys path seperated with dots
          * @returns {object}  
          */
          isset: function(obj, keys) {
              var stone;
  
              keys = keys || '';
  
              if (keys.indexOf('[') !== -1) {
                  throw new Error('Unsupported object path notation.');
              }
  
              keys = keys.split('.');
  
              do {
                  if (obj === undefined) {
                      return false;
                  }
  
                  stone = keys.shift();
  
                  if (!obj.hasOwnProperty(stone)) {
                      return false;
                  }
  
                  obj = obj[stone];
  
              } while (keys.length);
  
              return true;
          },
  
          /**
          * Gets highest z-index of the given element parents
          * @param {object} el jQuery element object
          * @returns {number}  
          */
          getHighestZindex: function(el) {
              var elem = $(el),
                  position, value;
  
              while (elem.length && elem[0] !== document) {
                  // Ignore z-index if position is set to a value where z-index is ignored by the browser
                  // This makes behavior of this function consistent across browsers
                  // WebKit always returns auto if the element is positioned
                  position = elem.css("position");
  
                  if (position === "absolute" || position === "relative" || position === "fixed") {
                      // IE returns 0 when zIndex is not specified
                      // other browsers return a string
                      // we ignore the case of nested elements with an explicit value of 0
                      // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
                      value = parseInt(elem.css("zIndex"), 10);
                      if (!isNaN(value) && value !== 0) {
                          return value;
                      }
                  }
                  elem = elem.parent();
              }
          },
  
          /**
          * Checks whether the element has given classes
          * @param {object} el jQuery element object
          * @param {string} Classes string
          * @returns {boolean}  
          */
          hasClasses: function(el, classes) {
              var classesArr = classes.split(" ");
  
              for ( var i = 0; i < classesArr.length; i++ ) {
                  if ( el.hasClass( classesArr[i] ) == false ) {
                      return false;
                  }
              }                
  
              return true;
          },
  
          /**
          * Gets element actual/real width
          * @param {object} el jQuery element object
          * @returns {number}  
          */
          realWidth: function(el){
              var clone = $(el).clone();
              clone.css("visibility","hidden");
              clone.css('overflow', 'hidden');
              clone.css("height","0");
              $('body').append(clone);
              var width = clone.outerWidth();
              clone.remove();
  
              return width;
          },
  
          /**
          * Checks whether the element has any parent with fixed position
          * @param {object} el jQuery element object
          * @returns {boolean}  
          */
          hasFixedPositionedParent: function(el) {
              var result = false;
              
              el.parents().each(function () {
                  if ($(this).css('position') == 'fixed') {
                      result = true;
                      return;
                  }
              });
  
              return result;
          },
  
          /**
          * Simulates delay
          */
          sleep: function(milliseconds) {
              var start = new Date().getTime();
              for (var i = 0; i < 1e7; i++) {
                  if ((new Date().getTime() - start) > milliseconds){
                      break;
                  }
              }
          },
  
          /**
          * Gets randomly generated integer value within given min and max range
          * @param {number} min Range start value
          * @param {number} min Range end value
          * @returns {number}  
          */
          getRandomInt: function(min, max) {
              return Math.floor(Math.random() * (max - min + 1)) + min;
          },
  
          /**
          * Gets state color's hex code by color name
          * @param {string} name Color name
          * @returns {string}  
          */
          getColor: function(name) {
              return colors[name];
          },
  
          /**
          * Checks whether Angular library is included
          * @returns {boolean}  
          */
          isAngularVersion: function() {
              return window.Zone !== undefined  ? true : false;
          }
      }
  }();
  
  //== Initialize mUtil class on document ready
  $(document).ready(function() {
      mUtil.init();
  });