PageSourceSearch

https://www.kridva.com/js/jquery.glasscase.min.js

js kridva.com collected 2026-10-04 07:08:57 UTC 143,517 bytes, 2,591 lines download raw bytes

1/*!
2 * VERSION: 3.0.1
3 * DATE: 2018-04-06
4 * DOCS AT: http://www.tinycomp.net/
5 * 
6 * @license Copyright (c) 2014-2018, tinyComp. All rights reserved.
7 * 
8 * @author: tinyComp, [email protected]
9 **/
10;
11(function ($, window, document, undefined) {
12    'use strict';
13
14    var Modernizr = window.Modernizr;
15
16    function GCLoader(colorLoading) {
17        this.color = colorLoading;
18
19        this.init = function () {
20            var _this = this;
21
22            var c;
23            _this.pLoadingClass = 'gc-ploading';
24            _this.gcLoadingClass = (Modernizr.csstransforms === true) ? 'gc-loading3' : 'gc-loading';
25            _this.gcLoading = $('<div class="' + _this.pLoadingClass + '"><div class="' + _this.gcLoadingClass + '"></div></div>"');
26
27            if (colorLoading !== -1 && Modernizr.csstransforms === true) {
28                if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(colorLoading)) {
29                    c = colorLoading.substring(1).split('');
30                    if (c.length == 3) {
31                        c = [c[0], c[0], c[1], c[1], c[2], c[2]];
32                    }
33                    c = '0x' + c.join('');
34                    var sC = 'rgba(' + [(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',') + ',1)';
35                    _this.gcLoading.find('.' + _this.gcLoadingClass).css({
36                        'border-top-color': sC + '0.2)',
37                        'border-right-color': sC + '0.2)',
38                        'border-bottom-color': sC + '0.2)',
39                        'border-left-color': sC + '1)'
40                    });
41                }
42
43                var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(colorLoading);
44                if (result) {
45                    var sC = 'rgba(' + parseInt(result[1], 16) + ', ' + parseInt(result[2], 16) + ', ' + parseInt(result[3], 16) + ', ';
46                    _this.gcLoading.find('.' + _this.gcLoadingClass).css({
47                        'border-top-color': sC + '0.2)',
48                        'border-right-color': sC + '0.2)',
49                        'border-bottom-color': sC + '0.2)',
50                        'border-left-color': sC + '1)'
51                    });
52                }
53            }
54        };
55        this.getInstance = function () {
56            return this.gcLoading;
57        };
58
59        //Execution
60        this.init();
61    }
62
63    function GCImage(element, config) {
64        //Properties
65        this.type = 'image';
66        this.width = 0;
67        this.height = 0;
68        this.url = $(element).attr('src'); //src
69        this.altTxt = window.decodeURIComponent($(element).attr('alt')) || 'image'; //alt
70        this.caption = $(element).data('gc-caption') || '';
71        this.state = 'new'; //new; loading; loaded; error;
72        this.dfdState = $.Deferred();
73        this.instanceCnt = [];
74        this.instance = [];
75        this.instanceDisplay = [];
76        this.errorTxt = config.textImageNotLoaded;
77        this.tmp = ['thumb', 'display', 'zoom', 'overlay'];
78        this.loader = [];
79        this.wDisplayR = 0;
80        this.hDisplayR = 0;
81        this.isMouseEventsOn = false;
82        this.colorLoading = config.colorLoading;
83
84        //Methods
85        this.init = function () {
86            var _this = this;
87
88            $.each(_this.tmp, function (index, tmpI) {
89                switch (tmpI) {
90                    case 'zoom':
91                        _this.instance.push($('<div class="gc-zoom-container">' +
92                          '<img src="' + _this.url + '" alt="' + _this.altTxt + '" />' +
93                          '</div>'));
94                        break;
95                    case 'display':
96                        _this.instance.push($('<div class="gc-slide-container">' +
97                          '<div class="gc-display-container">' +
98                          '<img class="gc-display-display" src="' + _this.url + '" alt="' + _this.altTxt + '" />' +
99                          '</div></div>'));
100                        break;
101                    case 'thumb':
102                        _this.instance.push($('<div class="gc-display-container">' +
103                          '<img class="gc-display-display" src="' + _this.url + '" alt="' + _this.altTxt + '" />' +
104                          '</div>'));
105                        break;
106                    case 'overlay':
107                        _this.instance.push($('<div class="gc-overlay-container-display">' +
108                          '<img class="gc-overlay-display" src="' + _this.url + '" alt="' + _this.altTxt + '" />' +
109                          '</div>'));
110                        break;
111                }
112
113                _this.instanceDisplay.push(_this.instance[index].find('img').hide());
114                _this.loader.push(new GCLoader(_this.colorLoading));
115            });
116
117            if (_this.state === 'new') {
118                _this.state = 'loading';
119                _this.addLoader();
120                $.when(_this.preload()).done(function () {
121                    if (_this.state === 'error') {
122                        $.each(_this.instance, function (index) {
123                            _this.instance[index].find('img').attr('src', _this.url);
124                        });
125                    }
126                    _this.removeLoader();
127                    _this.fitSize();
128                    _this.dfdState.resolve();
129                });
130            }
131        };
132        this.getInstance = function (area) {
133            var _this = this;
134
135            return _this.instance[$.inArray(area, _this.tmp)];
136        };
137        this.getInstanceDisplay = function (area) {
138            var _this = this;
139
140            return _this.instanceDisplay[$.inArray(area, _this.tmp)];
141        };
142        this.preload = function () {
143            var _this = this;
144
145            return $.Deferred(
146              function (dfd) {
147                  $('<img/>')
148                    .on('load', function () {
149                        _this.width = this.width;
150                        _this.height = this.height;
151                        _this.state = 'loaded';
152
153                        dfd.resolve();
154                    })
155                    .on('error', function () {
156                        this.onerror = '';
157
158                        _this.state = 'error';
159                        if (Modernizr.svg) {
160                            //Is needed the width and height of the li container
161                            _this.width = 150;
162                            _this.height = 150;
163
164                            var iEDB64 = window.btoa('<svg xmlns="http://www.w3.org/2000/svg" width="' + _this.width + '" height="' + _this.height + '"><rect width="' + _this.width + '" height="' + _this.height + '" fill="#fff"/><text text-anchor="middle" x="' + _this.width / 2 + '" y="' + _this.height / 2 + '" style="fill:#333;font-weight:bold;font-size:16px;font-family:Arial,Helvetica,sans-serif;dominant-baseline:central">' + _this.errorTxt + '</text></svg>');
165                            _this.url = 'data:image/svg+xml;base64,' + iEDB64;
166                        }
167
168                        dfd.resolve();
169                    }).attr('src', _this.url);
170              }
171            ).promise();
172        };
173        this.fitSize = function () {
174            var _this = this;
175
176            $.each(_this.instanceDisplay, function (index, el) {
177
178                if (_this.tmp[index] === 'display') {
179                    _this.instance[index].find('.gc-display-container').addClass('gc-dc-center');
180                }
181
182                if (_this.tmp[index] === 'thumb') {
183                    var wRatio = _this.instance[index].width() / _this.width;
184                    var hRatio = _this.instance[index].height() / _this.height;
185                    var ratioImg = wRatio > hRatio ? wRatio : hRatio;
186
187                    el.width(Math.ceil(_this.width * ratioImg, 10));
188                    el.height(Math.ceil(_this.height * ratioImg, 10));
189
190                    var percMarginLeft = ((el.outerWidth() / 2) * 100) / (_this.instance[index].outerWidth());
191                    var percMarginTop = ((el.outerHeight() / 2) * 100) / (_this.instance[index].outerWidth());
192
193                    el.css({
194                        'margin-top': "-" + percMarginTop + "%",
195                        'margin-left': "-" + percMarginLeft + "%"
196                    });
197                }
198
199                if (_this.tmp[index] === 'overlay') {
200                    _this.instanceDisplay[index].removeClass('gc-overlay-display-hcenter gc-overlay-display-vcenter')
201                      .addClass('gc-overlay-display-center');
202                }
203            });
204        };
205        this.isFitScr = function (width, height) {
206            var _this = this;
207
208            return (_this.width <= width) && (_this.height <= height);
209        };
210        this.showNF = function (displayType, width, height) { //displayType: fit [default], nat
211            var _this = this;
212            $.each(_this.tmp, function (index, tmpI) {
213                if (tmpI === 'overlay') {
214                    if (displayType === 'fit') {
215                        _this.instanceDisplay[index].removeClass('gc-overlay-display-hcenter gc-overlay-display-vcenter')
216                          .addClass('gc-overlay-display-center');
217                    } else {
218                        _this.instanceDisplay[index].removeClass('gc-overlay-display-center gc-overlay-display-hcenter gc-overlay-display-vcenter');
219
220                        if (_this.width <= width && _this.height <= height) {
221                            _this.instanceDisplay[index].addClass('gc-overlay-display-center');
222                        } else {
223                            if (_this.width <= width) {
224                                _this.instanceDisplay[index].addClass('gc-overlay-display-hcenter');
225                            }
226                            if (_this.height <= height) {
227                                _this.instanceDisplay[index].addClass('gc-overlay-display-vcenter');
228                            }
229                        }
230                    }
231                }
232            });
233        };
234        this.addLoader = function () {
235            var _this = this;
236            $.each(_this.instanceDisplay, function (index, el) {
237                $(el).before(_this.loader[index].getInstance());
238            });
239        };
240        this.removeLoader = function () {
241            var _this = this;
242            $.each(_this.instance, function (index, el) {
243                $(el).find('.' + _this.loader[index].pLoadingClass).remove();
244                $(_this.instanceDisplay[index]).fadeIn();
245            });
246        };
247
248        //Execution
249        this.init();
250    }
251
252    function GCIFrame(element, config) {
253        //Properties
254        this.type = 'iframe';
255        this.width = $(element).data('gc-width') || config.iframeWidth || 0;
256        this.height = $(element).data('gc-height') || config.iframeHeight || 0;
257        this.url = $(element).attr('href');
258        this.urlImgPoster = $(element).data('gc-poster-image') || ''; //NOT USED
259        this.txtImgThumb = config.txtImgThumbIframe || 'IFRAME';
260        this.state;
261        this.instance = [];
262        this.instanceIFrame = [];
263        this.dfdState = $.Deferred();
264        this.tmp = ['thumb', 'display', 'overlay'];
265        this.loader = [];
266        this.isMouseEventsOn = false;
267
268        //Methods
269        this.init = function () {
270            var _this = this;
271            $.each(_this.tmp, function (index, tmpI) {
272                _this.loader.push(new GCLoader());
273                if (tmpI === 'thumb') {
274                    _this.instance.push($('<div class="gc-display-container gc-thumb-img">' +
275                                                  '<div class="gc-icon gc-icon-play"></div>' +
276                                                  '<span>' + _this.txtImgThumb + '</span>' +
277                                              '</div>'));
278                    _this.instanceIFrame.push($(''));
279                    _this.instance[index].addClass('gc-dd-center');
280                }
281                if (tmpI === 'display') {
282                    _this.instance.push($('<div class="gc-slide-container">' +
283                                            '<div class="gc-display-container gc-dd-center" style="background-color: rgb(0, 0, 0);">' +
284                                                '<iframe class="gc-display-display" frameborder="0" allowfullscreen width="100%" height="100%" style = "background: #000;"/>' +
285                                            '</div>' +
286                                          '</div>'));
287                    _this.instanceIFrame.push(_this.instance[index].find('iframe'));
288                    _this.instanceIFrame[index].attr('src', '//about:blank');
289                    _this.instance[index].hide();
290
291                    $.when(_this.preload(tmpI)).done(function (result) {
292                        _this.fitSize(tmpI);
293                        _this.instance[index].fadeIn();
294                        _this.dfdState.resolve();
295                    });
296                }
297                if (tmpI === 'overlay') {
298                    _this.instance.push($('<div class="gc-overlay-container-display gc-dd-center" style="background-color: rgb(0, 0, 0);">' +
299                                            '<iframe frameborder="0" allowfullscreen width="100%" height="100%" style = "background: #000;"/>' +
300                                          '</div>'));
301                    _this.instanceIFrame.push(_this.instance[index].find('iframe'));
302                    _this.instanceIFrame[index].attr('src', '//about:blank');
303
304                    $.when(_this.preload(tmpI)).done(function (result) {
305                        _this.fitSize(tmpI);
306                        _this.dfdState.resolve();
307                    });
308                }
309            });
310        };
311        this.getInstance = function (area, width, height) {
312            var _this = this;
313
314            if (area !== 'thumb')
315                _this.fitSize(area, width, height);
316
317            return _this.instance[$.inArray(area, _this.tmp)];
318        };
319        this.preload = function (area) {
320            var _this = this;
321
322            return $.Deferred(
323				function (dfd) {
324				    _this.instanceIFrame[$.inArray(area, _this.tmp)].on('load', function () {
325				        dfd.resolve();
326				    }).attr('src', _this.url);
327				}
328			).promise();
329        };
330        this.fitSize = function (area, cWidth, cHeight) {
331            var _this = this;
332
333            var index = $.inArray(area, _this.tmp);
334
335            var oConfig = {};
336            if (_this.height <= cHeight &&
337                _this.width <= cWidth) {
338                oConfig = { 'width': _this.width, 'height': _this.height };
339            } else {
340                var ratio = _this.width / _this.height;
341
342                if (_this.height > cHeight &&
343                    _this.width <= cWidth) {
344                    oConfig = { 'width': cHeight * ratio, 'height': cHeight };
345                }
346
347                if (_this.height < cHeight &&
348                    _this.width > cWidth) {
349                    oConfig = { 'width': cWidth, 'height': cWidth / ratio };
350                }
351
352                if (_this.height > cHeight &&
353                    _this.width > cWidth) {
354                    var ratioC = cWidth / cHeight;
355                    if (ratioC < ratio) {
356                        if (ratio > 1) {
357                            oConfig = { 'width': cWidth, 'height': cWidth / ratio };
358                        } else {
359                            oConfig = { 'width': cHeight * ratio, 'height': cHeight };
360                        }
361                    } else {
362                        if (ratio > 1) {
363                            oConfig = { 'width': cHeight * ratio, 'height': cHeight };
364                        } else {
365                            oConfig = { 'width': cWidth, 'height': cWidth / ratio };
366                        }
367                    }
368                }
369            }
370           
370 
371            if (area === 'display') {
372                _this.instance[index].find('.gc-display-container').css(oConfig);
373            } else {
374                $(_this.instance[index]).css(oConfig);
375
376            }
377        };
378        this.addLoader = function () {
379            var _this = this;
380            $.each(_this.instanceIFrame, function (index, el) {
381                if (_this.tmp[index] !== 'thumb')
382                    $(el).before(_this.loader[index].getInstance());
383            });
384        };
385        this.removeLoader = function () {
386            var _this = this;
387
388            $.each(_this.instance, function (index, el) {
389                $(el).find('.' + _this.loader[index].pLoadingClass).remove();
390            });
391        };
392        this.navigate = function (area) {
393            var _this = this;
394            var index = $.inArray(area, _this.tmp);
395
396            _this.instanceIFrame[index].detach();
397            if (area === 'display') {
398                _this.instanceIFrame[index].appendTo(_this.instance[index].find('.gc-display-container'));
399            }
400            if (area === 'overlay') {
401                _this.instanceIFrame[index].appendTo(_this.instance[index]);
402            }
403        };
404
405        //Execution
406        this.init();
407    }
408
409    function GCVideo(element, config) {
410        //Properties
411        this.type = 'video';
412        this.url = $(element).attr('href');
413        this.width = parseInt($(element).data('gc-width'), 10) || config.videoWidth || 0;
414        this.height = parseInt($(element).data('gc-height'), 10) || config.videoHeight || 0;
415        this.formats = $(element).data('gc-formats') || [];
416        this.poster = $(element).data('gc-poster') || '';
417        this.txtImgThumb = config.txtImgThumbVideo || 'VIDEO';
418        this.instance = [];
419        this.instanceVC = []; // video container
420        this.instanceVideo = [];
421        this.state;
422        this.dfdState = $.Deferred();
423        this.tmp = ['thumb', 'display', 'overlay'];
424        this.isMouseEventsOn = false;
425
426        //Methods
427        this.init = function () {
428            var _this = this;
429
430            $.each(_this.tmp, function (index, tmpI) {
431                if (tmpI === 'thumb') {
432                    _this.instance.push($('<div class="gc-display-container gc-thumb-img">' +
433                                                  '<div class="gc-icon gc-icon-play"></div>' +
434                                                  '<span>' + _this.txtImgThumb + '</span>' +
435                                              '</div>'));
436                    _this.instanceVC.push($(''));
437                    _this.instanceVideo.push($(''));
438                    _this.instance[index].addClass('gc-dd-center');
439                }
440                if (tmpI === 'display') {
441                    _this.instance.push($('<div class="gc-slide-container">' +
442                                    '<div class="gc-display-container gc-dd-center" style = "background-color: #000;">' +
443                                        '<video class="gc-display-display" controls preload style="width: 100%; height: 100%;"' +
444                                            'poster="' + _this.poster + '"/>' +
445                                    '</div></div>'));
446                    _this.instanceVC.push(_this.instance[index].find('.gc-display-container'));
447                    _this.instanceVideo.push(_this.instanceVC[index].find('.gc-display-display'));
448
449                    _this.instance[index].hide();
450                    _this.formats.unshift(_this.url);
451                    $.each(_this.formats, function (i, v) {
452                        switch (v.split('.').pop()) {
453                            case 'webm':
454                                _this.instanceVideo[index].append('<source src="' + v + '" type="video/webm" />');
455                                break;
456                            case 'ogv':
457                                _this.instanceVideo[index].append('<source src="' + v + '" type="video/ogg" />');
458                                break;
459                            case 'mp4':
460                                _this.instanceVideo[index].append('<source src="' + v + '" type="video/mp4" />');
461                                break;
462                        }
463                    });
464                    _this.fitSize(tmpI);
465                    _this.instance[index].fadeIn();
466                    _this.dfdState.resolve();
467                }
468                if (tmpI === 'overlay') {
469                    _this.instance.push($('<div class="gc-overlay-container-display gc-dd-center" style = "background-color: #000;">
469' +
470                                            '<video class="gc-overlay-display" controls preload style="width: 100%; height: 100%;"' +
471                                                'poster="' + _this.poster + '"/>' +
472                                        '</div>'));
473                    _this.instanceVC.push('');
474                    _this.instanceVideo.push(_this.instance[index].find('.gc-overlay-display'));
475
476                    _this.instance[index].hide();
477                    _this.formats.unshift(_this.url);
478                    $.each(_this.formats, function (i, v) {
479                        switch (v.split('.').pop()) {
480                            case 'webm':
481                                _this.instanceVideo[index].append('<source src="' + v + '" type="video/webm" />');
482                                break;
483                            case 'ogv':
484                                _this.instanceVideo[index].append('<source src="' + v + '" type="video/ogg" />');
485                                break;
486                            case 'mp4':
487                                _this.instanceVideo[index].append('<source src="' + v + '" type="video/mp4" />');
488                                break;
489                        }
490                    });
491                    _this.instance[index].fadeIn();
492                    _this.dfdState.resolve();
493                }
494            });
495        };
496        this.getInstance = function (area, width, height) {
497            var _this = this;
498
499            if (area !== 'thumb') {
500                _this.fitSize(area, width, height);
501            }
502
503            return _this.instance[$.inArray(area, _this.tmp)];
504        };
505        this.fitSize = function (area, cWidth, cHeight) {
506            var _this = this;
507            var index = $.inArray(area, _this.tmp);
508            var oConfig = {};
509
510            if (_this.height <= cHeight &&
511                _this.width <= cWidth) {
512                oConfig = { 'width': _this.width, 'height': _this.height };
513            } else {
514                var ratio = _this.width / _this.height;
515
516                if (_this.height > cHeight &&
517                    _this.width <= cWidth) {
518                    oConfig = { 'width': cHeight * ratio, 'height': cHeight };
519                }
520
521                if (_this.height < cHeight &&
522                    _this.width > cWidth) {
523                    oConfig = { 'width': cWidth, 'height': cWidth / ratio };
524                }
525
526                if (_this.height > cHeight &&
527                    _this.width > cWidth) {
528                    var ratioC = cWidth / cHeight;
529                    if (ratioC < ratio) {
530                        if (ratio > 1) {
531                            oConfig = { 'width': cWidth, 'height': cWidth / ratio };
532                        } else {
533                            oConfig = { 'width': cHeight * ratio, 'height': cHeight };
534                        }
535                    } else {
536                        if (ratio > 1) {
537                            oConfig = { 'width': cHeight * ratio, 'height': cHeight };
538                        } else {
539                            oConfig = { 'width': cWidth, 'height': cWidth / ratio };
540                        }
541                    }
542                }
543            }
544            if (area === 'display') {
545                _this.instanceVC[index].css(oConfig);
546            } else {
547                $(_this.instance[index]).css(oConfig);
548            }
549        };
550        this.navigate = function (area) {
551            var _this = this;
552            var index = $.inArray(area, _this.tmp);
553
554            _this.instanceVideo[index].detach();
555            if (area === 'display') {
556                _this.instanceVideo[index].appendTo(_this.instanceVC[index]);
557            }
558            if (area === 'overlay') {
559                _this.instanceVideo[index].appendTo(_this.instance[index]);
560            }
561        };
562
563        //Execution
564        this.init();
565    }
566
567    function GCDisplay(config, component) {
568        //Properties
569        this.component = component;
570        this.width = config.widthDisplay;
571        this.height = config.heightDisplay;
572        this.wDperc = 100; //widthDisplayPerc
573        this.isShowAlwaysIcons = config.isShowAlwaysIcons;
574        this.speedHideIcons = config.speedHideIcons;
575        this.mouseEnterCB = config.mouseEnterDisplayCB;
576        this.mouseLeaveCB = config.mouseLeaveDisplayCB;
577        this.isAutoPlay = config.isAutoPlayDisplay;
578        this.pauseTime = config.pauseTimeDisplay;
579        this.isPauseOnHover = config.isPauseOnHoverDisplay;
580        this.isDownloadEnabled = config.isDownloadEnabled;
581        this.downloadPosition = config.downloadPosition;
582
583        this.instancePrime = $('<div class="gc-display-area">' +
584          '<div class = "gc-display-area-container">' +
585          '<div class="gc-icon gc-icon-download"></div>' +
586          '<div class="gc-icon gc-icon-next"></div>' +
587          '<div class="gc-icon gc-icon-prev"></div>' +
588          '</div>' +
589          '</div>');
590        this.instance = this.instancePrime.find('.gc-display-area-container');
591        this.lens = new GCLens(config, component);
592        this.zoom = new GCZoom(config, component);
593
594        if (this.zoom.isZCapEnabled === true) {
595            this.zoom.caption = new GCCaption(config, this.zoom);
596        }
597
598        //Methods
599        this.init = function () {
600            var _this = this;
601
602            _this.btnPrevious = _this.instance.find('.gc-icon-prev');
603            _this.btnNext = _this.instance.find('.gc-icon-next');
604            _this.btnDownload = _this.instance.find('.gc-icon-download');
605
606            if (_this.component.element.find('li').length === 1 || _this.isShowAlwaysIcons === false) {
607                _this.btnPrevious.hide();
608                _this.btnNext.hide();
609                _this.btnDownload.hide();
610            }
611            _this.currentMousePos = {
612                x: -1,
613                y: -1
614            };
615            _this.mousePos = 'out'; //in; out
616            _this.isMouseInDspArea = false;
617            _this.mouseTimer = 0;
618            _this.isTouchMove = false;
619            _this.tpStart = {
620                x: 0,
621                y: 0
622            };
623            _this.tpEnd = {
624                x: 0,
625                y: 0
626            };
627            _this.autoPlayInterval = '';
628            _this.supportCanvas = Modernizr.canvas;
629
630            if (_this.isDownloadEnabled === false || _this.supportCanvas === false) {
631                _this.btnDownload.addClass('gc-hide');
632            } else {
633                var cssDownloadPosition = {
634                    top: '',
635                    bottom: '',
636                    right: '',
637                    left: ''
638                };
639                var bW = '-' + _this.instancePrime.css('border-left-width');
640                switch (_this.downloadPosition) {
641                    case 1:
642                        cssDownloadPosition.top = bW;
643                        cssDownloadPosition.left = bW;
644                        break;
645                    case 2:
646                        cssDownloadPosition.top = bW;
647                        cssDownloadPosition.right = bW;
648                        break;
649                    case 4:
650                        cssDownloadPosition.bottom = bW;
651                        cssDownloadPosition.right = bW;
652                        break;
653                    default:
654                        cssDownloadPosition.bottom = bW;
655                        cssDownloadPosition.left = bW;
656                        break;
657                }
658                _this.btnDownload.css(cssDownloadPosition);
659            }
660        };
661        this.initEvents = function () {
662            var _this = this;
663
664            _this.instance.on('mouseenter.glasscaseA', function () {
665                _this.isMouseInDspArea = true;
666            }).on('mouseleave.glasscaseA', function () {
667                _this.isMouseInDspArea = false;
668            });
669
670            $(_this.lens.getInstance()).on('mousemove.glasscase', $.proxy(_this.mousemoveHandler, _this))
671              .on('mouseenter.glasscase', $.proxy(_this.mouseenterHandler, _this))
672              .on('mouseenter.glasscase', $.proxy(_this.mouseEnterCB, _this))
673              .on('mouseleave.glasscase', $.proxy(_this.mouseleaveHandler, _this))
674              .on('mouseleave.glasscase', $.proxy(_this.mouseLeaveCB, _this))
675              .on('touchstart.glasscase', $.proxy(_this.touchStart, _this))
676              .on('touchmove.glasscase', $.proxy(_this.touchMove, _this))
677              .on('touchend.glasscase', $.proxy(_this.touchEnd, _this));
678
679            if (_this.isShowAlwaysIcons === false && _this.component.thumbs.li.length > 1) {
680                _this.instance.on('mouseenter.glasscaseDA', $.proxy(_this.toggleNavBtn, _this, 'show', 'mouseenter'))
681                              .on('mouseleave.glasscaseDA', $.proxy(_this.toggleNavBtn, _this, 'hide' , 'mouseleave'))
682                              .on('mousemove.glasscaseDA', function (event) {
683                                  _this.toggleNavBtn('show');
684                                  clearTimeout(_this.mouseTimer);
685                                  _this.mouseTimer = setTimeout(function () {
686                                      _this.toggleNavBtn('hide');
687                                  }, _this.speedHideIcons);
688                              })
689                              .on('touchmove.glasscaseDA', function (event) {
690                                  _this.toggleNavBtn('show');
691                                  clearTimeout(_this.mouseTimer);
692                                  _this.mouseTimer = setTimeout(function () {
693                                      _this.toggleNavBtn('hide');
694                                  }, _this.speedHideIcons);
695
696                                  if (_this.zoom.isEnabled === true) {
697                                      event.preventDefault();
698                                  }
699                              });
700            }
701            if (_this.component.overlay.isEnabled === true) {
702                $.each(_this.component.items, function (index, slide) {
703                    $.when(slide.dfdstate).done(function () {
704                        if (slide.type === 'video') {
705                            $(slide.getInstance('display')).on('click.glasscase', function (event) {
706                                _this.component.overlay.toggle();
707                            }).find('video').on('click.glasscase', function (e) { return false;});
708                        } else {
709                            $(slide.getInstance('display')).on('click.glasscase', function (event) {
710                                _this.component.overlay.toggle();
711                            });
712                        }
713                    });
714
715                    
716                });
717            }
718
719            _this.btnPrevious.on('click.glasscase', function () {
720                _this.navigate('previous');
721            });
722            _this.btnNext.on('click.glasscase', function () {
723                _this.navigate('next');
724            });
725
726            _this.btnDownload.on('click.glasscase', function () {
727                var canvas = document.createElement('canvas');
728                canvas.width = _this.component.items[_this.component.thumbs.current].width;
729                canvas.height = _this.component.items[_this.component.thumbs.current].height;
730                var context = canvas.getContext('2d');
731                var image = _this.instance.find('.gc-display-display')[_this.component.thumbs.current];
732
733                context.drawImage(image, 0, 0);
734                var blob = new Blob();
735                canvas.toBlob(function (blob) {
736                    saveAs(blob, $(image).attr('src').replace(/^.*[\\\/]/, ''));
737                }, 'image/png');
738            });
739
740            if (_this.isAutoPlay === true) {
741                _this.autoPlay('start');
742
743                if (_this.isPauseOnHover === true) {
744                    _this.instance.on('mouseenter.glasscase', $.proxy(_this.autoPlay, _this, 'stop'))
745                      .on('mouseleave.glasscase', $.proxy(_this.autoPlay, _this, 'start'));
746                }
747            }
748        };
749        this.setup = function (wC) {
750            var _this = this;
751
752            wC = _this.component.element.outerWidth();
753            var nextDW = _this.wDperc * wC / 100;
754            var nextDH = nextDW * _this.height / _this.width;
755
756            _this.instancePrime.css({
757                'height': '0',
758                'width': '0'
759            })
760              .css({
761                  'height': Math.ceil(nextDH),
762                  'width': Math.ceil(nextDW)
763              });
764
765            $.each(_this.component.items, function (index, item) {
766                _this.instance.append(_this.component.items[index].getInstance('display', Math.ceil(nextDW), Math.ceil(nextDH)));
767            });
768
769            _this.slidesCnt = _this.instance.find('.gc-slide-container');
770            $(_this.slidesCnt[_this.component.thumbs.current]).addClass('gc-slide-container-current');
771            _this.slides = _this.slidesCnt.find('.gc-display-container');
772            _this.display = _this.slides.find('.gc-display-display');
773
774            $.each(_this.component.items, function (index, item) {
775                $.when(item.dfdState).done(function () {
776                    if (item.type === 'image') {
777                        _this.setupDisplay(index, item);
778                        _this.setupDisplay(index, item);
779                    }
780                });
781            });
782
783            _this.btnPrevious.css('margin-top', -(_this.btnPrevious.outerHeight() / 2));
784            _this.btnNext.css('margin-top', -(_this.btnNext.outerHeight() / 2));
785        };
786        this.setupZoomLens = function () {
787            var _this = this;
788
789            $.when(_this.component.items[_this.component.thumbs.current].dfdState).done(function () {
790                if (_this.component.items[_this.component.thumbs.current].isMouseEventsOn === false) {
791                    _this.mouseleaveHandler();
792                    return;
793                }
794
795                if (_this.component.items[_this.component.thumbs.current].type === 'image') {
796                    $(_this.slides[_this.component.thumbs.current]).append(_this.lens.getInstance());
797                    _this.zoom.changeCnt();
798
799                    $.when(_this.zoom.dfdState).done(function () {
800                        _this.lens.setup(_this, _this.component.items[_this.component.thumbs.current]);
801                        if (_this.isMousePosInDsp() && _this.isMouseInDspArea === true) {
802                            _this.mouseenterHandler();
803                        } else {
804                            _this.mouseleaveHandler();
805                        }
806                    });
807                }
808            });
809        };
810        this.setupDisplay = function (index, item) {
811            var _this = this;
812            var ratio;
813            var wdd;
814            var hdd;
815
816            $(_this.slides[index]).css({
817                'width': '0',
818                'height': '0'
819            })
820              .css({
821                  'width': _this.instance.width(),
822                  'height': _this.instance.height()
823              });
824
825            item.wDisplayR = $(_this.slides[index]).outerWidth() / item.width;
826            item.hDisplayR = $(_this.slides[index]).outerHeight() / item.height;
827
828            if ((item.wDisplayR < 1 || item.hDisplayR < 1)) {
829                item.isMouseEventsOn = _this.zoom.isEnabled === true ? true : false;
830                ratio = item.wDisplayR < item.hDisplayR ? item.wDisplayR : item.hDisplayR;
831            } else {
832                // In case that the image's width and height are smaller than the container's width and height
833                item.isMouseEventsOn = false;
834                ratio = 1;
835            }
836            wdd = ratio * item.width;
837            hdd = ratio * item.height;
838
839            if (_this.component.items[index].type === 'image') {
840                $(_this.display[index]).css({
841                    'width': wdd,
842                    'height': hdd
843                });
844            }
845            $(_this.slides[index]).css({
846                'width': wdd,
847                'height': hdd
848            });
849
850            // Positioning the container in the center of DisplayArea
851            var borderVal = parseFloat(_this.instance.css('border-left-width')) * 2;
852            var paddingVal = parseFloat(_this.instance.css('padding-top')) * 2;
853
854            var percMarginLeft = (($(_this.slides[index]).outerWidth() / 2) * 100) / (_this.instance.outerWidth() - borderVal - paddingVal);
855            var percMarginTop = (($(_this.slides[index]).outerHeight() / 2) * 100) / (_this.instance.outerWidth() - borderVal - paddingVal);
856
857            $(_this.slides[index]).css({
858                'margin-left': '-' + percMarginLeft + '%',
859                'margin-top': '-' + percMarginTop + '%'
860            });
861        };
862        this.getInstance = function () {
863            return this.instancePrime;
864        };
865        this.mousemoveHandler = function (event, oEventTrigger) {
866            var _this = this;
867
868            if (oEventTrigger !== undefined) {
869                event = oEventTrigger;
870            }
871
872            if (event !== undefined) {
873                _this.currentMousePos = _this.isTouchMove === true && event.originalEvent.touches.length === 1 ? {
874                    x: event.originalEvent.touches[0].pageX,
875                    y: event.originalEvent.touches[0].pageY
876                } : {
877                    x: event.pageX,
878                    y: event.pageY
879                };
880            }
881
882            if (_this.currentMousePos.x === -1 && _this.currentMousePos.y === -1) {
883                return;
884            }
885
886            _this.calcMousePos();
887
888            if ((_this.zoom.isSlowZoom === false) || (_this.zoom.isSlowZoom === true && event === undefined)) {
889                _this.zoom.display.css({
890                    'top': _this.zoom.newZoom.top,
891                    'left': _this.zoom.newZoom.left
892                });
893            }
894
895            if ((_this.lens.isSlowLens === false) || (_this.lens.isSlowLens === true && event === undefined)) {
896                _this.lens.display.css({
897                    'top': _this.lens.newLens.top,
898                    'left': _this.lens.newLens.left
899                });
900            }
901        };
902        this.mouseenterHandler = function (event, oEventTrigger) {
903            var _this = this;
904            if (_this.component.items[_this.component.thumbs.current].isMouseEventsOn === false) {
905                return;
906            }
907
908            if (oEventTrigger !== undefined) {
909                event = oEventTrigger;
910            }
911
912            _this.zoom.state = 'showing';
913
914            if (event !== undefined) {
915                _this.currentMousePos = _this.isTouchMove === true && event.originalEvent.touches.length === 1 ? {
916                    x: event.originalEvent.touches[0].pageX,
917                    y: event.originalEvent.touches[0].pageY
918                } : {
919                    x: event.pageX,
920                    y: event.pageY
921                };
922            }
923
924            _this.calcMousePos();
925
926            _this.zoom.currentZoom = {
927                top: _this.zoom.newZoom.top,
928                left: _this.zoom.newZoom.left
929            };
930            _this.zoom.display.css({
931                'top': _this.zoom.newZoom.top,
932                'left': _this.zoom.newZoom.left
933            });
934
935            _this.lens.currentLens = {
936                top: _this.lens.newLens.top,
937                left: _this.lens.newLens.left
938            };
939            _this.lens.display.css({
940                'top': _this.lens.newLens.top,
941                'left': _this.lens.newLens.left
942            });
943
944            if (_this.zoom.zooming === false) {
945                if (_this.zoom.position === 'inner' || _this.zoom.isAIZooming === true) {
946                    _this.zoom.instance.fadeIn(_this.component.config.speed);
947                } else {
948                    _this.lens.display.fadeIn(_this.component.config.speed);
949                    _this.zoom.instance.fadeIn(_this.component.config.speed);
950                }
951            }
952
953            if (_this.zoom.isSlowZoom === true) {
954                clearTimeout(_this.zoom.slowZoomTimer);
955                _this.zoom.slowDown();
956            }
957
958            if (_this.lens.isSlowLens === true) {
959                clearTimeout(_this.lens.slowLensTimer);
960                _this.lens.slowDown();
961            }
962            _this.zoom.zooming = true;
963        };
964        this.mouseleaveHandler = function (event, oEventTrigger) {
965            var _this = this;
966
967            _this.lens.display.stop().hide();
968            _this.zoom.instance.stop().fadeOut(_this.component.config.speed);
969            _this.zoom.state = 'hiding';
970
971            if (oEventTrigger !== undefined) {
972                event = oEventTrigger;
973            }
974
975            if (event !== undefined) {
976                _this.currentMousePos = _this.isTouchMove === true && event.originalEvent.touches.length === 1 ? {
977                    x: event.originalEvent.touches[0].pageX,
978                    y: event.originalEvent.touches[0].pageY
979                } : {
980                    x: event.pageX,
981                    y: event.pageY
982                };
983            }
984
985            if (_this.zoom.isSlowZoom === true) {
986                clearTimeout(_this.zoom.slowZoomTimer);
987            }
988
989            if (_this.lens.isSlowLens === true) {
990                clearTimeout(_this.lens.slowLensTimer);
991            }
992            _this.zoom.zooming = false;
993        };
994        this.touchStart = function (event) {
995
996            event.preventDefault();
997        };
998        this.touchMove = function (event) {
999            var _this = this;
1000
1001            if (_this.isTouchMove === false) {
1002                _this.isTouchMove = true;
1003                $(_this.lens.getInstance()).trigger('mouseenter.glasscase', event);
1004            }
1005            $(_this.lens.getInstance()).trigger('mousemove.glasscase', event);
1006
1007            event.preventDefault();
1008        };
1009        this.touchEnd = function (event) {
1010            var _this = this;
1011
1012            if (_this.isTouchMove === true) {
1013                $(_this.lens.getInstance()).trigger('mouseleave.glasscase', event);
1014                _this.isTouchMove = false;
1015            } else {
1016                _this.component.overlay.toggle();
1017            }
1018
1019            event.preventDefault();
1020        };
1021        this.calcMousePos = function () {
1022            var _this = this;
1023
1024            var areaDspOffset = $(_this.instance).offset(); 
1025            var imgOffset = $(_this.slides[_this.component.thumbs.current]).position();
1026            var mouseXRelative = _this.currentMousePos.x - (areaDspOffset.left + imgOffset.left + parseFloat($(_this.slides[_this.component.thumbs.current]).css('margin-left')));
1027            var mouseYRelative = _this.currentMousePos.y - (areaDspOffset.top + imgOffset.top + parseFloat($(_this.slides[_this.component.thumbs.current]).css('margin-top')));
1028            var imageDisplayHeight = $(_this.display[_this.component.thumbs.current]).outerHeight();
1029            var imageDisplayWidth = $(_this.display[_this.component.thumbs.current]).outerWidth();
1030            var lensWidth = _this.lens.display.outerWidth();
1031            var lensHeight = _this.lens.display.outerHeight();
1032            var lensTop = mouseYRelative - Math.round(lensHeight / 2);
1033            var lensLeft = mouseXRelative - Math.round(lensWidth / 2); // 2 -> the middle
1034            var ratio = _this.component.items[_this.component.thumbs.current].width / imageDisplayWidth;
1035            var zoomTop = -lensTop * ratio;
1036            var zoomLeft = -lensLeft * ratio;
1037
1038            if (mouseYRelative - lensHeight / 2 < 0) {
1039                lensTop = 0;
1040                zoomTop = 0;
1041            }
1042            if (mouseYRelative + lensHeight / 2 > 0 + imageDisplayHeight) {
1043                lensTop = imageDisplayHeight - lensHeight;
1044                zoomTop = -(_this.component.items[_this.component.thumbs.current].height - _this.zoom.instance.outerHeight());
1045            }
1046            if (mouseXRelative - lensWidth / 2 < 0) {
1047                lensLeft = 0;
1048                zoomLeft = 0;
1049            }
1050            if (mouseXRelative + lensWidth / 2 > 0 + imageDisplayWidth) {
1051                lensLeft = imageDisplayWidth - lensWidth;
1052                zoomLeft = -(_this.component.items[_this.component.thumbs.current].width - _this.zoom.instance.outerWidth());
1053            }
1054
1055            _this.zoom.newZoom = {
1056                top: zoomTop,
1057                left: zoomLeft
1058            };
1059            _this.lens.newLens = {
1060                top: lensTop,
1061                left: lensLeft
1062            };
1063        };
1064        this.isMousePosInDsp = function () {
1065            var _this = this;
1066
1067            var areaDspOffset = $(_this.instance).offset(); 
1068            var imgOffset = $(_this.slides[_this.component.thumbs.current]).position();
1069            var mouseXRelative = _this.currentMousePos.x - (areaDspOffset.left + imgOffset.left + parseFloat($(_this.slides[_this.component.thumbs.current]).css('margin-left')));
1070            var mouseYRelative = _this.currentMousePos.y - (areaDspOffset.top + imgOffset.top + parseFloat($(_this.slides[_this.component.thumbs.current]).css('margin-top')));
1071            var imageDisplayWidth = $(_this.display[_this.component.thumbs.current]).outerWidth();
1072            var imageDisplayHeight = $(_this.display[_this.component.thumbs.current]).outerHeight();
1073
1074            if ((mouseXRelative >= 0 && mouseYRelative >= 0) && (mouseXRelative <= imageDisplayWidth && mouseYRelative <= imageDisplayHeight)) {
1075                return true;
1076            } else {
1077                return false;
1078            }
1079        };
1080        this.navigate = function (direction, context) {
1081            var _this = context || this;
1082
1083            _this.component.thumbs.navigate(direction);
1084            _this.component.changeCnt();
1085        };
1086        this.changeCnt = function () {
1087            var _this = this;
1088            var currentEl = _this.slidesCnt[_this.component.thumbs.old];
1089            var nextEl = _this.slidesCnt[_this.component.thumbs.current];
1090            var dirRight = _this.component.thumbs.old === (_this.component.items.length - 1) && _this.component.thumbs.current === 0;
1091            var dirLeft = _this.component.thumbs.old === 0 && _this.component.thumbs.current === (_this.component.items.length - 1);
1092            var dir = ((_this.component.thumbs.old < _this.component.thumbs.current && !dirLeft) || dirRight) ? 'right' : 'left';
1093
1094            _this.setupZoomLens();
1095            dynamics.animate(currentEl, {
1096                opacity: 0
1097            }, {
1098                type: dynamics.easeInOut,
1099                duration: 100,
1100                complete: function () {
1101                    dynamics.css(currentEl, {
1102                        opacity: 0,
1103                        visibility: 'hidden'
1104                    });
1105
1106                    if (_this.component.items[_this.component.thumbs.old].type !== '
1106image') {
1107                        _this.component.items[_this.component.thumbs.old].navigate('display');
1108                    }
1109                }
1110            });
1111
1112            // set the right properties for the next element to come in
1113            dynamics.css(nextEl, {
1114                opacity: 1
1115            });
1116
1117            _this.slidesCnt.removeClass('gc-slide-container-current');
1118            $(nextEl).addClass('gc-slide-container-current');
1119
1120            // animate the next element in
1121            dynamics.animate(nextEl, {
1122                opacity: 1
1123            }, {
1124                type: dynamics.easeInOut,
1125                duration: 100,
1126                complete: function () {
1127                    dynamics.css(nextEl, {
1128                        opacity: 1,
1129                        visibility: 'visible'
1130                    });
1131                }
1132            });
1133        };
1134        this.toggleNavBtn = function (action, eventType, event) {
1135            var _this = this;
1136
1137            if (event !== undefined) {
1138                _this.currentMousePos = _this.isTouchMove === true && event.originalEvent.touches.length === 1 ? {
1139                    x: event.originalEvent.touches[0].pageX,
1140                    y: event.originalEvent.touches[0].pageY
1141                } : {
1142                    x: event.pageX,
1143                    y: event.pageY
1144                };
1145            }
1146
1147            if (eventType === 'mouseleave') {
1148                _this.mousePos = 'out';
1149            }
1150
1151            if (eventType === 'mouseenter') {
1152                _this.mousePos = 'in';
1153            }
1154
1155            if (action === 'hide') {
1156                _this.btnPrevious.hide();
1157                _this.btnNext.hide();
1158                if (_this.isDownloadEnabled === true) {
1159                    _this.btnDownload.hide();
1160                }
1161            } else {
1162                _this.btnPrevious.show();
1163                _this.btnNext.show();
1164                if (_this.isDownloadEnabled === true) {
1165                    _this.btnDownload.show();
1166                }
1167            }
1168        };
1169        this.autoPlay = function (action) {
1170            var _this = this;
1171
1172            if (action === 'stop') {
1173                clearInterval(_this.autoPlayInterval);
1174            } else {
1175                _this.autoPlayInterval = setInterval(_this.navigate, _this.pauseTime, 'next', _this);
1176            }
1177
1178        };
1179
1180        //Execution
1181        this.init();
1182    }
1183
1184    function GCLens(config, component) {
1185        //Properties
1186        this.component = component;
1187        this.isSlowLens = config.isSlowLens;
1188        this.speedSlowLens = config.speedSlowLens;
1189        this.instance = $('<div class="gc-lens-container">' +
1190          '<div class="gc-lens-display"></div>' +
1191          '</div>');
1192        this.display = this.instance.find('.gc-lens-display');
1193        this.slowLensTimer = 0;
1194        this.newLens = {
1195            left: 0,
1196            top: 0
1197        };
1198        this.currentLens = {
1199            left: 0,
1200            top: 0
1201        };
1202
1203        //Methods
1204        this.init = function () {
1205            var _this = this;
1206
1207            _this.display.hide();
1208            _this.newLens = {
1209                left: 0,
1210                top: 0
1211            };
1212            _this.currentLens = {
1213                left: 0,
1214                top: 0
1215            };
1216            _this.slowLensTimer = 0;
1217        };
1218        this.setup = function (display, slide) {
1219            var _this = this;
1220
1221            var percZoomWidth = Math.round(display.zoom.instance.outerWidth() / slide.width * 100);
1222            //var valueLensW = Math.round(display.display.outerWidth() * percZoomWidth / 100);
1223            var valueLensW = Math.round($(display.display[_this.component.thumbs.current]).outerWidth() * percZoomWidth / 100);
1224            var percZoomHeight = Math.round(display.zoom.instance.outerHeight() / slide.height * 100);
1225            var valueLensH = Math.round($(display.display[_this.component.thumbs.current]).outerHeight() * percZoomHeight / 100);
1226            var height = $(display.display[_this.component.thumbs.current]).outerHeight();
1227            var width = $(display.display[_this.component.thumbs.current]).outerWidth();
1228
1229            _this.instance.css({
1230                'width': width,
1231                'height': height
1232            });
1233            _this.instance.css({
1234                'top': $(display.display[_this.component.thumbs.current]).position().top,
1235                'left': $(display.display[_this.component.thumbs.current]).position().left
1236            });
1237            _this.display.css({
1238                'width': (valueLensW),
1239                'height': (valueLensH)
1240            });
1241
1242            if (display.zoom.position === 'inner' || display.zoom.isAIZooming === true) {
1243                display.zoom.instance.appendTo(_this.instance);
1244            }
1245        };
1246        this.getInstance = function () {
1247            return this.instance;
1248        };
1249        this.slowDown = function () {
1250            var _this = this;
1251            var diffLensPos = {
1252                left: 0,
1253                top: 0
1254            };
1255            var moveLensPos = {
1256                left: 0,
1257                top: 0
1258            };
1259
1260            diffLensPos = {
1261                top: _this.newLens.top - _this.currentLens.top,
1262                left: _this.newLens.left - _this.currentLens.left
1263            };
1264            moveLensPos = {
1265                top: -diffLensPos.top / (_this.speedSlowLens / 100),
1266                left: -diffLensPos.left / (_this.speedSlowLens / 100)
1267            };
1268            _this.currentLens = {
1269                top: _this.currentLens.top - moveLensPos.top,
1270                left: _this.currentLens.left - moveLensPos.left
1271            };
1272
1273            if (diffLensPos.top < 1 && diffLensPos.top > -1) {
1274                _this.currentLens.top = _this.newLens.top;
1275            }
1276            if (diffLensPos.left < 1 && diffLensPos.left > -1) {
1277                _this.currentLens.left = _this.newLens.left;
1278            }
1279
1280            _this.display.css({
1281                'top': _this.currentLens.top,
1282                'left': _this.currentLens.left
1283            });
1284            _this.slowLensTimer = setTimeout(function () {
1285                _this.slowDown();
1286            }, 25);
1287        };
1288
1289        //Execution
1290        this.init();
1291    }
1292
1293    function GCZoom(config, component) {
1294        //Properties
1295        this.component = component;
1296        this.position = config.zoomPosition;
1297        this.autoInnerZoom = config.autoInnerZoom;
1298        this.isEnabled = config.isZoomEnabled;
1299        this.isSlowZoom = config.isSlowZoom;
1300        this.speedSlowZoom = config.speedSlowZoom;
1301        this.isDiffWH = config.isZoomDiffWH;
1302        this.width = config.zoomWidth;
1303        this.height = config.zoomHeight;
1304        this.alignment = config.zoomAlignment;
1305        this.margin = config.zoomMargin;
1306        this.isZCapEnabled = config.isZCapEnabled;
1307
1308        this.instance = $('<div class = "gc-zoom-area"/>');
1309        this.isAIZooming = false; //for internal use
1310        this.dfdState = $.Deferred();
1311        this.state = 'showing'; //showing, hiding
1312
1313        //Methods
1314        this.init = function () {
1315            var _this = this;
1316
1317            _this.instance.hide();
1318            _this.container = _this.instance.find('.gc-zoom-container');
1319            _this.display = _this.container.find('img');
1320
1321            if (_this.position === 'inner') {
1322                _this.isDiffWH = true;
1323                _this.width = 0;
1324                _this.height = 0;
1325            }
1326            _this.zooming = false;
1327            _this.newZoom = {
1328                left: 0,
1329                top: 0
1330            };
1331            _this.currentZoom = {
1332                left: 0,
1333                top: 0
1334            };
1335            _this.slowZoomTimer = 0;
1336        };
1337        this.setup = function () {
1338            var _this = this;
1339
1340            _this.container.detach();
1341            _this.instance.append(_this.component.items[_this.component.thumbs.current].getInstance('zoom'));
1342            _this.container = _this.instance.find('.gc-zoom-container');
1343            _this.display = _this.container.find('img');
1344
1345            _this.calcSettings();
1346        };
1347        this.calcSettings = function () {
1348            var _this = this;
1349
1350            if (_this.position !== 'inner') {
1351                _this.isAIZooming = false;
1352                _this.instance.appendTo(_this.component.element).removeClass('gc-zoom-inner');
1353            }
1354
1355            if (_this.position === 'inner' || _this.isAIZooming === true) {
1356                _this.instance.appendTo(_this.component.display.slides[_this.component.thumbs.current]).addClass('gc-zoom-inner');
1357            }
1358
1359            var borderVal = parseFloat(_this.instance.css('border-left-width')) * 2 || 0;
1360            var paddingVal = parseFloat(_this.instance.css('padding-top')) * 2 || 0;
1361            var wZ = (_this.position === 'inner') ? paddingVal : (borderVal + paddingVal);
1362            var hZ = (_this.position === 'inner') ? paddingVal : (borderVal + paddingVal);
1363
1364            for (var i = 0; i < 2; i++) {
1365                if ((_this.isDiffWH && _this.width > 0)) {
1366                    wZ += _this.width < _this.component.items[_this.component.thumbs.current].width ? _this.width : _this.component.items[_this.component.thumbs.current].width;
1367                } else {
1368                    wZ += $(_this.component.display.display[_this.component.thumbs.current]).outerWidth();
1369                }
1370                if ((_this.isDiffWH && _this.height > 0)) {
1371                    hZ += _this.height < _this.component.items[_this.component.thumbs.current].height ? _this.height : _this.component.items[_this.component.thumbs.current].height;
1372                } else {
1373                    hZ += $(_this.component.display.display[_this.component.thumbs.current]).outerHeight();
1374                }
1375                if (_this.isDiffWH === false && this.isAIZooming === false) {
1376                    wZ = hZ;
1377                }
1378                if (_this.autoInnerZoom === true && _this.position !== 'inner') {
1379                    if (_this.component.element.outerWidth() + wZ > $(window).width()) {
1380                        _this.isAIZooming = true;
1381                        if (i === 0) {
1382                            wZ = hZ = paddingVal;
1383                        }
1384                    } else {
1385                        break;
1386                    }
1387                } else {
1388                    break;
1389                }
1390
1391                if (_this.position === 'inner') { 
1392                    break;
1393                }
1394            }
1395
1396            _this.container.css({
1397                'width': 0,
1398                'height': 0
1399            });
1400            _this.instance.css({
1401                'width': wZ,
1402                'height': hZ
1403            });
1404            _this.container.css({
1405                'width': _this.instance.outerWidth(),
1406                'height': _this.instance.outerHeight()
1407            });
1408
1409            //setupZoomPos
1410            if (_this.position === 'inner' || _this.isAIZooming === true) {
1411                _this.instance.appendTo(_this.component.display.slides[_this.component.thumbs.current]).addClass('gc-zoom-inner');
1412            } else {
1413                _this.instance.appendTo(_this.component.element).removeClass('gc-zoom-inner');
1414
1415                if (_this.position === 'left') {
1416                    _this.instance.css({
1417                        'right': (_this.component.element.outerWidth(true)),
1418                        'margin-right': _this.margin + 'px'
1419                    });
1420                } else {
1421                    _this.instance.css({
1422                        'left': (_this.component.element.outerWidth(true)),
1423                        'margin-left': _this.margin + 'px'
1424                    });
1425                }
1426
1427                var topZ = _this.alignment === 'displayArea' ? 0 : $(_this.component.display.slides[_this.component.thumbs.current]).position().top +
1428                  parseFloat($(_this.component.display.slides[_this.component.thumbs.current]).css('margin-top'));
1429
1430                if (_this.component.thumbs.position === 'top') {
1431                    var topT = _this.component.thumbs.instance.outerHeight() + parseFloat(_this.component.thumbs.margin);
1432                    _this.instance.css({
1433                        'top': topZ + topT
1434                    });
1435                } else {
1436                    _this.instance.css({
1437                        'top': topZ
1438                    });
1439                }
1440            }
1441        };
1442        this.changeCnt = function () {
1443            var _this = this;
1444
1445            _this.setup();
1446            if (_this.isZCapEnabled === true) {
1447                _this.caption.setup();
1448            }
1449
1450            _this.dfdState.resolve();
1451        };
1452        this.getInstance = function () {
1453            return this.instance;
1454        };
1455        this.slowDown = function () {
1456            var _this = this;
1457            var diffZoomPos = {
1458                left: 0,
1459                top: 0
1460            };
1461            var moveZoomPos = {
1462                left: 0,
1463                top: 0
1464            };
1465
1466            diffZoomPos = {
1467                top: _this.newZoom.top - _this.currentZoom.top,
1468                left: _this.newZoom.left - _this.currentZoom.left
1469            };
1470            moveZoomPos = {
1471                top: -diffZoomPos.top / (_this.speedSlowZoom / 100),
1472                left: -diffZoomPos.left / (_this.speedSlowZoom / 100)
1473            };
1474            _this.currentZoom = {
1475                top: _this.currentZoom.top - moveZoomPos.top,
1476                left: _this.currentZoom.left - moveZoomPos.left
1477            };
1478
1479            if (diffZoomPos.top < 1 && diffZoomPos.top > -1) {
1480                _this.currentZoom.top = _this.newZoom.top;
1481            }
1482            if (diffZoomPos.left < 1 && diffZoomPos.left > -1) {
1483                _this.currentZoom.left = _this.newZoom.left;
1484            }
1485            _this.display.css({
1486                'top': _this.currentZoom.top,
1487                'left': _this.currentZoom.left
1488            });
1489            _this.slowZoomTimer = setTimeout(function () {
1490                _this.slowDown();
1491            }, 25);
1492        };
1493
1494        //Execution
1495        this.init();
1496    }
1497
1498    function GCThumbs(config, component) {
1499        //Properties
1500        this.component = component;
1501        this.position = config.thumbsPosition;
1502        this.nrThumbsPerRow = config.nrThumbsPerRow;
1503        this.isThumbsOneRow = config.isThumbsOneRow;
1504        this.isOneThumbShown = config.isOneThumbShown;
1505        this.firstThumbSelected = config.firstThumbSelected ? config.firstThumbSelected : 0;
1506        this.colorActiveThumb = config.colorActiveThumb;
1507        this.margin = config.thumbsMargin;
1508        this.isHoverShowThumbs = config.isHoverShowThumbs;
1509        this.slideType = config.slideType;
1510
1511        //Methods
1512        this.init = function () {
1513            var _this = this;
1514
1515            var sVT = (_this.position === 'right' || _this.position === 'left') ? '-vt' : '';
1516            var ctntThumbsPrevNext = '<div class="gc-thumbs-area-prev"><div class="gc-icon gc-icon-prev' + sVT + '"></div></div>' +
1517              '<div class="gc-thumbs-area-next"><div class="gc-icon gc-icon-next' + sVT + '"></div></div>';
1518
1519            _this.ul = _this.component.element.find('ul');
1520            _this.ul.removeClass('gc-start');
1521            _this.ul.wrap('<div class="gc-thumbs-area"></div>');
1522            _this.li = _this.ul.find('li');
1523            _this.instance = _this.ul.parent();
1524            _this.instance.append(ctntThumbsPrevNext);
1525            _this.abtnPrevious = _this.instance.find('.gc-thumbs-area-prev');
1526            _this.btnPrevious = _this.abtnPrevious.find('.gc-icon-prev' + sVT);
1527            _this.abtnNext = _this.instance.find('.gc-thumbs-area-next');
1528            _this.btnNext = _this.abtnNext.find('.gc-icon-next' + sVT);
1529            _this.current = 0; //default value
1530            _this.old = 0;
1531
1532            _this.position === 'left' || _this.position === 'right' ? _this.instance.addClass('gc-vt') : _this.instance.addClass('gc-hz');
1533
1534            if (parseFloat(_this.firstThumbSelected) > -1 &&
1535              parseFloat(_this.firstThumbSelected) <= (_this.li.length - 1)) {
1536                _this.current = _this.firstThumbSelected;
1537                _this.old = _this.firstThumbSelected;
1538            }
1539
1540            _this.currentSlide = Math.floor(_this.current / _this.nrThumbsPerRow);
1541            _this.currentSlideElement = _this.current;
1542
1543            _this.tpStart = {
1544                x: 0,
1545                y: 0
1546            };
1547            _this.tpEnd = {
1548                x: 0,
1549                y: 0
1550            };
1551        };
1552        this.setup = function () {
1553            var _this = this;
1554            var display = _this.component.display.getInstance();
1555
1556            if (_this.isOneThumbShown === false && _this.li.length === 1) {
1557                _this.instance.outerHeight(0);
1558                _this.instance.addClass('gc-hide');
1559                return;
1560            } else {
1561                _this.isOneThumbShown = true;
1562            }
1563            if (_this.position === 'right') {
1564                _this.setupLR();
1565                display.css({
1566                    'top': '0',
1567                    'left': '0'
1568                });
1569                _this.instance.css({
1570                    'top': '0',
1571                    'left': display.outerWidth() + _this.margin
1572                });
1573            }
1574            if (_this.position === 'left') {
1575                _this.setupLR();
1576                _this.instance.css({
1577                    'top': '0',
1578                    'left': '0'
1579                });
1580                display.css({
1581                    'top': '0',
1582                    'left': _this.instance.outerWidth() + _this.margin
1583                });
1584            }
1585            if (_this.position === 'bottom') {
1586                _this.setupTB();
1587                display.css({
1588                    'top': '0',
1589                    'left': '0'
1590                });
1591                _this.instance.css({
1592                    'top': display.outerHeight() + _this.margin,
1593                    'left': '0'
1594                });
1595            }
1596            if (_this.position === 'top') {
1597                _this.setupTB();
1598                _this.instance.css({
1599                    'top': '0',
1600                    'left': '0'
1601                });
1602                display.css({
1603                    'top': _this.instance.outerHeight() + _this.margin,
1604                    'left': '0'
1605                });
1606            }
1607            if (parseFloat(_this.firstThumbSelected) > 0 && _this.currentSlide > 0) {
1608                _this.currentSlide -= 1;
1609                _this.slide('false', '');
1610            }
1611        };
1612        this.setupLR = function () {
1613            var _this = this;
1614            var display = _this.component.display.getInstance();
1615
1616            _this.instance.css('height', display.outerHeight());
1617
1618            var mgL = parseFloat(_this.li.css('margin-bottom'));
1619            var ratio = _this.component.display.width / _this.component.display.height;
1620            var hL = (_this.instance.outerHeight() / _this.nrThumbsPerRow - (_this.nrThumbsPerRow - 1) * mgL / _this.nrThumbsPerRow);
1621            var wL = hL * ratio;
1622            var hLPerc = (hL * 100) / (((hL + mgL) * _this.li.length) - mgL);
1623
1624            _this.li.css({
1625                'width': wL,
1626                'height': hLPerc + '%'
1627            });
1628            _this.li.last().css('margin-bottom', 0);
1629
1630            _this.ul.css({
1631                'width': Math.ceil(wL),
1632                'height': Math.ceil((((hL + mgL) * _this.li.length) - mgL))
1633            });
1634            _this.instance.css('width', Math.ceil(wL));
1635            _this.abtnPrevious.removeClass('gc-hide');
1636            _this.btnPrevious.css('margin-left', (-_this.btnPrevious.outerWidth() / 2));
1637            _this.abtnNext.removeClass('gc-hide');
1638            _this.btnNext.css('margin-left', (-_this.btnNext.outerWidth() / 2));
1639
1640            _this.setupSlider();
1641            if (_this.component.iOS) {
1642                var brwLiHeight = _this.li.outerHeight();
1643                var brwDiff = _this.instance.outerHeight() - (brwLiHeight * _this.nrThumbsPerRow + (_this.nrThumbsPerRow - 1) * mgL);
1644                _this.ul.find(':nth-child(' + _this.nrThumbsPerRow + 'n)').css('height', brwLiHeight + brwDiff);
1645            }
1646        };
1647        this.setupTB = function () {
1648            var _this = this;
1649            var display = _this.component.display.getInstance();
1650
1651            _this.instance.css('width', display.outerWidth());
1652
1653            var mgL = parseFloat(_this.li.css('margin-right'));
1654            var ratio = _this.component.display.width / _this.component.display.height;
1655            var wL = (_this.instance.outerWidth() / _this.nrThumbsPerRow - (_this.nrThumbsPerRow - 1) * mgL / _this.nrThumbsPerRow);
1656            var hL = wL / ratio;
1657            var wLPerc;
1658
1659            if (_this.isThumbsOneRow === true) {
1660                wLPerc = (wL * 100) / (((wL + mgL) * _this.li.length) - mgL);
1661            } else {
1662                wLPerc = (wL * 100) / _this.instance.outerWidth();
1663            }
1664            _this.li.css({
1665                'width': wLPerc + '%',
1666                'height': hL
1667            });
1668
1669            if (_this.isThumbsOneRow === true) {
1670                _this.li.last().css('margin-right', 0);
1671            } else {
1672                _this.ul.find(':nth-child(' + _this.nrThumbsPerRow + 'n)').css('margin-right', 0);
1673                _this.ul.find(':nth-child(n +' + (parseFloat(_this.nrThumbsPerRow) + 1) + ')').css('margin-top', mgL + 'px');
1674            }
1675            if (_this.isThumbsOneRow === true) {
1676                _this.ul.css({
1677                    'width': Math.ceil((wL * _this.li.length + (_this.li.length - 1) * mgL)),
1678                    'height': Math.ceil(hL)
1679                });
1680                _this.instance.css('height', Math.ceil(hL));
1681            } else {
1682                var totalRows = Math.ceil((_this.li.length) / _this.nrThumbsPerRow);
1683                var lHeight = Math.ceil(hL * totalRows + mgL * (totalRows - 1));
1684
1685                _this.ul.css({
1686                    'width': _this.instance.outerWidth(),
1687                    'height': lHeight
1688                });
1689                _this.instance.css('height', lHeight);
1690            }
1691            if (_this.isThumbsOneRow === true) {
1692                _this.abtnPrevious.removeClass('gc-hide');
1693                _this.btnPrevious.css('margin-top', (-_this.btnPrevious.outerHeight() / 2));
1694                _this.abtnNext.removeClass('gc-hide');
1695                _this.btnNext.css('margin-top', (-_this.btnNext.outerHeight() / 2));
1696
1697                _this.setupSlider();
1698            } else {
1699                _this.abtnPrevious.addClass('gc-hide');
1700                _this.abtnNext.addClass('gc-hide');
1701            }
1702            if (_this.component.iOS) {
1703                var brwLiWidth = _this.li.outerWidth(),
1704                  brwDiff = _this.instance.outerWidth() - (brwLiWidth * _this.nrThumbsPerRow + (_this.nrThumbsPerRow - 1) * mgL);
1705                _this.ul.find(':nth-child(' + _this.nrThumbsPerRow + 'n)').css('width', brwLiWidth + brwDiff);
1706            }
1707        };
1708        this.setupSlider = function () {
1709            var _this = this;
1710
1711            if (_this.li.length <= _this.nrThumbsPerRow) {
1712                _this.abtnPrevious.addClass('gc-hide');
1713                _this.abtnNext.addClass('gc-hide');
1714                return;
1715            }
1716            _this.abtnPrevious.removeClass('gc-disabled');
1717            _this.abtnNext.removeClass('gc-disabled');
1718
1719            if (_this.slideType !== 'slideElement') {
1720                if (_this.currentSlide === 0) {
1721                    _this.abtnPrevious.addClass('gc-disabled');
1722                }
1723                if (_this.currentSlide === Math.floor((_this.li.length - 1) / _this.nrThumbsPerRow)) {
1724                    _this.abtnNext.addClass('gc-disabled');
1725                }
1726            }
1727            
1728        };
1729        this.changeCnt = function () {
1730            var _this = this;
1731
1732            if (_this.colorActiveThumb !== -1) {
1733                _this.ul.find('.gc-active').css('border-color', '');
1734            }
1735
1736            _this.li.removeClass('gc-active').eq(_this.current).addClass('gc-active');
1737
1738            if (_this.colorActiveThumb !== -1) {
1739                _this.ul.find('.gc-active').css('border-color', _this.colorActiveThumb);
1740            }
1741            _this.slide('true', '');
1742        };
1743        this.getInstance = function () {
1744            return this.instance;
1745        };
1746        this.initEvents = function () {
1747            var _this = this;
1748
1749            _this.li.on('click.glasscase', function () {
1750                _this.changeThumbs($(this).index());
1751            });
1752            if (_this.isHoverShowThumbs === true) {
1753                _this.li.on('mouseenter', function () {
1754                    _this.changeThumbs($(this).index());
1755                });
1756            }
1757            _this.abtnPrevious.on('click.glasscase', function () {
1758                _this.slide('false', 'previous');
1759            });
1760            _this.abtnNext.on('click.glasscase', function () {
1761                _this.slide('false', 'next');
1762            });
1763            _this.ul.on('touchstart.glasscase', $.proxy(_this.touchStart, _this))
1764              .on('touchmove.glasscase', $.proxy(_this.touchMove, _this))
1765              .on('touchend.glasscase', $.proxy(_this.touchEnd, _this));
1766        };
1767        this.touchStart = function (event) {
1768            var _this = this;
1769
1770            if (event.originalEvent.touches.length === 1) {
1771                _this.tpStart.x = event.originalEvent.touches[0].pageX;
1772                _this.tpEnd.x = _this.tpStart.x;
1773                _this.tpStart.y = event.originalEvent.touches[0].pageY;
1774                _this.tpEnd.y = _this.tpStart.y;
1775            }
1776        };
1777        this.touchMove = function (event) {
1778            var _this = this;
1779
1780            if (event.originalEvent.touches.length === 1) {
1781                _this.tpEnd.x = event.originalEvent.touches[0].pageX;
1782                _this.tpEnd.y = event.originalEvent.touches[0].pageY;
1783            }
1784        };
1785        this.touchEnd = function (event) {
1786            var _this = this;
1787
1788            if (_this.tpEnd.x !== _this.tpStart.x || _this.tpEnd.y !== _this.tpStart.y) {
1789                event.preventDefault();
1790
1791                if (_this.position === 'right' || _this.position === 'left') {
1792                    if (_this.tpStart.y - _this.tpEnd.y > 10) {
1793                        _this.slide('false', 'next');
1794                    }
1795                    if (_this.tpStart.y - _this.tpEnd.y < -10) {
1796                        _this.slide('false', 'previous');
1797                    }
1798                } else {
1799                    if (_this.tpStart.x - _this.tpEnd.x > 10) {
1800                        _this.slide('false', 'next');
1801                    }
1802                    if (_this.tpStart.x - _this.tpEnd.x < -10) {
1803                        _this.slide('false', 'previous');
1804                    }
1805                }
1806            }
1807        };
1808        this.slide = function (isImageChange, slideChange) { //isImageChange: true || false; slideChange:   previous || next
1809            var _this = this;
1810            var nextSlide = 0;
1811            var nextSlideElement = 0;
1812            var vMargin;
1813            var config;
1814            var configAnimProp;
1815
1816            if (_this.isThumbsOneRow === false && (_this.position === 'bottom' || _this.position === 'top')) {
1817                return;
1818            }
1819            config = {
1820                type: dynamics.easeInOut,
1821                duration: 800,
1822                change: function () {
1823                    _this.setupSlider();
1824                }
1825            };
1826            if (_this.slideType === 'slideElement') {
1827                if (isImageChange === 'true') {
1828                    nextSlideElement = _this.current;
1829                } else {
1830                    if (slideChange === 'previous') {
1831                        nextSlideElement = _this.currentSlideElement > 0 ? _this.currentSlideElement - 1 : _this.li.length - 1 /*was 0*/;
1832                    } else {
1833                        nextSlideElement = (_this.currentSlideElement + 1) > (_this.li.length - 1) ? 0 : _this.currentSlideElement + 1;
1834                    }
1835                }
1836
1837                _this.currentSlideElement = nextSlideElement;
1838                //Making the slide
1839                if (_this.position === 'bottom' || _this.position === 'top') {
1840                    vMargin = _this.li.outerWidth() + parseFloat(_this.li.css('margin-right'));
1841                    configAnimProp = {
1842                        left: -(nextSlideElement * vMargin)
1843                    };
1844                } else {
1845                    vMargin = _this.li.outerHeight() + parseFloat(_this.li.css('margin-bottom'));
1846                    configAnimProp = {
1847                        top: -(nextSlideElement * vMargin)
1848                    };
1849                }
1850            } else {
1851                if (isImageChange === 'true') {
1852                    nextSlide = Math.floor(_this.current / _this.nrThumbsPerRow);
1853                } else {
1854                    if (slideChange === 'previous') {
1855                        nextSlide = _this.currentSlide > 0 ? _this.currentSlide - 1 : 0;
1856                    } else {
1857                        nextSlide = _this.currentSlide + 1 > Math.floor((_this.li.length - 1) / _this.nrThumbsPerRow) ? Math.floor((_this.li.length - 1) / _this.nrThumbsPerRow) : _this.currentSlide + 1;
1858                    }
1859                }
1860
1861                if (nextSlide === _this.currentSlide) {
1862                    return;
1863                }
1864
1865                _this.currentSlide = nextSlide;
1866                //Making the slide
1867                if (_this.position === 'bottom' || _this.position === 'top') {
1868                    vMargin = _this.instance.outerWidth() + parseFloat(_this.li.css('margin-right'));
1869                    configAnimProp = {
1870                        translateX: -(nextSlide * vMargin)
1871                    };
1872                } else {
1873                    vMargin = _this.instance.outerHeight() + parseFloat(_this.li.css('margin-bottom'));
1874                    configAnimProp = {
1875                        translateY: -(nextSlide * vMargin)
1876                    };
1877                }
1878            }
1879            dynamics.animate(_this.ul[0], configAnimProp, config);
1880        };
1881        this.changeThumbs = function (index) {
1882            var _this = this;
1883
1884            if (_this.current !== index) {
1885                _this.old = _this.current;
1886                _this.current = index;
1887                _this.component.changeCnt();
1888            }
1889        };
1890        this.navigate = function (direction) {
1891            var _this = this;
1892
1893            _this.old = _this.current;
1894            if (direction === 'next') {
1895                _this.current = _this.current === (_this.li.length - 1) ? 0 : _this.current + 1;
1896            } else {
1897                _this.current = _this.current === 0 ? (_this.li.length - 1) : _this.current - 1;
1898            }
1899        };
1900
1901        //Execution
1902        this.init(component);
1903    }
1904
1905    function GCOverlay(options, component) {
1906        //Properties
1907        this.component = component;
1908        this.isEnabled = options.isOverlayEnabled;
1909        this.isFullImage = options.isOverlayFullImage;
1910        this.isOpened = false;
1911        this.displayState = ''; //enlarged; compressed
1912        this.instance = $('<div class="gc-overlay-area">' +
1913          '<div class="gc-overlay-top-icons">' +
1914          '<div class="gc-icon gc-icon-close">&nbsp;</div>' +
1915          '<div class="gc-icon gc-icon-enlarge">&nbsp;</div>' +
1916          '<div class="gc-icon gc-icon-compress">&nbsp;</div>' +
1917          '</div>' +
1918          '<div class="gc-overlay-left-icons">' +
1919          '<div class="gc-icon gc-icon-prev">&nbsp;</div>' +
1920          '</div>' +
1921          '<div class="gc-overlay-right-icons">' +
1922          '<div class="gc-icon gc-icon-next">&nbsp;</div>' +
1923          '</div>' +
1924          '<div class="gc-overlay-gcontainer">' +
1925          '<div class="gc-overlay-container" />' +
1926          '</div>' +
1927          '</div>');
1928
1929        //Methods
1930        this.init = function () {
1931            var _this = this;
1932
1933            _this.gcontainer = _this.instance.find('.gc-overlay-gcontainer');
1934            _this.slidesCnt = _this.gcontainer.find('.gc-overlay-container');
1935
1936            $.each(_this.component.items, function (index, item) {
1937                _this.slidesCnt.append(_this.component.items[index].getInstance('overlay', _this.slidesCnt.width(), _this.slidesCnt.height()));
1938            });
1939
1940            _this.slides = _this.slidesCnt.find('.gc-overlay-container-display');
1941            _this.display = _this.slides.find('.gc-overlay-display');
1942
1943            _this.btnPrevious = _this.instance.find('.gc-icon-prev');
1944            _this.btnNext = _this.instance.find('.gc-icon-next');
1945            _this.btnClose = _this.instance.find('.gc-icon-close');
1946            _this.btnEnlarge = _this.instance.find('.gc-icon-enlarge');
1947            _this.btnCompress = _this.instance.find('.gc-icon-compress');
1948
1949            _this.tpStart = {
1950                x: 0,
1951                y: 0
1952            };
1953            _this.tpEnd = {
1954                x: 0,
1955                y: 0
1956            };
1957
1958            _this.instance.hide();
1959            _this.btnEnlarge.hide();
1960            _this.btnCompress.hide();
1961        };
1962        this.setup = function () {
1963            var _this = this;
1964
1965            $.each(_this.component.items, function (index, item) {
1966                _this.slidesCnt.append(_this.component.items[index].getInstance('overlay', _this.slidesCnt.width(), _this.slidesCnt.height()));
1967            });
1968
1969            if (_this.component.items[_this.component.thumbs.current].type !== 'image') {
1970                _this.btnCompress.hide();
1971                _this.btnEnlarge.hide();
1972                return;
1973            }
1974
1975            var isNatSizeSMScr = _this.component.items[_this.component.thumbs.current].isFitScr(_this.instance.outerWidth(), _this.instance.outerHeight());
1976
1977            if (isNatSizeSMScr || _this.isFullImage) {
1978                _this.btnCompress.hide();
1979                _this.btnEnlarge.hide();
1980                _this.component.items[_this.component.thumbs.current].showNF('nat', $(_this.slides[_this.component.thumbs.current]).outerWidth(), $(_this.slides[_this.component.thumbs.current]).outerHeight());
1981            } else {
1982                if (_this.displayState === 'enlarged') { //case when the image is enlarge mode and the browser is resised
1983                    _this.btnCompress.show();
1984                    _this.btnEnlarge.hide();
1985                    _this.component.items[_this.component.thumbs.current].showNF('nat', $(_this.slides[_this.component.thumbs.current]).outerWidth(), $(_this.slides[_this.component.thumbs.current]).outerHeight());
1986                } else {
1987                    _this.displayState = 'compressed';
1988                    _this.btnCompress.hide();
1989                    _this.btnEnlarge.show();
1990                    _this.component.items[_this.component.thumbs.current].showNF('fit', $(_this.slides[_this.component.thumbs.current]).outerWidth(), $(_this.slides[_this.component.thumbs.current]).outerHeight());
1991                }
1992            }
1993        };
1994
1995        this.changeCnt = function (action) {
1996            var _this = this;
1997            var currentEl = _this.slides[_this.component.thumbs.old];
1998            var nextEl = _this.slides[_this.component.thumbs.current];
1999            var dirRight = _this.component.thumbs.old === (_this.component.items.length - 1) && _this.component.thumbs.current === 0;
2000            var dirLeft = _this.component.thumbs.old === 0 && _this.component.thumbs.current === (_this.component.items.length - 1);
2001            var dir = ((_this.component.thumbs.old < _this.component.thumbs.current && !dirLeft) || dirRight) ? 'right' : 'left';
2002
2003            if (!_this.isOpened) { //overlay on
2004                return;
2005            }
2006
2007            $.when(_this.component.items[_this.component.thumbs.current].dfdState).done(function () {
2008                _this.setup();
2009            });
2010
2011            if (action === 'opening') { //when opening the overlay
2012                if (_this.component.items[_this.component.thumbs.current].type === 'video' || _this.component.items[_this.component.thumbs.current].type === 'iframe') {
2013                    _this.component.items[_this.component.thumbs.current].navigate('display');
2014                }
2015                dynamics.css(nextEl, { opacity: 0 });
2016
2017                // animate the next element in
2018                dynamics.animate(nextEl, {
2019                    opacity: 1
2020                }, {
2021                    type: dynamics.easeInOut,
2022                    duration: 100,
2023                    complete: function () {
2024
2025                        dynamics.css(nextEl, {
2026                            opacity: 1,
2027                            visibility: 'visible'
2028                        });
2029
2030                        _this.slides.removeClass('gc-slide-container-current');
2031                        $(nextEl).addClass('gc-slide-container-current');
2032                    }
2033                });
2034                return;
2035                //End opening the overlay
2036            }
2037
2038            dynamics.animate(currentEl, {
2039                opacity: 0
2040            }, {
2041                type: dynamics.easeInOut,
2042                duration: 100,
2043                complete: function () {
2044                    dynamics.css(currentEl, {
2045                        opacity: 0,
2046                        visibility: 'hidden'
2047                    });
2048                    if (_this.component.items[_this.component.thumbs.old].type !== '
2048image') {
2049                        _this.component.items[_this.component.thumbs.old].navigate('overlay');
2050                    }
2051                }
2052            });
2053
2054            // set the right properties for the next element to come in
2055            dynamics.css(nextEl, {
2056                opacity: 1,
2057                visibility: 'visible'
2058            });
2059            dynamics.css(nextEl, {
2060                opacity: 0
2061            });
2062
2063            // animate the next element in
2064            dynamics.animate(nextEl, {
2065                opacity: 1
2066            }, {
2067                type: dynamics.easeInOut,
2068                duration: 100,
2069                complete: function () {
2070                    _this.slides.removeClass('gc-slide-container-current');
2071                    $(nextEl).addClass('gc-slide-container-current');
2072                }
2073            });
2074        };
2075        this.getInstance = function () {
2076            return this.instance;
2077        };
2078        this.initEvents = function () {
2079            var _this = this;
2080
2081            _this.btnClose.on('click.glasscase', function () {
2082                _this.toggle();
2083            });
2084
2085            _this.slidesCnt.on('click.glasscase', function () {
2086                _this.toggle();
2087            });
2088
2089            if (!_this.isFullImage) {
2090                $.each(_this.component.items, function (index, slide) {
2091                    if (slide.type === 'image') {
2092                        $.when(slide.dfdstate).done(function () {
2093                            $(slide.getInstance('overlay')).on('dblclick.glasscase', function () {
2094                                _this.toggleEC('toggle');
2095                            });
2096                            $(slide.getInstanceDisplay('overlay')).on('click.glasscase', function (e) {
2097                                e.stopPropagation();
2098                            });
2099                        });
2100                    }
2101                });
2102
2103                _this.btnEnlarge.on('click.glasscase', function () {
2104                    _this.toggleEC('nat');
2105                });
2106                _this.btnCompress.on('click.glasscase', function () {
2107                    _this.toggleEC('fit');
2108                });
2109            }
2110
2111            _this.btnPrevious.on('click.glasscase', function () {
2112                _this.navigate('previous');
2113            });
2114            _this.btnNext.on('click.glasscase', function () {
2115                _this.navigate('next');
2116            });
2117
2118            if (_this.isFullImage === false) {
2119                _this.slidesCnt.on('touchstart.glasscase', $.proxy(_this.touchStart, _this))
2120                  .on('touchmove.glasscase', $.proxy(_this.touchMove, _this))
2121                  .on('touchend.glasscase', $.proxy(_this.touchEnd, _this));
2122            }
2123
2124            $.each(_this.component.items, function (index, slide) {
2125                if (slide.type === 'image') {
2126                    $.when(slide.dfdstate).done(function () {
2127                        $(slide.getInstance('overlay')).on('mousemove.glasscase', function (e) {
2128                            $(this).scrollTop(e.clientY).scrollLeft(e.clientX);
2129                        });
2130                    });
2131                }
2132            });
2133        };
2134        this.touchStart = function (event) {
2135            var _this = this;
2136
2137            if (event.originalEvent.touches.length === 1) {
2138                _this.tpStart.x = event.originalEvent.touches[0].pageX;
2139                _this.tpEnd.x = _this.tpStart.x;
2140                _this.tpStart.y = event.originalEvent.touches[0].pageY;
2141                _this.tpEnd.y = _this.tpStart.y;
2142            }
2143        };
2144        this.touchMove = function (event) {
2145            var _this = this;
2146
2147            if (event.originalEvent.touches.length === 1) {
2148                _this.tpEnd.x = event.originalEvent.touches[0].pageX;
2149                _this.tpEnd.y = event.originalEvent.touches[0].pageY;
2150            }
2151        };
2152        this.touchEnd = function (event) {
2153            var _this = this;
2154
2155            if (_this.tpEnd.x !== _this.tpStart.x || _this.tpEnd.y !== _this.tpStart.y) {
2156                event.preventDefault();
2157                if (_this.tpStart.x - _this.tpEnd.x > 10) {
2158                    _this.navigate('next');
2159                }
2160                if (_this.tpStart.x - _this.tpEnd.x < -10) {
2161                    _this.navigate('previous');
2162                }
2163            }
2164        };
2165        this.toggle = function (action) {
2166            var _this = this;
2167
2168            if ($('body').hasClass('gc-noscroll')) { //overlay on
2169                _this.close();
2170            } else {
2171                if (action === 'esc') {
2172                    return;
2173                }
2174
2175                _this.instance.fadeIn(500, function () {
2176                    _this.isOpened = true;
2177                    _this.changeCnt('opening');
2178                });
2179                $('body').addClass('gc-noscroll');
2180            }
2181        };
2182        this.close = function () {
2183            var _this = this;
2184
2185            if (_this.component.items[_this.component.thumbs.current].type === 'video' || _this.component.items[_this.component.thumbs.current].type === 'iframe') {
2186                _this.component.items[_this.component.thumbs.current].navigate('overlay');
2187            }
2188            _this.instance.fadeOut(500, function () {
2189                _this.isOpened = false;
2190                $('body').removeClass('gc-noscroll');
2191                _this.slides.removeClass('gc-slide-container-current');
2192                $(_this.slides).attr('style', '');
2193            });
2194        };
2195        this.toggleEC = function (displayType) {
2196            var _this = this;
2197
2198            if (_this.component.items[_this.component.thumbs.current].type !== '
2198image') {
2199                return;
2200            }
2201
2202            if (displayType === 'toggle' &&
2203              _this.component.items[_this.component.thumbs.current].isFitScr(_this.instance.outerWidth(), _this.instance.outerHeight())) {
2204                return;
2205            }
2206
2207            if (displayType === 'toggle') {
2208                displayType = _this.displayState === 'compressed' ? 'nat' : 'fit';
2209            }
2210
2211            if (displayType === 'fit') {
2212                _this.displayState = 'compressed';
2213                _this.btnCompress.hide();
2214                _this.btnEnlarge.show();
2215
2216                _this.slidesCnt.on('touchstart.glasscase', $.proxy(_this.touchStart, _this))
2217                  .on('touchmove.glasscase', $.proxy(_this.touchMove, _this))
2218                  .on('touchend.glasscase', $.proxy(_this.touchEnd, _this));
2219            }
2220
2221            if (displayType === 'nat') {
2222                _this.displayState = 'enlarged';
2223                _this.btnCompress.show();
2224                _this.btnEnlarge.hide();
2225
2226                _this.slidesCnt.off('touchstart.glasscase', $.proxy(_this.touchStart, _this))
2227                  .off('touchmove.glasscase', $.proxy(_this.touchMove, _this))
2228                  .off('touchend.glasscase', $.proxy(_this.touchEnd, _this));
2229            }
2230
2231            //_this.component.items[_this.component.thumbs.current].showNF(displayType, _this.slides.outerWidth(), _this.slides.outerHeight());
2232            _this.component.items[_this.component.thumbs.current].showNF(displayType, _this.instance.outerWidth(), _this.instance.outerHeight());
2233        };
2234        this.navigate = function (direction) {
2235            var _this = this;
2236
2237            _this.component.thumbs.navigate(direction);
2238            _this.component.changeCnt();
2239            if (_this.component.items[_this.component.thumbs.current].isFitScr(_this.instance.outerWidth(), _this.instance.outerHeight()) && _this.displayState === 'enlarged') {
2240                _this.slidesCnt.on('touchstart.glasscase', $.proxy(_this.touchStart, _this))
2241                  .on('touchmove.glasscase', $.proxy(_this.touchMove, _this))
2242                  .on('touchend.glasscase', $.proxy(_this.touchEnd, _this));
2243            }
2244            if (!_this.component.items[_this.component.thumbs.current].isFitScr(_this.instance.outerWidth(), _this.instance.outerHeight()) && _this.displayState === 'enlarged') {
2245                _this.slidesCnt.off('touchstart.glasscase', $.proxy(_this.touchStart, _this))
2246                  .off('touchmove.glasscase', $.proxy(_this.touchMove, _this))
2247                  .off('touchend.glasscase', $.proxy(_this.touchEnd, _this));
2248            }
2249        };
2250        //Execution
2251        this.init();
2252    }
2253
2254    function GCCaption(options, zoom) {
2255        //Properties
2256        this.zoom = zoom;
2257
2258        this.zType = options.capZType;
2259        this.zPosition = options.capZPos;
2260        this.zAlign = options.capZAlign;
2261        this.instance = $('<div class="gc-caption-container"><div></div></div>');
2262        this.display = this.instance.find('div');
2263
2264        //Methods
2265        this.init = function () {
2266            var _this = this;
2267            var cssClass = 'gc-caption-' + _this.zType + _this.zPosition;
2268
2269            if (_this.zoom.position === 'inner') {
2270                _this.zType = 'in';
2271            }
2272
2273            if ($.inArray(cssClass, ['gc-caption-outtop', 'gc-caption-outbottom', 'gc-caption-intop', 'gc-caption-inbottom']) === -1) {
2274                cssClass = 'gc-caption-' + _this.zoom.component.defaults.capZType + _this.zoom.component.defaults.capZPos;
2275            }
2276
2277            $.inArray(_this.zAlign, ['left', 'right', 'center']) === -1 ?
2278              cssClass += ' gc-alignment-' + _this.zoom.component.defaults.capZAlign :
2279              cssClass += ' gc-alignment-' + _this.zAlign;
2280
2281            _this.instance.addClass(cssClass).appendTo(_this.zoom.instance);
2282        };
2283        this.setup = function () {
2284            var _this = this;
2285
2286            var capTxt = _this.zoom.component.items[_this.zoom.component.thumbs.current].caption;
2287            capTxt === '' ? _this.instance.hide() : (_this.instance.show(), _this.display.empty().append(capTxt));
2288
2289            if (_this.zoom.isAIZooming === true) {
2290                if (_this.zType === 'out') {
2291                    _this.instance.removeClass('gc-caption-outtop gc-caption-outbottom')
2292                      .addClass(_this.zPosition === 'top' ? 'gc-caption-intop' : 'gc-caption-inbottom');
2293                }
2294            } else {
2295                if (_this.zType === 'out' && (_this.instance.hasClass('gc-caption-intop') || _this.instance.hasClass('gc-caption-inbottom'))) {
2296                    _this.instance.removeClass('gc-caption-intop gc-caption-inbottom')
2297                      .addClass(_this.zPosition === 'top' ? 'gc-caption-outtop' : 'gc-caption-outbottom');
2298                }
2299            }
2300        };
2301        this.getInstance = function () {
2302            return this.instance;
2303        };
2304
2305        //Execution
2306        this.init();
2307    }
2308
2309    function GlassCase(element, options) {
2310        var _this = this;
2311
2312        _this.defaults = {
2313            //DISPLAY AREA
2314            widthDisplay: 400, // Default width of the display image
2315            heightDisplay: 534, // Default height of the display image
2316            isAutoScaleDisplay: true,
2317            isAutoScaleHeight: true,
2318            isDownloadEnabled: false,
2319            downloadPosition: 3,
2320            isShowAlwaysIcons: false,
2321            speedHideIcons: 3000,
2322            mouseEnterDisplayCB: function () { },
2323            mouseLeaveDisplayCB: function () { },
2324            isAutoPlayDisplay: false,
2325            pauseTimeDisplay: 3000,
2326            isPauseOnHoverDisplay: true,
2327            //THUMBS AREA        
2328            thumbsPosition: 'bottom', // Default position of thumbs. Position is relative to the image display. Can take the values: top; bottom      
2329            nrThumbsPerRow: 5, // Number of images per row        
2330            isThumbsOneRow: true, // Show one row or all images: true -> will be shown only one row; false -> will be shown all images
2331            isOneThumbShown: false,
2332            firstThumbSelected: 0, // Current element's index
2333            colorActiveThumb: '-1', 
2334            thumbsMargin: 4, // in px
2335            isHoverShowThumbs: false,
2336            slideType: 'slideRow', //slideRow; slideElement
2337            //ZOOM AREA
2338            zoomPosition: 'right', // Default position for the zoom. It can take values: right; left; inner
2339            autoInnerZoom: true, // true; false
2340            isZoomEnabled: true,
2341            isSlowZoom: false,
2342            speedSlowZoom: 1200,
2343            isZoomDiffWH: false,
2344            zoomWidth: 0,
2345            zoomHeight: 0,
2346            zoomAlignment: 'displayImage', //displayImage, displayArea
2347            zoomMargin: 4, // in px    
2348            //LENS AREA
2349            isSlowLens: false,
2350            speedSlowLens: 600,
2351            //OVERLAY AREA
2352            isOverlayEnabled: true,
2353            isOverlayFullImage: false,
2354            //GENERAL
2355            speed: 400, // Default speed
2356            isKeypressEnabled: true,
2357            colorIcons: '-1', // The color of the icons 
2358            colorLoading: '-1', 
2359            textImageNotLoaded: 'NO IMAGE',
2360            //CAPTION
2361            isZCapEnabled: true,
2362            capZType: 'in', // in, out
2363            capZPos: 'bottom', // top, bottom
2364            capZAlign: 'center', // left, center, right
2365            //VIDEO && IFRAME 
2366            iframeWidth: 640,
2367            iframeHeight: 390,
2368            txtImgThumbIframe: 'IFRAME',
2369            videoWidth: 640,
2370            videoHeight: 390,
2371            txtImgThumbVideo: 'VIDEO'
2372        };
2373
2374        _this.element = element.wrap('<div class="glass-case"></div>').parent();
2375        _this.config = $.extend(true, {}, _this.defaults, options);
2376        _this.options = options;
2377        _this.items = [];
2378        _this.windowWidth = $(window).width();
2379        _this.process();
2380    }
2381
2382    function GCItemFactory() { }
2383    GCItemFactory.prototype = {
2384        createItem: function (element, config) {
2385            switch ($(element).find(':first').data('gc-type')) {
2386                 case 'iframe':
2387                   GCItemFactory.prototype.itemClass = GCIFrame;
2388                   break;
2389                 case 'video':
2390                   GCItemFactory.prototype.itemClass = GCVideo;
2391                   break;
2392                case 'image':
2393                    GCItemFactory.prototype.itemClass = GCImage;
2394                    break;
2395                default:
2396                    GCItemFactory.prototype.itemClass = GCImage;
2397                    break;
2398            }
2399
2400            return new this.itemClass($(element).find(':first'), config);
2401        }
2402    };
2403
2404    GlassCase.prototype = {
2405        process: function () {
2406            var _this = this;
2407
2408            _this.processInput();
2409            _this.init();
2410
2411            _this.setup();
2412            _this.changeCnt();
2413            _this.initEvents();
2414        },
2415        processInput: function () {
2416            var _this = this;
2417
2418            var itemFactory = new GCItemFactory();
2419
2420            _this.element.find('li').each(function () {
2421                _this.items.push(itemFactory.createItem($(this), _this.config));
2422            });
2423
2424            _this.element.find('li').empty();
2425            $.each(_this.element.find('li'), function (index, li) {
2426                $(li).append(_this.items[index].getInstance('thumb'));
2427            });
2428        },
2429        init: function () {
2430            var _this = this;
2431
2432            _this.display = new GCDisplay(_this.config, _this);
2433            _this.thumbs = new GCThumbs(_this.config, _this);
2434            _this.overlay = new GCOverlay(_this.config, _this);
2435
2436            _this.iOS = $.inArray(window.navigator.platform, ['iPad', 'iPhone', 'iPod']) > -1 ? true : false;
2437            _this.isTouchMove = false;
2438            _this.mouseTimer = 0;
2439            _this.resizeTimer = 0;
2440            _this.current = 0;
2441            _this.isFullScreenOn = false;
2442
2443            if (_this.config.colorIcons !== -1) {
2444                _this.display.getInstance().find('.gc-icon').css('color', _this.config.colorIcons);
2445                _this.thumbs.getInstance().find('.gc-icon').css('color', _this.config.colorIcons);
2446                _this.overlay.getInstance().find('.gc-icon').css('color', _this.config.colorIcons);
2447            }
2448        },
2449        initEvents: function () {
2450            var _this = this;
2451
2452            _this.thumbs.initEvents();
2453            _this.display.initEvents();
2454            _this.overlay.initEvents();
2455
2456            $(document).on('fullscreenchange.glasscase', $.proxy(_this.fullScreenHandler, _this))
2457                       .on('webkitfullscreenchange.glasscase', $.proxy(_this.fullScreenHandler, _this))
2458                       .on('mozfullscreenchange.glasscase', $.proxy(_this.fullScreenHandler, _this));
2459
2460            $(document).on('keydown', function (event) {
2461                if (_this.config.isKeypressEnabled === true) {
2462                    if (event.keyCode === 37) { //<-
2463                        _this.display.navigate('previous');
2464                        _this.thumbs.changeCnt();
2465                    }
2466
2467                    if (event.keyCode === 39) { //->
2468                        _this.display.navigate('next');
2469                        _this.thumbs.changeCnt();
2470                    }
2471                }
2472                if (event.keyCode === 27) { //esc
2473                    _this.overlay.close();
2474                }
2475            });
2476
2477            $(window).resize(function () {
2478                clearTimeout(_this.resizeTimer);
2479                _this.resizeTimer = setTimeout(function () {
2480                    _this.resize();
2481                }, 100);
2482            });
2483        },
2484        setup: function () {
2485            var _this = this;
2486
2487            _this.config = $.extend(true, {}, _this.defaults, _this.options);
2488            _this.thumbs.isOneThumbShown = _this.config.isOneThumbShown;
2489
2490            var wC; //width component
2491            var display = _this.display.getInstance();
2492            if (_this.overlay.isEnabled === true) {
2493                _this.element.prepend(_this.overlay.instance);
2494            }
2495            if (_this.thumbs.position === 'top' || _this.thumbs.position === 'left') {
2496                _this.element.append(display);
2497            } else {
2498                _this.element.prepend(display);
2499            }
2500            if ((_this.thumbs.position === 'right' || _this.thumbs.position === 'left') &&
2501              (_this.thumbs.isOneThumbShown === false && (_this.thumbs.li.length > 1))) {
2502
2503                var mgL = parseFloat(_this.thumbs.li.css('margin-bottom'));
2504                var hL = (parseFloat(_this.config.heightDisplay) - (_this.config.nrThumbsPerRow - 1) * mgL) / _this.config.nrThumbsPerRow;
2505                var ratio = _this.config.widthDisplay / _this.config.heightDisplay;
2506                var wL = hL * ratio;
2507                wC = wL + _this.config.thumbsMargin + parseFloat(_this.config.widthDisplay);
2508
2509                _this.display.wDperc = Math.round(_this.config.widthDisplay * 100 / wC);
2510
2511                wC = _this.element.parent().width() > wC ? wC : _this.element.parent().width();
2512
2513            } else {
2514                wC = _this.element.parent().width() > _this.config.widthDisplay ? (_this.config.widthDisplay) : _this.element.parent().width();
2515            }
2516
2517            _this.element.css({
2518                'width': wC
2519            });
2520            _this.display.setup();
2521            _this.thumbs.setup();
2522            _this.overlay.setup();
2523
2524            if (_this.thumbs.position === 'top' || _this.thumbs.position === 'bottom') {
2525                var hT = _this.thumbs.isOneThumbShown === false ? 0 : _this.thumbs.instance.outerHeight();
2526                _this.element.css({
2527                    'height': hT + display.outerHeight() + parseFloat(_this.thumbs.margin)
2528                });
2529            } else {
2530                var wT = _this.thumbs.isOneThumbShown === false ? 0 : _this.thumbs.instance.outerWidth();
2531                _this.element.css({
2532                    'width': wT + display.outerWidth() + parseFloat(_this.thumbs.margin)
2533                });
2534                _this.element.css({
2535                    'height': display.outerHeight()
2536                });
2537            }
2538        },
2539        changeCnt: function () {
2540            var _this = this;
2541
2542            _this.thumbs.changeCnt();
2543            _this.display.changeCnt();
2544            _this.overlay.changeCnt();
2545        },
2546        resize: function () {
2547            var _this = this;
2548            if (_this.isFullScreenOn)
2549                return;
2550            //on mobile devices any scrolling is triggering [resize], therefore we keep track of the window.width. If the width is changing => resize
2551            if (_this.windowWidth === $(window).width()) {
2552                return;
2553            }
2554            _this.windowWidth = $(window).width();
2555
2556            _this.element.css({
2557                'height': '0',
2558                'width': '0'
2559            });
2560            _this.setup();
2561            //Resising the component item, fit size of the thumb images
2562            $.each(_this.element.find('li'), function (index, li) {
2563                _this.items[index].fitSize();
2564            });
2565        },
2566        fullScreenHandler: function (event, context) {
2567            var _this = context || this;
2568
2569            if (!_this.overlay.isOpened) {
2570                _this.isFullScreenOn = !_this.isFullScreenOn;
2571            }
2572        }
2573    };
2574    $.fn.glassCase = function (options) {
2575        this.each(function () {
2576            var instance = $.data(this, 'gcglasscase');
2577            if (!instance) {
2578                $.data(this, 'gcglasscase', new GlassCase($(this), options));
2579            }
2580        });
2581    };
2582})(jQuery, window, document);
2583
2584/*!
2585Dynamics.js
2586
2587Dynamics.js is a JavaScript library to create physics-based animations.
2588To see some demos, check out http://dynamicsjs.com.
2589*/
2590
2591(function () { var t, e, n, r, o, i, s, a, u, l, f, h, p, c, m, d, g, y, v, b, w, x, M, S, k, T, C, H, R, q, I, X, Y, A, j, z, F, G, O, V, Z, E, L, D, P, W, N, U, $, B, K, J, Q, _, te, ee, ne, re, oe = function (t, e) { return function () { return t.apply(e, arguments) } }; I = function () { return "visible" === document.visibilityState || null != H.tests }, z = function () { var t; return t = [], "undefined" != typeof document && null !== document && document.addEventListener("visibilitychange", function () { var e, n, r, o; for (o = [], n = 0, r = t.length; r > n; n++) e = t[n], o.push(e(I())); return o }), function (e) { return t.push(e) } }(), S = function (t) { var e, n, r; n = {}; for (e in t) r = t[e], n[e] = r; return n }, x = function (t) { var e; return e = {}, function () { var n, r, o, i, s; for (r = "", i = 0, s = arguments.length; s > i; i++) n = arguments[i], r += n.toString() + ","; return o = e[r], o || (e[r] = o = t.apply(this, arguments)), o } }, j = function (t) { return function (e) { var n, r, o; return e instanceof Array || e instanceof NodeList || e instanceof HTMLCollection ? o = function () { var o, i, s; for (s = [], r = o = 0, i = e.length; i >= 0 ? i > o : o > i; r = i >= 0 ? ++o : --o) n = Array.prototype.slice.call(arguments, 1), n.splice(0, 0, e[r]), s.push(t.apply(this, n)); return s }.apply(this, arguments) : t.apply(this, arguments) } }, y = function (t, e) { var n, r, o; o = []; for (n in e) r = e[n], o.push(null != t[n] ? t[n] : t[n] = r); return o }, v = function (t, e) { var n, r, o; if (null != t.style) return b(t, e); o = []; for (n in e) r = e[n], o.push(t[n] = r.format()); return o }, b = function (t, e) { var n, r, o, i, s; e = F(e), i = [], n = X(t); for (r in e) s = e[r], ee.contains(r) ? i.push([r, s]) : (null != s.format && (s = s.format()), "number" == typeof s && (s = "" + s + re(r, s)), null != t.hasAttribute && t.hasAttribute(r) ? t.setAttribute(r, s) : null != t.style && (t.style[O(r)] = s), r in t && (t[r] = s)); return i.length > 0 ? n ? (o = new l, o.applyProperties(i), t.setAttribute("transform", o.decompose().format())) : (s = i.map(function (t) { return ne(t[0], t[1]) }).join(" "), t.style[O("transform")] = s) : void 0 }, X = function (t) { var e, n; return "undefined" != typeof SVGElement && null !== SVGElement && "undefined" != typeof SVGSVGElement && null !== SVGSVGElement ? t instanceof SVGElement && !(t instanceof SVGSVGElement) : null != (e = null != (n = H.tests) && "function" == typeof n.isSVG ? n.isSVG(t) : void 0) ? e : !1 }, E = function (t, e) { var n; return n = Math.pow(10, e), Math.round(t * n) / n }, f = function () { function t(t) { var e, n, r; for (this.obj = {}, n = 0, r = t.length; r > n; n++) e = t[n], this.obj[e] = 1 } return t.prototype.contains = function (t) { return 1 === this.obj[t] }, t }(), te = function (t) { return t.replace(/([A-Z])/g, function (t) { return "-" + t.toLowerCase() }) }, V = new f("marginTop,marginLeft,marginBottom,marginRight,paddingTop,paddingLeft,paddingBottom,paddingRight,top,left,bottom,right,translateX,translateY,translateZ,perspective
2591X,perspectiveY,perspectiveZ,width,height,maxWidth,maxHeight,minWidth,minHeight,borderRadius".split(",")), C = new f("rotate,rotateX,rotateY,rotateZ,skew,skewX,skewY,skewZ".split(",")), ee = new f("translate,translateX,translateY,translateZ,scale,scaleX,scaleY,scaleZ,rotate,rotateX,rotateY,rotateZ,rotateC,rotateCX,rotateCY,skew,skewX,skewY,skewZ,perspective".split(",")), K = new f("accent-height,ascent,azimuth,baseFrequency,baseline-shift,bias,cx,cy,d,diffuseConstant,divisor,dx,dy,elevation,filterRes,fx,fy,gradientTransform,height,k1,k2,k3,k4,kernelMatrix,kernelUnitLength,letter-spacing,limitingConeAngle,markerHeight,markerWidth,numOctaves,order,overline-position,overline-thickness,pathLength,points,pointsAtX,pointsAtY,pointsAtZ,r,radius,rx,ry,seed,specularConstant,specularExponent,stdDeviation,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,surfaceScale,target,targetX,targetY,transform,underline-position,underline-thickness,viewBox,width,x,x1,x2,y,y1,y2,z".split(",")), re = function (t, e) { return "number" != typeof e ? "" : V.contains(t) ? "px" : C.contains(t) ? "deg" : "" }, ne = function (t, e) { var n, r; return n = ("" + e).match(/^([0-9.-]*)([^0-9]*)$/), null != n ? (e = n[1], r = n[2]) : e = parseFloat(e), e = E(parseFloat(e), 10), (null == r || "" === r) && (r = re(t, e)), "" + t + "(" + e + r + ")" }, F = function (t) { var e, n, r, o, i, s, a, u; r = {}; for (o in t) if (i = t[o], ee.contains(o)) if (n = o.match(/(translate|rotateC|rotate|skew|scale|perspective)(X|Y|Z|)/), n && n[2].length > 0) r[o] = i; else for (u = ["X", "Y", "Z"], s = 0, a = u.length; a > s; s++) e = u[s], r[n[1] + e] = i; else r[o] = i; return r }, T = function (t) { var e; return e = "opacity" === t ? 1 : 0, "" + e + re(t, e) }, R = function (t, e) { var n, r, o, i, s, a, f, h, p, m, d; if (i = {}, n = X(t), null != t.style) for (s = window.getComputedStyle(t, null), f = 0, p = e.length; p > f; f++) r = e[f], ee.contains(r) ? null == i.transform && (o = n ? new l(null != (d = t.transform.baseVal.consolidate()) ? d.matrix : void 0) : u.fromTransform(s[O("transform")]), i.transform = o.decompose()) : (a = null != t.hasAttribute && t.hasAttribute(r) ? t.getAttribute(r) : r in t ? t[r] : s[r], null != a && "d" !== r || !K.contains(r) || (a = t.getAttribute(r)), ("" === a || null == a) && (a = T(r)), i[r] = k(a)); else for (h = 0, m = e.length; m > h; h++) r = e[h], i[r] = k(t[r]); return c(t, i), i }, c = function (t, e) { var n, r; for (r in e) n = e[r], n instanceof i && null != t.style && r in t.style && (n = new a([n, re(r, 0)])), e[r] = n; return e }, k = function (t) { var e, n, o, u, l; for (o = [r, s, i, a], u = 0, l = o.length; l > u; u++) if (n = o[u], e = n.create(t), null != e) return e; return null }, a = function () { function t(t) { this.parts = t, this.format = oe(this.format, this), this.interpolate = oe(this.interpolate, this) } return t.prototype.interpolate = function (e, n) { var r, o, i, s, a, u; for (s = this.parts, r = e.parts, i = [], o = a = 0, u = Math.min(s.length, r.length) ; u >= 0 ? u > a : a > u; o = u >= 0 ? ++a : --a) i.push(null != s[o].interpolate ? s[o].interpolate(r[o], n) : s[o]); return new t(i) }, t.prototype.format = function () { var t; return t = this.parts.map(function (t) { return null != t.format ? t.format() : t }), t.join("") }, t.create = function (e) { var n, r, s, a, u, l, f, h, p, c, m; for (e = "" + e, s = [], f = [{ re: /(#[a-f\d]{3,6})/gi, klass: o, parse: function (t) { return t } }, { re: /(rgba?\([0-9.]*, ?[0-9.]*, ?[0-9.]*(?:, ?[0-9.]*)?\))/gi, klass: o, parse: function (t) { return t } }, { re: /([-+]?[\d.]+)/gi, klass: i, parse: parseFloat }], h = 0, c = f.length; c > h; h++) for (l = f[h], u = l.re; r = u.exec(e) ;) s.push({ index: r.index, length: r[1].length, interpolable: l.klass.create(l.parse(r[1])) }); for (s = s.sort(function (t, e) { return t.index > e.index ? 1 : -1 }), a = [], n = 0, p = 0, m = s.length; m > p; p++) r = s[p], r.index < n || (r.index > n && a.push(e.substring(n, r.index)), a.push(r.interpolable), n = r.index + r.length); return n < e.length && a.push(e.substring(n)), new t(a) }, t }(), s = function () { function t(t) { this.format = oe(this.format, this), this.interpolate = oe(this.interpolate, this), this.obj = t } return t.prototype.interpolate = function (e, n) { var r, o, i, s, a; s = this.obj, r = e.obj, i = {}; for (o in s) a = s[o], i[o] = null != a.interpolate ? a.interpolate(r[o], n) : a; return new t(i) }, t.prototype.format = function () { return this.obj }, t.create = function (e) { var n, r, o; if (e instanceof Object) { r = {}; for (n in e) o = e[n], r[n] = k(o); return new t(r) } return null }, t }(), i = function () { function t(t) { this.format = oe(this.format, this), this.interpolate = oe(this.interpolate, this), this.value = parseFloat(t) } return t.prototype.interpolate = function (e, n) { var r, o; return o = this.value, r = e.value, new t((r - o) * n + o) }, t.prototype.format = function () { return E(this.value, 5) }, t.create = function (e) { return "number" == typeof e ? new t(e) : null }, t }(), r = function () { function t(t) { this.values = t, this.format = oe(this.format, this), this.interpolate = oe(this.interpolate, this) } return t.prototype.interpolate = function (e, n) { var r, o, i, s, a, u; for (s = this.values, r = e.values, i = [], o = a = 0, u = Math.min(s.length, r.length) ; u >= 0 ? u > a : a > u; o = u >
2591= 0 ? ++a : --a) i.push(null != s[o].interpolate ? s[o].interpolate(r[o], n) : s[o]); return new t(i) }, t.prototype.format = function () { return this.values.map(function (t) { return null != t.format ? t.format() : t }) }, t.createFromArray = function (e) { var n; return n = e.map(function (t) { return k(t) || t }), n = n.filter(function (t) { return null != t }), new t(n) }, t.create = function (e) { return e instanceof Array ? t.createFromArray(e) : null }, t }(), t = function () { function t(t, e) { this.rgb = null != t ? t : {}, this.format = e, this.toRgba = oe(this.toRgba, this), this.toRgb = oe(this.toRgb, this), this.toHex = oe(this.toHex, this) } return t.fromHex = function (e) { var n, r; return n = e.match(/^#([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$/i), null != n && (e = "#" + n[1] + n[1] + n[2] + n[2] + n[3] + n[3]), r = e.match(/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i), null != r ? new t({ r: parseInt(r[1], 16), g: parseInt(r[2], 16), b: parseInt(r[3], 16), a: 1 }, "hex") : null }, t.fromRgb = function (e) { var n, r; return n = e.match(/^rgba?\(([0-9.]*), ?([0-9.]*), ?([0-9.]*)(?:, ?([0-9.]*))?\)$/), null != n ? new t({ r: parseFloat(n[1]), g: parseFloat(n[2]), b: parseFloat(n[3]), a: parseFloat(null != (r = n[4]) ? r : 1) }, null != n[4] ? "rgba" : "rgb") : null }, t.componentToHex = function (t) { var e; return e = t.toString(16), 1 === e.length ? "0" + e : e }, t.prototype.toHex = function () { return "#" + t.componentToHex(this.rgb.r) + t.componentToHex(this.rgb.g) + t.componentToHex(this.rgb.b) }, t.prototype.toRgb = function () { return "rgb(" + this.rgb.r + ", " + this.rgb.g + ", " + this.rgb.b + ")" }, t.prototype.toRgba = function () { return "rgba(" + this.rgb.r + ", " + this.rgb.g + ", " + this.rgb.b + ", " + this.rgb.a + ")" }, t }(), o = function () { function e(t) { this.color = t, this.format = oe(this.format, this), this.interpolate = oe(this.interpolate, this) } return e.prototype.interpolate = function (n, r) { var o, i, s, a, u, l, f, h; for (a = this.color, o = n.color, s = {}, h = ["r", "g", "b"], l = 0, f = h.length; f > l; l++) i = h[l], u = Math.round((o.rgb[i] - a.rgb[i]) * r + a.rgb[i]), s[i] = Math.min(255, Math.max(0, u)); return i = "a", u = E((o.rgb[i] - a.rgb[i]) * r + a.rgb[i], 5), s[i] = Math.min(1, Math.max(0, u)), new e(new t(s, o.format)) }, e.prototype.format = function () { return "hex" === this.color.format ? this.color.toHex() : "rgb" === this.color.format ? this.color.toRgb() : "rgba" === this.color.format ? this.color.toRgba() : void 0 }, e.create = function (n) { var r; if ("string" == typeof n) return r = t.fromHex(n) || t.fromRgb(n), null != r ? new e(r) : null }, e }(), n = function () { function t(t) { this.props = t, this.applyRotateCenter = oe(this.applyRotateCenter, this), this.format = oe(this.format, this), this.interpolate = oe(this.interpolate, this) } return t.prototype.interpolate = function (e, n) { var r, o, i, s, a, u, l, f, h, p, c, m; for (i = {}, p = ["translate", "scale", "rotate"], s = 0, f = p.length; f > s; s++) for (o = p[s], i[o] = [], r = a = 0, c = this.props[o].length; c >= 0 ? c > a : a > c; r = c >= 0 ? ++a : --a) i[o][r] = (e.props[o][r] - this.props[o][r]) * n + this.props[o][r]; for (r = u = 1; 2 >= u; r = ++u) i.rotate[r] = e.props.rotate[r]; for (m = ["skew"], l = 0, h = m.length; h > l; l++) o = m[l], i[o] = (e.props[o] - this.props[o]) * n + this.props[o]; return new t(i) }, t.prototype.format = function () { return "translate(" + this.props.translate.join(",") + ") rotate(" + this.props.rotate.join(",") + ") skewX(" + this.props.skew + ") scale(" + this.props.scale.join(",") + ")" }, t.prototype.applyRotateCenter = function (t) { var e, n, r, o, i, s; for (n = w.createSVGMatrix(), n = n.translate(t[0], t[1]), n = n.rotate(this.props.rotate[0]), n = n.translate(-t[0], -t[1]), r = new l(n), o = r.decompose().props.translate, s = [], e = i = 0; 1 >= i; e = ++i) s.push(this.props.translate[e] -= o[e]); return s }, t }(), w = "undefined" != typeof document && null !== document ? document.createElementNS("http://www.w3.org/2000/svg", "svg") 
2591: void 0, l = function () { function t(t) { this.m = t, this.applyProperties = oe(this.applyProperties, this), this.decompose = oe(this.decompose, this), this.m || (this.m = w.createSVGMatrix()) } return t.prototype.decompose = function () { var t, e, r, o, i; return o = new h([this.m.a, this.m.b]), i = new h([this.m.c, this.m.d]), t = o.length(), r = o.dot(i), o = o.normalize(), e = i.combine(o, 1, -r).length(), new n({ translate: [this.m.e, this.m.f], rotate: [180 * Math.atan2(this.m.b, this.m.a) / Math.PI, this.rotateCX, this.rotateCY], scale: [t, e], skew: r / e * 180 / Math.PI }) }, t.prototype.applyProperties = function (t) { var e, n, r, o, i, s, a, u; for (e = {}, i = 0, s = t.length; s > i; i++) r = t[i], e[r[0]] = r[1]; for (n in e) o = e[n], "translateX" === n ? this.m = this.m.translate(o, 0) : "translateY" === n ? this.m = this.m.translate(0, o) : "scaleX" === n ? this.m = this.m.scaleNonUniform(o, 1) : "scaleY" === n ? this.m = this.m.scaleNonUniform(1, o) : "rotateZ" === n ? this.m = this.m.rotate(o) : "skewX" === n ? this.m = this.m.skewX(o) : "skewY" === n && (this.m = this.m.skewY(o)); return this.rotateCX = null != (a = e.rotateCX) ? a : 0, this.rotateCY = null != (u = e.rotateCY) ? u : 0 }, t }(), h = function () { function t(t) { this.els = t, this.combine = oe(this.combine, this), this.normalize = oe(this.normalize, this), this.length = oe(this.length, this), this.cross = oe(this.cross, this), this.dot = oe(this.dot, this), this.e = oe(this.e, this) } return t.prototype.e = function (t) { return 1 > t || t > this.els.length ? null : this.els[t - 1] }, t.prototype.dot = function (t) { var e, n, r; if (e = t.els || t, r = 0, n = this.els.length, n !== e.length) return null; for (n += 1; --n;) r += this.els[n - 1] * e[n - 1]; return r }, t.prototype.cross = function (e) { var n, r; return r = e.els || e, 3 !== this.els.length || 3 !== r.length ? null : (n = this.els, new t([n[1] * r[2] - n[2] * r[1], n[2] * r[0] - n[0] * r[2], n[0] * r[1] - n[1] * r[0]])) }, t.prototype.length = function () { var t, e, n, r, o; for (t = 0, o = this.els, n = 0, r = o.length; r > n; n++) e = o[n], t += Math.pow(e, 2); return Math.sqrt(t) }, t.prototype.normalize = function () { var e, n, r, o, i; r = this.length(), o = [], i = this.els; for (n in i) e = i[n], o[n] = e / r; return new t(o) }, t.prototype.combine = function (e, n, r) { var o, i, s, a; for (i = [], o = s = 0, a = this.els.length; a >= 0 ? a > s : s > a; o = a >= 0 ? ++s : --s) i[o] = n * this.els[o] + r * e.els[o]; return new t(i) }, t }(), e = function () { function t() { this.toMatrix = oe(this.toMatrix, this), this.format = oe(this.format, this), this.interpolate = oe(this.interpolate, this) } return t.prototype.interpolate = function (e, n, r) { var o, i, s, a, u, l, f, h, p, c, m, d, g, y, v, b, w, x; for (null == r && (r = null), s = this, i = new t, w = ["translate", "scale", "skew", "perspective"], d = 0, b = w.length; b > d; d++) for (f = w[d], i[f] = [], a = g = 0, x = s[f].length - 1; x >= 0 ? x >= g : g >= x; a = x >= 0 ? ++g : --g) i[f][a] = null == r || r.indexOf(f) > -1 || r.indexOf("" + f + ["x", "y", "z"][a]) > -1 ? (e[f][a] - s[f][a]) * n + s[f][a] : s[f][a]; if (null == r || -1 !== r.indexOf("rotate")) { if (h = s.quaternion, p = e.quaternion, o = h[0] * p[0] + h[1] * p[1] + h[2] * p[2] + h[3] * p[3], 0 > o) { for (a = y = 0; 3 >= y; a = ++y) h[a] = -h[a]; o = -o } for (o + 1 > .05 ? 1 - o >= .05 ? (m = Math.acos(o), l = 1 / Math.sin(m), c = Math.sin(m * (1 - n)) * l, u = Math.sin(m * n) * l) : (c = 1 - n, u = n) : (p[0] = -h[1], p[1] = h[0], p[2] = -h[3], p[3] = h[2], c = Math.sin(piDouble * (.5 - n)), u = Math.sin(piDouble * n)), i.quaternion = [], a = v = 0; 3 >= v; a = ++v) i.quaternion[a] = h[a] * c + p[a] * u } else i.quaternion = s.quaternion; return i }, t.prototype.format = function () { return this.toMatrix().toString() }, t.prototype.toMatrix = function () { var t, e, n, r, o, i, s, a, l, f, h, p, c, m, d, g; for (t = this, o = u.I(4), e = c = 0; 3 >= c; e = ++c) o.els[e][3] = t.perspective[e]; for (i = t.quaternion, f = i[0], h = i[1], p = i[2], l = i[3], s = t.skew, r = [[1, 0], [2, 0], [2, 1]], e = m = 2; m >= 0; e = --m) s[e] && (a = u.I(4), a.els[r[e][0]][r[e][1]] = s[e], o = o.multiply(a)); for (o = o.multiply(new u([[1 - 2 * (h * h + p * p), 2 * (f * h - p * l), 2 * (f * p + h * l), 0], [2 * (f * h + p * l), 1 - 2 * (f * f + p * p), 2 * (h * p - f * l), 0], [2 * (f * p - h * l), 2 * (h * p + f * l), 1 - 2 * (f * f + h * h), 0], [0, 0, 0, 1]])
2591), e = d = 0; 2 >= d; e = ++d) { for (n = g = 0; 2 >= g; n = ++g) o.els[e][n] *= t.scale[e]; o.els[3][e] = t.translate[e] } return o }, t }(), u = function () { function t(t) { this.els = t, this.toString = oe(this.toString, this), this.decompose = oe(this.decompose, this), this.inverse = oe(this.inverse, this), this.augment = oe(this.augment, this), this.toRightTriangular = oe(this.toRightTriangular, this), this.transpose = oe(this.transpose, this), this.multiply = oe(this.multiply, this), this.dup = oe(this.dup, this), this.e = oe(this.e, this) } return t.prototype.e = function (t, e) { return 1 > t || t > this.els.length || 1 > e || e > this.els[0].length ? null : this.els[t - 1][e - 1] }, t.prototype.dup = function () { return new t(this.els) }, t.prototype.multiply = function (e) { var n, r, o, i, s, a, u, l, f, h, p, c, m; for (c = e.modulus ? !0 : !1, n = e.els || e, "undefined" == typeof n[0][0] && (n = new t(n).els), h = this.els.length, u = h, l = n[0].length, o = this.els[0].length, i = [], h += 1; --h;) for (s = u - h, i[s] = [], p = l, p += 1; --p;) { for (a = l - p, m = 0, f = o, f += 1; --f;) r = o - f, m += this.els[s][r] * n[r][a]; i[s][a] = m } return n = new t(i), c ? n.col(1) : n }, t.prototype.transpose = function () { var e, n, r, o, i, s, a; for (a = this.els.length, e = this.els[0].length, n = [], i = e, i += 1; --i;) for (r = e - i, n[r] = [], s = a, s += 1; --s;) o = a - s, n[r][o] = this.els[o][r]; return new t(n) }, t.prototype.toRightTriangular = function () { var t, e, n, r, o, i, s, a, u, l, f, h, p, c; for (t = this.dup(), a = this.els.length, o = a, i = this.els[0].length; --a;) { if (n = o - a, 0 === t.els[n][n]) for (r = f = p = n + 1; o >= p ? o > f : f > o; r = o >= p ? ++f : --f) if (0 !== t.els[r][n]) { for (e = [], u = i, u += 1; --u;) l = i - u, e.push(t.els[n][l] + t.els[r][l]); t.els[n] = e; break } if (0 !== t.els[n][n]) for (r = h = c = n + 1; o >= c ? o > h : h > o; r = o >= c ? ++h : --h) { for (s = t.els[r][n] / t.els[n][n], e = [], u = i, u += 1; --u;) l = i - u, e.push(n >= l ? 0 : t.els[r][l] - t.els[n][l] * s); t.els[r] = e } } return t }, t.prototype.augment = function (e) { var n, r, o, i, s, a, u, l, f; if (n = e.els || e, "undefined" == typeof n[0][0] && (n = new t(n).els), r = this.dup(), o = r.els[0].length, l = r.els.length, a = l, u = n[0].length, l !== n.length) return null; for (l += 1; --l;) for (i = a - l, f = u, f += 1; --f;) s = u - f, r.els[i][o + s] = n[i][s]; return r }, t.prototype.inverse = function () { var e, n, r, o, i, s, a, u, l, f, h, p, c; for (f = this.els.length, a = f, e = this.augment(t.I(f)).toRightTriangular(), u = e.els[0].length, i = [], f += 1; --f;) { for (o = f - 1, r = [], h = u, i[o] = [], n = e.els[o][o], h += 1; --h;) p = u - h, l = e.els[o][p] / n, r.push(l), p >= a && i[o].push(l); for (e.els[o] = r, s = c = 0; o >= 0 ? o > c : c > o; s = o >= 0 ? ++c : --c) { for (r = [], h = u, h += 1; --h;) p = u - h, r.push(e.els[s][p] - e.els[o][p] * e.els[s][o]); e.els[s] = r } } return new t(i) }, t.I = function (e) { var n, r, o, i, s; for (n = [], i = e, e += 1; --e;) for (r = i - e, n[r] = [], s = i, s += 1; --s;) o = i - s, n[r][o] = r === o ? 1 : 0; return new t(n) }, t.prototype.decompose = function () { var t, n, r, o, i, s, a, u, l, f, p, c, m, d, g, y, v, b, w, x, M, S, k, T, C, H, R, q, I, X, Y, A, j, z, F, G, O, V; for (s = this, x = [], v = [], b = [], f = [], u = [], t = [], n = I = 0; 3 >= I; n = ++I) for (t[n] = [], o = X = 0; 3 >= X; o = ++X) t[n][o] = s.els[n][o]; if (0 === t[3][3]) return !1; for (n = Y = 0; 3 >= Y; n = ++Y) for (o = A = 0; 3 >= A; o = ++A) t[n][o] /= t[3][3]; for (l = s.dup(), n = j = 0; 2 >= j; n = ++j) l.els[n][3] = 0; if (l.els[3][3] = 1, 0 !== t[0][3] || 0 !== t[1][3] || 0 !== t[2][3]) { for (c = new h(t.slice(0, 4)[3]), r = l.inverse(), M = r.transpose(), u = M.multiply(c).els, n = z = 0; 2 >= z; n = ++z) t[n][3] = 0;
2591 t[3][3] = 1 } else u = [0, 0, 0, 1]; for (n = F = 0; 2 >= F; n = ++F) x[n] = t[3][n], t[3][n] = 0; for (d = [], n = G = 0; 2 >= G; n = ++G) d[n] = new h(t[n].slice(0, 3)); if (v[0] = d[0].length(), d[0] = d[0].normalize(), b[0] = d[0].dot(d[1]), d[1] = d[1].combine(d[0], 1, -b[0]), v[1] = d[1].length(), d[1] = d[1].normalize(), b[0] /= v[1], b[1] = d[0].dot(d[2]), d[2] = d[2].combine(d[0], 1, -b[1]), b[2] = d[1].dot(d[2]), d[2] = d[2].combine(d[1], 1, -b[2]), v[2] = d[2].length(), d[2] = d[2].normalize(), b[1] /= v[2], b[2] /= v[2], a = d[1].cross(d[2]), d[0].dot(a) < 0) for (n = O = 0; 2 >= O; n = ++O) for (v[n] *= -1, o = V = 0; 2 >= V; o = ++V) d[n].els[o] *= -1; g = function (t, e) { return d[t].els[e] }, m = [], m[1] = Math.asin(-g(0, 2)), 0 !== Math.cos(m[1]) ? (m[0] = Math.atan2(g(1, 2), g(2, 2)), m[2] = Math.atan2(g(0, 1), g(0, 0))) : (m[0] = Math.atan2(-g(2, 0), g(1, 1)), m[1] = 0), w = g(0, 0) + g(1, 1) + g(2, 2) + 1, w > 1e-4 ? (y = .5 / Math.sqrt(w), C = .25 / y, H = (g(2, 1) - g(1, 2)) * y, R = (g(0, 2) - g(2, 0)) * y, q = (g(1, 0) - g(0, 1)) * y) : g(0, 0) > g(1, 1) && g(0, 0) > g(2, 2) ? (y = 2 * Math.sqrt(1 + g(0, 0) - g(1, 1) - g(2, 2)), H = .25 * y, R = (g(0, 1) + g(1, 0)) / y, q = (g(0, 2) + g(2, 0)) / y, C = (g(2, 1) - g(1, 2)) / y) : g(1, 1) > g(2, 2) ? (y = 2 * Math.sqrt(1 + g(1, 1) - g(0, 0) - g(2, 2)), H = (g(0, 1) + g(1, 0)) / y, R = .25 * y, q = (g(1, 2) + g(2, 1)) / y, C = (g(0, 2) - g(2, 0)) / y) : (y = 2 * Math.sqrt(1 + g(2, 2) - g(0, 0) - g(1, 1)), H = (g(0, 2) + g(2, 0)) / y, R = (g(1, 2) + g(2, 1)) / y, q = .25 * y, C = (g(1, 0) - g(0, 1)) / y), f = [H, R, q, C], p = new e, p.translate = x, p.scale = v, p.skew = b, p.quaternion = f, p.perspective = u, p.rotate = m; for (k in p) { S = p[k]; for (i in S) T = S[i], isNaN(T) && (S[i] = 0) } return p }, t.prototype.toString = function () { var t, e, n, r, o; for (n = "matrix3d(", t = r = 0; 3 >= r; t = ++r) for (e = o = 0; 3 >= o; e = ++o) n += E(this.els[t][e], 10), (3 !== t || 3 !== e) && (n += ","); return n += ")" }, t.matrixForTransform = x(function (t) { var e, n, r, o, i, s; return e = document.createElement("div"), e.style.position = "absolute", e.style.visibility = "hidden", e.style[O("transform")] = t, document.body.appendChild(e), r = window.getComputedStyle(e, null), n = null != (o = null != (i = r.transform) ? i : r[O("transform")]) ? o : null != (s = H.tests) ? s.matrixForTransform(t) : void 0, document.body.removeChild(e), n }), t.fromTransform = function (e) { var n, r, o, i, s, a; for (i = null != e ? e.match(/matrix3?d?\(([-0-9,e \.]*)\)/) : void 0, i ? (n = i[1].split(","), n = n.map(parseFloat), r = 6 === n.length ? [n[0], n[1], 0, 0, n[2], n[3], 0, 0, 0, 0, 1, 0, n[4], n[5], 0, 1] : n) : r = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], s = [], o = a = 0; 3 >= a; o = ++a) s.push(r.slice(4 * o, 4 * o + 4)); return new t(s) }, t }(), G = x(function (t) { var e, n, r, o, i, s, a, u, l, f; if (void 0 !== document.body.style[t]) return ""; for (o = t.split("-"), i = "", s = 0, u = o.length; u > s; s++) r = o[s], i += r.substring(0, 1).toUpperCase() + r.substring(1); for (f = ["Webkit", "Moz", "ms"], a = 0, l = f.length; l > a; a++) if (n = f[a], e = n + i, void 0 !== document.body.style[e]) return n; return "" }), O = x(function (t) { var e; return e = G(t), "Moz" === e ? "" + e + (t.substring(0, 1).toUpperCase() + t.substring(1)) : "" !== e ? "-" + e.toLowerCase() + "-" + te(t) : te(t) }), Z = "undefined" != typeof window && null !== window ? window.requestAnimationFrame : void 0, d = [], g = [], N = !1, U = 1, "undefined" != typeof window && null !== window && window.addEventListener("keyup", function (t) { return 68 === t.keyCode && t.shiftKey && t.ctrlKey ? H.toggleSlow() : void 0 }), null == Z && (Y = 0, Z = function (t) { var e, n, r; return e = Date.now(), r = Math.max(0, 16 - (e - Y)), n = window.setTimeout(function () { return t(e + r) }, r), Y = e + r, n }), D = !1, L = !1, B = function () { return D ? void 0 : (D = !0, Z(P)) }, P = function (t) { var e, n, r, o; if (L) return void Z(P); for (n = [], r = 0, o = d.length; o > r; r++) e = d[r], m(t, e) || n.push(e); return d = d.filter(function (t) { return -1 === n.indexOf(t) }), 0 === d.length ? D = !1 : Z(P) }, m = function (t, e) { var n, r, o, i, s, a, u, l; if (null == e.tStart && (e.tStart = t), i = (t - e.tStart) / e.options.duration, s = e.curve(i), r = {}, i >= 1) r = e.curve.returnsToSelf ? e.properties.start : e.properties.end; else { l = e.properties.start; for (n in l) o = l[n], r[n] = q(o, e.properties.end[n], s) } return v(e.el, r), "function" == typeof (a = e.options).change && a.change(e.el, Math.min(1, i)), i >= 1 && "function" == typeof (u = e.options).complete && u.complete(e.el), 1 > i }, q = function (t, e, n) { return null != t && null != t.interpolate ? t.interpolate(e, n) : null }, $ = function (t, e, n, r) { var o, i, s, a, f, h, p; if (null != r && (g = g.filter(function (t) { return t.id !== r })), H.stop(t, { timeout: !1 }), !n.animated) return H.css(t, e), void ("function" == typeof n.complete && n.complete(this)); f = R(t, Object.keys(e)), e = F(e), o = {}, h = []; for (s in e) p = e[s], null != t.style && ee.contains(s) ? h.push([s, p]) : o[s] = k(p); return h.length > 0 && (i = X(t), i ? (a = new l, a.applyProperties(h)) : (p = h.map(function (t) { return ne(t[0], t[1]) }).join(" "), a = u.fromTransform(u.matrixForTransform(p))), o.transform = a.decompose(), i && f.transform.applyRotateCenter([o.transform.props.rotate[1], o.transform.props.rotate[2]])), c(t, o), d.push({ el: t, properties: { start: f, end: o }, options: n, curve: n.type.call(n.type, n) }), B() }, _ = [], Q = 0, W = function (t) { return I() ? Z(function () { return -1 !== _.indexOf(t) ? t.realTimeoutId = setTimeout(function () { return t.fn(), M(t.
2591id) }, t.delay) : void 0 }) : void 0 }, p = function (t, e) { var n; return Q += 1, n = { id: Q, tStart: Date.now(), fn: t, delay: e, originalDelay: e }, W(n), _.push(n), Q }, M = function (t) { return _ = _.filter(function (e) { return e.id === t && e.realTimeoutId && clearTimeout(e.realTimeoutId), e.id !== t }) }, A = function (t, e) { var n; return null != t ? (n = t - e.tStart, e.originalDelay - n) : e.originalDelay }, "undefined" != typeof window && null !== window && window.addEventListener("unload", function () { }), J = null, z(function (t) { var e, n, r, o, i, s, a, u, l, f; if (L = !t, t) { if (D) for (n = Date.now() - J, i = 0, u = d.length; u > i; i++) e = d[i], null != e.tStart && (e.tStart += n); for (s = 0, l = _.length; l > s; s++) r = _[s], r.delay = A(J, r), W(r); return J = null } for (J = Date.now(), f = [], o = 0, a = _.length; a > o; o++) r = _[o], f.push(clearTimeout(r.realTimeoutId)); return f }), H = {}, H.linear = function () { return function (t) { return t } }, H.spring = function (t) { var e, n, r, o, i, s; return null == t && (t = {}), y(t, H.spring.defaults), o = Math.max(1, t.frequency / 20), i = Math.pow(20, t.friction / 100), s = t.anticipationSize / 1e3, r = Math.max(0, s), e = function (e) { var n, r, o, i, a; return n = .8, i = s / (1 - s), a = 0, o = (i - n * a) / (i - a), r = (n - o) / i, r * e * t.anticipationStrength / 100 + o }, n = function (t) { return Math.pow(i / 10, -t) * (1 - t) }, function (t) { var r, i, a, u, l, f, h, p; return f = t / (1 - s) - s / (1 - s), s > t ? (p = s / (1 - s) - s / (1 - s), h = 0 / (1 - s) - s / (1 - s), l = Math.acos(1 / e(p)), a = (Math.acos(1 / e(h)) - l) / (o * -s), r = e) : (r = n, l = 0, a = 1), i = r(f), u = o * (t - s) * a + l, 1 - i * Math.cos(u) } }, H.bounce = function (t) { var e, n, r, o; return null == t && (t = {}), y(t, H.bounce.defaults), r = Math.max(1, t.frequency / 20), o = Math.pow(20, t.friction / 100), e = function (t) { return Math.pow(o / 10, -t) * (1 - t) }, n = function (t) { var n, o, i, s; return s = -1.57, o = 1, n = e(t), i = r * t * o + s, n * Math.cos(i) }, n.returnsToSelf = !0, n }, H.gravity = function (t) { var e, n, r, o, i, s, a; return null == t && (t = {}), y(t, H.gravity.defaults), n = Math.min(t.bounciness / 1250, .8), o = t.elasticity / 1e3, a = 100, r = [], e = function () { var r, o; for (r = Math.sqrt(2 / a), o = { a: -r, b: r, H: 1 }, t.returnsToSelf && (o.a = 0, o.b = 2 * o.b) ; o.H > .001;) e = o.b - o.a, o = { a: o.b, b: o.b + e * n, H: o.H * n * n }; return o.b }(), s = function (n, r, o, i) { var s, a; return e = r - n, a = 2 / e * i - 1 - 2 * n / e, s = a * a * o - o + 1, t.returnsToSelf && (s = 1 - s), s }, function () { var i, s, u, l; for (s = Math.sqrt(2 / (a * e * e)), u = { a: -s, b: s, H: 1 }, t.returnsToSelf && (u.a = 0, u.b = 2 * u.b), r.push(u), i = e, l = []; u.b < 1 && u.H > .001;) i = u.b - u.a, u = { a: u.b, b: u.b + i * n, H: u.H * o }, l.push(r.push(u)); return l }(), i = function (e) { var n, o, i; for (o = 0, n = r[o]; !(e >= n.a && e <= n.b) && (o += 1, n = r[o]) ;); return i = n ? s(n.a, n.b, n.H, e) : t.returnsToSelf ? 0 : 1 }, i.returnsToSelf = t.returnsToSelf, i }, H.forceWithGravity = function (t) { return null == t && (t = {}), y(t, H.forceWithGravity.defaults), t.returnsToSelf = !0, H.gravity(t) }, H.bezier = function () { var t, e, n; return e = function (t, e, n, r, o) { return Math.pow(1 - t, 3) * e + 3 * Math.pow(1 - t, 2) * t * n + 3 * (1 - t) * Math.pow(t, 2) * r + Math.pow(t, 3) * o }, t = function (t, n, r, o, i) { return { x: e(t, n.x, r.x, o.x, i.x), y: e(t, n.y, r.y, o.y, i.y) } }, n = function (t, e, n) { var r, o, i, s, a, u, l, f, h, p; for (r = null, h = 0, p = e.length; p > h && (o = e[h], t >= o(0).x && t <= o(1).x && (r = o), null === r) ; h++); if (!r) return n ? 0 : 1; for (f = 1e-4, s = 0, u = 1, a = (u + s) / 2, l = r(a).x, i = 0; Math.abs(t - l) > f && 100 > i;) t > l ? s = a : u = a, a = (u + s) / 2, l = r(a).x, i += 1; return r(a).y }, function (e) { var r, o, i; return null == e && (e = {}), i = e.points, r = function () { var e, n, o; r = [], o = function (e, n) { var o; return o = function (r) { return t(r, e, e.cp[e.cp.length - 1], n.cp[0], n) }, r.push(o) };
2591 for (e in i) { if (n = parseInt(e), n >= i.length - 1) break; o(i[n], i[n + 1]) } return r }(), o = function (t) { return 0 === t ? 0 : 1 === t ? 1 : n(t, r, this.returnsToSelf) }, o.returnsToSelf = 0 === i[i.length - 1].y, o } }(), H.easeInOut = function (t) { var e, n; return null == t && (t = {}), e = null != (n = t.friction) ? n : H.easeInOut.defaults.friction, H.bezier({ points: [{ x: 0, y: 0, cp: [{ x: .92 - e / 1e3, y: 0 }] }, { x: 1, y: 1, cp: [{ x: .08 + e / 1e3, y: 1 }] }] }) }, H.easeIn = function (t) { var e, n; return null == t && (t = {}), e = null != (n = t.friction) ? n : H.easeIn.defaults.friction, H.bezier({ points: [{ x: 0, y: 0, cp: [{ x: .92 - e / 1e3, y: 0 }] }, { x: 1, y: 1, cp: [{ x: 1, y: 1 }] }] }) }, H.easeOut = function (t) { var e, n; return null == t && (t = {}), e = null != (n = t.friction) ? n : H.easeOut.defaults.friction, H.bezier({ points: [{ x: 0, y: 0, cp: [{ x: 0, y: 0 }] }, { x: 1, y: 1, cp: [{ x: .08 + e / 1e3, y: 1 }] }] }) }, H.spring.defaults = { frequency: 300, friction: 200, anticipationSize: 0, anticipationStrength: 0 }, H.bounce.defaults = { frequency: 300, friction: 200 }, H.forceWithGravity.defaults = H.gravity.defaults = { bounciness: 400, elasticity: 200 }, H.easeInOut.defaults = H.easeIn.defaults = H.easeOut.defaults = { friction: 500 }, H.css = j(function (t, e) { return b(t, e, !0) }), H.animate = j(function (t, e, n) { var r; return null == n && (n = {}), n = S(n), y(n, { type: H.easeInOut, duration: 1e3, delay: 0, animated: !0 }), n.duration = Math.max(0, n.duration * U), n.delay = Math.max(0, n.delay), 0 === n.delay ? $(t, e, n) : (r = H.setTimeout(function () { return $(t, e, n, r) }, n.delay), g.push({ id: r, el: t })) }), H.stop = j(function (t, e) { return null == e && (e = {}), null == e.timeout && (e.timeout = !0), e.timeout && (g = g.filter(function (n) { return n.el !== t || null != e.filter && !e.filter(n) ? !0 : (H.clearTimeout(n.id), !1) })), d = d.filter(function (e) { return e.el !== t }) }), H.setTimeout = function (t, e) { return p(t, e * U) }, H.clearTimeout = function (t) { return M(t) }, H.toggleSlow = function () { return N = !N, U = N ? 3 : 1, "undefined" != typeof console && null !== console && "function" == typeof console.log ? console.log("dynamics.js: slow animations " + (N ? "enabled" : "disabled")) : void 0 }, "object" == typeof module && "object" == typeof module.exports ? module.exports = H : "function" == typeof define ? define("dynamics", function () { return H }) : window.dynamics = H }).call(this);

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.