PageSourceSearch

https://www.enter.ba/wp-content/plugins/wp-photo-gallery/js/jquery.gview-3.0-dev.js?ver=7.1.2

js enter.ba collected 2026-10-02 23:51:20 UTC 44,215 bytes, 1,152 lines download raw bytes

1/*
2
3GalleryView - jQuery Content Gallery Plugin
4Author:		Jack Anderson
5Version:	3.0 DEVELOPMENT
6
7See README.txt for instructions on how to markup your HTML
8*/
9
10// Make sure Object.create is available in the browser (for our prototypal inheritance)
11// Courtesy of Douglas Crockford
12if (typeof Object.create !== 'function') {
13    Object.create = function (o) {
14        function F() { }
15        F.prototype = o;
16        return new F();
17    };
18}
19
20(function ($) {
21    // custom image object
22    var gvImage = function (img) {
23
24        this.src = {
25            panel: img.attr('src'),
26            frame: img.data('frame') || img.attr('src')
27        };
28        this.scale = {
29            panel: null,
30            frame: null
31        };
32        this.height = 0;
33        this.width = 0;
34        this.attrs = {
35            title: img.attr('title') || img.attr('alt'),
36            description: img.data('description')
37        };
38        this.href = img.data('href');  // Important for clickable links
39        this.target = img.data('target');  // Important for clickable links
40        this.dom_obj = null;
41
42        return this;
43    },
44
45    // utility function wrapper
46	gv = {
47	    getInt: function (i) {
48	        i = parseInt(i, 10);
49	        return isNaN(i) ? 0 : i;
50	    },
51	    innerWidth: function (elem) {
52	        return this.getInt(elem.css('width')) || 0;
53	    },
54	    outerWidth: function (elem) {
55	        return this.innerWidth(elem) +
56					this.extraWidth(elem);
57	    },
58	    extraWidth: function (elem) {
59	        return this.getInt(elem.css('paddingLeft')) +
60					this.getInt(elem.css('paddingRight')) +
61					this.getInt(elem.css('borderLeftWidth')) +
62					this.getInt(elem.css('borderRightWidth'));
63	    },
64	    innerHeight: function (elem) {
65	        return this.getInt(elem.css('height')) || 0;
66	    },
67	    outerHeight: function (elem) {
68	        return this.innerHeight(elem) +
69					this.extraHeight(elem);
70	    },
71	    extraHeight: function (elem) {
72	        return this.getInt(elem.css('paddingTop')) +
73					this.getInt(elem.css('paddingBottom')) +
74					this.getInt(elem.css('borderTopWidth')) +
75					this.getInt(elem.css('borderBottomWidth'));
76	    }
77	},
78
79    /*
80    GalleryView - Object
81    The main gallery class
82    */
83	GalleryView = {
84	    // array of dom elements
85	    elems: [
86			'.gv_galleryWrap', '.gv_gallery', '.gv_panelWrap', '.gv_panel',
87			'img.gv_image', '.gv_infobar', '.gv_filmstripWrap', '.gv_filmstrip',
88			'.gv_frame', '.gv_thumbnail', '.gv_caption', 'img.gv_thumb',
89			'.gv_navWrap', '.gv_navNext', '.gv_navPrev', '.gv_navPlay',
90			'.gv_panelNavNext', '.gv_panelNavPrev', '.gv_overlay', '.gv_showOverlay',
91			'.gv_imageStore'
92		],
93
94	    // create a jQuery element and apply attributes
95	    createElem: function (attrs, elem) {
96	        elem = document.createElement(elem);
97	        var $elem = $(elem);
98	        return $elem.attr(attrs);
99	    },
100
101	    // get the position of an element with respect
102	    // to the gallery wrapper
103	    getPos: function (el) {
104	        var self = this,
105				dom = this.dom,
106				el = el[0],
107				el_id = el.id,
108				left = 0,
109				top = 0,
110				gPos, gLeft, gTop;
111
112	        if (!el) { return { top: 0, left: 0 }; }
113
114	        if (el.offsetParent) {
115	            do {
116	                left += el.offsetLeft;
117	                top += el.offsetTop;
118	            } while (el = el.offsetParent);
119	        }
120
121	        //If we want the position of the gallery itself, return it
122	        if (el_id === self.id) { return { left: left, top: top }; }
123
124	        //Otherwise, get position of element relative to gallery
125	        else {
126	            gPos = self.getPos(dom.galleryWrap);
127	            gLeft = gPos.left;
128	            gTop = gPos.top;
129	            return { left: left - gLeft, top: top - gTop };
130	        }
131	    },
132
133	    // determine if mouse is within the boundary of the gallery wrapper
134	    mouseIsOverGallery: function (x, y) {
135	        var self = this,
136				dom = this.dom,
137				pos = this.getPos(dom.gv_galleryWrap),
138				top = pos.top,
139				left = pos.left;
140
141	        return x > left && x < left + gv.outerWidth(dom.gv_galleryWrap) && y > top && y < top + gv.outerHeight(dom.gv_galleryWrap);
142	    },
143
144	    // determine if mouse is within the boundary of the panel
145	    mouseIsOverPanel: function (x, y) {
146	        var self = this,
147				dom = this.dom,
148				pos = this.getPos(dom.gv_panelWrap),
149				gPos = this.getPos(dom.gv_galleryWrap),
150				top = pos.top + gPos.top,
151				left = pos.left + gPos.left;
152
153	        return x > left && x < left + gv.outerWidth(dom.gv_panelWrap) && y > top && y < top + gv.outerHeight(dom.gv_panelWrap);
154	    },
155
156	    // create gvImage objects for each image in gallery
157	    storeImages: function () {
158	        var self = this;
159	        this.sourceImgs = $('li>img', this.$el);
160	        this.numImages = this.sourceImgs.length;
161	        this.gvImages = [];
162	        this.sourceImgs.each(function (i, img) {
163	            self.gvImages[i] = new gvImage($(img));
164	        });
165	    },
166
167	    setDimensions: function () {
168	        var self = this,
169				dom = this.dom,
170				widths = {
171				    prev: gv.innerWidth(dom.gv_navPrev),
172				    play: gv.innerWidth(dom.gv_navPlay),
173				    next: gv.innerWidth(dom.gv_navNext),
174				    filmstrip: this.opts.frame_width,
175				    fsMax: 0,
176				    fsFull: 0
177				},
178				heights = {
179				    prev: gv.innerHeight(dom.gv_navPrev),
180				    play: gv.innerHeight(dom.gv_navPlay),
181				    next: gv.innerHeight(dom.gv_navNext),
182				    filmstrip: this.opts.frame_height + (this.opts.show_captions ? gv.outerHeight(dom.gv_caption) : 0),
183				    fsMax: 0,
184				    fsFull: 0
185				},
186				panels = [];
187
188	        // nav
189	        if (this.filmstripOrientation === 'horizontal') {
190	            dom.gv_navWrap.css({
191	                width: widths.prev + widths.play + widths.next,
192	                height: Math.max(heights.prev, heights.play, heights.next)
193	            });
194	        } else {
195	            if (this.opts.filmstrip_style === 'scroll' && this.opts.frame_width < (widths.prev + widths.play + widths.next)) {
196	                dom.gv_navWrap.css({
197	                    width: Math.max(widths.prev, widths.play, widths.next),
198	                    height: heights.prev + heights.play + heights.next
199	                });
200	            } else {
201	                dom.gv_navWrap.css({
202	                    width: widths.prev + widths.play + widths.next,
203	                    height: Math.max(heights.prev, heights.play, heights.next)
204	                });
205	            }
206	        }
207
208	        if (this.filmstripOrientation === 'vertical' && widths.filmstrip < (widths.prev + widths.play + widths.next)) {
209	            dom.gv_navWrap.css({
210	                width: Math.max(widths.prev, widths.play, widths.next),
211	                height: heights.prev + heights.play + heights.next
212	            });
213	        } else {
214	            dom.gv_navWrap.css({
215	                width: widths.prev + widths.play + widths.next,
216	                height: Math.max(heights.prev, heights.play, heights.next)
217	            });
218	        }
219
220	        // panels
221	        dom.gv_panel.css({
222	            width: this.opts.panel_width,
223	            height: this.opts.panel_height
224	        });
225	        dom.gv_panelWrap.css({
226	            width: gv.outerWidth(dom.gv_panel),
227	            height: gv.outerHeight(dom.gv_panel)
228	        });
229	        dom.gv_overlay.css({
230	            width: this.opts.panel_width
231	        });
232
233
234
235	        $.each(this.gvImages, function (i, img) {
236	            dom.gv_panelWrap.append(dom.gv_panel.clone(true));
237	        });
238
239	        dom.gv_panels = dom.gv_panelWrap.find('.gv_panel');
240	        dom.gv_panels.remove();
241
242	        // filmstrip
243	        dom.gv_thumbnail.css({
244	            width: this.opts.frame_width,
245	            height: this.opts.frame_height
246	        });
247	        dom.gv_frame.css({
248	            width: gv.outerWidth(dom.gv_thumbnail),
249	            height: gv.outerHeight(dom.gv_thumbnail) + (this.opts.show_captions ? gv.outerHeight(dom.gv_caption) : 0),
250	            marginRight: this.opts.frame_gap,
251	            marginBottom: this.opts.frame_gap
252	        });
253
254
255	        if (this.filmstripOrientation === 'horizontal') {
256	            this.filmstripSize = Math.floor((gv.outerWidth(dom.gv_panelWrap) - gv.outerWidth(dom.gv_navWrap)) / (gv.outerWidth(dom.gv_frame) + this.opts.frame_gap));
257	            widths.fsMax = this.filmstripSize * (gv.outerWidth(dom.gv_frame) + this.opts.frame_gap);
258	            widths.fsFull = this.gvImages.length * (gv.outerWidth(dom.gv_frame) + this.opts.frame_gap);
259	            widths.filmstrip = Math.min(widths.fsMax, widths.fsFull);
260	            if (this.opts.filmstrip_style !== 'scroll') {
261	                heights.filmstrip = (Math.ceil(this.gvImages.length / this.filmstripSize) * (gv.outerHeight(dom.gv_frame) + this.opts.frame_gap)) - this.opts.frame_gap;
262	            }
263	        } else {
264	            this.filmstripSize = Math.floor((gv.outerHeight(dom.gv_panelWrap) - gv.outerHeight(dom.gv_navWrap)) / (gv.outerHeight(dom.gv_frame) + this.opts.frame_gap));
265	            heights.fsMax = this.filmstripSize * (gv.outerHeight(dom.gv_frame) + this.opts.frame_gap);
266	            heights.fsFull = this.gvImages.length * (gv.outerHeight(dom.gv_frame) + this.opts.frame_gap);
267	            heights.filmstrip = Math.min(heights.fsMax, heights.fsFull);
268	            if (this.opts.filmstrip_style !== 'scroll') {
269	                widths.filmstrip = (Math.ceil(this.gvImages.length / this.filmstripSize) * (gv.outerWidth(dom.gv_frame) + this.opts.frame_gap)) - this.opts.frame_gap;
270	            }
271	        }
272	        dom.gv_filmstripWrap.css({
273	            width: widths.filmstrip,
274	            height: heights.filmstrip
275	        });
276
277	        // gallery
278	        if (this.opts.show_filmstrip) {
279	            if (this.filmstripOrientation === 'horizontal') {
280	                dom.gv_gallery.css({
281	                    width: gv.outerWidth(dom.gv_panelWrap),
282	                    height: gv.outerHeight(dom.gv_panelWrap) + this.opts.frame_gap + (this.opts.show_filmstrip ? Math.max(gv.outerHeight(dom.gv_filmstripWrap), gv.outerHeight(dom.gv_navWrap)) : gv.outerHeight(dom.gv_filmstripWrap))
283	                });
284	            } else {
285	                dom.gv_gallery.css({
286	                    width: gv.outerWidth(dom.gv_panelWrap) + this.opts.frame_gap + (this.opts.show_filmstrip ? Math.max(gv.outerWidth(dom.gv_filmstripWrap), gv.outerWidth(dom.gv_navWrap)) : gv.outerWidth(dom.gv_filmstripWrap)),
287	                    height: gv.outerHeight(dom.gv_panelWrap)
288	                });
289	            }
290	        } else {
291	            dom.gv_gallery.css({
292	                width: gv.outerWidth(dom.gv_panelWrap),
293	                height: gv.outerHeight(dom.gv_panelWrap)
294	            });
295	        }
296
297	        dom.gv_galleryWrap.css({
298	            width: gv.outerWidth(dom.gv_gallery),
299	            height: gv.outerHeight(dom.gv_gallery),
300	            padding: this.opts.frame_gap
301	        });
302	    },
303
304	    setPositions: function () {
305	        var self = this,
306				dom = this.dom,
307				navVert = 0, fsVert = 0,
308				navHorz = 0, fsHorz = 0,
309				vert, horz;
310
311	        // determine vertical or horizontal offset
312	        // if negative, apply to filmstrip, otherwise apply to navbar
313	        if (this.filmstripOrientation === 'horizontal') {
314	            vert = Math.round((gv.outerHeight(dom.gv_filmstripWrap) - gv.outerHeight(dom.gv_navWrap)) / 2);
315	            if (vert < 0) { fsVert = -1 * vert; }
316	            else { navVert = vert; }
317	        } else {
318	            horz = Math.round((gv.outerWidth(dom.gv_filmstripWrap) - gv.outerWidth(dom.gv_navWrap)) / 2);
319	            if (horz < 0) { fsHorz = -1 * horz; }
320	            else { navHorz = horz; }
321	        }
322
323	        // for horizontal filmstrips w/o navigation, center the filmstrip under the panel
324	        if (!this.opts.show_filmstrip_nav && this.filmstripOrientation === 'horizontal') {
325	            fsHorz = Math.floor((gv.outerWidth(dom.gv_panelWrap) - gv.outerWidth(dom.gv_filmstripWrap)) / 2);
326	        }
327
328	        dom.gv_panelNavNext.css({ top: (gv.outerHeight(dom.gv_panel) - gv.outerHeight(dom.gv_panelNavNext)) / 2, right: 10 });
329	        dom.gv_panelNavPrev.css({ top: (gv.outerHeight(dom.gv_panel) - gv.outerHeight(dom.gv_panelNavPrev)) / 2, left: 10 });
330
331	        // pin elements to gallery corners according to filmstrip position
332	        switch (this.opts.filmstrip_position) {
333	            case 'top':
334	                dom.gv_navWrap.css({ top: navVert, right: navHorz });
335	                dom.gv_panelWrap.css({ bottom: 0, left: 0 });
336	                dom.gv_filmstripWrap.css({ top: fsVert, left: fsHorz });
337	                break;
338
339	            case 'right':
340	                dom.gv_navWrap.css({ bottom: navVert, right: navHorz });
341	                dom.gv_panelWrap.css({ top: 0, left: 0 });
342	                dom.gv_filmstripWrap.css({ top: fsVert, right: fsHorz });
343	                break;
344
345	            case 'left':
346	                dom.gv_navWrap.css({ bottom: navVert, left: navHorz });
347	                dom.gv_panelWrap.css({ top: 0, right: 0 });
348	                dom.gv_filmstripWrap.css({ top: fsVert, left: fsHorz });
349	                break;
350
351	            default:
352	                dom.gv_navWrap.css({ bottom: navVert, right: navHorz });
353	                dom.gv_panelWrap.css({ top: 0, left: 0 });
354	                dom.gv_filmstripWrap.css({ bottom: fsVert, left: fsHorz });
355	                break;
356	        }
357
358	        if (this.opts.overlay_position === 'top') {
359	            dom.gv_overlay.css({ top: 0, left: -99999 });
360	            dom.gv_showOverlay.css({ top: 0, left: 0 });
361	        } else {
362	            dom.gv_overlay.css({ bottom: 0, left: -99999 });
363	            dom.gv_showOverlay.css({ bottom: 0, left: 0 });
364	        }
365
366	        if (!this.opts.show_filmstrip_nav) {
367	            dom.gv_navWrap.remove();
368	        }
369	    },
370
371	    buildFilmstrip: function () {
372	        var self = this,
373				dom = this.dom,
374				framesLength = this.gvImages.length * ((this.filmstripOrientation === 'horizontal' ? this.opts.frame_width : this.opts.frame_height) + this.opts.frame_gap);
375
376	        dom.gv_frame.append(dom.gv_thumbnail);
377	        if (this.opts.show_captions) {
378	            dom.gv_frame.append(dom.gv_caption);
379	        }
380	        dom.gv_thumbnail.css('opacity', this.opts.frame_opacity);
381
382	        dom.gv_thumbnail.bind({
383	            mouseover: function () {
384	                if (!$(this).hasClass('current')) {
385	                    $(this).stop().animate({ opacity: 1 }, 250);
386	                }
387	            },
388	            mouseout: function () {
389	                if (!$(this).hasClass('current')) {
390	                    $(this).stop().animate({ opacity: self.opts.frame_opacity }, 250);
391	                }
392	            }
393	        });
394
395	        // Drop a clone of the frame element into the filmstrip for each source image
396	        $.each(this.gvImages, function (i, img) {
397	            dom.gv_frame.clone(true).prependTo(dom.gv_filmstrip);
398	        });
399
400	        dom.gv_filmstrip.css({
401	            width: gv.outerWidth(dom.gv_frame),
402	            height: gv.outerHeight(dom.gv_frame)
403	        });
404
405	        // If we are scrolling the filmstrip, and we can't show all frames at once,
406	        // make two additional copies of each frame
407	        if (this.opts.filmstrip_style === 'scroll') {
408	            if (this.filmstripOrientation === 'horizontal') {
409	                if (framesLength > gv.innerWidth(dom.gv_filmstripWrap)) {
410	                    dom.gv_filmstrip.find('.gv_frame').clone(true).appendTo(dom.gv_filmstrip).clone(true).appendTo(dom.gv_filmstrip);
411	                    dom.gv_filmstrip.css('width', framesLength * 3);
412	                    this.scrolling = true;
413	                } else {
414	                    dom.gv_filmstrip.css('width', framesLength);
415	                }
416	            } else {
417	                if (framesLength >
417 gv.innerHeight(dom.gv_filmstripWrap)) {
418	                    dom.gv_filmstrip.find('.gv_frame').clone(true).appendTo(dom.gv_filmstrip).clone(true).appendTo(dom.gv_filmstrip);
419	                    dom.gv_filmstrip.css('height', framesLength * 3);
420	                    this.scrolling = true;
421	                } else {
422	                    dom.gv_filmstrip.css('height', framesLength);
423	                }
424	            }
425	        } else {
426	            dom.gv_filmstrip.css({
427	                width: parseInt(dom.gv_filmstripWrap.css('width'), 10) + this.opts.frame_gap,
428	                height: parseInt(dom.gv_filmstripWrap.css('height'), 10) + this.opts.frame_gap
429	            });
430	        }
431	        dom.gv_frames = dom.gv_filmstrip.find('.gv_frame');
432	        $.each(dom.gv_frames, function (i, frame) {
433	            $(frame).data('frameIndex', i);
434	        });
435	        dom.gv_thumbnails = dom.gv_filmstrip.find('div.gv_thumbnail');
436	    },
437
438	    buildGallery: function () {
439	        var self = this,
440				dom = this.dom;
441
442	        this.setDimensions();
443	        this.setPositions();
444
445	        if (this.opts.show_filmstrip) {
446	            this.buildFilmstrip();
447	        }
448	    },
449
450	    showInfoBar: function () {
451	        if (!this.opts.show_infobar) { return; }
452	        var self = this,
453				dom = this.dom;
454
455	        dom.gv_infobar.stop().stopTime('hideInfoBar_' + self.id).html((this.iterator + 1) + ' of ' + this.numImages).show().css('opacity', this.opts.infobar_opacity);
456
457	        dom.gv_infobar.oneTime(2000 + this.opts.transition_speed, 'hideInfoBar_' + self.id, function () {
458	            dom.gv_infobar.fadeOut(1000);
459	        });
460	    },
461
462	    initImages: function () {
463	        var self = this,
464				dom = this.dom;
465	        $.each(this.gvImages, function (i, gvImage) {
466	            var img = $('<img/>');
467	            img.css('visibility', 'hidden').data('index', i);
468	            img.bind('load.galleryview', function () {
469	                var _img = $(this),
470						index = _img.data('index'),
471						width = this.width,
472						height = this.height,
473						parent = dom[(_img.data('parent')).type].eq((_img.data('parent')).index),
474						widthFactor = gv.innerWidth(parent) / width,
475						heightFactor = gv.innerHeight(parent) / height,
476						parentType = parent.hasClass('gv_panel') ? 'panel' : 'frame',
477						heightOffset = 0, widthOffset = 0;
478
479	                gvImage.scale[parentType] = self.opts[parentType + '_scale'] === 'fit' ? Math.min(widthFactor, heightFactor) : Math.max(widthFactor, heightFactor);
480
481	                widthOffset = Math.round((gv.innerWidth(parent) - (width * gvImage.scale[parentType])) / 2);
482	                heightOffset = Math.round((gv.innerHeight(parent) - (height * gvImage.scale[parentType])) / 2);
483
484	                _img.css({
485	                    width: width * gvImage.scale[parentType],
486	                    height: height * gvImage.scale[parentType],
487	                    top: heightOffset,
488	                    left: widthOffset
489	                });
490	                _img.hide().css('visibility', 'visible');
491	                _img.remove().appendTo(parent);
492
493	                if (parentType === 'frame') {
494	                    _img.fadeIn();
495	                    parent.parent().removeClass('gv_frame-loading');
496	                    parent.parent().find('.gv_caption').html(gvImage.attrs.title);
497	                } else if (index === self.opts.start_frame - 1) {
498	                    parent.prependTo(dom.gv_panelWrap);
499	                    parent.removeClass('gv_panel-loading');
500	                    _img.fadeIn();
501	                    self.showInfoBar();
502	                } else {
503	                    parent.removeClass('gv_panel-loading');
504	                    _img.show();
505	                }
506	            });
507
508	            // store eventual image container as data property
509	            // append to temporary storage element and set src
510	            if (self.opts.show_panels) {
511	                img.clone(true)
512						.data('parent', { type: 'gv_panels', index: i })
513						.appendTo(dom.gv_imageStore)
514						.attr('src', gvImage.src.panel);
515	            }
516
517	            if (self.opts.show_filmstrip) {
518	                img.clone(true)
519						.data('parent', { type: 'gv_thumbnails', index: i })
520						.appendTo(dom.gv_imageStore)
521						.attr('src', gvImage.src.frame);
522
523	                if (dom.gv_frames.length > dom.gv_panels.length) {
524	                    img.clone(true)
525							.data('parent', { type: 'gv_thumbnails', index: i + self.numImages })
526							.appendTo(dom.gv_imageStore)
527							.attr('src', gvImage.src.frame);
528
529	                    img.clone(true)
530							.data('parent', { type: 'gv_thumbnails', index: i + self.numImages + self.numImages })
531							.appendTo(dom.gv_imageStore)
532							.attr('src', gvImage.src.frame);
533	                }
534	            }
535	        });
536	    },
537
538	    showNext: function () {
539	        this.navAction = 'next';
540            if (this.playing && this.opts.play_random_order) {
541                var nextImage = this.frameIterator;
542                while (nextImage == this.frameIterator) {
543                    nextImage = Math.floor(Math.random()*(this.numImages + 1));
544                }
545                this.showItem(nextImage);
546            } else {
547	            this.showItem(this.frameIterator + 1);
548            }
549	    },
550
551	    showPrev: function () {
552	        this.navAction = 'prev';
553	        this.showItem(this.frameIterator - 1);
554	    },
555
556	    showItem: function (i) {
557	        if (isNaN(i)) { return; }
558	        if (!this.opts.show_filmstrip) { i = i % this.numImages; }
559
560	        var self = this,
561				dom = this.dom,
562				frame_i = i,
563				newPanelStart,
564				oldPanelEnd,
565				oldIterator,
566				panel,
567				playing = false;
568
569	        // don't go out of bounds
570	        if (i >= this.numImages) {
571	            i = i % this.numImages;
572	        } else if (i < 0) {
573	            i = this.numImages - 1;
574	            if (dom.gv_frames != undefined) {
575	                frame_i = dom.gv_frames.length - 1;
576	            } else {
577	                frame_i = dom.gv_panels.length - 1;
578	            }
579	        }
580
581	        panel = dom.gv_panels.eq(i);
582
583	        playing = this.playing;
584
585	        if (playing) {
586	            this.stopSlideshow(false);
587	        }
588
589	        this.unbindActions();
590
591	        dom.gv_gallery.oneTime(this.opts.transition_speed, 'bindActions_' + self.id, function () { if (playing) { self.startSlideshow(false); } self.bindActions(); });
592
593	        switch (this.opts.panel_animation) {
594	            case 'crossfade':
595	                dom.gv_panels.eq(this.iterator).fadeOut(this.opts.transition_speed, function () { $(this).remove(); });
596	                panel.hide().prependTo(dom.gv_panelWrap).fadeIn(this.opts.transition_speed);
597	                break;
598	            case 'fade':
599	                dom.gv_panels.eq(this.iterator).remove();
600	                panel.hide().prependTo(dom.gv_panelWrap).fadeIn(this.opts.transition_speed);
601	                break;
602	            case 'slide':
603	                if (this.navAction === 'next' || (this.navAction === 'frame' && frame_i > this.iterator)) {
604	                    newPanelStart = gv.outerWidth(dom.gv_panel);
605	                    oldPanelEnd = -1 * gv.outerWidth(dom.gv_panel);
606	                } else {
607	                    newPanelStart = -1 * gv.outerWidth(dom.gv_panel);
608	                    oldPanelEnd = gv.outerWidth(dom.gv_panel);
609	                }
610
611	                panel.css({ left: newPanelStart }).appendTo(dom.gv_panelWrap).animate(
612						{ left: 0 },
613						{ duration: this.opts.transition_speed, easing: this.opts.easing }
614					);
615
616	                dom.gv_panels.eq(this.iterator).animate(
617						{ left: oldPanelEnd },
618						{ duration: this.opts.transition_speed, easing: this.opts.easing, complete: function () { $(this).remove(); } }
619					);
620	                break;
621	            default:
622	                dom.gv_panels.eq(this.iterator).remove();
623	                panel.prependTo(dom.gv_panelWrap);
624	                break;
625	        }
626
627	        this.updateOverlay(i);
628            this.updateClickable(i);
629
630	        this.iterator = i;
631	        this.updateFilmstrip(frame_i);
632	        this.showInfoBar();
633
634
635	    },
636
637	    updateOverlay: function (i) {
638	        var self = this,
639				dom = this.dom;
640
641            var cursorStyle = '';
642
643            if (this.opts.clickable == 'overlay' || this.opts.clickable == 'all') {
644                cursorStyle = ' class="cursor_pointer"';
645            }
646
647            var overlayHtml = '<h4' + cursorStyle + '>' + 
648                self.gvImages[i].attrs.title + '</h4><p>' + 
649                self.gvImages[i].attrs.description + '</p>';
650
651	        if (this.overlayVisible) {
652	            this.hideOverlay(null, function () {
653	                dom.gv_overlay.html(overlayHtml);
654	                self.showOverlay();
655	            });
656	        } else {
657	            dom.gv_overlay.html(overlayHtml);
658	            dom.gv_overlay.css(this.opts.overlay_position, -1 * dom.gv_overlay.outerHeight());
659	        }
660
661            if (this.opts.clickable == 'overlay' || this.opts.clickable == 'all') {
662                dom.gv_panelWrap.undelegate('.gv_overlay h4', 'click.galleryview');
663	            dom.gv_panelWrap.delegate('.gv_overlay h4', 'click.galleryview', this.doClick(self.gvImages[i].href,self.gvImages[i].target));
664            }
665	    },
666
667	    hideOverlay: function (s, callback) {
668	        var self = this,
669				dom = this.dom,
670				endOverlay = {},
671				endButton = {},
672				speed = s || self.opts.transition_speed / 2;
673
674	        callback = callback || function () { };
675
676	        endOverlay[this.opts.overlay_position] = -1 * dom.gv_overlay.outerHeight();
677	        endButton[this.opts.overlay_position] = 0;
678
679	        dom.gv_overlay.animate(endOverlay, {
680	            duration: speed,
681	            easing: 'swing',
682	            complete: callback
683	        });
684	        dom.gv_showOverlay.animate(endButton, {
685	            duration: speed,
686	            easing: 'swing'
687	        });
688
689	        this.overlayVisible = false;
690	    },
691
692	    showOverlay: function (s) {
693	        var self = this,
694				dom = this.dom,
695				startOverlay = {},
696				endOverlay = {},
697				endButton = {},
698				speed = s || self.opts.transition_speed / 2;
699
700	        startOverlay[this.opts.overlay_position] = -1 * dom.gv_overlay.outerHeight();
701	        startOverlay.left = 0;
702
703	        endOverlay[this.opts.overlay_position] = 0;
704
705	        endButton[this.opts.overlay_position] = dom.gv_overlay.outerHeight();
706
707	        dom.gv_overlay.css(startOverlay);
708	        dom.gv_overlay.animate(endOverlay, { duration: speed, easing: 'swing' });
709	        dom.gv_showOverlay.animate(endButton, { duration: speed, easing: 'swing' });
710
711	        this.overlayVisible = true;
712	    },
713
714	    updateFilmstrip: function (to) {
715	        if (!this.opts.show_filmstrip) { this.frameIterator = to; return; }
716	        var self = this,
717				dom = this.dom,
718				targetThumbs = dom.gv_thumbnails.eq(this.iterator),
719				filmstripIterator,
720				distance;
721
722	        if (this.scrolling) {
723	            targetThumbs = targetThumbs.
724								add(dom.gv_thumbnails.eq(this.iterator + this.numImages)).
725								add(dom.gv_thumbnails.eq(this.iterator + (2 * this.numImages)));
726	        }
727
728	        dom.gv_thumbnails.removeClass('current').animate({ opacity: this.opts.frame_opacity });
729	        targetThumbs.stop().addClass('current').animate({ opacity: 1 }, 500);
730
731
732	        if (this.scrolling) {
733	            if (this.filmstripOrientation === 'horizontal') {
734	                distance = (gv.outerWidth(dom.gv_frame) + this.opts.frame_gap) * (this.frameIterator - to);
735
736	                if (distance > 0) {
737	                    distance = '+=' + Math.abs(distance);
738	                } else {
739	                    distance = '-=' + Math.abs(distance);
740	                }
741	                dom.gv_filmstrip.animate({
742	                    left: distance
743	                }, {
744	                    duration: this.opts.transition_speed,
745	                    easing: this.opts.easing,
746	                    complete: function () {
747	                        if (to < self.numImages) {
748	                            dom.gv_filmstrip.css('left', gv.getInt(dom.gv_filmstrip.css('left')) - (self.numImages * (gv.outerWidth(dom.gv_frame) + self.opts.frame_gap)));
749	                        } else if (to >= (self.numImages * 2)) {
750	                            dom.gv_filmstrip.css('left', gv.getInt(dom.gv_filmstrip.css('left')) + (self.numImages * (gv.outerWidth(dom.gv_frame) + self.opts.frame_gap)));
751	                        }
752	                        self.frameIterator = (to % self.numImages) + self.numImages;
753	                    }
754	                });
755	            } else {
756	                distance = (gv.outerHeight(dom.gv_frame) + this.opts.frame_gap) * (this.frameIterator - to);
757
758	                if (distance > 0) {
759	                    distance = '+=' + Math.abs(distance);
760	                } else {
761	                    distance = '-=' + Math.abs(distance);
762	                }
763	                dom.gv_filmstrip.animate({
764	                    top: distance
765	                }, {
766	                    duration: this.opts.transition_speed,
767	                    easing: this.opts.easing,
768	                    complete: function () {
769	                        // adjust filmstrip position to ensure that there is always at least one frame behind
770	                        // and (2 * filmstripSize) ahead
771	                        if (to === 0) {
772	                            dom.gv_filmstrip.css('top', gv.getInt(dom.gv_filmstrip.css('top')) - (self.numImages * (gv.outerHeight(dom.gv_frame) + self.opts.frame_gap)));
773	                            self.frameIterator = self.numImages;
774	                        } else if (to > ((self.numImages * 3) - (self.filmstripSize * 2))) {
775	                            dom.gv_filmstrip.css('top', gv.getInt(dom.gv_filmstrip.css('top')) + (self.numImages * (gv.outerHeight(dom.gv_frame) + self.opts.frame_gap)));
776	                            self.frameIterator = to - self.numImages;
777	                        } else {
778	                            self.frameIterator = to;
779	                        }
780	                    }
781	                });
782	            }
783
784	        } else {
785	            this.frameIterator = to;
786	        }
787	    },
788
789	    startSlideshow: function (changeIcon) {
790	        var self = this,
791				dom = this.dom;
792
793	        if (!self.opts.enable_slideshow) { return; }
794
795	        if (changeIcon) {
796	            dom.gv_navPlay.removeClass('gv_navPlay').addClass('gv_navPause');
797	        }
798	        this.playing = true;
799	        dom.gv_galleryWrap.everyTime(this.opts.transition_interval, 'slideshow_' + this.id, function () { self.showNext(); });
800	    },
801
802	    stopSlideshow: function (changeIcon) {
803	        var self = this,
804				dom = this.dom;
805
806	        if (changeIcon) {
807	            dom.gv_navPlay.removeClass('gv_navPause').addClass('gv_navPlay');
808	        }
809	        this.playing = false;
810	        dom.gv_galleryWrap.stopTime('slideshow_' + this.id);
811	    },
812
813	    enablePanning: function () {
814	        var self = this,
815				dom = this.dom;
816
817	        if (!self.opts.enable_slideshow) { return; }
818
819	        dom.gv_panel.css('cursor', 'url(http://www.google.com/intl/en_ALL/mapfiles/openhand.cur), n-resize');
820	        if (this.opts.pan_style === 'drag') {
821	            dom.gv_panelWrap.delegate('.gv_panel img', 'mousedown.galleryview', function (e) {
822	                self.isMouseDown = true;
823	                $(this).css('cursor', 'url(http://www.google.com/intl/en_ALL/mapfiles/closedhand.cur), n-resize');
824	            }).delegate('.gv_panel img', 'mouseup.galleryview', function (e) {
825	                self.isMouseDown = false;
826	                $(this).css('cursor', 'url(http://www.google.com/intl/en_ALL/mapfiles/openhand.cur), n-resize');
827	            }).delegate('.gv_panel img', 'mousemove.galleryview', function (e) {
828	                var distY, distX,
829						image = $(this),
830						new_top, new_left;
831
832	                if (self.isMouseDown) {
833	                    distY = e.pageY - self.mouse.y;
834	                    distX = e.pageX - self.mouse.x;
835	                    new_top = gv.getInt(image.css('top')) + distY;
836	                    new_left = gv.getInt(image.css('left')) + distX;
837
838	                    image.css('cursor', 'url(http://www.google.com/intl/en_ALL/mapfiles/closedhand.cur), n-resize');
839
840	                    if (new_top > 0) new_top = 0;
841	                    if (new_left > 0) new_left = 0;
842
843	                    if (new_top < (-1 * (gv.outerHeight(image) - gv.innerHeight(dom.gv_panel)))) { new_top = -1 * (gv.outerHeight(image) - gv.innerHeight(dom.gv_panel)); }
844	                    if (new_left < (-1 * (gv.outerWidth(image) - gv.innerWidth(dom.gv_panel)))) { new_left = -1 * (gv.outerWidth(image) - gv.innerWidth(dom.gv_panel)); }
845
846	                    image.css('top', new_top);
847	                    image.css('left', new_left);
848	                } else {
849	                    image.css('cursor', 'url(http://www.google.com/intl/en_ALL/mapfiles/openhand.cur), n-resize');
850	                }
851	            });
852	        } else {
853
854	        }
855	    },
856
857	    bindActions: function () {
858	        var self = this,
859				dom = this.dom;
860
861	        dom.gv_showOverlay.bind('click.galleryview', function () {
862	            if (self.overlayVisible) {
863	                self.hideOverlay(250);
864	            } else {
865	                self.showOverlay(250);
866	            }
867	        });
868
869	        dom.gv_navWrap.delegate('div', 'click.galleryview', function () {
870	            var el = $(this);
871	            if (el.hasClass('gv_navNext')) {
872	                self.showNext();
873	            } else if (el.hasClass('gv_navPrev')) {
874	                self.showPrev();
875	            } else if (el.hasClass('gv_navPlay')) {
876	                self.startSlideshow(true);
877	            } else if (el.hasClass('gv_navPause')) {
878	                self.stopSlideshow(true);
879	            }
880	            return false;
881	        });
882
883	        dom.gv_panelNavNext.bind('click.galleryview', function () {
884	            self.showNext();
885	            return false;
886	        });
887	        dom.gv_panelNavPrev.bind('click.galleryview', function () {
888	            self.showPrev();
889	            return false;
890	        });
891
892	        dom.gv_filmstripWrap.delegate('.gv_frame', 'click.galleryview', function () {
893	            var el = $(this),
894					i = el.data('frameIndex');
895
896	            this.navAction = 'frame';
897	            self.showItem(i);
898	            return false;
899	        });
900
901	        dom.gv_panelWrap.bind('mouseover.galleryview', function () {
902	            self.showPanelNav();
903	        }).bind('mouseout.galleryview', function () {
904	            self.hidePanelNav();
905	        });
906	    },
907
908	    unbindActions: function () {
909	        var self = this,
910				dom = this.dom;
911
912	        dom.gv_showOverlay.unbind('click.galleryview');
913	        dom.gv_panelNavNext.unbind('click.galleryview');
914	        dom.gv_panelNavPrev.unbind('click.galleryview');
915	        dom.gv_navWrap.undelegate('div', 'click.galleryview');
916	        dom.gv_filmstripWrap.undelegate('.gv_frame', 'click.galleryview');
917	    },
918
919	    showPanelNav: function () {
920	        var self = this,
921				dom = this.dom;
922
923	        dom.gv_panelNavNext.show();
924	        dom.gv_panelNavPrev.show();
925	    },
926
927	    hidePanelNav: function () {
928	        var self = this,
929				dom = this.dom;
930
931	        dom.gv_panelNavNext.hide();
932	        dom.gv_panelNavPrev.hide();
933	    },
934
935        // There's no need to repeat code, so let's just 
936        // abstract the click stuff a little
937        doClick: function (link,target) {
938	        var self = this,
939				dom = this.dom;
940
941            if (link != '') {
942	            var action;
943
944	            if (target) {
945	                action = function () {
946	                    window.open(link, "_blank");
947	                };
948	            }
949	            else {
950	                action = function () {
951	                    window.location = link;
952	                };
953	            }
954
955                return action;
956            }
957
958            // Just in case we have an empty href
959            return null;
960        },
961
962	    // Added to provide clickable link support for panels
963	    updateClickable: function (i) {
964	        var self = this,
965				dom = this.dom;
966
967            // If we don't undelegate here, we'll stack
968            // up click actions and cycling through the
969            // gallery can end up opening LOTS of links
970            dom.gv_panelWrap.undelegate('.gv_panel', 'click.galleryview');
971	        dom.gv_panelWrap.delegate('.gv_panel', 'click.galleryview', this.doClick(self.gvImages[i].href,self.gvImages[i].target));
972
973	        return false;
974	    },
975
976	    init: function (options, el) {
977	        var self = this,
978				dom = this.dom = {};
979
980	        this.opts = $.extend({}, $.fn.galleryView.defaults, options);
981	        this.el = el;
982	        this.$el = $(el);
983	        this.id = el.id;
984	        this.iterator = this.frameIterator = this.opts.start_frame - 1;
985	        this.overlayVisible = false;
986	        this.playing = false;
987	        this.scrolling = false;
988	        this.isMouseDown = false;
989	        this.mouse = { x: 0, y: 0 };
990	        this.filmstripOrientation = (this.opts.filmstrip_position === 'top' || this.opts.filmstrip_position === 'bottom') ? 'horizontal' : 'vertical';
991
992	        $(document).bind('mousemove.galleryview', function (e) {
993	            self.mouse = { x: e.pageX, y: e.pageY };
994	        });
995
996	        // create all necessary DOM elements
997	        $.each(this.elems, function (i, elem) {
998	            var elem = elem.split('.');
999
1000	            // if there is no tag name, assume <div>
1001	            if (elem[0] === '') { elem[0] = 'div'; }
1002
1003	            // add jQuery element to dom object
1004	            dom[elem[1]] = self.createElem({ 'class': elem[1] }, elem[0]);
1005	        });
1006
1007	        dom.gv_imageStore.appendTo($('body'));
1008
1009	        dom.gv_galleryWrap.delegate('img', 'mousedown.galleryview', function (e) { if (e.preventDefault) { e.preventDefault(); } });
1010
1011	        dom.gv_panel.addClass('gv_panel-loading');
1012	        dom.gv_frame.addClass('gv_frame-loading');
1013
1014	        // nest DOM elements
1015	        dom.gv_galleryWrap.hide().append(dom.gv_gallery);
1016
1017	        if (this.opts.show_panels) {
1018	            dom.gv_gallery.append(dom.gv_panelWrap);
1019	            if (this.opts.show_panel_nav) {
1020	                dom.gv_panelWrap.append(dom.gv_panelNavNext, dom.gv_panelNavPrev);
1021	            }
1022	            if (this.opts.show_infobar) {
1023	                dom.gv_panelWrap.append(dom.gv_infobar);
1024	            }
1025	        }
1026
1027	        if (this.opts.show_filmstrip) {
1028	            dom.gv_gallery.append(
1029					dom.gv_filmstripWrap.append(
1030						dom.gv_filmstrip
1031					)
1032				);
1033
1034	            if (this.opts.show_filmstrip_nav) {
1035	                dom.gv_gallery.append(
1036						dom.gv_navWrap.append(
1037							dom.gv_navPrev,
1038							(this.opts.enable_slideshow ? dom.gv_navPlay : $('<span></span>')),
1039							dom.gv_navNext
1040						)
1041					);
1042	            }
1043	        }
1044
1045	        if (this.opts.enable_overlays) {
1046	            dom.gv_panelWrap.append(dom.gv_overlay, dom.gv_showOverlay);
1047	        }
1048
1049	        if (this.opts.show_captions) {
1050	            dom.gv_frame.append(dom.gv_caption).appendTo(dom.gv_gallery);
1051	        }
1052
1053	        //swap out source element with gallery
1054	        this.$el.replaceWith(dom.gv_galleryWrap);
1055
1056	        if (this.opts.pan_images) {
1057	            this.enablePanning();
1058	        }
1059
1060	        // convert source images into gvImage objects
1061	        this.storeImages();
1062
1063	        // block out dimensions/positions of gallery elements
1064	        this.buildGallery();
1065
1066	        // begin loading images into gallery
1067	        this.initImages();
1068
1069	        // set up transitions, buttons
1070	        this.bindActions();
1071
1072	        // remove temporary frame element
1073	        dom.gv_frame.remove();
1074
1075	        // show gallery
1076	        dom.gv_galleryWrap.show();
1077
1078	        if (this.opts.autoplay) {
1079	            this.startSlideshow(true);
1080	        }
1081
1082	        // if panels should be clickable - set it up
1083	        if (this.opts.clickable == 'panel' || this.opts.clickable == 'all') {
1084	            this.updateClickable(this.iterator);
1085	        }
1086
1087	        this.updateOverlay(this.iterator);
1088	        this.updateFilmstrip(this.frameIterator);
1089	    }
1090
1091	}; // END GalleryView
1092
1093    /*
1094    MAIN PLUGIN CODE
1095    */
1096    $.fn.galleryView = function (options) {
1097        if (this.length) {
1098            return this.each(function () {
1099                var gallery = Object.create(GalleryView);
1100                gallery.init(options, this);
1101            });
1102        }
1103    };
1104
1105    /*
1106    Default Options
1107    Object literal storing default plugin options
1108    */
1109    $.fn.galleryView.defaults = {
1110
1111        // General Options
1112        transition_speed: 1000, 		//INT - duration of panel/frame transition (in milliseconds)
1113        transition_interval: 5000, 		//INT - delay between panel/frame transitions (in milliseconds)
1114        easing: 'swing', 				//STRING - easing method to use for animations (jQuery provides 'swing' or 'linear', more available with jQuery UI or Easing plugin)
1115
1116        // Panel Options
1117        show_panels: true, 				//BOOLEAN - flag to show or hide panel portion of gallery
1118        show_panel_nav: true, 			//BOOLEAN - flag to show or hide panel navigation buttons
1119        enable_overlays: false, 			//BOOLEAN - flag to show or hide panel overlays
1120        panel_width: 800, 				//INT - width of gallery panel (in pixels)
1121        panel_height: 400, 				//INT - height of gallery panel (in pixels)
1122        panel_animation: 'fade', 		//STRING - animation method for panel transitions (crossfade,fade,slide,none)
1123        panel_scale: 'crop', 			//STRING - cropping option for panel images (crop = scale image and fit to aspect ratio determined by panel_width and panel_height, fit = scale image and preserve original aspect ratio)
1124        overlay_position: 'bottom', 	//STRING - position of panel overlay (bottom, top)
1125        pan_images: false, 			//BOOLEAN - flag to allow user to grab/drag oversized images within gallery
1126        pan_style: 'drag', 			//STRING - panning method (drag = user clicks and drags image to pan, track = image automatically pans based on mouse position
1127        pan_smoothness: 15, 			//INT - determines smoothness of tracking pan animation (higher number = smoother)
1128        link_newwindow: true,           //BOOLEAN - flag to open clickable images in a new window
1129        clickable: 'none',              //BOOLEAN - flag to determine if the clickable items (panel, overlay, all, none)
1130
1131        // Filmstrip Options
1132        start_frame: 1, 				//INT - index of panel/frame to show first when gallery loads
1133        show_filmstrip: true, 			//BOOLEAN - flag to show or hide filmstrip portion of gallery
1134        show_filmstrip_nav: true, 		//BOOLEAN - flag indicating whether to display navigation buttons
1135        enable_slideshow: true, 		//BOOLEAN - flag indicating whether to display slideshow play/pause button
1136        autoplay: false, 			    //BOOLEAN - flag to start slideshow on gallery load
1137        play_random_order: false,       //BOOLEAN - while playing the images are "playing" use a random order
1138        show_captions: false, 			//BOOLEAN - flag to show or hide frame captions	
1139        filmstrip_size: 3, 				//INT - number of frames to show in filmstrip-only gallery
1140        filmstrip_style: 'scroll', 		//STRING - type of filmstrip to use (scroll = display one line of frames, scroll filmstrip if necessary, showall = display multiple rows of frames if necessary)
1141        filmstrip_position: 'bottom', 	//STRING - position of filmstrip within gallery (bottom, top, left, right)
1142        frame_width: 80, 				//INT - width of filmstrip frames (in pixels)
1143        frame_height: 40, 				//INT - width of filmstrip frames (in pixels)
1144        frame_opacity: 0.4, 			//FLOAT - transparency of non-active frames (1.0 = opaque, 0.0 = transparent)
1145        frame_scale: 'crop', 			//STRING - cropping option for filmstrip images (same as above)
1146        frame_gap: 5, 					//INT - spacing between frames within filmstrip (in pixels)
1147
1148        // Info Bar Options
1149        show_infobar: true, 			//BOOLEAN - flag to show or hide infobar
1150        infobar_opacity: 1				//FLOAT - transparency for info bar
1151    };
1152})(jQuery);

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.