PageSourceSearch

https://gloriousmarine.com/scripts/yoxview/jquery.yoxview-2.21.js

js gloriousmarine.com collected 2026-10-06 11:21:28 UTC 89,275 bytes, 2,311 lines download raw bytes

1/*!
2 * jquery.yoxview
3 * jQuery image gallery viewer
4 * http://yoxigen.com/yoxview
5 *
6 * Copyright (c) 2010 Yossi Kolesnicov
7 *
8 * Licensed under the MIT license.
9 * http://www.opensource.org/licenses/mit-license.php
10 *
11 * Date: 13th November, 2010
12 * Version : 2.2
13 */ 
14
15
16(function($){
17    if (!$.yoxview)
18        $.yoxview = new YoxView();
19        
20    $.fn.yoxview = function(options) 
21    {
22        if (this.length != 0)
23        {
24            if ($.yoxview[options])
25                return $.yoxview[options].apply(this, Array.prototype.slice.call(arguments, 1));
26            else if (typeof options === 'object' || !options)
27                $.yoxview.init(this, options);
28            else
29              $.error( 'Method ' +  options + ' does not exist on YoxView.' );
30        }
31        return this;
32    };
33    
34    $(Yox.getTopWindow()).unload(function(){
35        if ($.yoxview)
36        {
37            $.yoxview.unload();
38            delete $.yoxview;
39        }
40    });
41    
42    function YoxView()
43    {
44        var yoxviewPath = (yoxviewPath || Yox.getPath(/(.*\/)jquery\.yoxview/i));
45        var defaults = {
46            autoHideInfo: true, // If false, the info bar (with image count and title) is always displayed.
47            autoPlay: false, // If true, slideshow mode starts when the popup opens
48            backgroundColor: "#000000",
49            backgroundOpacity: 0.8,
50            buttonsFadeTime: 300, // The time, in milliseconds, it takes the buttons to fade in/out when hovered on. Set to 0 to force the Prev/Next buttons to remain visible.
51            cacheBuffer: 5, // The number of images to cache after the current image (directional, depends on the current viewing direction)
52            cacheImagesInBackground: true, // If true, full-size images are cached even while the gallery hasn't been opened yet.
53            controlsInitialFadeTime: 1500, // The time, in milliseconds, it takes the menu and prev/next buttons to fade in and out when the popup is opened.
54            controlsInitialDisplayTime: 1000, // The time, in milliseconds, to display the menu and prev/next buttons when the popup is opened. Set to 0 to not display them by default
55            dataFolder: yoxviewPath + "data/",
56            defaultDimensions: { // Default sizes for different types of media, in case none was specified
57                flash: { width: 720, height: 560 },
58                iframe: { width: 1024 }
59            },
60            flashVideoPlayer: "jwplayer", // The default player for Flash video files
61            imagesFolder: yoxviewPath + "images/",
62            infoBackColor: "#000000",
63            infoBackOpacity: 0.5,
64            isRTL : false, // Switch direction. For RTL languages such as Hebrew or Arabic, for example.
65            lang: "en", // The language for texts. The relevant language file should exist in the lang folder.
66            langFolder: yoxviewPath + "lang/",
67            loopPlay: true, // If true, slideshow play starts over after the last image
68            playDelay: 3000, // Time in milliseconds to display each image
69            popupMargin: 20, // the minimum margin between the popup and the window
70            popupResizeTime: 600, // The time in milliseconds it takes to make the resize transition from one image to the next.
71            renderButtons: true, // Set to false if you want to implement your own Next/Prev buttons, using the API.
72            renderMenu: true, // Set to false if you want to implement you own menu (Play/Help/Close).
73            showBarsOnOpen: true, // If true, displays the top (help) bar and bottom (info) bar momentarily when the popup opens.
74            showButtonsOnOpen: true, // If true, displays the Prev/Next buttons momentarily when the popup opens.
75            showDescription: true, // Set to false to not show the description text (the title will still show).
76            textLinksSelector: ".yoxviewLink", // A jQuery selector to identify links that are not thumbnails, which YoxView should try to open.
77            thumbnailsOptions: { thumbnailsClass: "yoxview_thumbnail" }, // Options for thumbnails generated by YoxView
78            titleAttribute: "title", // The attribute of an img used for the text in YoxView. Use either "title" or "alt".
79            titleDisplayDuration: 2000, // The time in ms to display the image's title, after which it fades out.
80            renderInfoPrevNext: false
81        };
82        
83        this.infoButtons = {};
84        this.isOpen = false;
85        this.yoxviewSkins = {};
86        
87        var ajaxLoader,
88            cacheVars = {},
89            cacheImg = new Image(),
90            countDisplay,
91            ctlButtons, // next and prev buttons
92            elementCount = 0,
93            currentItemIndex = 0,
94            currentLanguage = {},
95            currentMaxSize = {},
96            currentOptionsSetIndex,
97            currentViewIndex = 0,
98            currentViewIsInFrame = window != window.parent,
99            disableInfo = false,
100            flashDefaults = { wmode: "transparent", width: "100%", height: "100%", allowfullscreen: "true", allowscriptaccess: "true", hasVersion: 9 },
101            firstImage = true,
102            frameOffset,
103            helpPanel,
104            hideInfoTimeout,
105            hideMenuTimeout,
106            image1, image2,
107            images,
108            imagesCount = 0,
109            infoPanel,
110            infoPanelContent,
111            infoPanelLink,
112            infoPanelMinHeight = 30,
113            infoPanelWrap,
114            infoPinLink,
115            infoPinLinkImg,
116            infoText,
117            isFirstPanel = false,
118            isImageMode = true,
119            isPlaying = false,
120            isResizing = false,
121            itemVar,
122            loadedViews = [],
123            loaderTimeout,
124            loading = false,
125            mediaButtonsSize = {width: 100, height: 100},
126            mediaLoader,
127            mediaPanelClass = "yoxview_mediaPanel",
128            mediaProviderUrls = {
129                vimeo: "http://vimeo.com/api/oembed.json",
130                myspace: "http://vids.myspace.com/index.cfm?fuseaction=oembed"
131            },
132            menuHidePosition = -42,
133            menuPanel,
134            nextBtn,
135            notification,
136            onOpenCallback,
137            options, optionsSets = [],
138            panel1, panel2,
139	        playBtnText,
140            popup,
141            popupBackground,
142            popupMargins = {}, defaultPopupMargins = {},
143            popupTimeout,
144            popupWindow = $(Yox.getTopWindow()), // the window in which to create the YoxView popup (for use with frames)
145            popupWrap,
146            prevBtn,
147            resumePlay = false,
148            sprites,
149            tempImg = new Image(),
150            thumbnail,
151            thumbnailImg,
152            thumbnailPos,
153            thumbnailProperties,
154            windowDimensions,
155            yoxviewLanguages = {},
156            keyCodes = {
157	            40: 'DOWN',
158	            35: 'END',
159	            13: 'ENTER',
160	            36: 'HOME',
161	            37: 'LEFT',
162	            39: 'RIGHT',
163	            32: 'SPACE',
164	            38: 'UP',
165	            72: 'h',
166	            27: 'ESCAPE'
167            },
168            keyMappings;
169
170        // If the given options object is equal to any in the options set, return the existing set's index. Otherwise, add the new set and return its index:
171        function initOptionsSet(options){
172            var optionsSetsLength = optionsSets.length;
173            for(var i=0; i<optionsSetsLength; i++)
174            {
175                if (Yox.compare(optionsSets[i], options))
176                    return i;
177            }
178
179            optionsSets.push(options);
180            return optionsSetsLength;
181        }
182        
183        function getAllowedThumbnailsSelector(options){
184            return "a:has(img)" + (options.textLinksSelector !== null ? ",a" + options.textLinksSelector : "");
185        }
186        
187        this.init = function(views, opt)
188        {
189            var options = $.extend(true, {}, defaults, opt);
190            var optionsSetIndex;
191            if (optionsSets.length == 0)
192            {
193                optionsSets.push(options);
194                optionsSetIndex = 0;
195            }
196            else
197                optionsSetIndex = opt ? initOptionsSet(options) : null;
198            
199            function loadContents(){
200                views.each(function(i, view){
201                    view = $(view);
202                    var viewIndex = loadedViews.length;
203                    
204                    view.data("yoxview", {
205                        viewIndex : viewIndex, 
206                        cacheVars: {cachedImagesCount: 0, cacheDirectionForward: true, cacheBufferLastIndex: null, currentCacheImg: 0 }
207                    });
208                    
209                    var viewData = view.data("yoxview");
210                    if (optionsSetIndex)
211                        viewData.optionsSet = optionsSetIndex;
212                    
213                    options.allowedImageUrls = [Yox.Regex.image];
214                    if (options.allowedUrls)
215                        options.allowedImageUrls = options.allowedImageUrls.concat(options.allowedUrls);
216                                
217                    // First, get image data from thumbnails:
218		            var isSingleLink = view[0].tagName == "A";
219                    var thumbnails = isSingleLink ? view : view.find(getAllowedThumbnailsSelector(options));
220                    
221                    var viewImages = [];
222
223                    var imageIndex = 0;
224                    thumbnails.each(function(i, thumbnail){
225                        var $thumbnail = $(thumbnail);
226                        var imageData = getImageDataFromThumbnail($thumbnail, options);
227                        if (imageData)
228                        {
229                            viewImages.push(imageData);
230                            if (isSingleLink)
231                                $thumbnail.data("yoxview").imageIndex = imageIndex;
232                            else
233                                $thumbnail.data("yoxview", { imageIndex: imageIndex, viewIndex: viewIndex });
234                            imageIndex++;
235                        }
236                    });
237
238                    if (options.images)
239                        viewImages = viewImages.concat(options.images);
240
241                    if (options.dataSource)
242                    {                       
243                        Yox.dataSources[options.dataSource].getImagesData(options, function(data){
244                            viewImages = viewImages.concat(data.images);
245                            viewData.images = viewImages;
246
247                            if (data.title && options.thumbnailsOptions && options.thumbnailsOptions.setHeader){
248                                $(options.thumbnailsOptions.headerElement || "<h2>", {
249                                    html: data.title,
250                                    "class": options.thumbnailsOptions.headerClass
251                                }).appendTo(view);
252                            }
253                            var thumbnailsData = data.isGroup 
254                                ? [$.extend(data, {
255                                    media: {
256                                        title: data.title + " (" + data.images.length + " images)",
257                                        alt: data.title
258                                    }
259                                })]
260                                : data.images;
261
262                            createThumbnails(view, options, isSingleLink ? null : thumbnailsData, !data.createGroups ? null :
263                                function(e){
264                                    var viewData = $(e.currentTarget).data("yoxview");
265                                    var thumbnail = $(e.currentTarget);
266                                    var thumbnailData = thumbnail.data("yoxthumbs");
267                                    if (!viewData.imagesAreSet)
268                                    {
269                                        thumbnail.css("cursor", "wait");
270                                        var newOptions = $.extend({}, options);
271                                            
272                                        if (!newOptions.dataSourceOptions)
273                                            newOptions.dataSourceOptions = thumbnailData;
274                                        else
275                                            $.extend(newOptions.dataSourceOptions, thumbnailData);
276
277                                        Yox.dataSources[options.dataSource].getImagesData(newOptions, function(data){
278                                            viewData.images = data.images;
279                                            viewData.imagesAreSet = true;
280                                            thumbnail.css("cursor", "");
281                                            $.yoxview.open(viewData.viewIndex);
282                                        });
283                                    }
284                                    else
285                                    {
286                                        $.yoxview.open(viewData.viewIndex);
287                                    }
288                                }
289                            );
290				            if (data.createGroups)
291				                $.each(view.yoxthumbs("thumbnails"), function(i, thumbnail){
292					                thumbnail.data("yoxview", {viewIndex: ++viewIndex});
293					                loadedViews.push($(thumbnail));
294				                });
295                            else
296                            {
297                                $.each(view.yoxthumbs("thumbnails"), function(i, thumbnail){
298                                    var currentViewIndex = imageIndex + i;
299                                    var thumbImg = thumbnail.children("img");
300                                    if (thumbImg.length == 0)
301                                        thumbImg = thumbnail;
302                                        
303                		            viewImages[currentViewIndex].thumbnailImg = thumbImg;
304					                thumbnail.data("yoxview", {imageIndex: i, viewIndex: viewIndex });
305					            });
306				            }
307                            if (!$.yoxview.firstViewWithImages && data.images.length > 0)
308                            {
309                                $.yoxview.firstViewWithImages = view;
310                                
311                                if (options.cacheImagesInBackgroun
311d)
312                                    $.yoxview.startCache();
313                            }
314                        });
315                    }
316                    else
317		            {
318			            viewData.images = viewImages;
319                        createThumbnails(view, options);
320		            }
321                    
322                    loadedViews.push(view);
323                    if (!$.yoxview.firstViewWithImages && viewData.images && viewData.images != 0)
324                    {
325                        $.yoxview.firstViewWithImages = view;
326                        loadViewImages(view);
327
328                        if(options.cacheImagesInBackground && imagesCount != 0)
329                        {
330                            calculateCacheBuffer();
331                            cacheImages(0);
332                        }
333                    }
334                });
335            }
336
337            // Init external files then proceed:
338            loadLanguage(options.lang, function(langData){
339                loadSkin(options, function(skin){
340                    if (skin && skin.options)
341                        $.extend(options, skin.options);
342
343                    Yox.loadDataSource(options, loadContents);
344                });
345            });
346        }
347
348        function loadSkin(options, callback)
349        {
350            if (options.skin)
351            {
352                var skinName = options.skin;
353                if (!$.yoxview.yoxviewSkins[skinName])
354                {
355                    var skinUrl = yoxviewPath + "skins/" + skinName + "/yoxview." + skinName;
356                    $.ajax({
357                        url: skinUrl + ".js",
358                        dataType: "script",
359                        success: function(data)
360                        {
361                            if ($.yoxview.yoxviewSkins[skinName].css !== false)
362                                Yox.addStylesheet(top.document, skinUrl + ".css");
363   
364                            if (callback)
365                                callback($.yoxview.yoxviewSkins[skinName]);
366                        },
367                        error: function(){
368                            alert("Error loading skin file " + skinUrl + ".js");
369                        }
370                    });
371                }
372                else if (callback)
373                    callback($.yoxview.yoxviewSkins[skinName]);
374            }
375            else if (callback)
376                callback($.yoxview.yoxviewSkins[skinName]);
377        }
378        
379         // Load the language file if not already loaded:
380        function loadLanguage(langName, callback)
381        {
382            if (!yoxviewLanguages[langName])
383            {
384                yoxviewLanguages[langName] = {};
385                var langUrl = yoxviewPath + "lang/" + langName + ".js";
386                /*$.ajax({
387                    url : langUrl,
388                    async : false,
389                    dataType : "json",
390                    success: function(data){
391                        yoxviewLanguages[langName] = data;
392                        if (callback)
393                            callback(data);
394                    },
395                    error: function(){
396                        alert("Error loading language file " + langUrl); 
397                    }
398                });*/
399
400                        data = {
401                            "Direction" : "ltr",
402                            "Close" : "Close",
403                            "Help" : "Help",
404                            "FirstImage" : "To the first image",
405                            "LastImage" : "To the last image",
406                            "StartStopSlideShow" : "Play/Pause slideshow",
407                            "Pause" : "Pause",
408                            "Play" : "Play",
409                            "Prev" : "Prev",
410                            "PinInfo" : "Pin info",
411                            "UnpinInfo" : "Unpin info",
412                            "Next" : "Next",
413                            "PrevImage" : "Previous image",
414                            "NextImage" : "Next image",
415                            "Loading" : "Loading",
416                            "CloseHelp" : "Close help",  
417                            "HelpText" : "The gallery can be navigated using the keyboard:<br/><br/>LEFT/RIGHT ARROWS: Prev/Next<br/>SPACEBAR: Next<br/>ENTER: Start/Stop slideshow<br/>ESCAPE: Close gallery<br/>HOME/END: First/Last image<br/>H - This help panel",
418                            "Slideshow" : "Play",
419                            "OriginalContext": "View in original context"
420                        };
421                         yoxviewLanguages[langName] = data;
422                                if (callback)
423                                    callback(data);
424
425
426
427            }
428            else if (callback)
429                callback(yoxviewLanguages[langName]);
430        }
431                
432        function resetPopup()
433        {
434            if (popup)
435            {
436                popupWrap.remove();
437                popup = undefined;
438                prevBtn = undefined;
439                nextBtn = undefined;
440                image1 = undefined;
441                image2 = undefined;
442			    panel1 = undefined;
443			    panel2 = undefined;
444                currentItemIndex = 0;
445			    $.yoxview.infoButtons = {};
446            }
447            createPopup();
448        }
449        function loadViewImages(view)
450        {
451            var viewData = view.data("yoxview");
452
453            if (!images || currentViewIndex != viewData.viewIndex)
454            {
455                if (!viewData.cacheVars)
456                    viewData.cacheVars = {cachedImagesCount: 0, cacheDirectionForward: true, cacheBufferLastIndex: null, currentCacheImg: 0 };
457
458                images = viewData.images;
459                imagesCount = images.length;
460                currentViewIndex = viewData.viewIndex;
461 
462                var isResetPopup = false;
463                var changeOptions = !currentOptionsSetIndex || (currentOptionsSetIndex != viewData.optionsSet);
464
465                if (changeOptions)
466                {
467                    currentOptionsSetIndex = viewData.optionsSet || 0;
468                    options = optionsSets[currentOptionsSetIndex];
469                    isResetPopup = true;
470                }
471
472                if (options.onLoadImages)
473                    options.onLoadImages({ images: images, viewData: viewData });
474                 
475                else if ((prevBtn && imagesCount == 1) || (popup && !prevBtn && imagesCount > 0))
476                    isResetPopup = true;
477
478                if (isResetPopup)
479                    resetPopup();
480
481                cacheVars = viewData.cacheVars;
482            }
483        }
484        
485        function getElementDimensions(type, originalDimensions, options)
486        {
487            var size = originalDimensions && (originalDimensions.width || originalDimensions.height)
488                ? { width: parseInt(originalDimensions.width), height: parseInt(originalDimensions.height) }
489                : options.defaultDimensions[type];
490
491            if (isNaN(size.width))
492                size.width = null;
493            if (isNaN(size.height))
494                size.height = null;
495
496            return size;
497        }
498        var supportedTypes = {
499            image: function(thumbnail, thumbnailHref, thumbImg, options)
500            {
501                var imageData = null;
502                for(var i=0; i<options.allowedImageUrls.length && !imageData; i++)
503                {
504                    if (thumbnailHref.match(options.allowedImageUrls[i]))
505                    {
506                        imageData = {
507                            src: thumbnail.attr("href"),
508                            title: thumbImg.attr(options.titleAttribute),
509                            alt: thumbImg.attr("alt")
510                        };
511                    }
512                }
513                return imageData;
514            },
515            flash: function(thumbnail, thumbnailHref, thumbImg, options)
516            {
517                var imageData = null;
518                var matchFlash = thumbnailHref.match(Yox.Regex.flash);
519                var matchFlashVideo = matchFlash ? null : thumbnailHref.match(Yox.Regex.flashvideo);
520                
521                if (matchFlash || matchFlashVideo)
522                {
523                    var urlData = Yox.getUrlData(thumbnailHref);
524				    var elementSize = getElementDimensions("flash", urlData.queryFields, options);
525    				
526				    if (urlData.queryFields)
527				    {
528					    delete urlData.queryFields.width;
529					    delete urlData.queryFields.height;
530				    }
531    				
532                    var flashPanel = $("<div>", {
533                        "class": "yoxview_element",
534                        html: "<div class='yoxview_error'>Please install the latest version of the <a href='http://www.adobe.com/go/getflashplayer' target='_blank'>Flash player</a> to view content</div>"
535                    });
536                    var flashData = matchFlashVideo 
537                        ? Yox.flashVideoPlayers[options.flashVideoPlayer](
538                            options.flashVideoPlayerPath, urlData.path,
539                            (urlData.queryFields && urlData.queryFields.image) ? urlData.queryFields.image : 
540                                thumbImg[0].nodeName == "IMG" ? thumbImg.attr("src") : null, 
541                            thumbImg.attr(options.titleAttribute))
542                        : urlData.queryFields || {};
543                    
544                    if (matchFlash)
545                        flashData.swf = urlData.path;
546                        
547                    $.extend(flashData, flashDefaults);
548                    
549                    flashPanel.flash(flashData);
550                    imageData = {
551                        "element": flashPanel,
552                        title: thumbImg.attr(options.titleAttribute)
553                    };
554                    $.extend(imageData, elementSize);
555                }
556                
557                return imageData;
558            },
559            ooembed: function(thumbnail, thumbnailHref, thumbImg, options)
560            {
561                var imageData = null;
562                for(videoProvider in Yox.Regex.video)
563                {
564                    if (thumbnailHref.match(Yox.Regex.video[videoProvider]))
565                    {
566                        imageData = {
567                            provider: videoProvider,
568                            url: thumbnailHref
569                        };
570                        break;
571                    }
572                }
573                return imageData;
574            },
575            inline: function(thumbnail, thumbnailHref, thumbImg, options)
576            {
577                if (!options.allowInternalLinks)
578                    return null;
579                    
580                var imageData = null;
581                var urlData = Yox.getUrlData(thumbnailHref);
582                if (urlData && urlData.anchor)
583                {
584                    var element = $("#" + urlData.anchor);
585                    if (element.length != 0)
586                    {
587                        var elementSize = { width: parseInt(element.css("width")), height: parseInt(element.css("height")) };
588
589                        element.css({
590		                    position: "absolute",
591		                    top: 0,
592		                    left: 0,
593		                    width: "100%",
594		                    height: "100%",
595		                    display: "block"
596		                });
597    		            
598                        imageData = {
599                            type: "inlineElement",
600                            "element": element,
601                            title: element.attr("title")
602                        };
603                        var padding = { 
604                            horizontal: parseInt(element.css("padding-right")) + parseInt(element.css("padding-left")),
605                            vertical: parseInt(element.css("padding-top")) + parseInt(element.css("padding-bottom"))
606                        };
607                        
608                        elementSize.width = isNaN(elementSize.width) ? null : elementSize.width + padding.horizontal;
609                        elementSize.height = isNaN(elementSize.height) ? null : elementSize.height + padding.vertical;
610                        
611                        $.extend(imageData, elementSize);
612                        if (padding.horizontal != 0 || padding.vertical != 0)
613                            imageData.padding = padding;
614                            
615                        element.remove();
616                    }
617                }
618                
619                return imageData;
620            },
621            iframe: function(thumbnail, thumbnailHref, thumbImg, options)
622            {
623                var imageData = null;
624                var thumbnailTarget = thumbnail.attr("target");
625                if (thumbnailTarget && thumbnailTarget == "yoxview")
626                {
627                    var urlData = Yox.getUrlData(thumbnailHref);
628                    if (urlData && urlData.path)
629                    {
630                        var iframeSize = getElementDimensions("iframe", urlData.queryFields, options);
631					    if (urlData.queryFields)
632					    {
633						    delete urlData.queryFields.width;
634						    delete urlData.queryFields.height;
635                        }
636                        imageData = {
637                            "element": $("<iframe>", {
638                                src: Yox.urlDataToPath(urlData),
639                                "class": "yoxview_element"
640                            }),
641                            title: thumbImg.attr("title"),
642                            frameborder: "0"
643                        }
644                        $.extend(imageData, iframeSize);
645                    }
646                }
647                
648                return imageData;
649            }
650        };
651        function getImageDataFromThumbnail(thumbnail, options)
652        {
653            var imageData = {};
654            var thumbnailHref = thumbnail.attr("href");
655            var thumbImg = thumbnail.children("img:first");
656
657            if (thumbImg.length == 0)
658                thumbImg = thumbnail;
659
660            var imageData = {};
661            for (supportedType in supportedTypes)
662            {
663                var media = supportedTypes[supportedType](thumbn
663ail, thumbnailHref, thumbImg, options);
664                if (media)
665                {
666                    $.extend(media, {
667                        contentType: supportedType,
668                        elementId: elementCount++
669                    });
670
671                    imageData.media = media;
672                    break;
673                }
674            }
675            
676            if (!imageData.media)
677                return null;
678
679            imageData.thumbnailImg = thumbImg;
680            return imageData;
681        }
682
683        function createThumbnails(view, options, additionalImages, onClick)
684        {
685            var clickHandler = function(e){
686                var data = $(e.currentTarget).data("yoxview");
687                if (!data || data.imageIndex === null)
688                    return true;
689                else
690                {
691                    e.preventDefault();
692                    $.yoxview.open($(e.liveFired || e.currentTarget).data("yoxview").viewIndex, data.imageIndex);
693                }
694            };
695            
696            if (view[0].tagName == "A")
697                view.bind("click.yoxview", clickHandler);
698            else if (!additionalImages)
699                view.delegate(getAllowedThumbnailsSelector(options), "click.yoxview", clickHandler);
700            else
701                view.yoxthumbs($.extend({ 
702                    images: additionalImages,
703                    enableOnlyMedia: false,
704                    onClick: onClick || function(e){
705                        e.preventDefault();
706				        if (options.thumbnailsOptions && options.thumbnailsOptions.onClick)
707                            options.thumbnailsOptions.onClick(
708                                $(e.currentTarget).data("yoxview").imageIndex, 
709                                $(e.currentTarget),
710                                $(e.liveFired).data("yoxview").viewIndex);
711                        else
712                            $.yoxview.open($(e.liveFired || e.currentTarget).data("yoxview").viewIndex,
713                                $(e.currentTarget).data("yoxview").imageIndex);
714
715                        return false;
716                    }
717                }, options.thumbnailsOptions));
718        }
719        function setThumbnail(setToPopupImage)
720        {
721            var currentView = loadedViews[currentViewIndex];
722            thumbnail = currentView[0].tagName == "A"
723                ? currentView
724                : images[currentItemIndex].thumbnailImg;
725
726            if (!thumbnail || thumbnail.length == 0)
727                thumbnail = images[0].thumbnailImg;
728
729            if (thumbnail)
730            {
731                var thumbnailSrc = thumbnail.attr("src");
732
733                if (setToPopupImage && image1 && thumbnailSrc)
734                    image1.attr("src", thumbnailSrc);
735
736                if (currentViewIsInFrame && !frameOffset && window.name)
737                    frameOffset = $(top.document).find("[name='" + window.name + "']").offset();
738
739                thumbnailPos = thumbnail.offset();
740                thumbnailProperties = {
741                    width: thumbnail.width(), 
742                    height: thumbnail.height(), 
743                    top: Math.round(thumbnailPos.top - popupWindow.scrollTop() + (frameOffset ? frameOffset.top : 0)), 
744                    left: Math.round(thumbnailPos.left  + (frameOffset ? frameOffset.left : 0))
745                };
746            }
747        }
748        
749    //    Opens the viewer popup.
750    //    Arguments:
751    //    viewIndex: The 0-based index of the view to open, in case there are multiple instances of YoxView on the same page. Default is 0.
752    //    imageIndex: The 0-based index of the image to open, in the specified view. Default is 0.
753    //    callback: A function to call after the gallery has opened.
754        this.open = function(viewIndex, initialItemIndex, callback)
755        {
756            var isJquery = this instanceof jQuery;
757            if (isJquery)
758            {
759                if (viewIndex && typeof(viewIndex) == 'function')
760                    callback = viewIndex;
761                    
762                var itemData = this.data("yoxview");
763                viewIndex = itemData.viewIndex;
764                initialItemIndex = itemData.imageIndex;
765            }
766            else if (typeof(viewIndex) == 'function')
767            {
768                callback = viewIndex;
769                viewIndex = initialItemIndex = 0;
770            }
771            else if (typeof(initialItemIndex) == 'function')
772            {
773                callback = initialItemIndex;
774                initialItemIndex = 0;
775            }
776            viewIndex = viewIndex || 0;
777            initialItemIndex = initialItemIndex || 0;
778
779            $(document).bind('keydown.yoxview', catchPress);
780            
781            loadViewImages(loadedViews[viewIndex]);
782            if (!popup && imagesCount != 0)
783                createPopup();
784
785            $.yoxview.selectImage(initialItemIndex);
786            popupWrap.stop().css({ opacity: 0, display: "block" }).animate({ opacity: 1}, "slow", function(){ popupWrap.css("opacity", "") });
787            if(options.cacheImagesInBackground)
788                cacheImages(initialItemIndex);
789                
790            if (callback)
791                onOpenCallback = callback;
792
793            return isJquery ? this : false;
794        }
795
796        this.selectImage = function(itemIndex)
797        {
798            $.yoxview.currentImage = images[itemIndex];
799            currentItemIndex = itemIndex;
800
801            setThumbnail(true);
802            thumbnail.blur();
803
804            panel1.css({
805                "z-index" : "1",
806                width : "100%", 
807                height : "100%"             
808            });
809            panel2.css({
810                "display" : "none",
811                "z-index" : "2"
812            });
813            
814            firstImage = true;
815            popup.css(thumbnailProperties);
816            this.select(itemIndex);
817        }
818        this.refresh = function()
819        {
820            resumePlay = isPlaying;
821
822            if (isPlaying)
823                stopPlay();
824
825            setImage(currentItemIndex);
826            
827            if (resumePlay)
828                startPlay();
829        };
830        
831        //var optionsRequiringUpdate = 
832        this.options = function(opt, value){
833            if (!opt)
834                return this;
835                
836            if (value && typeof(opt) === "string"){
837                var pName = opt;
838                opt = {};
839                opt[pName] = value;
840            }
841            if (this instanceof jQuery)
842            {
843                var yoxviewData = this.data("yoxview");
844                if (yoxviewData)
845                {
846                    $.extend(optionsSets[yoxviewData.optionsSet || 0], opt);
847                    this.yoxview("update");
848                }
849                return this;
850            }
851            else
852            {
853                $.each(optionsSets, function(i, optionsSet){
854                    $.extend(optionsSet, opt);
855                });
856                $.yoxview.update();
857            }
858        };
859
860    //    Displays the specified image and shows the (optionally) specified button. Use when the viewer is open.
861    //    Arguments:
862    //    imageIndex: The 0-based index of the image to display.
863    //    pressedBtn: a jQuery element of a button to display momentarily in the viewer. 
864    //                For example, if the image has been selected by pressing the Next button 
865    //                on the keyboard, specify the Next button. If no button should be display, leave blank.
866        this.select = function(itemIndex, pressedBtn, viewIndex)
867        {
868            if (typeof pressedBtn === "number")
869            {
870                viewIndex = pressedBtn;
871                pressedBtn = undefined;
872            }
873            viewIndex = viewIndex || 0;
874
875            if (!isResizing)
876            {
877                if (itemIndex < 0)
878                {
879                    itemIndex = imagesCount - 1;
880                    if (options.onEnd)
881                    {
882                        options.onEnd();
883                        return;
884                    }
885                }
886                else if (itemIndex == imagesCount)
887                {
888                    itemIndex = 0;
889                    if (options.onEnd)
890                    {
891                        options.onEnd();
892                        return;
893                    }
894                }
895                if (!isPlaying && pressedBtn)
896                    flicker(pressedBtn);
897                    
898                $.yoxview.currentImage = images[itemIndex];
899                currentItemIndex = itemIndex;
900                setImage(currentItemIndex);
901                
902                // Set the cache buffer, if required:
903                calculateCacheBuffer();
904            
905                // Handle event onSelect:
906                if (options.onSelect)
907                    options.onSelect(itemIndex, images[itemIndex]);
908            }
909        }
910        this.prev = function(continuePlaying)
911        {
912            cacheVars.cacheDirectionForward = false;
913            this.select(currentItemIndex - 1, prevBtn);
914            if (isPlaying && continuePlaying !== true)
915                stopPlay();
916        }
917        this.next = function(continuePlaying)
918        {
919            cacheVars.cacheDirectionForward = true;
920            this.select(currentItemIndex + 1, nextBtn);
921            if (isPlaying && continuePlaying !== true)
922                stopPlay();
923        }
924        this.first = function()
925        {
926            if (!options.disableNotifications)
927                longFlicker("first");
928                
929            this.select(0);
930            if (isPlaying)
931                stopPlay();
932        };
933        this.last = function()
934        {
935            if (!options.disableNotifications)
936                longFlicker("last");
937                
938            this.select(imagesCount - 1);
939            if (isPlaying)
940                stopPlay();
941        };
942        this.setDefaults = function(options){
943            $.extend(true, defaults, options);
944        };
945        this.play = function()
946        {
947            if (!this.isOpen || imagesCount == 1)
948                return;
949                
950            cacheVars.cacheDirectionForward = true;
951            
952            if (!isPlaying)
953            {
954                if (!options.disableNotifications)
955                    longFlicker("play");
956                    
957                startPlay();
958            }
959            else
960            {
961                if (!options.disableNotifications)
962                    longFlicker("pause");
963                    
964                stopPlay();
965            }
966        };
967        function flicker(button)
968        {
969            if (button.css("opacity") == 0)
970                button.stop().animate({ opacity : 0 }, options.buttonsFadeTime, fadeOut(button));
971        }
972        function longFlicker(notificationName)
973        {
974            notification.css("background-position", sprites.getBackgroun
974dPosition("notifications", notificationName));
975            notification.stop().fadeIn(options.buttonsFadeTime, function(){ 
976                $(this).delay(500)
977                .fadeOut(options.buttonsFadeTime);
978            });
979        }
980        function fadeIn(button)
981        {
982            $(button).stop().animate({ opacity : 0 }, options.buttonsFadeTime);
983        }
984        function fadeOut(button)
985        {
986            $(button).stop().animate({ opacity : 0.5 }, options.buttonsFadeTime);
987        }
988
989        this.close = function()
990        {
991            if (!this.isOpen)
992                return;
993                
994            this.closeHelp();
995            setThumbnail(false);
996            resizePopup(thumbnailProperties, function(){ $.yoxview.isOpen = false; });
997            hideMenuPanel();
998            
999            if (infoPanel)
1000                hideInfoPanel(function(){
1001                    infoText.html("");
1002                });
1003
1004            newPanel.animate({
1005                width: thumbnailProperties.width,
1006                height: thumbnailProperties.height
1007            }, options.popupResizeTime, function(){
1008                newPanel.css("opacity", 1);
1009            });
1010    		
1011		    popupWrap.stop().fadeOut(1000);
1012    		 
1013		    if (isPlaying)
1014			    stopPlay();
1015    			
1016		    swipePanels();
1017            if (options.onClose)
1018                options.onClose();
1019
1020            $(document).unbind("keydown.yoxview");
1021            isResizing = false;
1022        }
1023        this.help = function()
1024        {
1025            if (!this.isOpen)
1026            return;
1027            
1028            if (helpPanel.css("display") == "none")
1029                helpPanel.css("display", "block").stop().animate({ opacity : 0.8 }, options.buttonsFadeTime);
1030            else
1031                this.closeHelp();
1032        }
1033        this.closeHelp = function()
1034        {
1035            if (helpPanel.css("display") != "none")
1036            helpPanel.stop().animate({ opacity: 0 }, options.buttonsFadeTime, function(){
1037                    helpPanel.css("display", "none");
1038                });
1039        }
1040        this.clickBtn = function(fn, stopPlaying)
1041        {
1042            if (stopPlaying && isPlaying)
1043                stopPlay();
1044                
1045            fn.call(this);
1046            return false;
1047        }
1048        
1049        function catchPress(e)
1050        {
1051            if ($.yoxview && $.yoxview.isOpen)
1052            {
1053                var pK = keyCodes[e.keyCode];
1054                var calledFunction = $.yoxview[keyMappings[pK]];
1055                if (calledFunction)
1056                {
1057                    e.preventDefault();
1058                    calledFunction.apply($.yoxview);
1059                    return false;
1060                }
1061                return true;
1062            }
1063            return true;
1064        }
1065        
1066        function createMenuButton(_title, btnFunction, stopPlay)
1067        {
1068            var btn = $("<a>", {
1069                href : "#",
1070                click : function(){
1071                    return $.yoxview.clickBtn($.yoxview[btnFunction], stopPlay);
1072                }         
1073            });
1074            var btnSpan = $("<span>" + _title + "</span>");
1075            btnSpan.css("opacity", "0")
1076            .appendTo(btn);
1077
1078            btn.append(sprites.getSprite("icons", btnFunction));
1079            return btn;
1080        }
1081
1082        // Prev and next buttons:
1083        function createNavButton(_function, _side, singleImage)
1084        {      
1085            var navBtnImg = new Image();
1086            navBtnImg.src = options.imagesFolder + _side + ".png";
1087            var navBtn = $("<a>", {
1088                css : {
1089                    "background" : "url(" + navBtnImg.src + ") no-repeat " + _side + " center",
1090                    "opacity" : "0",
1091                    "outline" : "0"
1092                },
1093                "class" : "yoxview_ctlBtn",
1094                href : "#"
1095            });
1096            
1097            navBtn.css(_side, "0");
1098            if (!singleImage)
1099            {
1100                navBtn.click(function(){
1101                    this.blur();
1102                    return $.yoxview.clickBtn(_function, true);
1103                });
1104                
1105                if (options.buttonsFadeTime != 0)
1106                {
1107                    navBtn.hover(
1108                        function(){
1109                            if ($.yoxview.isOpen)
1110                                $(this).stop().animate({ opacity : 0.6 }, options.buttonsFadeTime);
1111                        },
1112                        function(){
1113                            $(this).stop().animate({ opacity : 0 }, options.buttonsFadeTime);
1114                        }
1115                    );
1116                }
1117            }
1118            else
1119                navBtn.css("cursor", "default");
1120                
1121            return navBtn;
1122        }
1123
1124        popupWindow.bind("resize.yoxview", function(){
1125            windowDimensions = getWindowDimensions();
1126            if ($.yoxview.isOpen)
1127                $.yoxview.resize();
1128        });
1129        
1130        function calculateMargins()
1131        {
1132            var margins = typeof(options.popupMargin) == "number" ? [String(options.popupMargin)] : options.popupMargin.split(" ", 4);
1133            popupMargins.top = parseInt(margins[0]);
1134            switch(margins.length){
1135            case 1:
1136                popupMargins.bottom = popupMargins.right = popupMargins.left = popupMargins.top;
1137                break;
1138            case 2:
1139                popupMargins.bottom = popupMargins.top;
1140                popupMargins.right = popupMargins.left = parseInt(margins[1]);
1141                break;
1142            case 3:
1143                popupMargins.bottom = parseInt(margins[2]);
1144                popupMargins.right = popupMargins.left = parseInt(margins[1]);
1145                break;
1146            default:
1147                $.extend(popupMargins, {
1148                    right: parseInt(margins[1]),
1149                    bottom: parseInt(margins[2]),
1150                    left: parseInt(margins[3])
1151                });
1152                
1153                break;
1154            }
1155            popupMargins.totalHeight = popupMargins.top + popupMargins.bottom;
1156            popupMargins.totalWidth = popupMargins.left + popupMargins.right;
1157            
1158            if (options.renderInfoExternally)
1159                $.extend(defaultPopupMargins, popupMargins);
1160        }
1161
1162        function createPopup()
1163        {
1164            calculateMargins();
1165            windowDimensions = getWindowDimensions();
1166            
1167            sprites = new Yox.Sprites({
1168                notifications: {
1169                    width: 59,
1170                    height: 59,
1171                    sprites: [ 'empty', 'playRTL', 'play', 'pause', 'last', 'first' ]
1172                },
1173                icons: {
1174                    width: 18,
1175                    height: 18,
1176                    sprites: ['close', 'help', 'playpause', 'link', 'pin', 'unpin', 'play', 'pause', 'right', 'left']
1177                },
1178                menu: {
1179                    height: 42,
1180                    sprites: ['back']
1181                }
1182            }, options.imagesFolder + "sprites.png", options.imagesFolder + "empty.gif");
1183            
1184            keyMappings ={
1185                RIGHT: options.isRTL ? 'prev' : 'next',
1186                DOWN: 'next',
1187                UP: 'prev',
1188                LEFT: options.isRTL ? 'next' : 'prev',
1189                ENTER: 'play',
1190                HOME: 'first',
1191                END: 'last',
1192                SPACE: 'next',
1193                h: 'help',
1194                ESCAPE: 'close'
1195            };
1196            
1197            currentLanguage = yoxviewLanguages[options.lang];
1198            var skin = options.skin ? $.yoxview.yoxviewSkins[options.skin] : null;
1199            
1200            popup = $("<div>", {
1201                id: 'yoxview',
1202                click: function(e){ e.stopPropagation(); }
1203            });
1204                
1205            popupWrap = $("<div>", {
1206                id: "yoxview_popupWrap",
1207                click: function(e){ e.preventDefault(); $.yoxview.clickBtn($.yoxview.close, true); }
1208            });
1209            
1210            if (options.skin)
1211                popupWrap.attr("class", "yoxview_" + options.skin);
1212                
1213            if (options.backgroundOpacity === 0)
1214                popupWrap.css("background", "none")
1215            else if (Yox.Support.rgba())
1216                popupWrap.css("background-color", Yox.hex2rgba(options.backgroundColor, options.backgroundOpacity));
1217
1218            popupWrap.appendTo($(top.document.getElementsByTagName("body")[0])).append(popup);
1219            
1220		    panel1 = $("<div>", {
1221			    "class": "yoxview_imgPanel",
1222			    css: {
1223				    "z-index": "2"
1224			    }
1225		    });
1226		    panel2 = $("<div>", {
1227			    "class": "yoxview_imgPanel",
1228			    css: {
1229				    "z-index": "1",
1230				    "display": "none"
1231			    }
1232		    });
1233            
1234            // the first image:
1235            image1 = $("<img />", {
1236                "class" : "yoxview_fadeImg",
1237                css : {
1238				    "display" : "block",
1239				    "width" : "100%",
1240				    "height" : "100%"
1241			    }
1242            });
1243
1244            // the second image:
1245            image2 = $("<img />", {
1246                "class" : "yoxview_fadeImg",
1247                css : {
1248				    "display" : "block",
1249				    "width" : "100%",
1250				    "height" : "100%"
1251			    }
1252            });
1253            panel1.data("yoxviewPanel", {image: image1})
1254		    .append(image1).appendTo(popup);
1255		    panel2.data("yoxviewPanel", {image: image2})
1256		    panel2.append(image2).appendTo(popup);
1257            var singleImage = imagesCount == 1;
1258            if (singleImage && !images[0].media.title)
1259                options.renderInfo = false;
1260                
1261            // the menu:
1262            if (options.renderMenu !== false)
1263            {
1264                var menuPanelWrap = $("<div>", {
1265                    "class" : "yoxview_popupBarPanel yoxview_top"
1266                });
1267
1268                if (options.autoHideMenu !== false)
1269                {
1270                    menuPanelWrap.hover(
1271                        function(){
1272                            if ($.yoxview.isOpen)
1273                                showMenuPanel();
1274                        },
1275                        function(){
1276                            if ($.yoxview.isOpen)
1277                                hideMenuPanel();
1278                        }
1279                    );
1280                }
1281                
1282                menuPanel = $("<div>", {
1283                    id : "yoxview_menuPanel"
1284                });
1285                
1286                if (Yox.Support.rgba() && options.menuBackgroundColor)
1287                    menuPanel.css("background", Yox.hex2rgba(options.menuBackgroundColor, options.menuBackgroundOpacity || 0.8));
1288
1289                var helpBtn = createMenuButton(currentLanguage.Help, "help", false);
1290
1291                $.yoxview.infoButtons.playBtn = createMenuButton(currentLanguage.Slideshow, "play", false);
1292                playBtnText = $.yoxview.infoButtons.playBtn.children("span");
1293                
1294                menuPanel.append(
1295                    createMenuButton(currentLanguage.Close, "close", true),
1296                    helpBtn,
1297                    $.yoxview.infoButtons.playBtn
1298                );
1299                
1300                if (singleImage)
1301                {
1302                    $.yoxview.infoButtons.playBtn.css("display", "none");
1303                    helpBtn.css("display", "none");
1304                    menuPanel.css({
1305                        width: 58
1306                    });
1307                }
1308                
1309                menuPanel.find("a:last-child").attr("class", "last");
1310                menuPanelWrap.append(menuPanel).appendTo(popup);
1311                /* YSW
1312                menuPanel.delegate("a", "mouseenter", function(){
1313                    $(this).stop().animate({ top : "8px" }, "fast").find("span").stop().animate({opacity:1}, "fast");
1314                })
1315                .delegate("a", "mouseleave", function(){
1316                    $(this).stop().animate({ top : "0" }, "fast").find("span").stop().animate({opacity:0}
1316, "fast");
1317                });*/
1318            }
1319
1320            if (options.renderButtons !== false && (!singleImage || !$.support.opacity))
1321            {
1322                // prev and next buttons:            
1323                prevBtn = createNavButton($.yoxview.prev, options.isRTL ? "right" : "left", singleImage);            
1324                nextBtn = createNavButton($.yoxview.next, options.isRTL ? "left" : "right", singleImage);
1325
1326                popup.append(prevBtn, nextBtn);
1327                
1328                if (singleImage && !$.support.opacity)
1329                {
1330                    ctlButtons = $();
1331                    
1332                }
1333                else
1334                    ctlButtons = popup.find(".yoxview_ctlBtn");
1335            }
1336            else
1337                ctlButtons = $();        
1338
1339            // add the ajax loader:
1340            ajaxLoader = $("<div>", {
1341                id: "yoxview_ajaxLoader",
1342                "class": "yoxview_notification",
1343                css: { 
1344                    "display": "none"
1345                }
1346            });
1347            ajaxLoader.append($("<img>", {
1348                src: options.imagesFolder + "popup_ajax_loader.gif",
1349                alt: currentLanguage.Loading,
1350                css: {
1351                    /*width: 32,
1352                    height: 32,*/
1353                    width: 60,
1354                    height: 60,
1355                    "background-image": "url(" + options.imagesFolder + "sprites.png)",
1356                    "background-position": sprites.getBackgroundPosition("notifications", "empty")
1357                }
1358            }))
1359            .appendTo(popup);
1360            
1361            // notification image
1362            if (!options.disableNotifications)
1363            {
1364                notification = $("<img>", {
1365                    "class": "yoxview_notification"
1366                });
1367                popup.append(notification);
1368            }
1369            
1370            // help:
1371            helpPanel = $("<div>", {
1372                id : "yoxview_helpPanel", 
1373                href : "#", 
1374                title : currentLanguage.CloseHelp,
1375                css : {
1376                    "background" : "url(" + options.imagesFolder + "help_panel.png) no-repeat center top",
1377                    "direction" : currentLanguage.Direction,
1378                    "opacity" : "0"
1379                },
1380                click : function(){
1381                    return $.yoxview.clickBtn($.yoxview.help, false);
1382                }
1383            });
1384
1385            var helpTitle = document.createElement("h1");
1386            helpTitle.innerHTML = currentLanguage.Help.toUpperCase();
1387
1388            var helpText = document.createElement("p");
1389            helpText.style.fontSize = "11px"
1390            helpText.innerHTML = currentLanguage.HelpText;
1391            
1392            var closeHelp = document.createElement("span");
1393            closeHelp.id = "yoxview_closeHelp";
1394            //closeHelp.innerHTML = currentLanguage.CloseHelp; YSW
1395            
1396            helpPanel.append(helpTitle).append(helpText).append(closeHelp).appendTo(popup);
1397            
1398            // popup info:
1399            if (options.renderInfo !== false)
1400            {
1401                infoPanel = $("<div>", {
1402                    id: "yoxview_infoPanel",
1403                    click: function(e){ e.stopPropagation(); }
1404                });
1405
1406                if (options.infoBackOpacity === 0)
1407                {
1408                    infoPanel.css("background", "none");
1409                    infoPanelContent = infoPanel;
1410                }
1411                else
1412                {
1413                    if (Yox.Support.rgba())
1414                    {
1415                        infoPanelContent = infoPanel;
1416                        infoPanel.css("background-color", Yox.hex2rgba(options.infoBackColor, options.infoBackOpacity));
1417                    }
1418                    else
1419                    {
1420                        infoPanel.append(
1421                            $("<div>", {
1422                                id : "yoxview_infoPanelBack",
1423                                css : {
1424                                    "background" : options.infoBackColor,
1425                                    "opacity" : options.infoBackOpacity
1426                                }
1427                            })
1428                        );
1429                        infoPanelContent = $("<div>", {
1430                            id: "yoxview_infoPanelContent"
1431                        });
1432                    }
1433                }
1434                countDisplay = $("<span>", {
1435                    id: "yoxview_count"
1436                });
1437                
1438                infoText = $("<div>", {
1439                    id: "yoxview_infoText"
1440                });
1441                
1442                if (singleImage)
1443                {
1444                    infoText.css("margin-left", "10px");
1445                    countDisplay.css("display", "none");
1446                }
1447                infoPanelContent.append(countDisplay);
1448                
1449                if (options.renderInfoPin !== false)
1450                {
1451                    infoPinLinkImg = sprites.getSprite("icons", options.autoHideInfo ? "pin" : "unpin");
1452                    infoPinLink = $("<a>", {
1453                        "class": "yoxviewInfoLink",
1454                        href: "#",
1455                        title: options.autoHideInfo ? currentLanguage.PinInfo : currentLanguage.UnpinInfo,
1456                        css: { display: 'inline' },
1457                        click: function(e){
1458                            e.preventDefault();
1459                            options.autoHideInfo = !options.autoHideInfo;
1460                            infoPinLinkImg.css("background-position", sprites.getBackgroun
1460dPosition("icons", options.autoHideInfo ? "pin" : "unpin"));
1461                            this.title = options.autoHideInfo ? currentLanguage.PinInfo : currentLanguage.UnpinInfo;
1462                        }
1463                    });
1464                    infoPinLink.append(infoPinLinkImg).appendTo(infoPanelContent);
1465                }   
1466
1467                if(!singleImage && options.renderInfoPrevNext)
1468                {
1469                var infoNextImg = $("<img>", {
1470                src: options.imagesFolder + "right1.png",
1471                alt: currentLanguage.Next,
1472                css: {
1473                    width: 30,
1474                    height: 30,
1475                    'border-radius': 4,
1476                    'margin-top':5,
1477                    'margin-right':10
1478                }});
1479                infoNextLink = $("<a>", {
1480                    "class": "yoxviewInfoLink",
1481                    /*href: "#",*/
1482                    title: currentLanguage.Next,
1483                    css: { display: 'inline', cursor: 'pointer' },
1484                    click: function(e){
1485                        e.preventDefault();
1486                        $.yoxview.next();                        
1487                        this.title = currentLanguage.Next;
1488                    }
1489                });
1490                infoNextLink.append(infoNextImg).appendTo(infoPanelContent);
1491
1492                var infoPrevImg = $("<img>", {
1493                src: options.imagesFolder + "left1.png",
1494                alt: currentLanguage.Prev,
1495                css: {
1496                    width: 30,
1497                    height: 30,
1498                    'border-radius': 4,
1499                    'margin-top':5
1500                }});
1501                infoPrevLink = $("<a>", {
1502                    "class": "yoxviewInfoLink",
1503                    /*href: "#",*/
1504                    title: currentLanguage.Prev,
1505                    css: { display: 'inline', cursor: 'pointer' },
1506                    click: function(e){
1507                        e.preventDefault();
1508                        $.yoxview.prev();                        
1509                        this.title = currentLanguage.Prev;
1510                    }
1511                });
1512                infoPrevLink.append(infoPrevImg).appendTo(infoPanelContent);
1513                }
1514
1515                if (skin && skin.infoButtons)
1516                {
1517                    var skinButtons = skin.infoButtons(options, currentLanguage, sprites, popupWrap, popup);
1518                    if (options.infoButtons)
1519			            $.extend(options.infoButtons, skinButtons);
1520			        else
1521			            options.infoButtons = skinButtons;
1522			    }
1523			    if (options.infoButtons)
1524			    {  
1525				    $.extend($.yoxview.infoButtons, options.infoButtons);
1526				    for (infoButton in options.infoButtons)
1527				    {
1528					    options.infoButtons[infoButton].attr("class", "yoxviewInfoLink").css("display", "block").appendTo(infoPanelContent);
1529				    }
1530			    }
1531                
1532                if (options.linkToOriginalContext !== false)
1533                {
1534                    infoPanelLink = $("<a>", {
1535                        "class": "yoxviewInfoLink",
1536                        target: "_blank",
1537                        title: currentLanguage.OriginalContext
1538                    });
1539                    infoPanelLink.append(sprites.getSprite("icons", "link")).appendTo(infoPanelContent);
1540                }
1541                
1542                infoPanelContent.append(infoText);
1543                if (!Yox.Support.rgba())
1544                    infoPanel.append(infoPanelContent);
1545                    
1546                infoPanel.appendTo(options.renderInfoExternally ? popupWrap : popup);
1547                
1548                if (!options.renderInfoExternally)
1549                {
1550                    infoPanelWrap = $("<div>", {
1551                        "class" : "yoxview_popupBarPanel yoxview_bottom"
1552                    });
1553                    
1554                    infoPanelWrap.hover(
1555                        function(){
1556                            if ($.yoxview.isOpen && !disableInfo && options.autoHideInfo !== false)
1557                                setInfoPanelHeight();
1558                        },
1559                        function(){
1560                            if ($.yoxview.isOpen && !disableInfo && options.autoHideInfo !== false)
1561                                hideInfoPanel();
1562                        }
1563                    );
1564                    infoPanel.wrap(infoPanelWrap);
1565                    infoPanelWrap = infoPanel.parent();
1566                }
1567            }        
1568            // set the background if no RGBA support found:
1569            if (!Yox.Support.rgba())
1570            {
1571                popupBackground = $("<div>", {
1572                    css : {
1573                        "position" : "fixed",
1574                        "height" : "100%",
1575                        "width" : "100%",
1576                        "top" : "0",
1577                        "left" : "0",
1578                        "background" : options.backgroundColor,
1579                        "z-index" : "1",
1580                        "opacity" : options.backgroundOpacity
1581                    }
1582                }).appendTo(popupWrap);
1583            }
1584        }
1585        
1586	    // Cache stuff:
1587    	
1588        $(cacheImg).load(function()
1589        {
1590            $.extend(images[cacheVars.currentCacheImg].media, {
1591                width: this.width,
1592                height: this.height,
1593                loaded: true
1594            });
1595            advanceCache();
1596        })
1597        .error(function(){
1598            advanceCache();
1599	    });
1600    	
1601	    function advanceCache()
1602	    {
1603	        cacheVars.cachedImagesCount++;
1604            if (cacheVars.cachedImagesCount == imagesCount)
1605                cacheVars.cacheComplete = true;
1606            else
1607                getCacheBuffer();
1608	    }
1609        this.startCache = function()
1610        {
1611            loadViewImages(this.firstViewWithImages);
1612            calculateCacheBuffer();
1613            cacheImages(0);
1614        }
1615        function getCacheBuffer()
1616        {
1617            if (!options.cacheBuffer || cacheVars.currentCacheImg != cacheVars.cacheBufferLastIndex)
1618                cacheImages(cacheVars.currentCacheImg + (cacheVars.cacheDirectionForward ? 1 : -1));
1619        }
1620        function calculateCacheBuffer()
1621        {
1622            if (options.cacheBuffer)
1623            {
1624                cacheVars.cacheBufferLastIndex = cacheVars.cacheDirectionForward ? currentItemIndex + options.cacheBuffer : currentItemIndex - options.cacheBuffer;
1625                if (cacheVars.cacheBufferLastIndex < 0)
1626                    cacheVars.cacheBufferLastIndex += imagesCount;
1627                else if (cacheVars.cacheBufferLastIndex >= imagesCount)
1628                    cacheVars.cacheBufferLastIndex -= imagesCount;
1629            }
1630        }
1631        function cacheImages(imageIndexToCache)
1632        {
1633            if (cacheVars.cacheComplete)
1634                return;
1635
1636            if (imageIndexToCache == imagesCount)
1637                imageIndexToCache = 0;
1638            else if (imageIndexToCache < 0)
1639                imageIndexToCache += imagesCount;
1640                
1641            var image = images[imageIndexToCache].media;
1642            cacheVars.currentCacheImg = imageIndexToCache;
1643            if (image && !image.loaded)
1644            {
1645                if (!image.contentType || image.contentType === "image")
1646                    cacheImg.src = image.src;
1647                else
1648                    loadMedia(image, function(){
1649                        advanceCache();
1650                    });
1651            }
1652            else
1653                getCacheBuffer();
1654        }
1655	    // End cache stuff
1656    	
1657        function showLoaderIcon()
1658        {
1659            loading = true;
1660            clearTimeout(loaderTimeout);
1661            ajaxLoader.stop();
1662            loaderTimeout = setTimeout(function(){
1663                    ajaxLoader.css("opacity", "0.6").fadeIn(options.buttonsFadeTime);
1664                },
1665                options.buttonsFadeTime
1666            );
1667        }
1668
1669        function hideLoaderIcon()
1670        {
1671            loading = false;
1672            clearTimeout(loaderTimeout);
1673            ajaxLoader.stop().fadeOut(options.buttonsFadeTime);
1674        }
1675
1676        function setImage(itemIndex)
1677        {
1678            if (!isPlaying)
1679                showLoaderIcon();
1680
1681            loadAndDisplayMedia($.yoxview.currentImage.media);
1682        }
1683        
1684        function resizePopup(popupPosition, callback)
1685        {
1686            popup.stop().animate(popupPosition, options.popupResizeTime, callback);
1687            //popup.stop().animate(popupPosition, 5000, callback);
1688        }
1689        function startPlay()
1690        {
1691            if (imagesCount == 1)
1692                return;
1693
1694            isPlaying = true;
1695            if(playBtnText)
1696                playBtnText.text(currentLanguage.Pause);
1697            else if ($.yoxview.infoButtons.playBtn)
1698                $.yoxview.infoButtons.playBtn.attr("title", currentLanguage.Pause);
1699            
1700            if ($.yoxview.infoButtons.playBtn)
1701                $.yoxview.infoButtons.playBtn.find("img").css("background-position", sprites.getBackgroun
1701dPosition("icons", "pause"));
1702                
1703            if (currentItemIndex < imagesCount - 1)
1704            {
1705                popupTimeout = setTimeout(
1706                    function(){
1707                        $.yoxview.next(true);
1708                    },
1709                    options.playDelay
1710                );
1711            }
1712            else
1713            {
1714                if (options.loopPlay)
1715                    popupTimeout = setTimeout(
1716                        function(){
1717                            $.yoxview.select(0, null);
1718                        },
1719                        options.playDelay
1720                    );
1721                else
1722                    stopPlay();
1723                   
1724                if (options.onEnd)
1725                    setTimeout(options.onEnd, options.playDelay);
1726            }
1727        }
1728        function stopPlay()
1729        {
1730            clearTimeout(popupTimeout);
1731            isPlaying = false;
1732            if (playBtnText)
1733                playBtnText.text(currentLanguage.Play);
1734            else if ($.yoxview.infoButtons.playBtn)
1735                $.yoxview.infoButtons.playBtn.attr("title", currentLanguage.Play);
1736                
1737            if ($.yoxview.infoButtons.playBtn)
1738                $.yoxview.infoButtons.playBtn.find("img").css("background-position", sprites.getBackgroundPosition("icons", "play"));
1739        }
1740
1741        function blink(_element)
1742        {
1743            _element.animate({ opacity : 0.8 }, 1000, function()
1744            {
1745                $(this).animate({opacity: 0.2}, 1000, blink($(this)));
1746            });
1747        }
1748        
1749        var newPanel = panel2;
1750        var oldPanel = panel1;
1751        
1752        function getWindowDimensions()
1753        {
1754            var widthVal = popupWindow.width();
1755            var heightVal = popupWindow.height();
1756            var returnValue = {
1757                height : heightVal,
1758                width : widthVal,
1759			    usableArea: {
1760				    height : heightVal - popupMargins.totalHeight,
1761				    width : widthVal - popupMargins.totalWidth
1762			    }
1763            };
1764            return returnValue;
1765        }
1766        
1767        function getImagePosition(imageSize)
1768        {
1769            var imagePosition = (imageSize.width && imageSize.height)
1770                ? Yox.fitImageSize(imageSize, windowDimensions.usableArea)
1771                : { 
1772                    width: imageSize.width ? Math.min(imageSize.width, windowDimensions.usableArea.width) : windowDimensions.usableArea.width,
1773                    height: imageSize.height ? Math.min(imageSize.height, windowDimensions.usableArea.height) : windowDimensions.usableArea.height
1774                };
1775
1776            imagePosition.top = popupMargins.top + Math.round((windowDimensions.usableArea.height - imagePosition.height) / 2);
1777            imagePosition.left = popupMargins.left + Math.round((windowDimensions.usableArea.width - imagePosition.width) / 2);
1778
1779            return imagePosition;
1780        }
1781        this.resize = function(updateInfoPanel)
1782        {
1783            if (isPlaying)
1784            {
1785                resumePlay = true;
1786                stopPlay();
1787            }
1788
1789            var newImagePosition = getImagePosition(currentMaxSize);
1790            newPanel.css({ width: "100%", height: "100%"});
1791            
1792            isResizing = true;
1793            if (!isImageMode)
1794                ctlButtons.css({top: Math.round((newImagePosition.height - mediaButtonsSize.height) / 2)});
1795
1796            resizePopup(newImagePosition,
1797                function(){
1798                    var newImageSize = { width: popup.width(), height: popup.height() };
1799                    if (currentMaxSize.padding)
1800                    {
1801                        newImageSize.width -= currentMaxSize.padding.horizontal;
1802                        newImageSize.height -= currentMaxSize.padding.vertical;
1803                    }
1804
1805                    newPanel.css(newImageSize);
1806                    isResizing = false;
1807
1808                    if (infoPanel && updateInfoPanel !== false)
1809                        setInfoPanelHeight();
1810                    
1811                    if (resumePlay)
1812                    {
1813                        startPlay();
1814                        resumePlay = false;
1815                    }
1816                }
1817            );
1818        }
1819
1820        function setInfoPanelHeight(callback)
1821        {
1822            clearTimeout(hideInfoTimeout);
1823            var titleHeight = infoText.outerHeight();
1824
1825            if (titleHeight < infoPanelMinHeight)
1826                titleHeight = infoPanelMinHeight;
1827            
1828            if (infoPanel.height() !== titleHeight){
1829                infoPanel.stop().animate({height : titleHeight}, 500, function(){ 
1830                
1831                    if (options.renderInfoExternally){
1832                    
1833                        var infoPanelPosition = infoPanel.position();
1834                        $.extend(popupMargins, defaultPopupMargins);
1835                        if (infoPanelPosition.top === 0)
1836                            popupMargins.top += titleHeight;
1837                        else
1838                            popupMargins.bottom += titleHeight;
1839
1840                        popupMargins.totalHeight = popupMargins.top + popupMargins.bottom;
1841                        windowDimensions = getWindowDimensions();
1842                        $.yoxview.resize(false);                   
1843                    }
1844                        
1845                    if (callback)
1846                        callback();
1847                });
1848            }
1849        }
1850        function hideInfoPanel(callback)
1851        {
1852            clearTimeout(hideInfoTimeout);
1853            infoPanel.stop().animate({ height: 0 }, 500, function(){
1854                if (callback)
1855                    callback();
1856            });
1857        }
1858        function hideMenuPanel(callback)
1859        {
1860            if (menuPanel)
1861            {
1862                clearTimeout(hideMenuTimeout);
1863                menuPanel.stop().animate({ top: menuHidePosition }, 500, function(){
1864                    if (callback)
1865                        callback();
1866                });
1867            }
1868        }
1869        function showMenuPanel(callback)
1870        {
1871            if (menuPanel)
1872            {
1873                clearTimeout(hideMenuTimeout);
1874                menuPanel.stop().animate({ top: 0 }, 500, function(){
1875                    if (callback)
1876                        callback();
1877                });
1878            }
1879        }
1880        
1881        function swipePanels()
1882        {
1883            oldPanel = newPanel;
1884	        newPanel = isFirstPanel ? panel2 : panel1;
1885	        isFirstPanel = !isFirstPanel;
1886        }
1887	    function changeMedia(media) {
1888	        if (media.width == 500) return;
1889	        //$('#debug').html($('#debug').html() + ',' + media.width);
1890	        //alert($.yoxview.currentImage.media.width)
1891
1892	        var mediaIsImage = media.contentType === "image" || !media.contentType;
1893    	    
1894	        if (mediaIsImage && disableInfo && infoPanelWrap)
1895	            infoPanelWrap.css("display", "block");
1896    	        
1897	        clearTimeout(hideInfoTimeout);
1898    	    
1899	        swipePanels();
1900	        var panelData = newPanel.data("yoxviewPanel");
1901    	    
1902	        currentMaxSize.width = media.width;
1903	        currentMaxSize.height = media.height;
1904	        currentMaxSize.padding = media.padding;
1905
1906	        if (infoPanel)
1907            {
1908                var infoTextValue = media.title || "";
1909                if (options.showDescription && media.description)
1910                    infoTextValue += infoTextValue != ""
1911                        ? "<div id='yoxview_infoTextDescription'>" + media.description + "</div>"
1912                        : media.description;
1913
1914                infoText.html(infoTextValue);
1915                
1916                if (imagesCount > 1)
1917                    countDisplay.html(currentItemIndex + 1 + "/" + imagesCount);
1918                
1919                if (infoPanelLink)
1920                {
1921                    if ($.yoxview.currentImage.link)
1922                        infoPanelLink.attr("href", $.yoxview.currentImage.link).css("display", "inline");
1923                    else
1924                        infoPanelLink.css("display", "none");
1925                }
1926            }
1927            
1928            var newImagePosition = getImagePosition(media);
1929	        if (mediaIsImage)
1930	        {
1931	            currentImageElement = isFirstPanel ? image1 : image2;
1932		        currentImageElement.attr({
1933			        src : media.src,
1934			        title : media.title,
1935			        alt: media.alt
1936		        });
1937    			
1938			    panelData.image = currentImageElement;
1939    			
1940		        // change to image mode:
1941		        if (!panelData.isImage && panelData.element)
1942		        {
1943		            panelData.element.css("display", "none");
1944                    panelData.image.css("display", "block");
1945		            panelData.isImage = true;
1946		        }
1947    		    
1948		        if (!isImageMode)
1949		        {
1950		            if (options.renderButtons)
1951		                ctlButtons.css({"height": "100%", "width": "50%", "top": "0"});
1952    		            
1953		            disableInfo = false;
1954		            isImageMode = true;
1955		        }
1956		    }
1957		    else
1958            {
1959                if (panelData.element && panelData.elementId != media.elementId)
1960                {
1961                    panelData.element.remove();
1962                    panelData.element = undefined;
1963                }
1964                if (!panelData.element)
1965                {
1966                    if (media.html)
1967                    {
1968                        panelData.element = $("<div>", {
1969	                        "class": mediaPanelClass
1970	                    });
1971	                    popup.append(panelData.element);
1972                    }
1973                    else
1974                    {
1975                        popup.append(media.element);
1976                        panelData.element = media.element;
1977                    }
1978                }
1979
1980                if (media.html)
1981                    panelData.element.html(media.html);
1982
1983                newPanel = panelData.element;
1984                
1985                if (isImageMode)
1986                {
1987                    if (infoPanelWrap)
1988		            {
1989		                if (options.autoHideInfo !== false)
1990		                    hideInfoPanel();
1991            			    
1992		                infoPanelWrap.css("display", "none");
1993		                disableInfo = true;
1994		            }
1995    		        
1996		            if (options.renderButtons)
1997		                ctlButtons.css({
1998			                "width": mediaButtonsSize.width,
1999			                "height": mediaButtonsSize.height
2000			            });
2001    			    
2002                    isImageMode = false;
2003                }
2004                
2005                if (options.renderButtons)
2006                    ctlButtons.css({top: (newImagePosition.height - mediaButtonsSize.height) / 2 });
2007
2008                // change to element mode:
2009                if (panelData.isImage === undefined || panelData.isImage)
2010                {
2011                    panelData.element.css("display", "block");
2012                    panelData.image.css("display", "none");
2013                    panelData.isImage = false;
2014                }
2015            }
2016            
2017            var newImageDimensions = { width: newImagePosition.width, height: newImagePosition.height };
2018            newPanel.css(firstImage ? { width: "100%", height: "100%" } : newImageDimensions);
2019            
2020            if (loading)
2021                hideLoaderIcon();
2022
2023            isResizing = true;
2024            resizePopup(newImagePosition,
2025                function()
2026                {
2027                    if (firstImage)
2028                    {
2029                        $.yoxview.isOpen = true;
2030                        newPanel.css(newImageDimensions);
2031                        if (options.controlsInitialDisplayTime > 0)
2032                        {
2033                            if (options.showButtonsOnOpen)
2034                                ctlButtons.animate({opacity: 0.5}, options.controlsInitialFadeTime, function(){ 
2035                                    if(options.buttonsFadeTime != 0)
2036                                        $(this).delay(options.controlsInitialDisplayTime).animate({opacity : 0}, options.controlsInitialFadeTime);
2037                                });
2038                            
2039                            if (options.showBarsOnOpen)
2040                            {
2041                                showMenuPanel(function(){
2042                                    if (options.autoHideMenu !== false)
2043                                        hideMenuTimeout = setTimeout(function(){ 
2044                                                hideMenuPanel();
2045                                            }, 
2046                                            options.controlsInitialDisplayTime
2047                                        );
2048                                });
2049                                if (infoPanel)
2050                                    setInfoPanelHeight(function(){
2051                                        if (options.autoHideInfo !== false)
2052                                            hideInfoTimeout = setTimeout(function(){ hideInfoPanel(); }, options.controlsInitialDisplayTime);
2053                                    });
2054                            }
2055                        }
2056
2057                        if (options.autoPlay)
2058                            $.yoxview.play();
2059
2060                        if (options.onOpen)
2061                            options.onOpen();
2062                            
2063                        if (onOpenCallback)
2064                        {
2065                            onOpenCallback();
2066                            onOpenCallback = undefined;
2067                        }
2068                
2069                        firstImage = false;
2070                    }
2071                    
2072                    if (currentMaxSize.padding)
2073                    {
2074                        var newImageWidth = popup.width();
2075                        var newImageHeight = popup.height();
2076
2077                        if (currentMaxSize.padding)
2078                        {
2079                            newImageWidth -= currentMaxSize.padding.horizontal;
2080                            newImageHeight -= currentMaxSize.padding.vertical;
2081                        }
2082                        newPanel.css({ "width" : newImageWidth + "px", "height" : newImageHeight + "px" });                    
2083                    }
2084                    isResizing = false;
2085                }
2086            );
2087
2088            newPanel.css({'z-index': '2', opacity: 1});
2089            if (oldPanel)
2090                oldPanel.css('z-index', '1');
2091            
2092            if (!firstImage){
2093                newPanel.fadeIn(options.popupResizeTime, function(){
2094                    if (oldPanel)
2095                        oldPanel.css('display', 'none');
2096                        
2097                    if (infoPanel)
2098                        setInfoPanelHeight(function(){
2099                            if (options.autoHideInfo !== false)
2100                                hideInfoTimeout = setTimeout(function(){ hideInfoPanel(); }, options.titleDisplayDuration);
2101                        });
2102
2103                    if (imagesCount > 1)
2104                    {
2105                        if (options.cacheImagesInBackground && !cacheVars.cacheComplete)
2106                                cacheImages(currentItemIndex + (cacheVars.cacheDirectionForward ? 1 : -1));
2107
2108                        if (isPlaying)
2109                            startPlay();
2110                    }
2111                });
2112            }
2113            else{
2114                newPanel.css({ display: "block", width: "100%", height: "100%" });
2115            }
2116            
2117	    }
2118        $(tempImg).load(function()
2119        {
2120		    if (this.width == 0)
2121		    {
2122		        displayError("Image error");
2123                return;
2124            }
2125            changeMedia($.extend({}, $.yoxview.currentImage.media, {
2126                width: this.width,
2127                height: this.height
2128            }));
2129        })
2130        .error(function(){
2131            displayError("Image not found:<br /><span class='errorUrl'>" + this.src + "</span>");
2132        });
2133
2134        function loadMediaFromProvider(provider, url, availableSize, onLoad, onError)
2135        {
2136            $.ajax({  /*jQuery.jsonp YSW*/
2137                url: (mediaProviderUrls[provider] || "http://oohembed.com/oohembed/"),
2138                data: jQuery.extend({
2139                    "url" : url,
2140                    "format": "json"
2141                }, availableSize),
2142                dataType: 'jsonp',
2143                callbackParameter: "callback",
2144                success: function(data)
2145                {
2146                    var media = {
2147                        title: data.title,
2148                        width: data.width,
2149                        height: data.height,
2150                        type: data.type
2151                    };
2152                    
2153                    if (data.type === "video")
2154                    {
2155                        media.html = data.html
2156                            .replace(/<embed /, "<embed wmode=\"transparent\" ")
2157                            .replace(/<param/, "<param name=\"wmode\" value=\"transparent\"><param")
2158                            .replace(/width=\"[\d]+\"/ig, "width=\"100%\"")
2159                            .replace(/height=\"[\d]+\"/ig, "height=\"100%\"");
2160                    }
2161                    else if (data.type === "photo")
2162                    {
2163                        jQuery.extend(media, {
2164                            src: data.url,
2165                            alt: data.title,
2166                            type: "image"
2167                        });
2168                    }
2169                    onLoad(media);
2170                },
2171                error: function(errorSender, errorMsg){
2172                    if (onError)
2173                        onError(errorSender, errorMsg);
2174                }
2175            });
2176        };
2177
2178        function loadAndDisplayMedia(media)
2179        {
2180            try
2181            {
2182                if (!media)
2183                    throw("Error: Media is unavailable.");
2184
2185                if (media.contentType === "image" || !media.contentType)
2186                {
2187                    // Resets the src attribute for the image - avoids a rendering problem in Chrome.
2188                    // $.opacity is tested so this isn't applied in IE (up to IE8), 
2189                    // since it creates a problem with the image's fading:
2190                    if ($.support.opacity)
2191                        tempImg.src = "";
2192
2193                    tempImg.src = media.src;
2194                }
2195                else
2196                {
2197                    if (!media.loaded && media.contentType == "ooembed")
2198                    {
2199                        loadMedia(
2200                            media, 
2201                            function(loadedMedia){
2202                                changeMedia(loadedMedia);
2203                            },
2204                            function(errorSender)
2205                            {
2206                                displayError("Error getting data from:<br /><span class='errorUrl'>" + errorSender.data.url + "</span>");
2207                            }
2208                        );
2209		            }
2210		            else
2211		                changeMedia($.yoxview.currentImage.media);
2212		        }
2213		    }
2214		    catch(error)
2215		    {
2216		        displayError(error);
2217		    }
2218        }
2219        function loadMedia(media, onLoad, onError)
2220        {
2221            if (media.contentType == "ooembed")
2222            {
2223	            loadMediaFromProvider(
2224	                media.provider,
2225	                media.url,
2226	                options.defaultDimensions.video,
2227	                function(mediaData){
2228	                    $.extend(media, mediaData, {loaded: true});
2229	                    if (onLoad)
2230	                        onLoad(media);
2231	                },
2232	                onError
2233                );
2234            }
2235        }
2236        function displayError(errorMsg)
2237        {
2238            changeMedia({
2239                html: "<span class='yoxview_error'>" + errorMsg + "</span>",
2240                width: 500,
2241                height: 300,
2242                type: "error",
2243                title: ""
2244            });
2245        }
2246        this.update = function(){
2247            var options;
2248            if (this instanceof jQuery)
2249            {
2250                options = optionsSets[this.data("yoxview").optionsSet || 0];
2251                this.yoxview("unload", function(caller){ caller.yoxview(options) });
2252                return this;
2253            }
2254            else
2255            {
2256                options = optionsSets[0];
2257                this.unload();
2258                $.each(loadedViews, function(i, view){
2259                    view.yoxview(options);
2260                });
2261            }
2262        }
2263        this.unload = function(callback){
2264            var caller = this;
2265            
2266            if (!options)
2267                return(this);
2268                
2269            function doUnload(){
2270                var allowedThumbnailsSelector = getAllowedThumbnailsSelector(options);           
2271                function removeFromView(view){   
2272                    view.undelegate(allowedThumbnailsSelector, "click.yoxview")
2273                    .removeData("yoxview")
2274                    .yoxthumbs("unload", "yoxview")
2275                    .find(allowedThumbnailsSelector).removeData("yoxview");
2276                }
2277                function removeFromDocument(){
2278                    popupWindow.unbind(".yoxview");
2279                    
2280                    if (popup){
2281                        popupWrap.remove();
2282                        popup = undefined;
2283                    }
2284                }
2285                if (caller instanceof jQuery)
2286                {
2287                    if (caller.data("yoxview"))
2288                        removeFromView(caller);
2289                }
2290                else
2291                {
2292                    jQuery.each(loadedViews, function(i, view){
2293                        removeFromView(view);
2294                    });
2295                    
2296                    removeFromDocument();                
2297                }
2298
2299                if (callback)
2300                    callback(caller);
2301                else
2302                    return caller;
2303            }
2304            
2305            if (options.onBeforeUnload)
2306                options.onBeforeUnload(doUnload)
2307            else
2308                doUnload();
2309        };
2310    }
2311})(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.