text: /*
   *  webui popover plugin  - v1.2.5
   *  A lightWeight popover plugin with jquery ,enchance the  popover plugin of bootstrap with some awesome new features. It works well with bootstrap ,but bootstrap is not necessary!
   *  https://github.com/sandywalker/webui-popover
   *
   *  Made by Sandy Duan
   *  Under MIT License
   */
  (function(window, document, undefined) {
      'use strict';
      (function(factory) {
          if (typeof define === 'function' && define.amd) {
              // Register as an anonymous AMD module.
              define(['jquery'], factory);
          } else if (typeof exports === 'object') {
              // Node/CommonJS
              module.exports = factory(require('jquery'));
          } else {
              // Browser globals
              factory(window.jQuery);
          }
      }(function($) {
          // Create the defaults once
          var pluginName = 'webuiPopover';
          var pluginClass = 'webui-popover';
          var pluginType = 'webui.popover';
          var defaults = {
              placement: 'auto',
              width: 'auto',
              height: 'auto',
              trigger: 'click', //hover,click,sticky,manual
              style: '',
              delay: {
                  show: null,
                  hide: null
              },
              async: {
                  type: 'GET',
                  before: null, //function(that, xhr){}
                  success: null, //function(that, xhr){}
                  error: null //function(that, xhr, data){}
              },
              cache: true,
              multi: false,
              arrow: true,
              title: '',
              content: '',
              closeable: false,
              padding: true,
              url: '',
              type: 'html',
              animation: null,
              template: '<div class="webui-popover">' +
                  '<div class="webui-arrow"></div>' +
                  '<div class="webui-popover-inner">' +
                  '<a href="#" class="close"></a>' +
                  '<h3 class="webui-popover-title"></h3>' +
                  '<div class="webui-popover-content"><i class="icon-refresh"></i> <p>&nbsp;</p></div>' +
                  '</div>' +
                  '</div>',
              backdrop: false,
              dismissible: true,
              onShow: null,
              onHide: null,
              abortXHR: true,
              autoHide: false,
              offsetTop: 0,
              offsetLeft: 0,
              iframeOptions: {
                  frameborder: '0',
                  allowtransparency: 'true',
                  id: '',
                  name: '',
                  scrolling: '',
                  onload: '',
                  height: '',
                  width: ''
              }
          };
  
  
          var _srcElements = [];
          var backdrop = $('<div class="webui-popover-backdrop"></div>');
          var _globalIdSeed = 0;
          var _isBodyEventHandled = false;
          var _offsetOut = -2000; // the value offset  out of the screen
          var $document = $(document);
  
          var toNumber = function(numeric, fallback) {
              return isNaN(numeric) ? (fallback || 0) : Number(numeric);
          };
  
          var getPopFromElement = function($element) {
              return $element.data('plugin_' + pluginName);
          };
  
          var hideAllPop = function() {
              for (var i = 0; i < _srcElements.length; i++) {
                  _srcElements[i].webuiPopover('hide');
              }
              $document.trigger('hiddenAll.' + pluginType);
          };
  
          //var removeAllTargets = function() {
          // for (var i = 0; i < _srcElements.length; i++) {
          //     var pop = getPopFromElement(_srcElements[i]);
          //     console.log(pop.$target);
          // }
          //};
  
          var pointerEventToXY = function(e) {
              var out = {
                  x: 0,
                  y: 0
              };
              if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') {
                  var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
                  out.x = touch.pageX;
                  out.y = touch.pageY;
              } else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'click') {
                  out.x = e.pageX;
                  out.y = e.pageY;
              }
              return out;
          };
  
  
  
          // The actual plugin constructor
          function WebuiPopover(element, options) {
              this.$element = $(element);
              if (options) {
                  if ($.type(options.delay) === 'string' || $.type(options.delay) === 'number') {
                      options.delay = {
                          show: options.delay,
                          hide: options.delay
                      }; // bc break fix
                  }
              }
              this.options = $.extend({}, defaults, options);
              this._defaults = defaults;
              this._name = pluginName;
              this._targetclick = false;
              this.init();
              _srcElements.push(this.$element);
          }
  
          WebuiPopover.prototype = {
              //init webui popover
              init: function() {
                  //init the event handlers
                  if (this.getTrigger() === 'click') {
                      this.$element.off('click touchend').on('click touchend', $.proxy(this.toggle, this));
                  } else if (this.getTrigger() === 'hover') {
                      this.$element
                          .off('mouseenter mouseleave click')
                          .on('mouseenter', $.proxy(this.mouseenterHandler, this))
                          .on('mouseleave', $.proxy(this.mouseleaveHandler, this));
                  }
                  this._poped = false;
                  this._inited = true;
                  this._opened = false;
                  this._idSeed = _globalIdSeed;
                  if (this.options.backdrop) {
                      backdrop.appendTo(document.body).hide();
                  }
                  _globalIdSeed++;
                  if (this.getTrigger() === 'sticky') {
                      this.show();
                  }
  
              },
              /* api methods and actions */
              destroy: function() {
                  var index = -1;
  
                  for (var i = 0; i < _srcElements.length; i++) {
                      if (_srcElements[i] === this.$element) {
                          index = i;
                          break;
                      }
                  }
  
                  _srcElements.splice(index, 1);
  
  
                  this.hide();
                  this.$element.data('plugin_' + pluginName, null);
                  if (this.getTrigger() === 'click') {
                      this.$element.off('click');
                  } else if (this.getTrigger() === 'hover') {
                      this.$element.off('mouseenter mouseleave');
                  }
                  if (this.$target) {
                      this.$target.remove();
                  }
              },
              /*
                  param: force    boolean value, if value is true then force hide the popover
                  param: event    dom event,
              */
              hide: function(force, event) {
                  if (!force && this.getTrigger() === 'sticky') {
                      return;
                  }
  
                  if (!this._opened) {
                      return;
                  }
                  if (event) {
                      event.preventDefault();
                      event.stopPropagation();
                  }
  
                  if (this.xhr && this.options.abortXHR === true) {
                      this.xhr.abort();
                      this.xhr = null;
                  }
  
  
                  var e = $.Event('hide.' + pluginType);
                  this.$element.trigger(e, [this.$target]);
                  if (this.$target) {
                      this.$target.removeClass('in').addClass(this.getHideAnimation());
                      var that = this;
                      setTimeout(function() {
                          that.$target.hide();
                      }, 300);
                  }
                  if (this.options.backdrop) {
                      backdrop.hide();
                  }
                  this._opened = false;
                  this.$element.trigger('hidden.' + pluginType, [this.$target]);
  
                  if (this.options.onHide) {
                      this.options.onHide(this.$target);
                  }
  
              },
              resetAutoHide: function() {
                  var that = this;
                  var autoHide = that.getAutoHide();
                  if (autoHide) {
                      if (that.autoHideHandler) {
                          clearTimeout(that.autoHideHandler);
                      }
                      that.autoHideHandler = setTimeout(function() {
                          that.hide();
                      }, autoHide);
                  }
              },
              toggle: function(e) {
                  if (e) {
                      e.preventDefault();
                      e.stopPropagation();
                  }
                  this[this.getTarget().hasClass('in') ? 'hide' : 'show']();
              },
              hideAll: function() {
                  hideAllPop();
              },
              /*core method ,show popover */
              show: function() {
                  //removeAllTargets();
                  var
                      $target = this.getTarget().removeClass().addClass(pluginClass).addClass(this._customTargetClass);
                  if (!this.options.multi) {
                      this.hideAll();
                  }
                  if (this._opened) {
                      return;
                  }
                  // use cache by default, if not cache setted  , reInit the contents 
                  if (!this.getCache() || !this._poped || this.content === '') {
                      this.content = '';
                      this.setTitle(this.getTitle());
                      if (!this.options.closeable) {
                          $target.find('.close').off('click').remove();
                      }
                      if (!this.isAsync()) {
                          this.setContent(this.getContent());
                      } else {
                          this.setContentASync(this.options.content);
                      }
                      $target.show();
                  }
                  this.displayContent();
  
                  if (this.options.onShow) {
                      this.options.onShow($target);
                  }
  
                  this.bindBodyEvents();
                  if (this.options.backdrop) {
                      backdrop.show();
                  }
                  this._opened = true;
                  this.resetAutoHide();
              },
              displayContent: function() {
                  var
                  //element postion
                      elementPos = this.getElementPosition(),
                      //target postion
                      $target = this.getTarget().removeClass().addClass(pluginClass).addClass(this._customTargetClass),
                      //target content
                      $targetContent = this.getContentElement(),
                      //target Width
                      targetWidth = $target[0].offsetWidth,
                      //target Height
                      targetHeight = $target[0].offsetHeight,
                      //placement
                      placement = 'bottom',
                      e = $.Event('show.' + pluginType);
                  //if (this.hasContent()){
                  this.$element.trigger(e, [$target]);
                  //}
                  // support width as data attribute
                  var optWidth = this.$element.data('width') || this.options.width;
                  if (optWidth === '') {
                      optWidth = this._defaults.width;
                  }
  
                  if (optWidth !== 'auto') {
                      $target.width(optWidth);
                  }
  
                  // support height as data attribute
                  var optHeight = this.$element.data('height') || this.options.height;
                  if (optHeight === '') {
                      optHeight = this._defaults.height;
                  }
  
                  if (optHeight !== 'auto') {
                      $targetContent.height(optHeight);
                  }
  
                  if (this.options.style) {
                      this.$target.addClass(pluginClass + '-' + this.options.style);
                  }
  
                  //init the popover and insert into the document body
                  if (!this.options.arrow) {
                      $target.find('.webui-arrow').remove();
                  }
                  $target.detach().css({
                      top: _offsetOut,
                      left: _offsetOut,
                      display: 'block'
                  });
  
                  if (this.getAnimation()) {
                      $target.addClass(this.getAnimation());
                  }
                  $target.appendTo(document.body);
  
  
                  placement = this.getPlacement(elementPos);
  
                  //This line is just for compatible with knockout custom binding
                  this.$element.trigger('added.' + pluginType);
  
                  this.initTargetEvents();
  
                  if (!this.options.padding) {
                      if (this.options.height !== 'auto') {
                          $targetContent.css('height', $targetContent.outerHeight());
                      }
                      this.$target.addClass('webui-no-padding');
                  }
                  targetWidth = $target[0].offsetWidth;
                  targetHeight = $target[0].offsetHeight;
  
                  var postionInfo = this.getTargetPositin(elementPos, placement, targetWidth, targetHeight);
  
                  this.$target.css(postionInfo.position).addClass(placement).addClass('in');
  
                  if (this.options.type === 'iframe') {
                      var $iframe = $target.find('iframe');
                      var iframeWidth = $target.width();
                      var iframeHeight = $iframe.parent().height();
  
                      if (this.options.iframeOptions.width !== '' && this.options.iframeOptions.width !== 'auto') {
                          iframeWidth = this.options.iframeOptions.width;
                      }
  
                      if (this.options.iframeOptions.height !== '' && this.options.iframeOptions.height !== 'auto') {
                          iframeHeight = this.options.iframeOptions.height;
                      }
  
                      $iframe.width(iframeWidth).height(iframeHeight);
                  }
  
  
  
  
                  if (!this.options.arrow) {
                      this.$target.css({
                          'margin': 0
                      });
                  }
                  if (this.options.arrow) {
                      var $arrow = this.$target.find('.webui-arrow');
                      $arrow.removeAttr('style');
  
                      //prevent arrow change by content size
                      if (placement === 'left' || placement === 'right') {
                          $arrow.css({
                              top: this.$target.height() / 2
                          });
                      } else if (placement === 'top' || placement === 'bottom') {
                          $arrow.css({
                              left: this.$target.width() / 2
                          });
                      }
  
                      if (postionInfo.arrowOffset) {
                          //hide the arrow if offset is negative 
                          if (postionInfo.arrowOffset.left === -1 || postionInfo.arrowOffset.top === -1) {
                              $arrow.hide();
                          } else {
                              $arrow.css(postionInfo.arrowOffset);
                          }
                      }
  
                  }
                  this._poped = true;
                  this.$element.trigger('shown.' + pluginType, [this.$target]);
              },
  
              isTargetLoaded: function() {
                  return this.getTarget().find('i.glyphicon-refresh').length === 0;
              },
  
              /*getter setters */
              getTriggerElement: function() {
                  return this.$element;
              },
              getTarget: function() {
                  if (!this.$target) {
                      var id = pluginName + this._idSeed;
                      this.$target = $(this.options.template)
                          .attr('id', id)
                          .data('trigger-element', this.getTriggerElement());
                      this._customTargetClass = this.$target.attr('class') !== pluginClass ? this.$target.attr('class') : null;
                      this.getTriggerElement().attr('data-target', id);
                  }
                  return this.$target;
              },
              getTitleElement: function() {
                  return this.getTarget().find('.' + pluginClass + '-title');
              },
              getContentElement: function() {
                  if (!this.$contentElement) {
                      this.$contentElement = this.getTarget().find('.' + pluginClass + '-content');
                  }
                  return this.$contentElement;
              },
              getTitle: function() {
                  return this.$element.attr('data-title') || this.options.title || this.$element.attr('title');
              },
              getUrl: function() {
                  return this.$element.attr('data-url') || this.options.url;
              },
              getAutoHide: function() {
                  return this.$element.attr('data-auto-hide') || this.options.autoHide;
              },
              getOffsetTop: function() {
                  return toNumber(this.$element.attr('data-offset-top')) || this.options.offsetTop;
              },
              getOffsetLeft: function() {
                  return toNumber(this.$element.attr('data-offset-left')) || this.options.offsetLeft;
              },
              getCache: function() {
                  var dataAttr = this.$element.attr('data-cache');
                  if (typeof(dataAttr) !== 'undefined') {
                      switch (dataAttr.toLowerCase()) {
                          case 'true':
                          case 'yes':
                          case '1':
                              return true;
                          case 'false':
                          case 'no':
                          case '0':
                              return false;
                      }
                  }
                  return this.options.cache;
              },
              getTrigger: function() {
                  return this.$element.attr('data-trigger') || this.options.trigger;
              },
              getDelayShow: function() {
                  var dataAttr = this.$element.attr('data-delay-show');
                  if (typeof(dataAttr) !== 'undefined') {
                      return dataAttr;
                  }
                  return this.options.delay.show === 0 ? 0 : this.options.delay.show || 100;
              },
              getHideDelay: function() {
                  var dataAttr = this.$element.attr('data-delay-hide');
                  if (typeof(dataAttr) !== 'undefined') {
                      return dataAttr;
                  }
                  return this.options.delay.hide === 0 ? 0 : this.options.delay.hide || 100;
              },
              getAnimation: function() {
                  var dataAttr = this.$element.attr('data-animation');
                  return dataAttr || this.options.animation;
              },
              getHideAnimation: function() {
                  var ani = this.getAnimation();
                  return ani ? ani + '-out' : 'out';
              },
              setTitle: function(title) {
                  var $titleEl = this.getTitleElement();
                  if (title) {
                      $titleEl.html(title);
                  } else {
                      $titleEl.remove();
                  }
              },
              hasContent: function() {
                  return this.getContent();
              },
              getIframe: function() {
                  var $iframe = $('<iframe></iframe>').attr('src', this.getUrl());
                  var self = this;
                  $.each(this._defaults.iframeOptions, function(opt) {
                      if (typeof self.options.iframeOptions[opt] !== 'undefined') {
                          $iframe.attr(opt, self.options.iframeOptions[opt]);
                      }
                  });
  
                  return $iframe;
              },
              getContent: function() {
                  if (this.getUrl()) {
                      switch (this.options.type) {
                          case 'iframe':
                              this.content = this.getIframe();
                              break;
                          case 'html':
                              try {
                                  this.content = $(this.getUrl());
                                  if (!this.content.is(':visible')) {
                                      this.content.show();
                                  }
                              } catch (error) {
                                  throw new Error('Unable to get popover content. Invalid selector specified.');
                              }
                              break;
                      }
                  } else if (!this.content) {
                      var content = '';
                      if ($.isFunction(this.options.content)) {
                          content = this.options.content.apply(this.$element[0], [this]);
                      } else {
                          content = this.options.content;
                      }
                      this.content = this.$element.attr('data-content') || content;
                      if (!this.content) {
                          var $next = this.$element.next();
  
                          if ($next && $next.hasClass(pluginClass + '-content')) {
                              this.content = $next;
                          }
                      }
                  }
                  return this.content;
              },
              setContent: function(content) {
                  var $target = this.getTarget();
                  var $ct = this.getContentElement();
                  if (typeof content === 'string') {
                      $ct.html(content);
                  } else if (content instanceof jQuery) {
                      $ct.html('');
                      //Don't want to clone too many times. 
                      if (!this.options.cache) {
                          content.clone(true, true).removeClass(pluginClass + '-content').appendTo($ct);
                      } else {
                          content.removeClass(pluginClass + '-content').appendTo($ct);
                      }
                  }
                  this.$target = $target;
              },
              isAsync: function() {
                  return this.options.type === 'async';
              },
              setContentASync: function(content) {
                  var that = this;
                  if (this.xhr) {
                      return;
                  }
                  this.xhr = $.ajax({
                      url: this.getUrl(),
                      type: this.options.async.type,
                      cache: this.getCache(),
                      beforeSend: function(xhr) {
                          if (that.options.async.before) {
                              that.options.async.before(that, xhr);
                          }
                      },
                      success: function(data) {
                          that.bindBodyEvents();
                          if (content && $.isFunction(content)) {
                              that.content = content.apply(that.$element[0], [data]);
                          } else {
                              that.content = data;
                          }
                          that.setContent(that.content);
                          var $targetContent = that.getContentElement();
                          $targetContent.removeAttr('style');
                          that.displayContent();
                          if (that.options.async.success) {
                              that.options.async.success(that, data);
                          }
                      },
                      complete: function() {
                          that.xhr = null;
                      },
                      error: function(xhr, data) {
                          if (that.options.async.error) {
                              that.options.async.error(that, xhr, data);
                          }
                      }
                  });
              },
  
              bindBodyEvents: function() {
                  if (this.options.dismissible && this.getTrigger() === 'click' && !_isBodyEventHandled) {
                      $document.off('keyup.webui-popover').on('keyup.webui-popover', $.proxy(this.escapeHandler, this));
                      $document.off('click.webui-popover touchend.webui-popover').on('click.webui-popover touchend.webui-popover', $.proxy(this.bodyClickHandler, this));
                  }
              },
  
              /* event handlers */
              mouseenterHandler: function() {
                  var self = this;
                  if (self._timeout) {
                      clearTimeout(self._timeout);
                  }
                  self._enterTimeout = setTimeout(function() {
                      if (!self.getTarget().is(':visible')) {
                          self.show();
                      }
                  }, this.getDelayShow());
              },
              mouseleaveHandler: function() {
                  var self = this;
                  clearTimeout(self._enterTimeout);
                  //key point, set the _timeout  then use clearTimeout when mouse leave
                  self._timeout = setTimeout(function() {
                      self.hide();
                  }, this.getHideDelay());
              },
              escapeHandler: function(e) {
                  if (e.keyCode === 27) {
                      this.hideAll();
                  }
              },
  
              bodyClickHandler: function(e) {
                  _isBodyEventHandled = true;
                  //alert(pointerEventToXY(e).x);
                  var canHide = true;
                  for (var i = 0; i < _srcElements.length; i++) {
                      var pop = getPopFromElement(_srcElements[i]);
                      if (pop && pop._opened) {
                          var popX1 = pop.getTarget().offset().left;
                          var popY1 = pop.getTarget().offset().top;
                          var popX2 = pop.getTarget().offset().left + pop.getTarget().width();
                          var popY2 = pop.getTarget().offset().top + pop.getTarget().height();
                          var pt = pointerEventToXY(e);
                          var inPop = pt.x >= popX1 && pt.x <= popX2 && pt.y >= popY1 && pt.y <= popY2;
                          if (inPop) {
                              canHide = false;
                              break;
                          }
                      }
                  }
                  if (canHide) {
                      hideAllPop();
                  }
              },
  
              /*
              targetClickHandler: function() {
                  this._targetclick = true;
              },
              */
  
              //reset and init the target events;
              initTargetEvents: function() {
                  if (this.getTrigger() === 'hover') {
                      this.$target
                          .off('mouseenter mouseleave')
                          .on('mouseenter', $.proxy(this.mouseenterHandler, this))
                          .on('mouseleave', $.proxy(this.mouseleaveHandler, this));
                  }
                  this.$target.find('.close').off('click').on('click', $.proxy(this.hide, this, true));
                  //this.$target.off('click.webui-popover').on('click.webui-popover', $.proxy(this.targetClickHandler, this));
              },
              /* utils methods */
              //caculate placement of the popover
              getPlacement: function(pos) {
                  var
                      placement,
                      de = document.documentElement,
                      db = document.body,
                      clientWidth = de.clientWidth,
                      clientHeight = de.clientHeight,
                      scrollTop = Math.max(db.scrollTop, de.scrollTop),
                      scrollLeft = Math.max(db.scrollLeft, de.scrollLeft),
                      pageX = Math.max(0, pos.left - scrollLeft),
                      pageY = Math.max(0, pos.top - scrollTop);
                  //arrowSize = 20;
  
                  //if placement equals auto，caculate the placement by element information;
                  if (typeof(this.options.placement) === 'function') {
                      placement = this.options.placement.call(this, this.getTarget()[0], this.$element[0]);
                  } else {
                      placement = this.$element.data('placement') || this.options.placement;
                  }
  
                  var isH = placement === 'horizontal';
                  var isV = placement === 'vertical';
                  var detect = placement === 'auto' || isH || isV;
  
                  if (detect) {
                      if (pageX < clientWidth / 3) {
                          if (pageY < clientHeight / 3) {
                              placement = isH ? 'right-bottom' : 'bottom-right';
                          } else if (pageY < clientHeight * 2 / 3) {
                              if (isV) {
                                  placement = pageY <= clientHeight / 2 ? 'bottom-right' : 'top-right';
                              } else {
                                  placement = 'right';
                              }
                          } else {
                              placement = isH ? 'right-top' : 'top-right';
                          }
                          //placement= pageY>targetHeight+arrowSize?'top-right':'bottom-right';
                      } else if (pageX < clientWidth * 2 / 3) {
                          if (pageY < clientHeight / 3) {
                              if (isH) {
                                  placement = pageX <= clientWidth / 2 ? 'right-bottom' : 'left-bottom';
                              } else {
                                  placement = 'bottom';
                              }
                          } else if (pageY < clientHeight * 2 / 3) {
                              if (isH) {
                                  placement = pageX <= clientWidth / 2 ? 'right' : 'left';
                              } else {
                                  placement = pageY <= clientHeight / 2 ? 'bottom' : 'top';
                              }
                          } else {
                              if (isH) {
                                  placement = pageX <= clientWidth / 2 ? 'right-top' : 'left-top';
                              } else {
                                  placement = 'top';
                              }
                          }
                      } else {
                          //placement = pageY>targetHeight+arrowSize?'top-left':'bottom-left';
                          if (pageY < clientHeight / 3) {
                              placement = isH ? 'left-bottom' : 'bottom-left';
                          } else if (pageY < clientHeight * 2 / 3) {
                              if (isV) {
                                  placement = pageY <= clientHeight / 2 ? 'bottom-left' : 'top-left';
                              } else {
                                  placement = 'left';
                              }
                          } else {
                              placement = isH ? 'left-top' : 'top-left';
                          }
                      }
                  } else if (placement === 'auto-top') {
                      if (pageX < clientWidth / 3) {
                          placement = 'top-right';
                      } else if (pageX < clientWidth * 2 / 3) {
                          placement = 'top';
                      } else {
                          placement = 'top-left';
                      }
                  } else if (placement === 'auto-bottom') {
                      if (pageX < clientWidth / 3) {
                          placement = 'bottom-right';
                      } else if (pageX < clientWidth * 2 / 3) {
                          placement = 'bottom';
                      } else {
                          placement = 'bottom-left';
                      }
                  } else if (placement === 'auto-left') {
                      if (pageY < clientHeight / 3) {
                          placement = 'left-top';
                      } else if (pageY < clientHeight * 2 / 3) {
                          placement = 'left';
                      } else {
                          placement = 'left-bottom';
                      }
                  } else if (placement === 'auto-right') {
                      if (pageY < clientHeight / 3) {
                          placement = 'right-top';
                      } else if (pageY < clientHeight * 2 / 3) {
                          placement = 'right';
                      } else {
                          placement = 'right-bottom';
                      }
                  }
                  return placement;
              },
              getElementPosition: function() {
                  return $.extend({}, this.$element.offset(), {
                      width: this.$element[0].offsetWidth,
                      height: this.$element[0].offsetHeight
                  });
              },
  
              getTargetPositin: function(elementPos, placement, targetWidth, targetHeight) {
                  var pos = elementPos,
                      de = document.documentElement,
                      db = document.body,
                      clientWidth = de.clientWidth,
                      clientHeight = de.clientHeight,
                      elementW = this.$element.outerWidth(),
                      elementH = this.$element.outerHeight(),
                      scrollTop = Math.max(db.scrollTop, de.scrollTop),
                      scrollLeft = Math.max(db.scrollLeft, de.scrollLeft),
                      position = {},
                      arrowOffset = null,
                      arrowSize = this.options.arrow ? 20 : 0,
                      padding = 10,
                      fixedW = elementW < arrowSize + padding ? arrowSize : 0,
                      fixedH = elementH < arrowSize + padding ? arrowSize : 0,
                      refix = 0,
                      pageH = clientHeight + scrollTop,
                      pageW = clientWidth + scrollLeft;
  
  
  
                  var validLeft = pos.left + pos.width / 2 - fixedW > 0;
                  var validRight = pos.left + pos.width / 2 + fixedW < pageW;
                  var validTop = pos.top + pos.height / 2 - fixedH > 0;
                  var validBottom = pos.top + pos.height / 2 + fixedH < pageH;
  
                  switch (placement) {
                      case 'bottom':
                          position = {
                              top: pos.top + pos.height,
                              left: pos.left + pos.width / 2 - targetWidth / 2
                          };
                          break;
                      case 'top':
                          position = {
                              top: pos.top - targetHeight,
                              left: pos.left + pos.width / 2 - targetWidth / 2
                          };
                          break;
                      case 'left':
                          position = {
                              top: pos.top + pos.height / 2 - targetHeight / 2,
                              left: pos.left - targetWidth
                          };
                          break;
                      case 'right':
                          position = {
                              top: pos.top + pos.height / 2 - targetHeight / 2,
                              left: pos.left + pos.width
                          };
                          break;
                      case 'top-right':
                          position = {
                              top: pos.top - targetHeight,
                              left: validLeft ? pos.left - fixedW : padding
                          };
                          arrowOffset = {
                              left: validLeft ? Math.min(elementW, targetWidth) / 2 + fixedW : _offsetOut
                          };
                          break;
                      case 'top-left':
                          refix = validRight ? fixedW : -padding;
                          position = {
                              top: pos.top - targetHeight,
                              left: pos.left - targetWidth + pos.width + refix
                          };
                          arrowOffset = {
                              left: validRight ? targetWidth - Math.min(elementW, targetWidth) / 2 - fixedW : _offsetOut
                          };
                          break;
                      case 'bottom-right':
                          position = {
                              top: pos.top + pos.height,
                              left: validLeft ? pos.left - fixedW : padding
                          };
                          arrowOffset = {
                              left: validLeft ? Math.min(elementW, targetWidth) / 2 + fixedW : _offsetOut
                          };
                          break;
                      case 'bottom-left':
                          refix = validRight ? fixedW : -padding;
                          position = {
                              top: pos.top + pos.height,
                              left: pos.left - targetWidth + pos.width + refix
                          };
                          arrowOffset = {
                              left: validRight ? targetWidth - Math.min(elementW, targetWidth) / 2 - fixedW : _offsetOut
                          };
                          break;
                      case 'right-top':
                          refix = validBottom ? fixedH : -padding;
                          position = {
                              top: pos.top - targetHeight + pos.height + refix,
                              left: pos.left + pos.width
                          };
                          arrowOffset = {
                              top: validBottom ? targetHeight - Math.min(elementH, targetHeight) / 2 - fixedH : _offsetOut
                          };
                          break;
                      case 'right-bottom':
                          position = {
                              top: validTop ? pos.top - fixedH : padding,
                              left: pos.left + pos.width
                          };
                          arrowOffset = {
                              top: validTop ? Math.min(elementH, targetHeight) / 2 + fixedH : _offsetOut
                          };
                          break;
                      case 'left-top':
                          refix = validBottom ? fixedH : -padding;
                          position = {
                              top: pos.top - targetHeight + pos.height + refix,
                              left: pos.left - targetWidth
                          };
                          arrowOffset = {
                              top: validBottom ? targetHeight - Math.min(elementH, targetHeight) / 2 - fixedH : _offsetOut
                          };
                          break;
                      case 'left-bottom':
                          position = {
                              top: validTop ? pos.top - fixedH : padding,
                              left: pos.left - targetWidth
                          };
                          arrowOffset = {
                              top: validTop ? Math.min(elementH, targetHeight) / 2 + fixedH : _offsetOut
                          };
                          break;
  
                  }
                  position.top += this.getOffsetTop();
                  position.left += this.getOffsetLeft();
  
                  return {
                      position: position,
                      arrowOffset: arrowOffset
                  };
              }
          };
          $.fn[pluginName] = function(options, noInit) {
              var results = [];
              var $result = this.each(function() {
  
                  var webuiPopover = $.data(this, 'plugin_' + pluginName);
                  if (!webuiPopover) {
                      if (!options) {
                          webuiPopover = new WebuiPopover(this, null);
                      } else if (typeof options === 'string') {
                          if (options !== 'destroy') {
                              if (!noInit) {
                                  webuiPopover = new WebuiPopover(this, null);
                                  results.push(webuiPopover[options]());
                              }
                          }
                      } else if (typeof options === 'object') {
                          webuiPopover = new WebuiPopover(this, options);
                      }
                      $.data(this, 'plugin_' + pluginName, webuiPopover);
                  } else {
                      if (options === 'destroy') {
                          webuiPopover.destroy();
                      } else if (typeof options === 'string') {
                          results.push(webuiPopover[options]());
                      }
                  }
              });
  
              return (results.length) ? results : $result;
          };
      }));
  })(window, document);
  