text: define([
      "skylark-jquery",
      "../light-gallery"
  ],function($,lightGallery){
  
      'use strict';
  
      var getUseLeft = function() {
          var useLeft = false;
          var isChrome = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
          if (isChrome && parseInt(isChrome[2], 10) < 54) {
              useLeft = true;
          }
  
          return useLeft;
      };
  
      var defaults = {
          scale: 1,
          zoom: true,
          actualSize: true,
          enableZoomAfter: 300,
          useLeftForZoom: getUseLeft()
      };
  
      var Zoom = function(element) {
  
          this.core = $(element).data('lightGallery');
  
          this.core.s = $.extend({}, defaults, this.core.s);
  
          if (this.core.s.zoom && this.core.doCss()) {
              this.init();
  
              // Store the zoomable timeout value just to clear it while closing
              this.zoomabletimeout = false;
  
              // Set the initial value center
              this.pageX = $(window).width() / 2;
              this.pageY = ($(window).height() / 2) + $(window).scrollTop();
          }
  
          return this;
      };
  
      Zoom.prototype.init = function() {
  
          var _this = this;
          var zoomIcons = '<button type="button" aria-label="Zoom in" id="lg-zoom-in" class="lg-icon"></button><button type="button" aria-label="Zoom out" id="lg-zoom-out" class="lg-icon"></button>';
  
          if (_this.core.s.actualSize) {
              zoomIcons += '<button type="button" aria-label="Actual size" id="lg-actual-size" class="lg-icon"></button>';
          }
  
          if (_this.core.s.useLeftForZoom) {
              _this.core.$outer.addClass('lg-use-left-for-zoom');
          } else {
              _this.core.$outer.addClass('lg-use-transition-for-zoom');
          }
  
          this.core.$outer.find('.lg-toolbar').append(zoomIcons);
  
          // Add zoomable class
          _this.core.$el.on('onSlideItemLoad.lg.tm.zoom', function(event, index, delay) {
  
              // delay will be 0 except first time
              var _speed = _this.core.s.enableZoomAfter + delay;
  
              // set _speed value 0 if gallery opened from direct url and if it is first slide
              if ($('body').hasClass('lg-from-hash') && delay) {
  
                  // will execute only once
                  _speed = 0;
              } else {
  
                  // Remove lg-from-hash to enable starting animation.
                  $('body').removeClass('lg-from-hash');
              }
  
              _this.zoomabletimeout = setTimeout(function() {
                  _this.core.$slide.eq(index).addClass('lg-zoomable');
              }, _speed + 30);
          });
  
          var scale = 1;
          /**
           * @desc Image zoom
           * Translate the wrap and scale the image to get better user experience
           *
           * @param {String} scaleVal - Zoom decrement/increment value
           */
          var zoom = function(scaleVal) {
  
              var $image = _this.core.$outer.find('.lg-current .lg-image');
              var _x;
              var _y;
  
              // Find offset manually to avoid issue after zoom
              var offsetX = ($(window).width() - $image.prop('offsetWidth')) / 2;
              var offsetY = (($(window).height() - $image.prop('offsetHeight')) / 2) + $(window).scrollTop();
  
              _x = _this.pageX - offsetX;
              _y = _this.pageY - offsetY;
  
              var x = (scaleVal - 1) * (_x);
              var y = (scaleVal - 1) * (_y);
  
              $image.css('transform', 'scale3d(' + scaleVal + ', ' + scaleVal + ', 1)').attr('data-scale', scaleVal);
  
              if (_this.core.s.useLeftForZoom) {
                  $image.parent().css({
                      left: -x + 'px',
                      top: -y + 'px'
                  }).attr('data-x', x).attr('data-y', y);
              } else {
                  $image.parent().css('transform', 'translate3d(-' + x + 'px, -' + y + 'px, 0)').attr('data-x', x).attr('data-y', y);
              }
          };
  
          var callScale = function() {
              if (scale > 1) {
                  _this.core.$outer.addClass('lg-zoomed');
              } else {
                  _this.resetZoom();
              }
  
              if (scale < 1) {
                  scale = 1;
              }
  
              zoom(scale);
          };
  
          var actualSize = function(event, $image, index, fromIcon) {
              var w = $image.prop('offsetWidth');
              var nw;
              if (_this.core.s.dynamic) {
                  nw = _this.core.s.dynamicEl[index].width || $image[0].naturalWidth || w;
              } else {
                  nw = _this.core.$items.eq(index).attr('data-width') || $image[0].naturalWidth || w;
              }
  
              var _scale;
  
              if (_this.core.$outer.hasClass('lg-zoomed')) {
                  scale = 1;
              } else {
                  if (nw > w) {
                      _scale = nw / w;
                      scale = _scale || 2;
                  }
              }
  
              if (fromIcon) {
                  _this.pageX = $(window).width() / 2;
                  _this.pageY = ($(window).height() / 2) + $(window).scrollTop();
              } else {
                  _this.pageX = event.pageX || event.originalEvent.targetTouches[0].pageX;
                  _this.pageY = event.pageY || event.originalEvent.targetTouches[0].pageY;
              }
  
              callScale();
              setTimeout(function() {
                  _this.core.$outer.removeClass('lg-grabbing').addClass('lg-grab');
              }, 10);
          };
  
          var tapped = false;
  
          // event triggered after appending slide content
          _this.core.$el.on('onAferAppendSlide.lg.tm.zoom', function(event, index) {
  
              // Get the current element
              var $image = _this.core.$slide.eq(index).find('.lg-image');
  
              $image.on('dblclick', function(event) {
                  actualSize(event, $image, index);
              });
  
              $image.on('touchstart', function(event) {
                  if (!tapped) {
                      tapped = setTimeout(function() {
                          tapped = null;
                      }, 300);
                  } else {
                      clearTimeout(tapped);
                      tapped = null;
                      actualSize(event, $image, index);
                  }
  
                  event.preventDefault();
              });
  
          });
  
          // Update zoom on resize and orientationchange
          $(window).on('resize.lg.zoom scroll.lg.zoom orientationchange.lg.zoom', function() {
              _this.pageX = $(window).width() / 2;
              _this.pageY = ($(window).height() / 2) + $(window).scrollTop();
              zoom(scale);
          });
  
          $('#lg-zoom-out').on('click.lg', function() {
              if (_this.core.$outer.find('.lg-current .lg-image').length) {
                  scale -= _this.core.s.scale;
                  callScale();
              }
          });
  
          $('#lg-zoom-in').on('click.lg', function() {
              if (_this.core.$outer.find('.lg-current .lg-image').length) {
                  scale += _this.core.s.scale;
                  callScale();
              }
          });
  
          $('#lg-actual-size').on('click.lg', function(event) {
              actualSize(event, _this.core.$slide.eq(_this.core.index).find('.lg-image'), _this.core.index, true);
          });
  
          // Reset zoom on slide change
          _this.core.$el.on('onBeforeSlide.lg.tm', function() {
              scale = 1;
              _this.resetZoom();
          });
  
          // Drag option after zoom
          _this.zoomDrag();
  
          _this.zoomSwipe();
  
      };
  
      /**
       * 
       * @param {Element} el 
       * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0);
       * Get the current transform value
       */
      Zoom.prototype.getCurrentTransform = function (el) {
          if (!el) {
              return 0;
          }
          var st = window.getComputedStyle(el, null);
          var tm = st.getPropertyValue('-webkit-transform') ||
              st.getPropertyValue('-moz-transform') ||
              st.getPropertyValue('-ms-transform') ||
              st.getPropertyValue('-o-transform') ||
              st.getPropertyValue('transform') ||
              'none';
          if (tm !== 'none') {
              return tm.split('(')[1].split(')')[0].split(',');
          }
          return 0;
      };
  
      Zoom.prototype.getCurrentRotation = function (el) {
          if (!el) {
              return 0;
          }
          var values = this.getCurrentTransform(el);
          if (values) {
              return Math.round(Math.atan2(values[1], values[0]) * (180 / Math.PI));
              // If you want rotate in 360
              //return (angle < 0 ? angle + 360 : angle);
          }
          return 0;
      };
  
      Zoom.prototype.getModifier = function (rotateValue, axis, el) {
          var originalRotate = rotateValue;
          rotateValue = Math.abs(rotateValue);
          var transformValues = this.getCurrentTransform(el);
          if (!transformValues) {
              return 1;
          }
          var modifier = 1;
          if (axis === 'X') {
              var flipHorizontalValue = Math.sign(parseFloat(transformValues[0]));
              if (rotateValue === 0 || rotateValue === 180) {
                  modifier = 1;
              } else if (rotateValue === 90) {
                  if ((originalRotate === -90 && flipHorizontalValue === 1) || (originalRotate === 90 && flipHorizontalValue === -1)) {
                      modifier = -1;
                  } else {
                      modifier = 1;
                  }
              }
              modifier = modifier * flipHorizontalValue;
          } else {
              var flipVerticalValue = Math.sign(parseFloat(transformValues[3]));
              if (rotateValue === 0 || rotateValue === 180) {
                  modifier = 1;
              } else if (rotateValue === 90) {
                  var sinX = parseFloat(transformValues[1]);
                  var sinMinusX = parseFloat(transformValues[2]);
                  modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue);
              }
              modifier = modifier * flipVerticalValue;
          }
          return modifier;
      };
  
      Zoom.prototype.getImageSize = function ($image, rotateValue, axis) {
          var imageSizes = {
              y: 'offsetHeight',
              x: 'offsetWidth'
          };
          if (rotateValue === 90) {
              // Swap axis 
              if (axis === 'x') {
                  axis = 'y';
              } else {
                  axis = 'x';
              }
          }
          return $image.prop(imageSizes[axis]);
      };
  
      Zoom.prototype.getDragCords = function (e, rotateValue) {
          if (rotateValue === 90) {
              return {
                  x: e.pageY,
                  y: e.pageX
              };
          } else {
              return {
                  x: e.pageX,
                  y: e.pageY
              };
          }
      };
      Zoom.prototype.getSwipeCords = function (e, rotateValue) {
          var x = e.originalEvent.targetTouches[0].pageX;
          var y = e.originalEvent.targetTouches[0].pageY;
          if (rotateValue === 90) {
              return {
                  x: y,
                  y: x
              };
          } else {
              return {
                  x: x,
                  y: y
              };
          }
      };
  
      Zoom.prototype.getPossibleDragCords = function ($image, rotateValue) {
  
          var minY = (this.core.$outer.find('.lg').height() - this.getImageSize($image, rotateValue, 'y')) / 2;
          var maxY = Math.abs((this.getImageSize($image, rotateValue, 'y') * Math.abs($image.attr('data-scale'))) - this.core.$outer.find('.lg').height() + minY);
          var minX = (this.core.$outer.find('.lg').width() - this.getImageSize($image, rotateValue, 'x')) / 2;
          var maxX = Math.abs((this.getImageSize($image, rotateValue, 'x') * Math.abs($image.attr('data-scale'))) - this.core.$outer.find('.lg').width() + minX);
          if (rotateValue === 90) {
              return {
                  minY: minX,
                  maxY: maxX,
                  minX: minY,
                  maxX: maxY,
              };
          } else {
              return {
                  minY: minY,
                  maxY: maxY,
                  minX: minX,
                  maxX: maxX,
              };
          }
      };
  
      Zoom.prototype.getDragAllowedAxises = function ($image, rotateValue) {
          var allowY = this.getImageSize($image, rotateValue, 'y') * $image.attr('data-scale') > this.core.$outer.find('.lg').height();
          var allowX = this.getImageSize($image, rotateValue, 'x') * $image.attr('data-scale') > this.core.$outer.find('.lg').width();
          if (rotateValue === 90) {
              return {
                  allowX: allowY,
                  allowY: allowX
              };
          } else {
              return {
                  allowX: allowX,
                  allowY: allowY
              };
          }
      };
  
      // Reset zoom effect
      Zoom.prototype.resetZoom = function() {
          this.core.$outer.removeClass('lg-zoomed');
          this.core.$slide.find('.lg-img-wrap').removeAttr('style data-x data-y');
          this.core.$slide.find('.lg-image').removeAttr('style data-scale');
  
          // Reset pagx pagy values to center
          this.pageX = $(window).width() / 2;
          this.pageY = ($(window).height() / 2) + $(window).scrollTop();
      };
  
      Zoom.prototype.zoomSwipe = function() {
          var _this = this;
          var startCoords = {};
          var endCoords = {};
          var isMoved = false;
  
          // Allow x direction drag
          var allowX = false;
  
          // Allow Y direction drag
          var allowY = false;
  
          var rotateValue = 0;
          var rotateEl;
  
          _this.core.$slide.on('touchstart.lg', function(e) {
  
              if (_this.core.$outer.hasClass('lg-zoomed')) {
                  var $image = _this.core.$slide.eq(_this.core.index).find('.lg-object');
  
                  rotateEl = _this.core.$slide.eq(_this.core.index).find('.lg-img-rotate')[0];
                  rotateValue = _this.getCurrentRotation(rotateEl);    
  
                  var dragAllowedAxises = _this.getDragAllowedAxises($image, Math.abs(rotateValue));
                  allowY = dragAllowedAxises.allowY;
                  allowX = dragAllowedAxises.allowX;
      
                  if ((allowX || allowY)) {
                      e.preventDefault();
                      startCoords = _this.getSwipeCords(e, Math.abs(rotateValue));
                  }
              }
  
          });
  
          _this.core.$slide.on('touchmove.lg', function(e) {
  
              if (_this.core.$outer.hasClass('lg-zoomed')) {
  
                  var _$el = _this.core.$slide.eq(_this.core.index).find('.lg-img-wrap');
                  var distanceX;
                  var distanceY;
  
                  e.preventDefault();
                  isMoved = true;
  
                  endCoords = _this.getSwipeCords(e, Math.abs(rotateValue));
  
                  // reset opacity and transition duration
                  _this.core.$outer.addClass('lg-zoom-dragging');
  
                  if (allowY) {
                      distanceY = (-Math.abs(_$el.attr('data-y'))) + ((endCoords.y - startCoords.y) * _this.getModifier(rotateValue, 'Y', rotateEl));
                  } else {
                      distanceY = -Math.abs(_$el.attr('data-y'));
                  }
  
                  if (allowX) {
                      distanceX = (-Math.abs(_$el.attr('data-x'))) + ((endCoords.x - startCoords.x) * _this.getModifier(rotateValue, 'X', rotateEl));
  
                  } else {
                      distanceX = -Math.abs(_$el.attr('data-x'));
                  }
  
                  if ((Math.abs(endCoords.x - startCoords.x) > 15) || (Math.abs(endCoords.y - startCoords.y) > 15)) {
  
                      if (_this.core.s.useLeftForZoom) {
                          _$el.css({
                              left: distanceX + 'px',
                              top: distanceY + 'px'
                          });
                      } else {
                          _$el.css('transform', 'translate3d(' + distanceX + 'px, ' + distanceY + 'px, 0)');
                      }
                  }
  
              }
  
          });
  
          _this.core.$slide.on('touchend.lg', function() {
              if (_this.core.$outer.hasClass('lg-zoomed')) {
                  if (isMoved) {
                      isMoved = false;
                      _this.core.$outer.removeClass('lg-zoom-dragging');
                      _this.touchendZoom(startCoords, endCoords, allowX, allowY, rotateValue);
  
                  }
              }
          });
  
      };
  
      Zoom.prototype.zoomDrag = function() {
  
          var _this = this;
          var startCoords = {};
          var endCoords = {};
          var isDraging = false;
          var isMoved = false;
  
          // Allow x direction drag
          var allowX = false;
  
          // Allow Y direction drag
          var allowY = false;
  
          var rotateValue = 0;
          var rotateEl;
          
          _this.core.$slide.on('mousedown.lg.zoom', function(e) {
              rotateEl = _this.core.$slide.eq(_this.core.index).find('.lg-img-rotate')[0];
              rotateValue = _this.getCurrentRotation(rotateEl);
              // execute only on .lg-object
              var $image = _this.core.$slide.eq(_this.core.index).find('.lg-object');
              var dragAllowedAxises = _this.getDragAllowedAxises($image, Math.abs(rotateValue));
              allowY = dragAllowedAxises.allowY;
              allowX = dragAllowedAxises.allowX;
  
              if (_this.core.$outer.hasClass('lg-zoomed')) {
                  if ($(e.target).hasClass('lg-object') && (allowX || allowY)) {
                      e.preventDefault();
                      startCoords = _this.getDragCords(e, Math.abs(rotateValue));
  
                      isDraging = true;
  
                      // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
                      _this.core.$outer.scrollLeft += 1;
                      _this.core.$outer.scrollLeft -= 1;
  
                      _this.core.$outer.removeClass('lg-grab').addClass('lg-grabbing');
                  }
              }
          });
  
          $(window).on('mousemove.lg.zoom', function(e) {
              if (isDraging) {
                  var _$el = _this.core.$slide.eq(_this.core.index).find('.lg-img-wrap');
                  var distanceX;
                  var distanceY;
  
                  isMoved = true;
                  endCoords = _this.getDragCords(e, Math.abs(rotateValue));
  
                  // reset opacity and transition duration
                  _this.core.$outer.addClass('lg-zoom-dragging');
  
                  if (allowY) {
                      distanceY = (-Math.abs(_$el.attr('data-y'))) + ((endCoords.y - startCoords.y) * _this.getModifier(rotateValue, 'Y', rotateEl));
                  } else {
                      distanceY = -Math.abs(_$el.attr('data-y'));
                  }
                  
                  if (allowX) {
                      distanceX = (-Math.abs(_$el.attr('data-x'))) + ((endCoords.x - startCoords.x) * _this.getModifier(rotateValue, 'X', rotateEl));
                  } else {
                      distanceX = -Math.abs(_$el.attr('data-x'));
                  }
  
                  if (_this.core.s.useLeftForZoom) {
                      _$el.css({
                          left: distanceX + 'px',
                          top: distanceY + 'px'
                      });
                  } else {
                      _$el.css('transform', 'translate3d(' + distanceX + 'px, ' + distanceY + 'px, 0)');
                  }
              }
          });
  
          $(window).on('mouseup.lg.zoom', function(e) {
  
              if (isDraging) {
                  isDraging = false;
                  _this.core.$outer.removeClass('lg-zoom-dragging');
  
                  // Fix for chrome mouse move on click
                  if (isMoved && ((startCoords.x !== endCoords.x) || (startCoords.y !== endCoords.y))) {
                      endCoords = _this.getDragCords(e, Math.abs(rotateValue));
                      _this.touchendZoom(startCoords, endCoords, allowX, allowY, rotateValue);
  
                  }
  
                  isMoved = false;
              }
  
              _this.core.$outer.removeClass('lg-grabbing').addClass('lg-grab');
  
          });
      };
  
      Zoom.prototype.touchendZoom = function(startCoords, endCoords, allowX, allowY, rotateValue) {
  
          var _this = this;
          var _$el = _this.core.$slide.eq(_this.core.index).find('.lg-img-wrap');
          var $image = _this.core.$slide.eq(_this.core.index).find('.lg-object');
          var rotateEl = _this.core.$slide.eq(_this.core.index).find('.lg-img-rotate')[0];
          var distanceX = (-Math.abs(_$el.attr('data-x'))) + ((endCoords.x - startCoords.x) * _this.getModifier(rotateValue, 'X', rotateEl));
          var distanceY = (-Math.abs(_$el.attr('data-y'))) + ((endCoords.y - startCoords.y) * _this.getModifier(rotateValue, 'Y', rotateEl));
          var possibleDragCords = _this.getPossibleDragCords($image, Math.abs(rotateValue));
          if ((Math.abs(endCoords.x - startCoords.x) > 15) || (Math.abs(endCoords.y - startCoords.y) > 15)) {
              if (allowY) {
                  if (distanceY <= -possibleDragCords.maxY) {
                      distanceY = -possibleDragCords.maxY;
                  } else if (distanceY >= -possibleDragCords.minY) {
                      distanceY = -possibleDragCords.minY;
                  }
              }
  
              if (allowX) {
                  if (distanceX <= -possibleDragCords.maxX) {
                      distanceX = -possibleDragCords.maxX;
                  } else if (distanceX >= -possibleDragCords.minX) {
                      distanceX = -possibleDragCords.minX;
                  }
              }
  
              if (allowY) {
                  _$el.attr('data-y', Math.abs(distanceY));
              } else {
                  distanceY = -Math.abs(_$el.attr('data-y'));
              }
  
              if (allowX) {
                  _$el.attr('data-x', Math.abs(distanceX));
              } else {
                  distanceX = -Math.abs(_$el.attr('data-x'));
              }
  
              if (_this.core.s.useLeftForZoom) {
                  _$el.css({
                      left: distanceX + 'px',
                      top: distanceY + 'px'
                  });
              } else {
                  _$el.css('transform', 'translate3d(' + distanceX + 'px, ' + distanceY + 'px, 0)');
              }
  
          }
      };
  
      Zoom.prototype.destroy = function() {
  
          var _this = this;
  
          // Unbind all events added by lightGallery zoom plugin
          _this.core.$el.off('.lg.zoom');
          $(window).off('.lg.zoom');
          _this.core.$slide.off('.lg.zoom');
          _this.core.$el.off('.lg.tm.zoom');
          _this.resetZoom();
          clearTimeout(_this.zoomabletimeout);
          _this.zoomabletimeout = false;
      };
  
      $.fn.lightGallery.modules.zoom = Zoom;
  
  });
  