PageSourceSearch

https://www.valma.ee/wp-content/plugins/supsystic-gallery-pro/src/GridGalleryPro/Galleries/js/frontend.js

js valma.ee collected 2026-10-02 14:05:57 UTC 94,474 bytes, 2,469 lines download raw bytes

1(function ($) {
2  function ProGallery() {
3    this.topLvlItemSelector = null;
4    this.scrollInProgress = false;
5  }
6
7  ProGallery.prototype._parent = function (func, arguments) {
8    return typeof this.constructor.prototype[func] != 'undefined' ? this.constructor.prototype[func].call(this, arguments) : false;
9  };
10
11  ProGallery.prototype._afterInit = function ($callback) {
12    $(document).on('GalleryAfterInit', function (event, Gallery) {
13      $callback.call(Gallery);
14    });
15  };
16
17  ProGallery.prototype._beforeInit = function ($callback) {
18    var galleryBeforeInitId = 'GalleryBeforeInit' + this.galleryContainerId;
19    $(document).on(galleryBeforeInitId, (event, Gallery) => {
20      $callback.call(Gallery);
21    });
22  };
23
24  ProGallery.prototype.init = function () {
25    var self = this;
26    this._parent('init');
27    this._beforeInit(() => {
28      this.initInfiniteScroll();
29      this.initColorBoxOnLoadHandler();
30    });
31
32    this._afterInit(function () {
33      this.initVideoPopup();
34      this.initLinkedImages();
35      this.initDisableRightClick();
36      self.selectCategoryByUrlHash(self);
37      if (!this.afterInitFlag) {
38        this.initMosaicGalleryType();
39        this.setCaptionOnHoverImage();
40        this.afterInitFlag = true;
41        this.initPopupFunc();
42      }
43      this.initFilterByAttributes();
44      this.initSearchByKeywords();
45      this.initDownloadButtons();
46    });
47
48    $(window).on('hashchange', function (event) {
49      self.selectCategoryByUrlHash(self);
50    });
51
52    $(document).on('beforeResizeColorBoxResponsive', function (event) {
53      if (typeof self.currentVideoPlayer == 'object') {
54        if (typeof self.currentVideoPlayer.getCurrentTime == 'function') {
55          self.savedColorBoxVideoStartTime = self.currentVideoPlayer.getCurrentTime();
56        }
57      }
58    });
59
60    if (this.$container.data('caption-builder-icons') == '1' || (this.$container.data('caption-buider') != 1 && this.$container.data('icons') == true)) {
61      this.topLvlItemSelector = '.grid-gallery-caption ';
62    } else {
63      this.topLvlItemSelector = '.gg-link';
64    }
65  };
66
67  ProGallery.prototype.reinit = function () {
68    this.setIconsPosition();
69    this.setOverlayTransparency();
70    this.setImageOverlay();
71    this.setMouseShadow();
72    this.initRowsMode();
73    this.preventImages();
74    this.initPopup();
75    this.initVideoPopup();
76    this.initCaptionCalculations();
77    this.initCaptionEffects();
78    this.showCaption();
79    this.hidePopupCaptions();
80    this.correctMargin();
81    this.initHorizontalMode();
82    this.initWookmark();
83    this.$container.trigger('wookmark.changed');
84    if (this.socialSharing && this.socialSharing.enabled) {
85      this.initImageSocialSharing();
86    }
87    this.initMosaicGalleryType();
88  };
89
90  ProGallery.prototype.loadButtonsFontFamily = function (font, callback) {
91    callback = callback || function () {};
92
93    if (font && font !== 'Default') {
94      this._parent('importFontFamily', font);
95    }
96  };
97
98  ProGallery.prototype.shadeColor = function (color, percent) {
99    var f = parseInt(color.slice(1), 16),
100      t = percent < 0 ? 0 : 255,
101      p = percent < 0 ? percent * -1 : percent,
102      R = f >> 16,
103      G = (f >> 8) & 0x00ff,
104      B = f & 0x0000ff;
105    return '#' + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
106  };
107
108  ProGallery.prototype.initButtonStyles = function ($buttons, font, fontCallback, single) {
109    var self = this,
110      $paginationPrev = null,
111      $paginationNext = null;
112    this.loadButtonsFontFamily(font, fontCallback);
113
114    if (self.$container.data('use-pagination-prev-next') == 1) {
115      $paginationPrev = $('.grid-gallery-page.gg-prev-pagination-btn');
116      $paginationNext = $('.grid-gallery-page.gg-next-pagination-btn');
117    }
118
119    var background = (function ($button) {
120      var initial = $button.css('background-color'),
121        hasBackground = true;
122
123      if (initial == 'rgba(0, 0, 0, 0)' || initial == 'transparent' || initial == 'rgb(255, 255, 255)') {
124        hasBackground = false;
125        initial = $button.css('color');
126      }
127      if (typeof initial === 'undefined') {
128        initial = '#6f6f6f';
129      }
130      if (!initial.match(/^#?(?:[0-9a-f]{3}){1,2}$/)) {
131        initial = '#' + self.rgb2hex(initial);
132      }
133      var shaded = self.shadeColor(initial, 0.5);
134
135      return {
136        initial: initial,
137        shaded: shaded,
138        hasBackground: hasBackground,
139      };
140    })($buttons.first());
141
142    (function (background) {
143      var attribute = 'background-color';
144      if (!background.hasBackground) {
145        attribute = 'color';
146      }
147
148      if (typeof single === 'undefined') {
149        $buttons.not('.active').hover(
150          function () {
151            $(this).css(attribute, background.initial);
152          },
153          function () {
154            $(this).not('.active').css(attribute, background.shaded);
155          }
156        );
157
158        $buttons.on('click', function (event) {
159          event.preventDefault();
160          var multiselect = $buttons.closest('nav').data('multiselect') == '1',
161            isActiveButton = false;
162
163          if (multiselect) {
164            var curentTag = String($(event.currentTarget).data('tag')),
165              $active = $buttons.filter('.active[data-tag="' + curentTag + '"]');
166            if ($active && $active.length) {
167              $active.removeClass('active');
168              isActiveButton = true;
169            }
170            if (curentTag == '__all__') {
171              $buttons.removeClass('active');
172            } else {
173              $buttons.filter('.active[data-tag="__all__"]').removeClass('active');
174            }
175            $buttons.not('.active').css(attribute, background.shaded);
176          } else {
177            $buttons.css(attribute, background.shaded).removeClass('active');
178          }
179
180          if (self.$container.data('use-pagination-prev-next') == 1 && $paginationPrev.length && $paginationNext.length) {
181            var currBtn = $(event.currentTarget),
182              currPage = parseInt(currBtn.attr('data-page'), 10),
183              maxPrev = parseInt($paginationPrev.attr('data-pagemax'), 10),
184              maxNext = parseInt($paginationNext.attr('data-pagemax'), 10);
185
186            var $toSelectBtn = self.pagination.$wrapper.find('a.grid-gallery-page:not(.gg-prev-pagination-btn):not(.gg-next-pagination-btn)[data-page="' + currPage + '"]');
187            if ($toSelectBtn.length) {
188              $toSelectBtn.css(attribute, background.initial).addClass('active');
189
190              // recalc data-page for Prev/Next btn
191              if (!isNaN(currPage) && !isNaN(maxPrev) && !isNaN(maxNext)) {
192                if (currPage > 1) {
193                  if (maxPrev >= currPage) {
194                    $paginationPrev.attr('data-page', currPage - 1);
195                  } else {
196                    $paginationPrev.attr('data-page', maxPrev);
197                  }
198                  if (maxNext - 1 > currPage) {
199                    $paginationNext.attr('data-page', currPage + 1);
200                  } else {
201                    $paginationNext.attr('data-page', maxNext);
202                  }
203                } else {
204                  $paginationPrev.attr('data-page', 1);
205                  $paginationNext.attr('data-page', 2);
206                }
207              }
208            }
209            $('.grid-gallery-pagination-wrap').attr('data-page', currPage);
210          } else {
211            var $newActiveButton = $(event.currentTarget);
212            if (isActiveButton) {
213              $newActiveButton = null;
214              if ($buttons.filter('.active').length == 0) {
215                $newActiveButton = $buttons.eq(0);
216              }
217            }
218            if ($newActiveButton) {
219              $newActiveButton.css(attribute, background.initial).addClass('active');
220            }
221          }
222        });
223      } else {
224        $buttons.css(attribute, background.shaded);
225        $buttons.hover(
226          function () {
227            $(this).css(attribute, background.initial);
228          },
229          function () {
230            $(this).css(attribute, background.shaded);
231          }
232        );
233      }
234    })(background);
235  };
236
237  ProGallery.prototype.initFilterByAttributes = function () {
238    if (this.$container.attr('data-show-filter') != 1) return;
239    var $filterContainer = this.$container.find('.grid-gallery-filter'),
240      $namesContainer = $filterContainer.find('.gg-filter-attributes-names'),
241      $valuesContainer = $filterContainer.find('.gg-filter-attributes-values'),
242      $filterClear = $filterContainer.find('.gg-filter-attributes-clear'),
243      gallery = this,
244      attrValues;
245
246    if ($filterContainer.data('custom-buttons')) {
247      this.loadButtonsFontFamily($filterContainer.data('font'), null);
248    }
249
250    try {
251      attrValues = JSON.parse($valuesContainer.attr('data-values'));
252    } catch (err) {}
253    if (!$.isArray(attrValues)) {
254      attrValues = [];
255    }
256
257    $namesContainer.on('change', function (event) {
258      var $selected = $(this).find('option:selected');
259      ($valuesContainer.empty(), (display = 'none'));
260      if ($selected.length > 0 && $selected.val() != '0') {
261        var attrName = $selected.text();
262        for (var i = 0; i < attrValues.length; i++) {
263          if ('name' in attrValues[i] && attrValues[i]['name'] == attrName) {
264            if ('values' in attrValues[i] && $.isArray(attrValues[i]['values'])) {
265              $.each(attrValues[i]['values'], function (index, value) {
266                $valuesContainer.append($('<option value="' + index + '">' + value + '</option>'));
267              });
268            }
269            break;
270          }
271        }
272        display = 'block';
273      }
274      $filterClear.css('display', display);
275      $valuesContainer.css('display', display).trigger('change');
276    });
277
278    $valuesContainer.on('change', function (event) {
279      gallery.doFilterAndSearch();
280    });
281
282    $filterClear.on('click', function () {
283      $namesContainer.find('option[value="0"]').prop('selected', true);
284      $namesContainer.trigger('change');
285    });
286
287    $filterContainer.css('display', 'block');
288    $filterContainer.find('select').height($filterClear.height());
289    $filterClear.css('display', 'none');
290  };
291
292  ProGallery.prototype.doFilterAndSearch = function () {
293    var $container = this.$container,
294      $filterContainer = $container.find('.grid-gallery-filter'),
295      $searchContainer = this.$container.find('.grid-gallery-search'),
296      $elements = $container.find('.gg-link').removeClass('hidden-item');
297
298    if ($filterContainer.length) {
299      var $selectedName = $filterContainer.find('.gg-filter-attributes-names').find('option:selected');
300
301      if ($selectedName.length > 0 && $selectedName.val() != '') {
302        var attrName = $selectedName.text(),
303          attrValue = $filterContainer.find('.gg-filter-attributes-values').find('option:selected').text();
304
305        if (attrValue.length > 0) {
306          $elements.each(function () {
307            var found = false,
308              attributes;
309            try {
310              attributes = JSON.parse($($(this)).attr('data-attributes'));
311            } catch (err) {}
312            if (!$.isArray(attributes)) {
313              attributes = [];
314            }
315            for (var i = 0; i < attributes.length; i++) {
316              if ('name' in attributes[i] && attributes[i]['name'] == attrName) {
317                if ('value' in attributes[i] && attributes[i]['value'] == attrValue) {
318                  found = true;
319                  break;
320                }
321              }
322            }
323            if (!found) {
324              $(this).addClass('hidden-item');
325            }
326          });
327        }
328      }
329    }
330
331    if ($searchContainer.length) {
332      var search = $searchContainer.find('input.gg-search-keywords').val();
333      if (search.length > 0) {
334        $elements.not('[data-keywords *= "' + search.toLowerCase() + '"]').addClass('hidden-item');
335      }
336    }
337    if ($container.find('a.grid-gallery-page').length > 0) {
338      this.initPagination(false);
339      //$container.find('a.grid-gallery-page:not(.gg-prev-pagination-btn)').first().trigger('click');
340    } else {
341      this.initWookmark();
342      if (this.afterInitFlag) {
343        this.correctMargin();
344        this.initPopup();
345        this.initVideoPopup();
346      }
347    }
348  };
349
350  ProGallery.prototype.initSearchByKeywords = function () {
351    if (this.$container.attr('data-show-search') != 1) return;
352
353    var $searchContainer = this.$container.find('.grid-gallery-search'),
354      $searchButton = $searchContainer.find('a.gg-search-btn'),
355      gallery = this;
356
357    if ($searchContainer.data('custom-buttons')) {
358      this.loadButtonsFontFamily($searchContainer.data('font'), null);
359    }
360
361    $searchButton.on('click', function (e) {
362      e.preventDefault();
363      gallery.doFilterAndSearch();
364    });
365
366    $searchContainer.css('display', 'block');
367    $searchContainer.find('input').height($searchButton.height());
368  };
369
370  ProGallery.prototype.initDownloadButtons = function () {
371    var container = this.$container;
372    if (this.$container.attr('data-popup-enable-download-photos-button') == 1) {
373      var popupType = this.$container.data('popup-type'),
374        $downloadBtn = $('<a>').addClass('popup-download-photos-button'),
375        $downloadBtnTxt = this.$container.attr('data-popup-enable-download-photos-button-text'),
376        self = this,
377        galleryId = container.attr('data-gg-id');
378
379      $downloadBtn
380        .attr({
381          title: $downloadBtnTxt,
382          download: '',
383        })
384        .text($downloadBtnTxt);
385
386      switch (popupType) {
387        case 'photobox':
388        case 'pretty-photo':
389          self.initVideoPopup($downloadBtn);
390          break;
391        case 'colorbox':
392          $(document).bind('cbox_complete', function () {
393            var $element = $.colorbox.element();
394            $('#cboxContent').find('.popup-download-photos-button').remove();
395
396            var interval = setInterval(function () {
397              if (!$element.is('[data-video-source]')) {
398                clearInterval(interval);
399                $downloadBtn.attr({
400                  href: $('#cboxContent').find('.cboxPhoto').attr('src'),
401                });
402                $('#cboxContent').append($downloadBtn);
403              }
404            }, 500);
405          });
406          break;
407        default:
408          break;
409      }
410
411      // $(document).on('click','.popup-download-photos-button',function() {
412      // 	var href = $(this).attr('href'),
413      // 		url = window.sggHelperajax_url+'?action='+window.sggHelperaction_download+'&id='+galleryId+'&size=full';//&image='+$(this).attr('href');
414      // 		link = container.find('a[href="'+href+'"]'),
415      // 		attachment = false;
416      // 	if(link.length) {
417      // 		attachment = link.attr('data-attachment-id');
418      // 	}
419      // 	if(attachment) {
420      // 		url += '&attachment='+attachment+'&image='+href;
421      //         window.open(url,'_self');
422      //     }
423      //
424      // 	return false;
425      // });
426    }
427    var sizes = container.attr('data-popup-download-sizes');
428    if (typeof sizes != 'undefined' && sizes !== false) {
429      var galleryId = container.attr('data-gg-id'),
430        downloadSize = 'full',
431        oneSize = true;
432
433      if (sizes.length) {
434        var menuElems = sizes.split('|');
435        if (menuElems.length == 1) {
436          downloadSize = menuElems[0];
437        } else {
438          var menuContent = '<div class="gg-download-wrapper"><div class="gg-download-sizes">';
439          menuElems.push('cancel');
440
441          menuElems.forEach(function (s) {
442            var name = container.attr('data-popup-download-' + s);
443            menuContent += '<a href="#" class="gg-download-size" data-size="' + s + '">' + (typeof name == 'undefined' ? s : name) + '</a>';
444          });
445          oneSize = false;
446        }
447      }
448      $(document).on('click', '.gg-download-button', function () {
449        if (oneSize) {
450          var url = window.sggHelperajax_url + '?action=' + window.sggHelperaction_download + '&id=' + galleryId + '&size=' + downloadSize,
451            attachment = $(this).attr('data-attachment-id');
452          if (attachment) {
453            url += '&attachment=' + attachment;
454            window.open(url, '_self');
455          }
456        } else {
457          var figcaption = $(this).closest('figcaption');
458          if (figcaption.find('.gg-download-sizes').length) {
459            figcaption.find('.gg-download-sizes').show();
460          } else {
461            figcaption.append(menuContent);
462          }
463        }
464        return false;
465      });
466      if (!oneSize) {
467        $(document).on('click', '.gg-download-size', function () {
468          var size = $(this).attr('data-size');
469          if (size != 'cancel') {
470            var url = window.sggHelperajax_url + '?action=' + window.sggHelperaction_download + '&id=' + galleryId + '&size=' + size,
471              button = $(this).closest('figcaption').find('.gg-download-button');
472            if (button.length == 0) return false;
473            var attachment = button.attr('data-attachment-id');
474            if (attachment) {
475              url += '&attachment=' + attachment;
476              window.open(url, '_self');
477            }
478          }
479          $(this).parent().hide();
480          return false;
481        });
482      }
483    }
484  };
485
486  ProGallery.prototype.setPrettyPhotoDownloadBtn = function ($downloadBtn) {
487    $('.pp_content_container').find('.popup-download-photos-button').remove();
488    var interval = setInterval(function () {
489      if (typeof $('.pp_content_container') !== 'undefined') {
490        clearInterval(interval);
491
492        $downloadBtn
493          .attr({
494            href: $('#fullResImage').attr('src'),
495          })
496          .css({
497            bottom: '3px',
498            position: 'relative',
499          });
500        $('.pp_content_container').append($downloadBtn);
501      }
502    }, 500);
503  };
504
505  ProGallery.prototype.setPhotoboxDownloadBtn = function ($downloadBtn) {
506    $('.pbWrapper').find('.popup-download-photos-button').remove();
507    var interval = setInterval(function () {
508      if (typeof $('.pbWrapper') !== 'undefined') {
509        clearInterval(interval);
510
511        $downloadBtn
512          .attr({
513            href: $('.pbWrapper').find('img').attr('src'),
514          })
515          .css({
516            bottom: '75px',
517          });
518        $('.pbWrapper').append($downloadBtn);
519      }
520    }, 500);
521  };
522
523  ProGallery.prototype.initCategoriesButtons = function () {
524    var $navigation = this.$navigation,
525      $elements = $navigation.find('a'),
526      $defaultBackground = $elements.first().css('background-color'),
527      $background;
528
529    if (this.$navigation.data('custom-buttons')) {
530      this.initButtonStyles($elements, $navigation.data('font'), function () {
531        $navigation.css({
532          opacity: '1',
533          transition: 'all 0.5s ease-out',
534        });
535      });
536    } else {
537      // Old
538      $background = this.shadeColor('#' + this.rgb2hex($elements.first().css('borderTopColor')), 0.3);
539      this.$navigation.find('a').on('click', function (event) {
540        event.preventDefault();
541        $elements.css('background-color', $defaultBackground);
542        $(event.currentTarget).css('background-color', $background);
543      });
544    }
545  };
546
547  var showMorePause = false;
548
549  ProGallery.prototype.initCategories = function () {
550    this.initCategoriesButtons();
551
552    this.$navigation.find('a').on(
553      'click',
554      $.proxy(function (event) {
555        event.preventDefault();
556        var $category = $(event.currentTarget).parent().find('a.active'),
557          requested = [],
558          _defaultTag = '__all__',
559          self = this,
560          currentGallery = this.$navigation.parent().attr('id');
561
562        $category.each(function () {
563          requested.push(String($(this).data('tag')));
564        });
565
566        var aTagClick = false;
567        if (this.$navigation.parent().data('show-more-enabled')) {
568          aTagClick = true;
569          if (!showMorePause) {
570            self.showMore(aTagClick);
571            showMorePause = true;
572          }
573          setTimeout(function () {
574            showMorePause = false;
575          }, 1000);
576        }
577
578        if (requested.length == 1 && requested[0] == _defaultTag) {
579          this.$elements.each(function () {
580            var $parent = $(this).parent();
581
582            if ($parent.attr('data-rel')) {
583              $parent.attr('data-rel', 'prettyPhoto[' + currentGallery + ']');
584            } else if ((self.$container.data('captionBuider') == 1 && self.$container.data('caption-builder-icons') == 1) || (self.$container.data('captionBuider') != 1 && self.$container.data('icons') != false)) {
585              var $aLink = $(this).find('a');
586              if ($aLink.attr('data-rel')) {
587                $aLink.attr('data-rel', 'prettyPhoto[' + currentGallery + ']');
588              }
589            }
590
591            if ($parent.hasClass('pbox') || $parent.hasClass('gg-colorbox')) {
592              $parent.fadeIn();
593            }
594          });
595          this.$elements.fadeIn();
596          self.initWookmark();
597          $.when(this.$elements.fadeIn()).done(function () {
598            self.correctMargin();
599            //self.initWookmark();
600            //$(event.target).trigger('change.category');
601            self.initPopup();
602            self.initVideoPopup();
603            self.initLinkedImages();
604
605            if (!self.isFluidHeight() && self.$qsEnable) {
606              self.callQuicksand(self.$qsHolder, self.$qsData, self.$qsDuration);
607            }
608            self.initMosaicGalleryType();
609          });
610          return false;
611        }
612
613        if (!this.isFluidHeight() && this.$qsEnable) {
614          var $filteredData = this.$qsData.filter(function () {
615            var tags = $(this).children().data('tags');
616            if (typeof tags !== 'undefined') {
617              tags = tags.toString().split('|');
618            }
619            for (var i = 0; i < requested.length; i++) {
620              if ($.inArray(requested[i], tags) > -1) return true;
621            }
622            self.initMosaicGalleryType();
623            return false;
624          });
625          this.callQuicksand(this.$qsHolder, $filteredData, this.$qsDuration);
626        } else {
627          var activeTags = requested.join(','),
628            resultType = this.$navigation.data('multiselect-results');
629
630          $hidden = $();
631          $visible = $();
632          this.$elements.each(function () {
633            var $element = $(this),
634              tags = $element.data('tags'),
635              $parent = $element.parent();
636
637            if (typeof tags != 'string') {
638              tags = String(tags);
639            }
640
641            if (tags != undefined) {
642              tags = tags.toString().split('|');
643            }
644            var foundTag = null,
645              i;
646            switch (resultType) {
647              case 'all_selected':
648                for (i = 0; i < requested.length; i++) {
649                  var categorySorted = requested;
650                  if (!arraysEqual(categorySorted.sort(), tags.sort())) {
651                    foundTag = false;
652                    break;
653                  } else {
654                    foundTag = true;
655                  }
656                }
657                break;
658              default:
659                for (i = 0; i < tags.length; i++) {
660                  if ($.inArray(tags[i], requested) > -1) {
661                    foundTag = tags[i];
662                    break;
663                  }
664                }
665                break;
666            }
667            if (foundTag) {
668              if ($parent.attr('data-rel')) {
669                $parent.attr('data-rel', 'prettyPhoto[' + currentGallery + '-' + activeTags + ']');
670              } else if ((self.$container.data('captionBuider') == 1 && self.$container.data('caption-builder-icons') == 1) || (self.$container.data('captionBuider') != 1 && self.$container.data('icons') != false)) {
671                var $aLink = $(this).find('a');
672                if ($aLink.attr('data-rel')) {
673                  $aLink.attr('data-rel', 'prettyPhoto[' + currentGallery + '-' + activeTags + ']');
674                }
675              }
676
677              if ($parent.hasClass('pbox') || $parent.hasClass('gg-colorbox')) {
678                $visible.push($parent[0]);
679              } else {
680                $visible.push(this);
681              }
682            } else {
683              if ($parent.hasClass('pbox') || $parent.hasClass('gg-colorbox')) {
684                $hidden.push($parent[0]);
685              } else {
686                $hidden.push(this);
687              }
688            }
689          });
690
691          $.when($hidden.fadeOut()).done(function () {
692            $visible.fadeIn().css({ height: '' });
693            if (self.$container.data('gridType') == 1) {
694              $visible.closest('a.gg-link[data-type="link"]').css('display', 'inline-block');
695              $hidden.closest('a.gg-link[data-type="link"]').css('display', 'none');
696            }
697            self.correctMargin();
698            self.initWookmark();
699            self.initPopup();
700            self.initVideoPopup();
701            self.initLinkedImages();
702            //$(event.target).trigger('change.category');
703            self.lazyLoadTriggerHandler();
704            self.initMosaicGalleryType();
705            $visible.find('figure').css({ height: '' });
706          });
707        }
708
709        setTimeout(function () {
710          jQuery(window).trigger('resize');
711        }, 1000);
712      }, this)
713    );
714
715    if (!window.location.hash) {
716      this.selectFirstCategory();
717    }
718  };
719
720  ProGallery.prototype.initPaginationButtons = function () {
721    var $navigation = this.pagination.$wrapper;
722    var $elements = $navigation.find('a.grid-gallery-page');
723
724    if (this.pagination.$wrapper.data('custom-buttons')) {
725      this.initButtonStyles($elements, this.pagination.$wrapper.data('font'), function () {
726        $navigation.css({
727          opacity: '1',
728          transition: 'all 0.5s ease-out',
729        });
730      });
731    } else {
732      // Old
733      this.pagination.$wrapper.find('a.grid-gallery-page').on('click', function (event) {
734        event.preventDefault();
735        $elements.css('font-size', 'inherit');
736        $(this).css('font-size', '19pt');
737      });
738    }
739  };
740
741  ProGallery.prototype.initPagination = function (all) {
742    var all = typeof all == 'undefined' ? true : all;
743    if (all) {
744      this.initPaginationButtons();
745    }
746    this.buffer = [];
747
748    var perPage = parseInt(this.$container.find('.grid-gallery-photos').data('per-page'), 10),
749      buffer = this.buffer,
750      page = 1,
751      offset = 0,
752      $elements = this.$elements,
753      self = this;
754
755    if (isNaN(perPage)) {
756      this.$elements.fadeIn();
757      return false;
758    }
759
760    if (this.$container.data('gridType') == 4 && this.$container.data('show-mosaic-all-img') != 1) {
761      this.$elements.fadeIn();
762      this.pagination.wrapper.hide();
763      return false;
764    }
765
766    var showCurrentPage = function (page) {
767      $.when($elements.removeClass('current-page').hide().parent('a').hide()).done(function () {
768        $(buffer[page])
769          .addClass('current-page')
770          .css({ height: self.$container.data('height'), width: self.$container.data('width') })
771          .fadeIn()
772          .parent('a')
773          .show();
774        self.initWookmark();
775        if (self.afterInitFlag) {
776          self.correctMargin();
777          self.initPopup();
778          self.initVideoPopup();
779        }
780        self.initMosaicGalleryType();
781      });
782    };
783
784    this.pagination.limit = perPage;
785
786    // Create buffer
787    var viewIndex = 0;
788    $elements
789      .each(
790        $.proxy(function (index, el) {
791          if (all || $(el).closest('a.gg-link').hasClass('hidden-item') == false) {
792            if (all) {
793              var currentIndex = index + 1;
794            } else {
795              viewIndex++;
796              var currentIndex = viewIndex;
797            }
798            if (currentIndex - offset <= this.pagination.limit) {
799              if (!$.isArray(buffer[page])) {
800                buffer[page] = [];
801              }
802              buffer[page].push(el);
803            } else {
804              offset += this.pagination.limit;
805              page += 1;
806
807              buffer[page] = [el];
808            }
809          }
810        }, this)
811      )
812      .hide();
813
814    if (!all) {
815      $buttons = this.pagination.$wrapper;
816      $buttons.find('a.grid-gallery-page:not(.gg-prev-pagination-btn, .gg-next-pagination-btn)').css('display', 'none');
817      $.each(buffer, function (page, els) {
818        $buttons.find('a.grid-gallery-page[data-page="' + page + '"]').css('display', 'inline-block');
819      });
820    }
821
822    this.pagination.$wrapper
823      .find('a.grid-gallery-page')
824      .off('click.pagination')
825      .on('click.pagination', function (event) {
826        event.preventDefault();
827        if (self.$container.data('use-pagination-prev-next') == 1 && $('.grid-gallery-page.gg-prev-pagination-btn').length && $('.grid-gallery-page.gg-next-pagination-btn').length) {
828          showCurrentPage($('.grid-gallery-pagination-wrap').attr('data-page'));
829        } else {
830          showCurrentPage($(event.currentTarget).attr('data-page'));
831        }
832      });
833
834    this.pagination.$wrapper.find('a.grid-gallery-page:not(.gg-prev-pagination-btn)').first().trigger('click');
835    //bug fixed for pagination
836    setTimeout(function () {
837      self.initWookmark();
838    }, 500);
839  };
840
841  ProGallery.prototype.initInfiniteScroll = function () {
842    if (!this.$container.is('[data-show-more-amount]') || this.InfinityScrollIsInitialized) {
843      return;
844    }
845    // for Mosaic gallery type
846    if (this.$container.data('gridType') == 4 && this.$container.attr('data-useMosaic2Layout') != 1) {
847      return;
848    }
849
850    this.InfinityScrollIsInitialized = true;
851
852    var self = this,
853      $showMoreButton = this.$container.find('.showMore');
854
855    this.initButtonStyles($showMoreButton, $showMoreButton.data('font'), null, true);
856
857    if (self.$elements.length < $showMoreButton.data('total') || !$showMoreButton.data('total')) {
858      $showMoreButton.show();
859    }
860
861    $showMoreButton.after($('<span class="showMoreLoading">' + self.loadingText + '</span>').css('display', 'none'));
862
863    $showMoreButton.on('click', function (event) {
864      event.preventDefault();
865      self.showMore();
866    });
867
868    function onScrollHandler() {
869      var scroll = true;
870      self.showMore(false, scroll);
871    }
872
873    if (this.$container.data('show-more-scroll')) {
874      $(window).on('scroll', onScrollHandler);
875    }
876  };
877
878  ProGallery.prototype.showMore = function (aTagClick, scroll) {
879    aTagClick = typeof aTagClick == 'undefined' ? false : aTagClick;
880    scroll = typeof scroll == 'undefined' ? false : scroll;
881
882    var $lastGalleryCaption = $('.grid-gallery-caption:last');
883    var breakpoint = $lastGalleryCaption.length ? $lastGalleryCaption.offset().top : 0;
884
885    if (scroll) {
886      //previous load not completed
887      if (this.scrollInProgress) {
888        return;
889      }
890      //load new images if needed
891      if (!(window.pageYOffset + window.innerHeight > breakpoint - window.innerHeight * 2)) {
892        return;
893      }
894    }
895
896    var categories = $('.grid-gallery-nav a'),
897      pickedOutCategories = [],
898      activeCategory = [],
899      self = this,
900      isLazyLoad = this.$container.data('lazyload-enable') == '1',
901      $showMoreButton = this.$container.find('.showMore'),
902      $photoWrapper = this.$container.find('.grid-gallery-photos');
903
904    $.each(categories, function (index, item) {
905      if ($(item).hasClass('active')) {
906        activeCategory.push($(item).data('tag'));
907      }
908    });
909
910    var limit = aTagClick ? this.$container.data('show-more-img-first-load') : this.$container.data('show-more-amount');
911
912    if (aTagClick) {
913      $photoWrapper.find('*').not('.grid-gallery-clearfix').remove();
914    }
915
916    var request = {
917      action: window.sggHelperaction,
918      gallery_id: this.$container.data('id'),
919      limit: limit,
920      except: '',
921      category: '',
922      posts_except: '',
923      offset: 0,
924    };
925
926    function showMore() {
927      var except = [],
928        except_posts = [];
929
930      self.scrollInProgress = true;
931      request.category = '';
932
933      if (activeCategory.length) {
934        request.category = activeCategory.join(',');
935      }
936      //if click on category a tags no need except
937      if (!aTagClick) {
938        $.each(self.$elements, function (index, element) {
939          if (typeof $(element).data('id') !== 'undefined' && $(element).is(':visible')) {
940            except.push($(element).data('id'));
941          }
942
943          if (typeof $(element).data('post-id') !== 'undefined' && $(element).is(':visible')) {
944            except_posts.push($(element).data('post-id'));
945          }
946        });
947        request.except = except.join(',');
948        request.except_posts = except_posts.join(',');
949        request.offset++;
950      }
951
952      updateImages(request, function (response) {
953        if (response.success) {
954          $showMoreButton.next('.showMoreLoading').hide();
955          var $elements = $($.parseHTML(response.images.trim()));
956          if (!aTagClick) {
957            self.$container.find('.grid-gallery-photos > *').not('.grid-gallery-clearfix').last().after($elements);
958          } else {
959            self.$container.find('.grid-gallery-photos').prepend($elements);
960          }
961
962          self.$container.imagesLoaded(function () {
963            $.merge(self.$elements, $elements.find('figure.grid-gallery-caption').addBack().not($('.post, .gg-link')).fadeIn());
964
965            if (($elements.length < request.limit && response.remaining === 0) || (response.remaining === 0 && response.remaining_posts == 0)) {
966              $showMoreButton.hide();
967              if (request.category) {
968                pickedOutCategories.push(request.category);
969              } else {
970                $.each(categories, function (index, item) {
971                  pickedOutCategories.push($(item).data('tag'));
972                });
973                // console.log('off scroll');
974                // $(window).off('scroll', onScrollHandler);
975                //this.scrollInProgress = true;
976              }
977            } else {
978              if (!aTagClick) {
979                self.$container.one('wookmark.changed', function (event) {
980                  breakpoint = self.$elements.filter(':visible').last().offset().top;
981                });
982              }
983              $showMoreButton.show();
984              self.scrollInProgress = false;
985            }
986            self.reinit();
987            if (isLazyLoad) {
988              self._parent('initLazyLoad');
989              self._parent('lazyLoadDistanceRefresh');
990            }
991            self.initPopup();
992          });
993        }
994      });
995    }
996
997    function updateImages(request, response) {
998      $showMoreButton.add($showMoreButton.next('.showMoreLoading')).toggle();
999      $.post(window.sggHelperajax_url, request, response);
1000    }
1001
1002    showMore();
1003  };
1004
1005  ProGallery.prototype.initVideoPopup = function (download) {
1006    if (!this.$container.find('[data-video-source]').length && typeof download === 'undefined') {
1007      return;
1008    }
1009
1010    function loadApi(src) {
1011      var tag = document.createElement('script');
1012      tag.src = src;
1013      var firstScriptTag = document.getElementsByTagName('script')[0];
1014      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
1015    }
1016
1017    function createYouTubePlayer(options) {
1018      player = new YT.Player(options.node, {
1019        startFrom: options.start || 0,
1020        width: options.width || '853',
1021        height: options.height || '480',
1022        videoId: options.videoId,
1023        playerVars: options.params,
1024        events: {
1025          onReady:
1026            options.onReady ||
1027            function (event) {
1028              if (popupSettings.autoplay === 'true') {
1029                event.target.playVideo();
1030              }
1031            },
1032          onStateChange: options.onStateChange,
1033        },
1034      });
1035      return player;
1036    }
1037
1038    //HTML5 Player http://www.w3schools.com/tags/ref_av_dom.asp
1039    function createHTML5Player(src, $playerBox, endfunc, frame) {
1040      var $player = $(document.createElement('video')),
1041        $source = $(document.createElement('source')),
1042        videoWidth = Number(popupSettings.width || '853'),
1043        videoHeight = Number(popupSettings.height || '480'),
1044        onEndAction = Number(popupSettings.onEnd || 0);
1045
1046      //Init
1047      $source.attr('src', src);
1048      $player.attr('controls', 'controls');
1049      $player.attr('width', videoWidth);
1050
1051      if (window.innerWidth > videoWidth) {
1052        $player.attr('height', videoHeight);
1053        $player.css('margin-bottom', '0px');
1054      }
1055      if (popupSettings.autoplay == 'true') {
1056        $player.attr('autoplay', 'autoplay');
1057      }
1058      $player.append($source);
1059
1060      if (frame && frame != null) {
1061        $playerBox.contents().find('body').html($player);
1062      } else {
1063        $playerBox.html($player);
1064      }
1065
1066      //Controll
1067      $player.on('click', function () {
1068        if (this.paused) {
1069          this.play();
1070        } else {
1071          this.pause();
1072        }
1073      });
1074      $player.on('ended', endfunc);
1075      return $player;
1076    }
1077
1078    if ($('[data-video-source="youtube"]').length > 0) {
1079      loadApi('//www.youtube.com/iframe_api');
1080    }
1081
1082    if ($('[data-video-source="vimeo"]').length > 0) {
1083      loadApi('https://player.vimeo.com/api/player.js');
1084    }
1085
1086    var $videoIframe,
1087      isVideo,
1088      videoSource,
1089      videoId,
1090      popupType = this.$container.data('popup-type'),
1091      popupRel = this.$container.attr('id'),
1092      popupSettings = this.$container.data('popup-video') || {},
1093      videoWidth = Number(popupSettings.width || '853'),
1094      videoHeight = Number(popupSettings.height || '480'),
1095      onEndAction = Number(popupSettings.onEnd || 0),
1096      youTubeRegExp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/,
1097      slidePlay = this.$container.data('popup-slideshow') === true,
1098      slidePlayAuto = slidePlay && this.$container.data('popup-slideshow-auto') === true,
1099      popupHoverStop = slidePlay && this.$container.data('popup-hoverstop') === true,
1100      isLazyLoad = this.$container.data('lazyload-enable') == '1',
1101      self = this;
1102
1103    if (popupType == 'colorbox') {
1104      $('<style type="text/css">.video > .pbWrapper > div { width: ' + videoWidth + 'px; height: ' + videoHeight + 'px; } #cboxLoadedContent iframe { margin: 0; padding: 0;}</style>').appendTo('head');
1105
1106      function colorBoxVideoEnd() {
1107        if (onEndAction > 0) {
1108          if (onEndAction === 1) {
1109            $.colorbox.next();
1110          } else if (onEndAction === 2) {
1111            $.colorbox.close();
1112          }
1113        }
1114      }
1115
1116      if (videoWidth > window.innerWidth) {
1117        videoWidth = '90%';
1118      }
1119
1120      this.$colorbox = this.$container.find('.gg-video:visible').colorbox({
1121        iframe: true,
1122        fadeOut: this.$container.data('popup-fadeOut'),
1123        fixed: true,
1124        scrolling: false,
1125        scalePhotos: true,
1126        innerWidth: videoWidth,
1127        innerHeight: videoHeight,
1128        maxWidth: '90%',
1129        returnFocus: false,
1130        slideshow: this.$container.data('popup-slideshow'),
1131        slideshowAuto: this.$container.data('popup-slideshow-auto'),
1132        slideshowSpeed: this.$container.data('popup-slideshow-speed'),
1133        rel: popupRel,
1134        slideshowStart: self.popupTranslates.start_slideshow,
1135        slideshowStop: self.popupTranslates.stop_slideshow,
1136        current: self.popupTranslates.image + ' {current} ' + self.popupTranslates.of + ' {total}',
1137        previous: self.popupTranslates.previous,
1138        next: self.popupTranslates.next,
1139        close: self.popupTranslates.close,
1140        title: function () {
1141          return self.getPopupTitle($(this));
1142        },
1143        onLoad: function () {
1144          videoSource = $(this).data('video-source');
1145          $('#cboxContent').find('.popup-download-photos-button').remove();
1146        },
1147        onComplete: function (e) {
1148          self.changePopUpHash($(e.el).attr('id') || $(e.el).attr('data-id'));
1149          self.addSocialShareToPopUp($(e.el), $('#cboxContent'), 'popup');
1150          // $('#colorbox').css('padding', '0px');
1151          $('#cboxLoadedContent').css('opacity', 0);
1152          $('#cboxLoadingGraphic').show();
1153          $videoFrame = $('#cboxLoadedContent iframe');
1154          $videoFrameWrapper = $videoFrame.parent();
1155          if (videoSource == 'youtube') {
1156            if ($videoFrameWrapper.attr('data-iframe') === 'original_frame') {
1157              var width = $videoFrame.parent().width(),
1158                height = Math.round((width / 16) * 9);
1159              $videoFrame.css({ width: width, height: height });
1160
1161              $('#cboxLoadingGraphic').hide();
1162              $('#cboxLoadedContent').css({
1163                opacity: 1,
1164                overflow: 'hidden',
1165                transition: 'all 0.4s',
1166              });
1167            } else {
1168              $videoFrame.stop();
1169              $('<div/>', { id: 'sgg-youtube-player' }).insertBefore($videoFrame);
1170
1171              var width = $videoFrame.parent().width() - 4,
1172                height = Math.round((width / 16) * 9);
1173
1174              var startWith = typeof self.savedColorBoxVideoStartTime != 'undefined' ? self.savedColorBoxVideoStartTime : 0;
1175              self.currentVideoPlayer = createYouTubePlayer({
1176                startFrom: startWith,
1177                node: 'sgg-youtube-player',
1178                videoId: $(this).attr('href').match(youTubeRegExp) ? $(this).attr('href').match(youTubeRegExp)[1] : '',
1179                params: $(this)
1180                  .attr('href')
1181                  .match(/[\?&]rel=0/i)
1182                  ? { rel: 0 }
1183                  : {},
1184                onReady: function (event) {
1185                  $('#cboxLoadingGraphic').hide();
1186                  $('#cboxLoadedContent').css({
1187                    opacity: 1,
1188                    overflow: 'hidden',
1189                    transition: 'all 0.4s',
1190                  });
1191                  if (popupSettings.autoplay === 'true' || startWith) {
1192                    if (startWith) {
1193                      event.target.seekTo(startWith);
1194                    }
1195                    event.target.playVideo();
1196                  }
1197                },
1198                width: width,
1199                height: height,
1200                onStateChange: function (event) {
1201                  if (event.data === 0) {
1202                    colorBoxVideoEnd();
1203                  }
1204                  if (event.data === 1) {
1205                    $('.pp_nav a.pp_play').addClass('stop');
1206                    $('.pp_nav a.pp_pause').addClass('stop');
1207                  } else {
1208                    $('.pp_nav a.pp_play').removeClass('stop');
1209                    $('.pp_nav a.pp_pause').removeClass('stop');
1210                  }
1211                },
1212              });
1213              $videoFrame.remove();
1214            }
1215          }
1216
1217          if (videoSource == 'vimeo') {
1218            var player = new Vimeo.Player($videoFrame[0]); //$f($videoFrame[0]);
1219            self.currentVideoPlayer = player;
1220            player.ready().then(function () {
1221              $('#cboxLoadingGraphic').hide();
1222              $('#cboxLoadedContent').css({
1223                opacity: 1,
1224                overflow: 'hidden',
1225                transition: 'all 0.4s',
1226              });
1227              if (popupSettings.autoplay === 'true') {
1228                player.play().catch(function (error) {
1229                  console.error('error playing the video:', error.name);
1230                });
1231              }
1232              player.on('ended', colorBoxVideoEnd);
1233            });
1234          }
1235
1236          if (videoSource == 'other') {
1237            createHTML5Player($('#cboxLoadedContent iframe').attr('src'), $('#cboxLoadedContent'), colorBoxVideoEnd);
1238            $('#cboxLoadingGraphic').hide();
1239            $('#cboxLoadedContent').css({
1240              opacity: 1,
1241              overflow: 'hidden',
1242              transition: 'all 0.4s',
1243            });
1244          }
1245
1246          var width = $videoFrame.parent().width(),
1247            height = Math.round((width / 16) * 9);
1248
1249          if ($videoFrameWrapper.attr('data-iframe') !== 'original_frame') {
1250            $.colorbox.resize({ width: width, height: height });
1251          }
1252        },
1253        onClosed: function () {
1254          self.clearPopUpHash();
1255        },
1256      });
1257
1258      // need because after change category "theme class" disapearing
1259      $('#cboxOverlay')
1260        .removeClass()
1261        .addClass(self.$container.data('popup-theme') + '-overlay');
1262      $('#colorbox').removeClass().addClass(self.$container.data('popup-theme'));
1263    }
1264
1265    if (popupType == 'pretty-photo') {
1266      function prettyPhotoVideoEnd() {
1267        if (onEndAction > 0 && self.$prettyPhoto) {
1268          if (onEndAction === 1) {
1269            self.$prettyPhoto.changePage('next');
1270          } else if (onEndAction === 2) {
1271            self.$prettyPhoto.close();
1272          }
1273        }
1274      }
1275
1276      if (this.$container.attr('data-show-buttonlink-in-popup') == 1) {
1277        this.loadButtonsFontFamily(this.$container.attr('data-buttonlink-font'), null);
1278      }
1279
1280      var findPrettyItems =
1281        typeof download !== 'undefined'
1282          ? this.$container.find(".grid-gallery-photos > a[data-rel^='prettyPhoto'], .grid-gallery-photos .hi-icon-wrap > a[data-rel^='prettyPhoto'], .grid-gallery-photos .gg-mosaic-wrapper a[data-rel^='prettyPhoto']")
1283          : this.$container.find(".grid-gallery-photos > a[data-rel^='prettyPhoto'], .grid-gallery-photos .hi-icon-wrap > a[data-rel^='prettyPhoto']");
1284
1285      this.$prettyPhoto = findPrettyItems.ggPrettyPhoto({
1286        hook: 'data-rel',
1287        theme: 'light_square',
1288        default_width: this.popupMaxWidth,
1289        default_height: this.popupMaxHeight,
1290        default_movie_width: popupSettings.width || '853',
1291        default_movie_height: popupSettings.height || '480',
1292        allow_resize: true,
1293        allow_expand: false,
1294        slideshow: this.$container.data('popup-slideshow-speed'),
1295        autoplay_slideshow: this.$container.data('popup-slideshowAuto'),
1296        social_tools: '',
1297        deeplinking: false,
1298        // callback: function() {},
1299        is_lazy_load: isLazyLoad,
1300        ppTranslates: self.popupTranslates,
1301        isDisableRightClick: this.$container.attr('data-disable-right-click') == 'true',
1302        isShowRotateBtn: this.$container.attr('data-show-rotate-btn-in-popup') == 1,
1303        isShowAttributes: this.$container.attr('data-show-attributes-in-popup') == 1,
1304        attributesPosition: this.$container.attr('data-attributes-position'),
1305        attributesWidth: this.$container.attr('data-attributes-width'),
1306        isShowButtonLink: this.$container.attr('data-show-buttonlink-in-popup') == 1,
1307        buttonLinkStyle: this.$container.attr('data-buttonlink-style'),
1308        isShowLinkBtn: this.$container.attr('data-show-link-btn-in-popup') == 1,
1309        isShowHovThumbnail: this.$container.attr('data-show-thumb-hov-in-popup') == 1,
1310        galleryId: this.$container.attr('data-gg-id'),
1311        getImageDimensions: this.popupImageDimension,
1312        setImageTitleForPrepare: function ($element) {
1313          var imgTile = self.getPopupTitle($element);
1314          return imgTile;
1315        },
1316        changepicturecallback: function (element) {
1317          self.changePopUpHash(element.attr('id') || element.attr('data-id'));
1318          self.popup_opened_image = element;
1319          $('.pp_description').html(self.getPopupTitle(element)).show();
1320
1321          //hide thumbnails on video popup and show it on image popup
1322          isVideo = $(element).is('[data-video-source]');
1323          if (isVideo) {
1324            $('.pp_content_container').find('.popup-download-photos-button').remove();
1325            self.addSocialShareToPopUp(element, $('#pp_full_res'), 'popup prettyPhoto');
1326            $('.pp_gallery').hide();
1327          } else {
1328            self.addSocialShareToPopUp(element, $('.pp_hoverContainer'), 'popup');
1329            $('.pp_gallery').show();
1330          }
1331
1332          if (self.$container.attr('data-show-attributes-in-popup') == 1) {
1333            window.prettyPhotoAttributes(element, self.$container);
1334          }
1335
1336          //Enable/Disable stop slideshow on mouse hover
1337          if (popupHoverStop) {
1338            $('.pp_fade').hover(
1339              function () {
1340                $('.pp_nav .pp_pause').click();
1341              },
1342              function () {
1343                if (slidePlayAuto) {
1344                  $('.pp_nav .pp_play').click();
1345                }
1346              }
1347            );
1348          }
1349
1350          videoSource = $(element).data('video-source');
1351          $videoFrame = $('#pp_full_res iframe');
1352
1353          if (!slidePlay) {
1354            $('.pp_play').hide();
1355          }
1356
1357          if (videoSource == 'youtube') {
1358            var frameHtml = htmlDecode($(element).attr('href'));
1359
1360            if (frameHtml.match(/<iframe(.+)<\/iframe>/i)) {
1361              var frameWrapper = $('#pp_full_res');
1362              frameWrapper.html(frameHtml);
1363              frameWrapper.$videoFrame.attr('width');
1364              frameWrapper.$videoFrame.attr('height');
1365            } else {
1366              $videoFrame.stop();
1367              var videoSrc = $videoFrame.attr('src');
1368              videoId = videoSrc.match(youTubeRegExp)[1];
1369              var $newFrame = $('<div/>', { id: 'sgg-youtube-player' }).insertBefore($videoFrame);
1370              createYouTubePlayer({
1371                node: 'sgg-youtube-player',
1372                videoId: videoId,
1373                width: $videoFrame.attr('width'),
1374                height: $videoFrame.attr('height'),
1375                params: videoSrc.match(/[\?&]rel=0/i) ? { rel: 0 } : {},
1376                onStateChange: function (event) {
1377                  if (event.data === 0) {
1378                    prettyPhotoVideoEnd();
1379                  }
1380                  if (event.data === 1) {
1381                    $('.pp_nav a.pp_play').addClass('stop');
1382                    $('.pp_nav a.pp_pause').addClass('stop');
1383                  } else {
1384                    $('.pp_nav a.pp_play').removeClass('stop');
1385                    $('.pp_nav a.pp_pause').removeClass('stop');
1386                  }
1387                },
1388              });
1389              $videoFrame.remove();
1390            }
1391          }
1392
1393          if (videoSource == 'vimeo') {
1394            var player = new Vimeo.Player($videoFrame[0]);
1395            player.ready().then(function () {
1396              if (popupSettings.autoplay === 'true') {
1397                player.play().catch(function (error) {
1398                  console.error('error playing the video:', error.name);
1399                });
1400              }
1401              player.on('ended', prettyPhotoVideoEnd);
1402            });
1403          }
1404
1405          if (videoSource == 'other') {
1406            createHTML5Player($('#pp_full_res source').attr('src'), $('#pp_full_res'), prettyPhotoVideoEnd);
1407          }
1408          var $_desc = $('.pp_description'),
1409            desc_height = parseInt($_desc.height()),
1410            desc_line_height = parseInt($_desc.css('font-size'));
1411          if (desc_line_height < desc_height) {
1412            $('.pp_content').height($('.pp_content').height() + desc_height - desc_line_height);
1413          }
1414
1415          if (typeof download !== 'undefined' && !videoSource) {
1416            self.setPrettyPhotoDownloadBtn(download);
1417          }
1418        },
1419        callback: function () {
1420          self.popup_opened_image = false;
1421          self.clearPopUpHash();
1422        },
1423      });
1424    }
1425
1426    if (popupType == 'photobox') {
1427      var photoBoxConfig = null;
1428
1429      $('<style type="text/css">.video > .pbWrapper > div { width: ' + videoWidth + 'px; height: ' + videoHeight + 'px; }</style>').appendTo('head');
1430
1431      $('#pbOverlay .prevNext').on('click', function () {
1432        self.setPhotoboxMobileArrowPosition(1);
1433      });
1434
1435      function photoBoxVideoEnd() {
1436        if (onEndAction > 0) {
1437          if (onEndAction === 1) {
1438            $('#pbNextBtn').trigger('click');
1439          } else if (onEndAction === 2) {
1440            $('#pbCloseBtn').trigger('click');
1441          }
1442        }
1443      }
1444
1445      $(window).on('resize', function () {
1446        if (videoWidth > window.innerWidth) {
1447          $('.pbWrapper .zoomable').attr('style', 'width: ' + window.innerWidth * 0.8 + 'px; height: ' + ((window.innerWidth * 0.8) / 4) * 3 + 'px;');
1448          $('img.zoomable').removeAttr('style');
1449        }
1450        clearTimeout(window.photoBoxResizeTimeout);
1451        window.photoBoxResizeTimeout = setTimeout(function () {
1452          if ($('#pbOverlay').hasClass('thumbs') && window.screen.width < 900) {
1453            $('#pbOverlay').width(window.screen.width);
1454            $('#pbOverlay').height(window.screen.height);
1455            $(document).scrollLeft(0);
1456          }
1457          var $videoFrame = $('#pbOverlay .pbWrapper iframe');
1458          if ($videoFrame.length > 0) {
1459            if ($videoFrame.width() > window.screen.width) {
1460              $videoFrame.parent().css({
1461                width: window.screen.width,
1462                height: '100%',
1463              });
1464            }
1465            if ($videoFrame.height() > window.screen.height) {
1466              $videoFrame.parent().css({
1467                height: window.screen.height,
1468                width: '100%',
1469              });
1470            }
1471          }
1472        }, 100);
1473      });
1474
1475      this.$container.find('.grid-gallery-photos').photobox('destroy');
1476      photoBoxConfig = {
1477        autoplay: this.$container.data('popup-slideshowAuto'),
1478        beforeShow: function (element) {
1479          self.changePopUpHash($(element).attr('id') || $(element).attr('data-id'));
1480          self.addSocialShareToPopUp($(element), $('#pbCaption'), 'photobox', true);
1481          videoSource = $(element).data('video-source');
1482
1483          if (typeof download !== 'undefined' && !videoSource) {
1484            self.setPhotoboxDownloadBtn(download);
1485          } else {
1486            $('.pbWrapper').find('.popup-download-photos-button').remove();
1487          }
1488        },
1489        afterClose: function () {
1490          $('#pbOverlay .pbWrapper iframe').remove();
1491          self.clearPopUpHash();
1492        },
1493        getTitle: function (el) {
1494          return self.getPopupTitle($(el));
1495        },
1496        thumb: function (link) {
1497          if (self.$container.data('caption-buider') == '1' && self.$container.data('caption-builder-icons') == 1) {
1498            return link.closest('.grid-gallery-caption').find('img')[0];
1499          } else if (self.$container.data('icons')) {
1500            return link.closest('.grid-gallery-caption').find('img')[0];
1501          }
1502          return null;
1503        },
1504      };
1505      if (isLazyLoad) {
1506        photoBoxConfig['thumbAttr'] = 'data-gg-real-image-href';
1507      }
1508
1509      this.$container.find('.grid-gallery-photos').photobox('a.pbox', photoBoxConfig, function (event) {
1510        var $videoFrame = $('#pbOverlay .pbWrapper iframe');
1511        $videoFrameWrapper = $videoFrame.parent();
1512        if (videoSource == 'youtube') {
1513          if ($videoFrameWrapper.attr('data-iframe') !== 'original_frame') {
1514            $videoFrame.stop();
1515            var videoSrc = $videoFrame.attr('src');
1516            videoId = videoSrc.match(youTubeRegExp)[1];
1517            $('<div/>', { id: 'youtube-player' }).insertBefore($videoFrame);
1518            $videoFrame.remove();
1519            createYouTubePlayer({
1520              node: 'youtube-player',
1521              videoId: videoId,
1522              params: videoSrc.match(/[\?&]rel=0/i) ? { rel: 0 } : {},
1523              onReady: function (event) {
1524                $(window).trigger('resize');
1525                if (popupSettings.autoplay === 'true') {
1526                  event.target.playVideo();
1527                }
1528              },
1529              onStateChange: function (event) {
1530                if (event.data === 0) {
1531                  photoBoxVideoEnd();
1532                }
1533                // arrows visibility for mobile
1534                if (event.data == 1) {
1535                  self.setPhotoboxMobileArrowPosition(0);
1536                } else {
1537                  self.setPhotoboxMobileArrowPosition(1);
1538                }
1539                if (event.data === 1) {
1540                  $('.pp_nav a.pp_play').addClass('stop');
1541                  $('.pp_nav a.pp_pause').addClass('stop');
1542                } else {
1543                  $('.pp_nav a.pp_play').removeClass('stop');
1544                  $('.pp_nav a.pp_pause').removeClass('stop');
1545                }
1546              },
1547            });
1548          }
1549        }
1550        if (videoSource == 'vimeo') {
1551          var player = new Vimeo.Player($videoFrame[0]);
1552          player.ready().then(function () {
1553            if (popupSettings.autoplay === 'true') {
1554              $(window).trigger('resize');
1555              player.play().catch(function (error) {
1556                console.error('error playing the video:', error.name);
1557              });
1558            }
1559            player.on('ended', photoBoxVideoEnd);
1560            player.on('play', function (paused) {
1561              self.setPhotoboxMobileArrowPosition(0);
1562            });
1563            player.on('pause', function (paused) {
1564              self.setPhotoboxMobileArrowPosition(1);
1565            });
1566          });
1567        }
1568        if (videoSource == 'other') {
1569          createHTML5Player($videoFrame.attr('src'), $videoFrame, photoBoxVideoEnd, true);
1570          $(window).trigger('resize');
1571        }
1572      });
1573      $(document).on('pboxPreviewClicked', function () {
1574        self.setPhotoboxMobileArrowPosition(1);
1575      });
1576    }
1577  };
1578
1579  ProGallery.prototype.setPhotoboxMobileArrowPosition = function (pos) {
1580    if (this.$container.data('popupType') == 'photobox' && this.$container.data('isMobile') == 1) {
1581      var $arrows = $('#pbOverlay .prevNext');
1582      if (pos == 0) {
1583        $arrows.css('z-index', '0');
1584      } else {
1585        $arrows.css('z-index', '100');
1586      }
1587    }
1588  };
1589
1590  ProGallery.prototype.changeLinkedImageScrollOffset = function (event) {
1591    var $linkedImageObj = $('.linkedImages');
1592
1593    var scrollHeight = parseInt($linkedImageObj.prop('scrollHeight'));
1594    var currScroll = parseInt($linkedImageObj.scrollTop());
1595    var clickOffset = 85;
1596
1597    if (!isNaN(scrollHeight) && !isNaN(currScroll) && event && event.data) {
1598      var newScrollOfsset;
1599      if (event.data.direction == 0) {
1600        newScrollOfsset = currScroll - clickOffset;
1601        if (newScrollOfsset < 0) {
1602          newScrollOfsset = 0;
1603        }
1604      } else {
1605        newScrollOfsset = currScroll + clickOffset;
1606        if (newScrollOfsset > scrollHeight) {
1607          newScrollOfsset = scrollHeight;
1608        }
1609      }
1610      $linkedImageObj.stop(true, true).animate({ scrollTop: newScrollOfsset }, 500);
1611    }
1612  };
1613
1614  ProGallery.prototype.autoChangeLinkImgScrollOffset = function (selItem) {
1615    var $linkedImageObj = $('.linkedImages');
1616    if (selItem.length && selItem[0].offsetTop) {
1617      var wndPaddingTop = 55;
1618      if ($(window).width() < 500) {
1619        wndPaddingTop = 35;
1620      }
1621      var newOffset = parseInt(selItem[0].offsetTop) - wndPaddingTop;
1622      if (!isNaN(newOffset)) {
1623        $linkedImageObj.stop(true, true).animate({ scrollTop: newOffset }, 1000);
1624      }
1625    }
1626  };
1627
1628  ProGallery.prototype.getLinkedImagesContainer = function () {
1629    var $colorBoxObj = $('#colorbox');
1630    var $linkedImagesContainer = $('<div class="linkedImages">')
1631      .css({
1632        position: 'absolute',
1633        right: '0',
1634        bottom: '0',
1635        width: '75px',
1636      })
1637      .appendTo($colorBoxObj);
1638    $colorBoxObj.css('padding-right', '85px');
1639
1640    // add "right": "top arrow" and "bottom arrow"
1641    $('<div class="link-img-arr-top"></div>').appendTo($colorBoxObj);
1642    $('<div class="link-img-arr-bottom"></div>').appendTo($colorBoxObj);
1643    $('#colorbox .link-img-arr-top').on('click', { direction: 0 }, this.changeLinkedImageScrollOffset);
1644    $('#colorbox .link-img-arr-bottom').on('click', { direction: 1 }, this.changeLinkedImageScrollOffset);
1645    return $linkedImagesContainer;
1646  };
1647
1648  ProGallery.prototype.initColorBoxOnLoadHandler = function () {
1649    var self = this;
1650
1651    $(document).on('cbox_load', function (event) {
1652      if (self.popup_opened_image == $.colorbox.element()) return;
1653      self.popup_opened_image = $.colorbox.element();
1654
1655      var $linkElem = $($.colorbox.element
1655()),
1656        popupWindowWidth = parseFloat(($(window).width() * 95) / 100),
1657        mobileWidth = popupWindowWidth < 700,
1658        $colorBoxPopup = $('#colorbox'),
1659        linkedImage = $linkElem.is('.gg-video') ? undefined : $linkElem.children('figure').attr('data-linked-images');
1660
1661      if (linkedImage || $linkElem.hasClass('linked-element')) {
1662        if (!$linkElem.hasClass('linked-element')) {
1663          if (self.$container.data('popupDisableSourceImageForLinkedImg') == 1) {
1664            var images = $.parseJSON(linkedImage);
1665            if (images && images.length > 0) {
1666              $linkElem.attr('href', images[0]['full']);
1667            }
1668          }
1669          // its parameter show that linked images exists
1670          if ($colorBoxPopup.css('padding-right')) {
1671            var tmpPaddingRight = parseInt($colorBoxPopup.css('padding-right'), 10),
1672              tmpLeft = parseInt($colorBoxPopup.css('left'), 10);
1673            if (!isNaN(tmpPaddingRight) && !isNaN(tmpLeft)) {
1674              if (tmpLeft - tmpPaddingRight < 0) {
1675                $.colorbox.settings.left = 0;
1676              } else {
1677                if (mobileWidth) {
1678                  // only when left not settet previously
1679                  if ($.colorbox.settings.left == false) {
1680                    $.colorbox.settings.left = tmpLeft - tmpPaddingRight;
1681                  }
1682                }
1683              }
1684            } else {
1685              $.colorbox.settings.left = false;
1686            }
1687          }
1688        }
1689      } else {
1690        $.colorbox.settings.left = false;
1691        $.colorbox.settings.width = false;
1692      }
1693
1694      if (mobileWidth) {
1695        $.colorbox.settings.width = popupWindowWidth - tmpPaddingRight;
1696      }
1697
1698      // resize once
1699      if (!self.initPopupWndSizeForLinkedImages && $linkElem.children('figure').attr('data-linked-images')) {
1700        self.initPopupWndSizeForLinkedImages = true;
1701        $.colorbox.resizeResponsive(self.popup_opened_image);
1702      }
1703    });
1704  };
1705
1706  ProGallery.prototype.initLinkedImages = function () {
1707    if ($('#colorbox .linkedImages').length) {
1708      return;
1709    }
1710
1711    var self = this;
1712    var $linkedImagesContainer = self.getLinkedImagesContainer();
1713    var $linkedImagesColorbox;
1714    var isLinkedImage = false;
1715    var isIconsEnabled = false;
1716
1717    var $linkedImageTemplate = $('<a class="linked-element"><img></a>').on('click', function () {
1718      isLinkedImage = true;
1719    });
1720
1721    $(document).on('cbox_complete', function (event) {
1722      if (!$('#colorbox .linkedImages').length) {
1723        $linkedImagesContainer = self.getLinkedImagesContainer();
1724      }
1725
1726      var $colorboxElement = $.colorbox.element(),
1727        $element,
1728        paddingLeft = 0,
1729        $colorBoxPopup = $('#colorbox'),
1730        maxLinkedImgWindowWidth = parseFloat(($(window).width() * 95) / 100),
1731        colorboxSettings = $colorboxElement.data('colorbox');
1732
1733      if ($colorboxElement.hasClass('hi-icon')) {
1734        $element = $colorboxElement.closest('.grid-gallery-caption');
1735        isIconsEnabled = true;
1736      } else {
1737        $element = $colorboxElement.find('.grid-gallery-caption');
1738      }
1739
1740      if ($colorboxElement.hasClass('linked-element')) {
1741        $('#colorbox .linkedImages a').removeClass('active');
1742        $colorboxElement.addClass('active');
1743      }
1744
1745      if (isLinkedImage && !$element.length) {
1746        return;
1747      }
1748
1749      $('#colorbox .link-img-arr-top').hide();
1750      $('#colorbox .link-img-arr-bottom').hide();
1751      $('#colorbox .linkedImages').empty();
1752
1753      var linkedImages = $colorboxElement.is('.gg-video') ? undefined : $element.data('linked-images');
1754      if (linkedImages) {
1755        // fix maxWidth for linked images
1756        if ($colorBoxPopup.css('padding-right')) {
1757          var tmpVal = parseInt($colorBoxPopup.css('padding-right'), 10);
1758          if (!isNaN(tmpVal)) {
1759            paddingLeft = tmpVal;
1760          }
1761        }
1762        colorboxSettings.maxWidth = maxLinkedImgWindowWidth - paddingLeft;
1763
1764        for (var i = linkedImages.length - 1; i >= 0; i--) {
1765          var $template = $linkedImageTemplate.clone(true, true),
1766            linkImageText = null;
1767
1768          if ($element.data('linked-image-title') == 'data-description') {
1769            linkImageText = linkedImages[i].description;
1770          } else if ($element.data('linked-image-title') == 'data-title') {
1771            linkImageText = linkedImages[i].title;
1772          } else if ($element.data('linked-image-title') == 'alt') {
1773            linkImageText = linkedImages[i].alt;
1774          }
1775
1776          $template.attr('data-href', linkedImages[i].full);
1777          $template
1778            .find('img')
1779            .attr('src', linkedImages[i].thumbnail || linkedImages[i].full)
1780            .attr('title', linkImageText);
1781          $template.appendTo($linkedImagesContainer);
1782        }
1783
1784        $linkedImagesColorbox = $('#colorbox .linkedImages a').colorbox(
1785          $.extend({}
1785, colorboxSettings, {
1786            iframe: false,
1787            onComplete: function (e) {
1788              var $imgObj = $('#cboxWrapper .cboxPhoto');
1789              $imgObj.css({ margin: '0' });
1790              self.changePopUpHash($(e.el).attr('id') || $(e.el).attr('data-id'));
1791              self.addSocialShareToPopUp($(e.el), $('#cboxContent'), 'popup');
1792              self.$container.find('.grid-gallery-photos > .gg-colorbox, .hi-icon.gg-colorbox').colorbox.resize({
1793                width: $imgObj.width(),
1794                height: $imgObj.height(),
1795                innerHeight: $imgObj.innerHeight(),
1796                innerWidth: $imgObj.innerWidth(),
1797              });
1798              $('#cboxLoadedContent').append("<div id='cboxRight'></div><div id='cboxLeft'></div>");
1799            },
1800            rel: 'grid-gallery-' + $element.data('id'),
1801            href: function () {
1802              return $(this).attr('data-href');
1803            },
1804            onOpen: function (e) {
1805              colorboxSettings.onOpen(e);
1806            },
1807            onLoad: function (e) {
1808              if (self.popup_opened_image != false && self.popup_opened_image == e.el) return;
1809              self.popup_opened_image = e.el;
1810              self.autoChangeLinkImgScrollOffset($(self.popup_opened_image));
1811            },
1812            onClosed: function (e) {
1813              self.popup_opened_image = false;
1814              colorboxSettings.onClosed(e);
1815            },
1816          })
1817        );
1818
1819        var thumbnail = $element.find('img').attr('src'),
1820          thumbNailSize = self.$container.data('thumbnail-size');
1821        if (!thumbNailSize) {
1822          thumbNailSize = '150x150';
1823        }
1824
1825        if (/(-\d{2,}x\d{2,})(:?\..{3,})?$/.test(thumbnail)) {
1826          thumbnail = thumbnail.replace(/(-\d{2,}x\d{2,})(:?\..{3,})?$/, function (string, match, extension) {
1827            return string.replace(match + extension, '-' + thumbNailSize + extension);
1828          });
1829        }
1830
1831        if (self.$container.data('popupDisableSourceImageForLinkedImg') != 1) {
1832          var $parentTemplate = $linkedImageTemplate.clone(true, true);
1833          $parentTemplate.find('img').attr('src', thumbnail);
1834          $parentTemplate.prependTo($linkedImagesContainer);
1835          $parentTemplate.addClass('active');
1836          $parentTemplate.on('click', function () {
1837            if (isIconsEnabled) {
1838              $element.find('a').trigger('click');
1839            } else {
1840              $colorboxElement.trigger('click');
1841            }
1842          });
1843        }
1844
1845        $('#colorbox .linkedImages').fadeIn();
1846        $('#colorbox .linkedImages img').css('margin-bottom', '10px');
1847
1848        var $linkedImageObj = $('.linkedImages');
1849        var scrollHeight = parseInt($linkedImageObj.prop('scrollHeight'));
1850        if (scrollHeight > $linkedImageObj.height()) {
1851          $('#colorbox .link-img-arr-top').show();
1852          $('#colorbox .link-img-arr-bottom').show();
1853        }
1854
1855        if (self.$container.data('popupDisableSourceImageForLinkedImg') != 1) {
1856          // need to optimize and remove code bellow
1857          // fix for first Gallery show
1858          if (self.prevPopUpOpenedImg != self.popup_opened_image) {
1859            self.prevPopUpOpenedImg = self.popup_opened_image;
1860            setTimeout(function () {
1861              $.colorbox.resizeResponsive(self.popup_opened_image);
1862            }, 300);
1863          }
1864        }
1865      }
1866    });
1867  };
1868
1869  ProGallery.prototype.initDisableRightClick = function () {
1870    if (this.$container.attr('data-disable-right-click')) {
1871      $(this.$container.find('.grid-gallery-photos')).bind('contextmenu', function (e) {
1872        return false;
1873      });
1874    }
1875  };
1876
1877  ProGallery.prototype.addCaptionOnHoverImageEvent = function ($figure, $image, hoverImgSrc) {
1878    var fadeTimeout = 100;
1879    if ($image.hasClass('ggLazyImg')) return;
1880
1881    if ($image.attr('src') != hoverImgSrc) {
1882      // need setup width and height, because hover image proportion was incompatible
1883      if ($image.length && $image[0].naturalWidth && this.$container.data('gridType') != 4) {
1884        $image.css('width', $image[0].naturalWidth);
1885      } else {
1886        $image.css('width', $image.width());
1887      }
1888      if ($image.length && $image[0].naturalHeight && this.$container.data('gridType') != 4) {
1889        $image.css('height', $image[0].naturalHeight);
1890      } else {
1891        $image.css('height', $image.height());
1892      }
1893
1894      // save source image to attribute
1895      $image.attr('without-hover-img-effect', $image.attr('src'));
1896      if (!$image.is('[data-gg-real-image-href]')) {
1897        $image.attr('data-gg-real-image-href', $image.attr('src'));
1898      }
1899    }
1900
1901    $figure
1902      .on('mouseenter', function (event) {
1903        $image.attr('src', hoverImgSrc);
1904      })
1905      .on('mouseleave', function () {
1906        $image.attr('src', $image.attr('data-gg-real-image-href'));
1907      });
1908  };
1909
1910  ProGallery.prototype.setCaptionOnHoverImage = function () {
1911    //check for all images
1912    var hoverImgSrc = this.$container.data('image-on-hover'),
1913      self = this;
1914
1915    if (hoverImgSrc && hoverImgSrc.length) {
1916      this.$elements.each(function (index, figure) {
1917        var $figure = $(figure),
1918          $image = $figure.find('img');
1919        if ($image.length) {
1920          self.addCaptionOnHoverImageEvent($figure, $image, hoverImgSrc);
1921        }
1922      });
1923    } else if (this.$container.data('thumb-overlay-personal') == '1') {
1924      // check for one image
1925      this.$elements.each(function (index, figure) {
1926        var $figure = $(figure),
1927          $image = $figure.find('img[data-personal-hover-on-image]');
1928        if ($image.length) {
1929          hoverImgSrc = $image.data('personal-hover-on-image');
1930          self.addCaptionOnHoverImageEvent($figure, $image, hoverImgSrc);
1931        }
1932      });
1933    }
1934  };
1935
1936  ProGallery.prototype.selectCategoryByUrlHash = function (currGallery) {
1937    if (currGallery && currGallery.$container && currGallery.$container.attr && currGallery.$container.attr('id') && window.location.hash) {
1938      var galleryId = currGallery.$container.attr('data-gg-id'),
1939        openCategoryByLinkRegexp = new RegExp('^#gg-categ-' + galleryId + '-([- _\\|"@\\+!=\\w\\d]*)$', 'gi'),
1940        categoryMatches = openCategoryByLinkRegexp.exec(window.location.hash.replace(new RegExp('__', 'g'), ' '));
1941
1942      var catMatch = categoryMatches && categoryMatches.length && categoryMatches[1],
1943        catNames = catMatch ? null : window.location.hash.replace(new RegExp('__', 'g'), ' ').split('-');
1944
1945      if (catMatch || catNames) {
1946        var catName = catMatch ? categoryMatches[1] : catNames.slice(-1)[0];
1947        currGallery.$navigation.find('a[data-tag="' + catName + '"]').trigger('click');
1948      } else {
1949        this.selectFirstCategory();
1950      }
1951    } else {
1952      this.selectFirstCategory();
1953    }
1954  };
1955
1956  ProGallery.prototype.selectFirstCategory = function () {
1957    var firstTag = this.$navigation.find('a').first().data('tag');
1958    this.$navigation.find('a[data-tag="' + firstTag + '"]').trigger('click');
1959  };
1960
1961  ProGallery.prototype.initMosaicGalleryType = function () {
1962    // check mosaic
1963    if (this.$container.data('gridType') == 4) {
1964      // Event handler for "last image Click
1965      var $photoRemainDiv = $('.gg-mosaic-photo-remain'),
1966        $galleryCaptFigure = $('.gg-mosaic-photo-remain').closest('.grid-gallery-caption'),
1967        self2 = this,
1968        useMosaic2Layout = this.$container.attr('data-useMosaic2Layout') == 1;
1969      //
1970      if (useMosaic2Layout) {
1971        var wall = new Freewall('#' + self2.$container.attr('id') + ' .grid-gallery-photos');
1972
1973        function mosaicGalleryRefresh(wallScript) {
1974          setTimeout(function () {
1975            wallScript.fitWidth();
1976            // refresh some incorrect images
1977            setTimeout(function () {
1978              wallScript.fitWidth();
1979            }, 500);
1980          }, 5);
1981        }
1982        // first size save
1983        self2.$container.attr('data-mosaic2wnd-size', this.$container.width());
1984
1985        function render2MosaicLayout() {
1986          var cntColumns = parseInt(self2.$container.attr('data-useMosaicCountColumns'));
1987          if (isNaN(cntColumns) || cntColumns < 3) {
1988            cntColumns = 4;
1989          }
1990          if (cntColumns > 20) {
1991            cntColumns = 20;
1992          }
1993
1994          var imgMaxWidth = Math.round(self2.$container.width() / cntColumns),
1995            $imageContainer = self2.$container.find('.grid-gallery-photos'),
1996            $imageFigures = $imageContainer.find('.grid-gallery-caption'),
1997            notBigImage = Math.round($imageFigures.length / 3),
1998            imageDistance = parseInt(self2.$container.attr('data-offset')),
1999            sizesArr = [imgMaxWidth],
2000            maxColumnsForImg = Math.round(cntColumns * (cntColumns >= 8 ? 0.5 : 0.7));
2001          for (var i = maxColumnsForImg; i > 1; i--) {
2002            sizesArr.push(i * imgMaxWidth);
2003          }
2004
2005          $imageFigures.each(function (ind, item) {
2006            var $currWrapper = $(this),
2007              $wrapperParent = $currWrapper.parent(),
2008              imgHeight = 0,
2009              imgWidth = 0,
2010              $image = $currWrapper.find('.ggImg'),
2011              newIndex = Math.abs(Math.round(Math.random() * maxColumnsForImg - 0.5)),
2012              imgNewWidth = sizesArr[notBigImage < ind || newIndex != 1 ? newIndex : sizesArr.length - 1];
2013
2014            if ($currWrapper.css('block') == 'none') {
2015              mgNewWidth = 0;
2016              $wrapperParent.css({ height: '0', width: '0' });
2017            } else {
2018              $wrapperParent.css({ height: '', width: '' });
2019              if ($image.length) {
2020                imgHeight = parseInt($image[0].naturalHeight);
2021                imgWidth = parseInt($image[0].naturalWidth);
2022                if (imgHeight && imgWidth && !isNaN(imgHeight) && !isNaN(imgWidth)) {
2023                  if (imgWidth > imgHeight) {
2024                    if (imgHeight * 2 < imgWidth) {
2025                      // set max mask width for image
2026                      imgNewWidth = sizesArr[1];
2027                    }
2028                  } else {
2029                    // fix automaticaly set Widest mask, for Portrait images
2030                    if (newIndex == 1) {
2031                      imgNewWidth = sizesArr[0];
2032                    }
2033                  }
2034                }
2035              }
2036            }
2037            if ($wrapperParent.hasClass('gg-link')) {
2038              $wrapperParent.css({ width: imgNewWidth + 'px' });
2039              $currWrapper.css({ width: '100%' });
2040            } else {
2041              $currWrapper.css({ width: imgNewWidth + 'px' });
2042            }
2043          });
2044          if (isNaN(imageDistance)) {
2045            imageDistance = 0;
2046          }
2047
2048          wall.reset({
2049            selector: '.gg-link',
2050            animate: true,
2051            cellW: imgMaxWidth,
2052            cellH: 'auto',
2053            gutterX: imageDistance,
2054            gutterY: imageDistance,
2055            onResize: function () {
2056              var prevWndSize = self2.$container.attr('data-mosaic2wnd-size'),
2057                containerWidth = self2.$container.width();
2058              if (prevWndSize != containerWidth) {
2059                render2MosaicLayout();
2060              } else {
2061                mosaicGalleryRefresh(wall);
2062              }
2063              self2.$container.attr('data-mosaic2wnd-size', containerWidth);
2064            },
2065          });
2066          mosaicGalleryRefresh(wall);
2067        }
2068
2069        render2MosaicLayout();
2070      } else {
2071        self2.calcImgHeightInMosaicGallery();
2072        // save figcaption effect
2073        if (self2.$container.data('show-mosaic-all-img') != '1') {
2074          if ($galleryCaptFigure.length) {
2075            $galleryCaptFigure.attr('data-grid-gallery-type-original', $galleryCaptFigure.attr('data-grid-gallery-type'));
2076            //$galleryCaptFigure.attr('data-grid-gallery-type', 'none');
2077          }
2078        }
2079        // init once
2080        if (!this.isMosaicInit) {
2081          $(document).on('ggMosaicResizedEvent', function () {
2082            self2.initMosaicGalleryType();
2083          });
2084          this.isMosaicInit = true;
2085        }
2086
2087        $photoRemainDiv.off('click').on('click', function (event) {
2088          // remove Remain count div
2089          if (self2.$container.data('show-hide-mosaic-img-by-click') == '1') {
2090            event.preventDefault();
2091            event.stopPropagation();
2092
2093            // restore figcaption effect for "remain photo"
2094            if ($galleryCaptFigure.length) {
2095              $galleryCaptFigure.attr('data-grid-gallery-type', $galleryCaptFigure.attr('data-grid-gallery-type-original'));
2096              // show caption
2097              var $figcaption = $galleryCaptFigure.find('figcaption');
2098              if ($figcaption.length) {
2099                $figcaption.removeClass('sggDisplNone');
2100              }
2101            }
2102            // show other rows
2103            self2.$container.find('.gg-mosaic-wrapper .gg-mw-row').removeClass('sggDisplNone');
2104            // remove Remain div
2105            $photoRemainDiv.remove();
2106            self2.calcImgHeightInMosaicGallery();
2107            self2.initPopup();
2108            self2.initVideoPopup();
2109          }
2110        });
2111      }
2112    }
2113  };
2114
2115  ProGallery.prototype.calcImgHeightInMosaicGallery = function (recalc) {
2116    var $firstRows = this.$container.find('.gg-mw-row.gg-mw-first-row'),
2117      $secondRows = this.$container.find('.gg-mw-row.gg-mw-second-row'),
2118      imageMargin = parseInt(this.$container.data('offset')),
2119      $firstFigure = this.$container.find('.gg-mw-column.gg-mw-column-1:first figure'),
2120      self2 = this;
2121    if (isNaN(imageMargin)) {
2122      imageMargin = 0;
2123    }
2124
2125    $firstRows.each(function (ind, elem) {
2126      var $currRow = $(elem),
2127        $figure2 = $currRow.find('.gg-mw-column-1 figure'),
2128        $figure3 = $currRow.find('.gg-mw-column-2 figure'),
2129        $img2 = $figure2.find('img'),
2130        $img3 = $figure3.find('img'),
2131        height2 = self2._parent('getRealImgSizeInBrowser', [$img2, 'h']),
2132        height3 = self2._parent('getRealImgSizeInBrowser', [$img3, 'h']),
2133        correctHeight2 = height2,
2134        correctHeight3 = height3;
2135      // if item visible height more than 0
2136      if ($currRow.find('figure.initialized').length == 0) {
2137        if (height2 || height3) {
2138          // fix height for rows
2139          if ($img2.length && $img3.length && !isNaN(height2) && !isNaN(height3)) {
2140            if (height2 && height3) {
2141              if (height2 > height3) {
2142                correctHeight2 = height3;
2143              } else {
2144                correctHeight3 = height2;
2145              }
2146            }
2147          }
2148          // special prepare for "3d-cube" effect
2149          if ($firstFigure.data('grid-gallery-type') == '3d-cube') {
2150            self2._parent('changeImageHeightFor3dCubeEffect', { figure: $figure2, width: null, height: correctHeight2 });
2151            self2._parent('changeImageHeightFor3dCubeEffect', { figure: $figure3, width: null, height: correctHeight3 });
2152          } else {
2153            if ($img2.length && $img3.length && !isNaN(correctHeight2) && !isNaN(correctHeight3)) {
2154              $img2.parent().css('height', correctHeight2 + 'px');
2155              $img3.parent().css('height', correctHeight3 + 'px');
2156            }
2157          }
2158        }
2159        $currRow.css('height', height2 || height3 ? '' : '0');
2160      }
2161    });
2162    var recalc = typeof recalc == 'undefined' ? false : recalc,
2163      needRecalc = false,
2164      cntSecondRows = $secondRows.length,
2165      curRow = 0;
2166
2167    $secondRows.each(function (ind, elem) {
2168      var $currElem = $(elem),
2169        $figure1 = $currElem.find('.gg-mt-column1 figure'),
2170        $figures = $currElem.find('.gg-mt-row2-column figure'),
2171        $img1 = $figure1.find('img'),
2172        $images = $figures.find('img'),
2173        height1 = self2._parent('getRealImgSizeInBrowser', [$img1, 'h']),
2174        correctHeight1 = height1;
2175      curRow++;
2176      if ($images.length && $currElem.find('figure.initialized').length == 0) {
2177        var cntImages = $images.length,
2178          heights = [],
2179          groups = {},
2180          groupMin = 0;
2181        $images.each(function (i) {
2182          var $img = $(this),
2183            h = self2._parent('getRealImgSizeInBrowser', [$img, 'h']),
2184            g = $img.closest('td').attr('data-group');
2185          if (typeof g == 'undefined') {
2186            g = 1;
2187          }
2188          heights.push(h);
2189          if (g in groups) {
2190            groups[g]['imgs'].push(i);
2191            if (groups[g]['min'] == 0 || groups[g]['min'] > h) groups[g]['min'] = h;
2192          } else {
2193            groups[g] = { min: h, imgs: [i] };
2194          }
2195          if (groupMin == 0 || (groups[g]['min'] > 0 && groupMin > groups[g]['min'])) groupMin = groups[g]['min'];
2196        });
2197        var sumHeight = 2 * imageMargin;
2198        for (var g in groups) {
2199          if (groups[g]['min'] == 0) groups[g]['min'] = groupMin;
2200          $.each(groups[g]['imgs'], function (ind, i) {
2201            heights[i] = groups[g]['min'];
2202          });
2203        }
2204        var sumHeight = 2 * imageMargin;
2205        for (var g in groups) {
2206          $.each(groups[g]['imgs'], function (ind, i) {
2207            heights[i] = groups[g]['min'];
2208          });
2209          sumHeight += groups[g]['min'];
2210        }
2211        if (height1 > sumHeight) {
2212          if (Math.round(height1 / sumHeight) >= 2 && !recalc) {
2213            $img1.closest('tr').find('td.gg-mt-column1').css('width', '50%');
2214            needRecalc = true;
2215          } else if (curRow < cntSecondRows && sumHeight > 2 * imageMargin) {
2216            correctHeight1 = sumHeight;
2217          }
2218        } else if (correctHeight1 < sumHeight && correctHeight1 > 0) {
2219          var delta = ((sumHeight - correctHeight1) * 100) / (sumHeight - 2 * imageMargin);
2220          for (var g in groups) {
2221            var cut = groups[g]['min'] - (delta * groups[g]['min']) / 100;
2222            $.each(groups[g]['imgs'], function (ind, i) {
2223              heights[i] = cut;
2224            });
2225          }
2226        }
2227        // special prepare for "3d-cube" effect
2228        if ($firstFigure.data('grid-gallery-type') == '3d-cube') {
2229          self2._parent('changeImageHeightFor3dCubeEffect', { figure: $figure1, width: null, height: correctHeight1 });
2230          $.each(heights, function (i, h) {
2231            self2._parent('changeImageHeightFor3dCubeEffect', { figure: $images.eq(i).closest('figure'), width: null, height: h });
2232          });
2233        } else {
2234          $img1.parent().css('height', correctHeight1 + 'px');
2235          $.each(heights, function (i, h) {
2236            $images
2237              .eq(i)
2238              .parent()
2239              .css('height', h + 'px');
2240          });
2241        }
2242      }
2243    });
2244    if (!recalc && needRecalc) self2.calcImgHeightInMosaicGallery(true);
2245    else {
2246      $.each(self2.$elements, function (index, el) {
2247        var $el = $(el);
2248        if ($el.closest('table').find('img.ggLazyImg').length == 0) {
2249          $el.find('img').removeClass('ggNotInitImg');
2250          self2.polaroidCaptionCalculate($el);
2251        }
2252      });
2253    }
2254  };
2255
2256  ProGallery.prototype.initPopupFunc = function () {
2257    var popupType = this.$container.data('popup-type');
2258
2259    if (popupType == 'pretty-photo') {
2260      window.prettyPhotoShowContent = function (changeWidthAndHeight, currImgRotateVal, $ppPopupImage, $ppImageWrapper, pp_dimensions) {
2261        if (!changeWidthAndHeight) {
2262          // simple
2263          $ppImageWrapper.css({
2264            width: 'auto',
2265            height: 'auto',
2266          });
2267        } else {
2268          // show with ROTATE
2269          $ppImageWrapper.css({
2270            width: pp_dimensions['width'],
2271            height: pp_dimensions['height'],
2272          });
2273          // calc translate value
2274          var translateVal = (pp_dimensions['height'] - pp_dimensions['width']) / 2,
2275            maxWidthVal = pp_dimensions['width'],
2276            rotateVal = 90 * currImgRotateVal;
2277
2278          switch (currImgRotateVal) {
2279            case 3:
2280              translateVal *= -1;
2281              maxWidthVal = pp_dimensions['height'];
2282              break;
2283            case 2:
2284              translateVal = 0;
2285              break;
2286            case 1:
2287              maxWidthVal = pp_dimensions['height'];
2288              break;
2289            case 0:
2290            default:
2291              translateVal = 0;
2292              break;
2293          }
2294
2295          if (!isNaN(rotateVal)) {
2296            $ppPopupImage.css({
2297              width: 'auto',
2298              height: 'auto',
2299              'max-width': maxWidthVal,
2300              // some like "transform: rotateZ(90deg) translate(90px, 90px);"
2301              transform: 'rotateZ(' + rotateVal + 'deg) translate(' + translateVal + 'px, ' + translateVal + 'px)',
2302            });
2303          }
2304        }
2305        $ppPopupImage.show();
2306      };
2307
2308      window.prettyPhotoRotateCalcs = function (event, handlerFunc, needToIncrease) {
2309        if (event && event.preventDefault) {
2310          event.preventDefault();
2311        }
2312        // 0:   0 degree (or 360 degree)
2313        // 1:  90 degree
2314        // 2: 180 degree
2315        // 3: 270 degree
2316        var $imgForRotate = $('#fullResImage'),
2317          currImgRotateVal = parseInt($imgForRotate.attr('data-rotate-angl')),
2318          toFitWidth,
2319          toFitHeigth;
2320        $imgForRotate.hide();
2321        if (!$imgForRotate.length) {
2322          return;
2323        }
2324        if (currImgRotateVal < 0 || currImgRotateVal > 3 || isNaN(currImgRotateVal)) {
2325          currImgRotateVal = 0;
2326        }
2327        if (needToIncrease) {
2328          currImgRotateVal++;
2329          $imgForRotate.attr('data-rotate-angl', currImgRotateVal);
2330        }
2331
2332        if ([1, 3].indexOf(currImgRotateVal) != -1) {
2333          toFitHeigth = $imgForRotate[0].naturalWidth;
2334          toFitWidth = $imgForRotate[0].naturalHeight;
2335        } else {
2336          toFitHeigth = $imgForRotate[0].naturalHeight;
2337          toFitWidth = $imgForRotate[0].naturalWidth;
2338        }
2339        handlerFunc(toFitWidth, toFitHeigth, currImgRotateVal);
2340
2341        return false;
2342      };
2343      window.prettyPhotoInitRotate = function (handlerFunc) {
2344        var $rotateBtn = $('.sggRotateBtn[data-popup-theme-id="6"]');
2345        $rotateBtn.on('click', function (event) {
2346          window.prettyPhotoRotateCalcs(event, handlerFunc, 1);
2347        });
2348      };
2349
2350      window.prettyPhotoDetailLink = function (element) {
2351        var $popupDetailsLink = $('.sggTheme6PopupBtns .sggLinkBtn');
2352        $popupDetailsLink.hide();
2353        if (element.attr('data-link-url')) {
2354          $popupDetailsLink.attr('href', element.attr('data-link-url'));
2355          $popupDetailsLink.show();
2356        }
2357      };
2358
2359      window.prettyPhotoAttributes = function (element, container) {
2360        var $popupAttributes = $('#ppCustomAttributes').empty(),
2361          order,
2362          attributes;
2363
2364        try {
2365          order = JSON.parse(container.attr('data-attributes-order'));
2366          attributes = JSON.parse(element.attr('data-attributes'));
2367        } catch (err) {}
2368        if (!$.isArray(attributes)) {
2369          attributes = [];
2370        }
2371
2372        if ($.isArray(order)) {
2373          $.each(order, function (index, attrName) {
2374            $popupAttributes.append('<span class="pp_attribute_name">' + attrName + ':</span>');
2375
2376            for (var i = 0; i < attributes.length; i++) {
2377              if ('name' in attributes[i] && 'value' in attributes[i] && attributes[i]['name'] == attrName) {
2378                $popupAttributes.append('<span class="pp_attribute_value">' + attributes[i]['value'] + '</span>');
2379                break;
2380              }
2381            }
2382            $popupAttributes.append('</br>');
2383          });
2384        }
2385        if (container.attr('data-show-buttonlink-in-popup') == 1) {
2386          var title = element.attr('data-buttonlink-title'),
2387            url = element.attr('data-buttonlink-url');
2388          if (typeof title == 'undefined' || title == '') {
2389            title = container.attr('data-buttonlink-title');
2390          }
2391          if (typeof url == 'undefined' || url == '') {
2392            url = container.attr('data-buttonlink-url');
2393          }
2394          $('#ppAttributeButton').find('a').attr('href', url).html(title);
2395        }
2396      };
2397
2398      window.prettyPhotoInitOnHoverThumb = function ($element, galleryId, runPopupResizeHandler) {
2399        var $gallery = $('.grid-gallery[data-gg-id="' + galleryId + '"]'),
2400          $ggImgItem = $element.find('img.ggImg'),
2401          galleryOnHoverImgSrc = $gallery.attr('data-image-on-hover'),
2402          personalOnHoverSrc = $ggImgItem.attr('data-personal-hover-on-image'),
2403          $imgInPopup = $('.sggT6OnHoverThumbImg'),
2404          $imgWrapper = $('.sggTheme6OnHoverThumbWr'),
2405          imgSrc = $element.attr('href');
2406        // if personal on hover exists, then get him
2407        if (personalOnHoverSrc) {
2408          galleryOnHoverImgSrc = personalOnHoverSrc;
2409        }
2410        // reset values
2411        $imgInPopup.attr('src', galleryOnHoverImgSrc);
2412        $imgWrapper.attr('data-show-on-hover', 1);
2413
2414        if ($element.length && $gallery.length) {
2415          if (!galleryOnHoverImgSrc) {
2416            $imgWrapper.hide();
2417            $imgInPopup.attr('src', '');
2418          } else {
2419            $imgWrapper.show();
2420
2421            // init changing
2422            $imgWrapper.off('click').on('click', function (event) {
2423              var $currWrapper = $(this),
2424                $imgForPreview = $('#fullResImage');
2425              // if user click on Preview
2426              if ($currWrapper.attr('data-show-on-hover')) {
2427                $imgInPopup.attr('src', imgSrc);
2428                $currWrapper.attr('data-show-on-hover', '');
2429                $imgForPreview.attr('src', galleryOnHoverImgSrc);
2430              } else {
2431                $imgInPopup.attr('src', galleryOnHoverImgSrc);
2432                $currWrapper.attr('data-show-on-hover', 1);
2433                $imgForPreview.attr('src', imgSrc);
2434              }
2435              window.prettyPhotoRotateCalcs(null, runPopupResizeHandler, 0);
2436            });
2437          }
2438          // fix popup height bar, when change "item" in popup gallery preview
2439          // ...
2440        }
2441      };
2442    }
2443  };
2444
2445  $(document).on('GalleryExtend', function (event, Gallery) {
2446    $.extend(Gallery, new ProGallery());
2447  });
2448})(jQuery);
2449
2450function htmlDecode(input) {
2451  var e = document.createElement('div');
2452  e.innerHTML = input;
2453  return e.childNodes[0].nodeValue;
2454}
2455function arraysEqual(a, b) {
2456  if (a === b) return true;
2457  if (a == null || b == null) return false;
2458  if (a.length != b.length) return false;
2459
2460  // If you don't care about the order of the elements inside
2461  // the array, you should sort both arrays here.
2462  // Please note that calling sort on an array will modify that array.
2463  // you might want to clone your array first.
2464
2465  for (var i = 0; i < a.length; ++i) {
2466    if (a[i] !== b[i]) return false;
2467  }
2468  return true;
2469}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.