PageSourceSearch

https://ciscost.ru/js/jquery.lightbox.min.js

js ciscost.ru collected 2026-10-05 00:25:49 UTC 41,675 bytes, 1,532 lines download raw bytes

1/**
2 * jQuery Lightbox Plugin (balupton edition) - Lightboxes for jQuery
3 * Copyright (C) 2008 Benjamin Arthur Lupton
4 * http://jquery.com/plugins/project/jquerylightbox_bal
5 *
6 * This file is part of jQuery Lightbox (balupton edition).
7 * 
8 * jQuery Lightbox (balupton edition) is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
12 * 
13 * jQuery Lightbox (balupton edition) is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU Affero General Public License for more details.
17 * 
18 * You should have received a copy of the GNU Affero General Public License
19 * along with jQuery Lightbox (balupton edition).  If not, see <http://www.gnu.org/licenses/>.
20 *
21 * @name jquery_lightbox: jquery.lightbox.js
22 * @package jQuery Lightbox Plugin (balupton edition)
23 * @version 1.3.7-final
24 * @date April 25, 2009
25 * @category jQuery plugin
26 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
27 * @copyright (c) 2008 Benjamin Arthur Lupton {@link http://www.balupton.com}
28 * @license GNU Affero General Public License - {@link http://www.gnu.org/licenses/agpl.html}
29 * @example Visit {@link http://jquery.com/plugins/project/jquerylightbox_bal} for more information.
30 */
31
32// Start of our jQuery Plugin
33(function($)
34{	// Create our Plugin function, with $ as the argument (we pass the jQuery object over later)
35	// More info: http://docs.jquery.com/Plugins/Authoring#Custom_Alias
36	
37	// Debug
38	if ( typeof $.log === 'undefined' ) {
39		if ( !$.browser.safari && typeof window.console !== 'undefined' && typeof window.console.log === 'function' )
40		{	// Use window.console
41			$.log = function(){
42				var args = [];
43			    for(var i = 0; i < arguments.length; i++) {
44			        args.push(arguments[i]);
45			    }
46			    window.console.log.apply(window.console, args);
47			}
48			$.console = {
49				log:	$.log,
50				debug:	window.console.debug	|| $.log,
51				warn:	window.console.warn		|| $.log,
52				error:	window.console.error	|| $.log,
53				trace:	window.console.trace	|| $.log
54			}
55		}
56		else
57		{	// Don't use anything
58			$.log = function ( ) { };
59			$.console = {
60				log:	$.log,
61				debug:	$.log,
62				warn:	$.log,
63				error:	alert,
64				trace:	$.log
65			};
66		}
67	}
68	
69	// Pre-Req
70	$.params_to_json = $.params_to_json || function ( params )
71	{	// Turns a params string or url into an array of params
72		// Adjust
73		params = String(params);
74		// Remove url if need be
75		params = params.substring(params.indexOf('?')+1);
76		// params = params.substring(params.indexOf('#')+1);
77		// Change + to %20, the %20 is fixed up later with the decode
78		params = params.replace(/\+/g, '%20');
79		// Do we have JSON string
80		if ( params.substring(0,1) === '{' && params.substring(params.length-1) === '}' )
81		{	// We have a JSON string
82			return eval(decodeURIComponent(params));
83		}
84		// We have a params string
85		params = params.split(/\&|\&amp\;/);
86		var json = {};
87		// We have params
88		for ( var i = 0, n = params.length; i < n; ++i )
89		{
90			// Adjust
91			var param = params[i] || null;
92			if ( param === null ) { continue; }
93			param = param.split('=');
94			if ( param === null ) { continue; }
95			// ^ We now have "var=blah" into ["var","blah"]
96			
97			// Get
98			var key = param[0] || null;
99			if ( key === null ) { continue; }
100			if ( typeof param[1] === 'undefined' ) { continue; }
101			var value = param[1];
102			// ^ We now have the parts
103			
104			// Fix
105			key = decodeURIComponent(key);
106			value = decodeURIComponent(value);
107			try {
108			    // value can be converted
109			    value = eval(value);
110			} catch ( e ) {
111			    // value is a normal string
112			}
113			
114			// Set
115			// console.log({'key':key,'value':value}, split);
116			var keys = key.split('.');
117			if ( keys.length === 1 )
118			{	// Simple
119				json[key] = value;
120			}
121			else
122			{	// Advanced
123				var path = '';
124				for ( ii in keys )
125				{	//
126					key = keys[ii];
127					path += '.'+key;
128					eval('json'+path+' = json'+path+' || {}');
129				}
130				eval('json'+path+' = value');
131			}
132			// ^ We now have the parts added to your JSON object
133		}
134		return json;
135	};
136	
137	// Declare our class
138	$.LightboxClass = function ( )
139	{	// This is the handler for our constructor
140		this.construct();
141	};
142
143	// Extend jQuery elements for Lightbox
144	$.fn.lightbox = function ( options )
145	{	// Init a el for Lightbox
146		// Eg. $('#gallery a').lightbox();
147		
148		// If need be: Instantiate $.LightboxClass to $.Lightbox
149		$.Lightbox = $.Lightbox || new $.LightboxClass();
150		
151		// Handle IE6 appropriatly
152		if ( $.Lightbox.ie6 && !$.Lightbox.ie6_support )
153		{	// We are IE6 and we want to ignore
154			return this; // chain
155		}
156		
157		// Establish options
158		options = $.extend({start:false,events:true} /* default options */, options);
159		
160		// Get group
161		var group = $(this);
162		
163		// Events?
164		if ( options.events )
165		{	// Add events
166			$(group).unbind('click').click(function(){
167				// Get obj
168				var obj = $(this);
169				// Get rel
170				// var rel = $(obj).attr('rel');
171				// Init group
172				if ( !$.Lightbox.init($(obj)[0], group) )
173				{	return false;	}
174				// Display lightbox
175				if ( !$.Lightbox.start() )
176				{	return false;	}
177				// Cancel href
178				return false;
179			});
180			// Add style
181			$(group).addClass('lightbox-enabled');
182		}
183		
184		// Start?
185		if ( options.start )
186		{	// Start
187			// Get obj
188			var obj = $(this);
189			// Get rel
190			// var rel = $(obj).attr('rel');
191			// Init group
192			if ( !$.Lightbox.init($(obj)[0], group) )
193			{	return this;	}
194			// Display lightbox
195			if ( !$.Lightbox.start() )
196			{	return this;	}
197		}
198		
199		// And chain
200		return this;
201	};
202	
203	// Define our class
204	$.extend($.LightboxClass.prototype,
205	{	// Our LightboxClass definition
206		
207		// -----------------
208		// Everyting to do with images
209		
210		images: {
211			
212			// -----------------
213			// Variables
214			
215			// Our array of images
216			list:[], /* [ {
217				src: 'url to image',
218				link: 'a link to a page',
219				title: 'title of the image',
220				name: 'name of the image',
221				description: 'description of the image'
222			} ], */
223			
224			// The current active image
225			image: false,
226			
227			// -----------------
228			// Functions
229			
230			prev: function ( image )
231			{	// Get previous image
232				
233				// Get previous from current?
234				if ( typeof image === 'undefined' )
235				{	image = this.active();
236					if ( !image ) { return image; }
237				}
238				
239				// Is there a previous?
240				if ( this.first(image) )
241				{	return false;	}
242				
243				// Get the previous
244				return this.get(image.index-1);
245			},
246			
247			next: function ( image )
248			{	// Get next image
249				
250				// Get next from current?
251				if ( typeof image === 'undefined' )
252				{	image = this.active();
253					if ( !image ) { return image; }
254				}
255				
256				// Is there a next?
257				if ( this.last(image) )
258				{	return false;	}
259				
260				// Get the next
261				return this.get(image.index+1);
262			},
263			
264			first: function ( image )
265			{	//
266				// Get the first image?
267				if ( typeof image === 'undefined' )
268				{	return this.get(0);	}
269				
270				// Are we the first?
271				return image.index === 0;
272			},
273			
274			last: function ( image )
275			{	//
276				// Get the last image?
277				if ( typeof image === 'undefined' )
278				{	return this.get(this.size()-1);	}
279				
280				// Are we the last?
281				return image.index === this.size()-1;
282			},
283		
284			single: function ( )
285			{	// Are we only one
286				return this.size() === 1;
287			},
288			
289			size: function ( )
290			{	// How many images do we have
291				return this.list.length;
292			},
293			
294			empty: function ( )
295			{	// Are we empty
296				return this.size() === 0;
297			},
298			
299			clear: function ( )
300			{	// Clear image arrray
301				this.list = [];
302				this.image = false;
303			},
304		
305			active: function ( image )
306			{	// Set or get the active image
307				// Use false to reset
308				
309				// Get the active image?
310				if ( typeof image === 'undefined' )
311				{	return this.image;	}
312				
313				// Set the ative image
314				if ( image !== false )
315				{	// Make sure image exists
316					image = this.get(image);
317					if ( !image )
318					{	// Error
319						return image;
320					}
321				}
322				
323				// Set the active image
324				this.image = image;
325				return true;
326			},
327		
328			add: function ( obj )
329			{
330				// Do we need to recurse?
331				if ( obj[0] )
332				{	// We have a lot of images
333					for ( var i = 0; i < obj.length; i++ )
334					{	this.add(obj[i]);	}
335					return true;
336				}
337				
338				// Default image
339				
340				// Try and create a image
341				var image = this.create(obj);
342				if ( !image ) { return image; }
343				
344				// Set image index
345				image.index = this.size();
346				
347				// Push image
348				this.list.push(image);
349				
350				// Success
351				return true;
352			},
353			
354			create: function ( obj )
355			{	// Create image
356				
357				// Define
358				var image = { // default
359					src:	'',
360					title:	'Untitled',
361					description:	'',
362					name:	'',
363					index:	-1,
364					color:	null,
365					width:	null,
366					height:	null,
367					image:	true
368				};
369				
370				// Create
371				if ( obj.image )
372				{	// Already a image, so copy over values
373					image.src = obj.src || image.src;
374					image.title = obj.title || image.title;
375					image.description = obj.description || image.description;
376					image.name = obj.name || image.name;
377					image.color = obj.color || image.color;
378					image.width = obj.width || image.width;
379					image.height = obj.height || image.height;
380					image.index = obj.index || image.index;
381				}
382				else if ( obj.tagName )
383				{	// We are an element
384					obj = $(obj);
385					if ( obj.attr('src') || obj.attr('href') )
386					{
387						image.src = obj.attr('src') || obj.attr('href');
388						image.title = obj.attr('title') || obj.attr('alt') || image.title;
389						image.name = obj.attr('name') || '';
390						image.color = obj.css('backgroundColor');
391						// Extract description from title
392						var s = image.title.indexOf(': ');
393						if ( s > 0 )
394						{	// Description exists
395							image.description = image.title.substring(s+2) || image.description;
396							image.title = image.title.substring(0,s) || image.title;
397						}
398					}
399					else
400					{	// Unsupported element
401						image = false;
402					}
403				}
404				else
405				{	// Unknown
406					image = false;
407				}
408				
409				if ( !image )
410				{	// Error
411					$.console.error('We dont know what we have:', obj);
412					return false;
413				}
414				
415				// Success
416				return image;
417			},
418			
419			get: function ( image )
420			{	// Get the active, or specified image
421				
422				// Establish image
423				if ( typeof image === 'undefined' || image === null )
424				{	// Get the active image
425					return this.active();
426				}
427				else
428				if ( typeof image === 'number' )
429				{	// We have a index
430					
431					// Get image
432					image = this.list[image] || false;
433				}
434				else
435				{	// Create
436					image = this.create(image);
437					if ( !image ) { return false; }
438					
439					// Find
440					var f = false;
441					for ( var i = 0; i < this.size(); i++ )
442					{
443						var c = this.list[i];
444						if ( c.src === image.src && c.title === image.title && c.description === image.description )
445						{	f = c;	}
446					}
447					
448					// Found?
449					image = f;
450				}
451				
452				// Determine image
453				if ( !image )
454				{	// Image doesn't exist
455					$.console.error('The desired image does not exist: ', image, this.list);
456					return false;
457				}
458				
459				// Return image
460				return image;
461			},
462			
463			debug: function ( )
464			{
465				return $.Lightbox.debug(arguments);
466			}
467			
468		},
469		
470		// -----------------
471		// Variables
472		
473		constructed:		false,
474		compressed:			null,
475		
476		// -----------------
477		// Options
478		
479		src:				null,		// the source location of our js file
480		baseurl:			null,
481		
482		files: {
483			compressed: {
484				js: {
485					lightbox:	'/js/jquery.lightbox.min.js',
486					colorBlend:	'/js/jquery.color.min.js'
487				},
488				css: {
489					lightbox:	'/css/jquery.lightbox.css'
490				}
491			},
492			uncompressed: {
493				js: {
494					lightbox:	'/js/jquery.lightbox.js',
495					colorBlend:	'/js/jquery.color.js'
496				},
497				css: {
498					lightbox:	'/css/jquery.lightbox.css'
499				}
500			},
501			images: {
502				prev:		'/img/prev.gif',
503				next:		'/img/next.gif',
504				blank:		'/img/blank.gif',
505				loading:	'/img/loading.gif'
506			}
507		},
508		
509		text: {
510			// For translating
511			image:		'Image',
512			of:			'of',
513			close:		'Close X',
514			closeInfo:	'',
515			download:	'Download.',
516			help: {
517				close:		'Click to close',
518				interact:	'Hover to interact'
519			},
520			about: {
521				text: 	'',
522				title:	'',
523				link:	''
524			}
525		},
526		
527		keys: {
528			close:	'c',
529			prev:	'p',
530			next:	'n'
531		},
532		
533		handlers: {
534			// For custom actions
535			show:	null
536		},
537		
538		opacity:		0.9,
539		padding:		null,		// if null - autodetect
540		
541		speed:			400,		// Duration of effect, milliseconds
542		
543		rel:			'lightbox',	// What to look for in the rels
544		
545		auto_relify:	true,		// should we automaticly do the rels?
546		
547		auto_scroll:	'follow',	// should the lightbox scroll with the page? follow, disabled, ignore
548		auto_resize:	true,		// true or false
549		
550		ie6:			null,		// are we ie6?
551		ie6_support:	true,		// have ie6 support
552		ie6_upgrade:	true,		// show ie6 upgrade message
553		
554		colorBlend:		null,		// null - auto-detect, true - force, false - no
555		
556		download_link:		true,	// Display the download link
557		
558		show_helper_text:	true,	// Display the helper text up the top right
559		show_linkback:		true,	// true, false
560		show_info:			'auto',	// auto - automaticly handle, true - force
561		show_extended_info:	'auto',	// auto - automaticly handle, true - force	
562		
563		// names of the options that can be modified
564		options:	['show_helper_text', 'auto_scroll', 'auto_resize', 'download_link', 'show_info', 'show_extended_info', 'ie6_support', 'ie6_upgrade', 'colorBlend', 'baseurl', 'files', 'text', 'show_linkback', 'keys', 'opacity', 'padding', 'speed', 'rel', 'auto_relify'],
565		
566		// -----------------
567		// Functions
568		
569		construct: function ( options )
570		{	// Construct our Lightbox
571			
572			// -------------------
573			// Prepare
574			
575			// Initial construct
576			var initial = typeof this.constructed === 'undefined' || this.constructed === false;
577			this.constructed = true;
578			
579			// Perform domReady
580			var domReady = initial;
581			
582			// Prepare options
583			options = options || {};
584			
585			// -------------------
586			// Handle files
587			
588			// Prepend function to use later
589			var prepend = function(item, value) {
590				if ( typeof item === 'object' ) {
591					for (var i in item) {
592						item[i] = prepend(item[i], value);
593					}
594				} else if ( typeof value === 'array' ) {
595					for (var i=0,n=item.length; i<n; ++i) {
596						item[i] = prepend(item[i], value);
597					}
598				} else {
599					item = value+item;
600				}
601				return item;
602			}
603			
604			// Add baseurl
605			if ( initial && (typeof options.files === 'undefined') )
606			{	// Load the files like default
607				
608				// Reset compressed
609				this.compressed = null;
610				
611				// Get the src of the first script tag that includes our js file (with or without an appendix)
612				var $script = $('script[src*='+this.files.compressed.js.lightbox+']:first');
613				if ( $script.length !== 0 ) {
614					// Compressed
615					$.extend(true, this.files, this.files.compressed);
616					this.compressed = true;
617				} else {
618					// Uncompressed
619					$script = $('script[src*='+this.files.uncompressed.js.lightbox+']:first');
620					if ( $script.length !== 0 ) {
621						// Uncompressed
622						$.extend(true, this.files, this.files.uncompressed);
623						this.compressed = false;
624					} else {
625						// Nothing
626					}
627				}
628				
629				// Make sure we found ourselves
630				if ( this.compressed === null )
631				{	// We didn't
632					$.console.error('Lightbox was not able to find it\'s javascript script tag necessary for auto-inclusion.');
633					// We don't work with files anymore, so don't care for domReady
634					domReady = false;
635				}
636				else
637				{	// We found ourself
638					
639					// Grab the script src
640					this.src = $script.attr('src');
641					
642					// The baseurl is the src up until the start of our js file
643					this.baseurl = this.src.substring(0, this.src.indexOf(this.files.js.lightbox));
644					
645					// Prepend baseurl to files
646					this.files = prepend(this.files, this.baseurl);
647					
648					// Now as we have source, we may have more params
649					options = $.extend(options, $.params_to_json(this.src));
650				}
651				
652			}
653			else
654			if ( typeof options.files === 'object' )
655			{	// We have custom files
656				// Prepend baseurl to files
657				options.files = prepend(options.files, this.baseurl);
658			}
659			else
660			{	// Don't have any files, so no need to perform domReady
661				domReady = false;
662			}
663			
664			// -------------------
665			// Apply options
666			
667			for ( var i in this.options )
668			{	// Cycle through the options
669				var name = this.options[i];
670				if ( (typeof options[name] === 'object') && (typeof this[name] === 'object') )
671				{	// We have a group like text or files
672					this[name] = $.extend(true, this[name], options[name]);
673				}
674				else if ( typeof options[name] !== 'undefined' )
675				{	// We have that option, so apply it
676					this[name] = options[name];
677				}
678			}	delete i;
679			
680			// -------------------
681			// Figure out what to do
682			
683			// Handle IE6
684			if ( initial && navigator.userAgent.indexOf('MSIE 6') >= 0 )
685			{	// Is IE6
686				this.ie6 = true;
687			}
688			else
689			{	// We are not IE6
690				this.ie6 = false;
691			}
692			
693			// -------------------
694			// Handle our DOM
695			
696			if ( domReady || typeof options.download_link !== 'undefined' ||  typeof options.colorBlend !== 'undefined' || typeof options.files === 'object' || typeof options.text === 'object' || typeof options.show_linkback !== 'undefined' || typeof options.scroll_with !== 'undefined' )
697			{	// We have reason to handle the dom
698				$(function() {
699					// DOM is ready, so fire our DOM handler
700					$.Lightbox.domReady();
701				});
702			}
703			
704			// -------------------
705			// Finish Up
706			
707			// All good
708			return true;
709		},
710		
711		domReady: function ( )
712		{
713			// -------------------
714			// Include resources
715			
716			// Grab resources
717			var bodyEl = document.getElementsByTagName($.browser.safari ? 'head' : 'body')[0];
718			var stylesheets = this.files.css;
719			var scripts = this.files.js;
720			
721			// Handle IE6 appropriatly
722			if ( this.ie6 && this.ie6_upgrade )
723			{	// Add the upgrade message
724				scripts.ie6 = 'http://www.savethedevelopers.org/say.no.to.ie.6.js';
725			}
726			
727			// colorBlend
728			if ( this.colorBlend === true && typeof $.colorBlend === 'undefined' )
729			{	// Force colorBlend
730				this.colorBlend = true;
731				// Leave file in place to be loaded
732			}
733			else
734			{	// We either have colorBlend or we don't
735				this.colorBlend = typeof $.colorBlend !== 'undefined';
736				// Remove colorBlend file
737				delete scripts.colorBlend;
738			}
739			
740			// Include stylesheets
741			for ( stylesheet in stylesheets )
742			{
743				var linkEl = document.createElement('link');
744				linkEl.type = 'text/css';
745				linkEl.rel = 'stylesheet';
746				linkEl.media = 'screen';
747				linkEl.href = stylesheets[stylesheet];
748				linkEl.id = 'lightbox-stylesheet-'+stylesheet.replace(/[^a-zA-Z0-9]/g, '');
749				$('#'+linkEl.id).remove();
750				bodyEl.appendChild(linkEl);
751			}
752			
753			// Include javascripts
754			for ( script in scripts )
755			{
756				var scriptEl = document.createElement('script');
757				scriptEl.type = 'text/javascript';
758				scriptEl.src = scripts[script];
759				scriptEl.id = 'lightbox-script-'+script.replace(/[^a-zA-Z0-9]/g, '');
760				$('#'+scriptEl.id).remove();
761				bodyEl.appendChild(scriptEl);
762			}
763			
764			// Cleanup
765			delete scripts;
766			delete stylesheets;
767			delete bodyEl;
768			
769			// -------------------
770			// Append display
771			
772			// Append markup
773			$('#lightbox,#lightbox-overlay').remove();
774			$('body').append('<div id="lightbox-overlay"><div id="lightbox-overlay-text">'+(this.show_linkback?'<p><span id="lightbox-overlay-text-about"><a href="#" title="'+this.text.about.title+'">'+this.text.about.text+'</a></span></p><p>&nbsp;</p>':'')+(this.show_helper_text?'<p><span id="lightbox-overlay-text-close">'+this.text.help.close+'</span><br/>&nbsp;<span id="lightbox-overlay-text-interact">'+this.text.help.interact+'</span></p>':'')+'</div></div><div id="lightbox"><div id="lightbox-imageBox"><div id="lightbox-imageContainer"><img id="lightbox-image" /><div id="lightbox-nav"><a href="#" id="lightbox-nav-btnPrev"></a><a href="#" id="lightbox-nav-btnNext"></a></div><div id="lightbox-loading"><a href="#" id="lightbox-loading-link"><img src="' + this.files.images.loading + '" /></a></div></div></div><div id="lightbox-infoBox"><div id="lightbox-infoContainer"><div id="lightbox-infoHeader"><span id="lightbox-caption">'+(this.download_link ? '<a href="#" title="' + this.text.download + '" id="lightbox-caption-title"></a>' : '<span id="lightbox-caption-title"></span>')+'<span id="lightbox-caption-seperator"></span><span id="lightbox-caption-description"></span></span></div><div id="lightbox-infoFooter"><span id="lightbox-currentNumber"></span><span id="lightbox-close"><a href="#" id="lightbox-close-button" title="'+this.text.closeInfo+'">' + this.text.close + '</a></span></div><div id="lightbox-infoContainer-clear"></div></div></div></div>');
775			
776			// Update Boxes - for some crazy reason this has to be before the hide in safari and konqueror
777			this.resizeBoxes();
778			this.repositionBoxes();
779			
780			// Hide
781			$('#lightbox,#lightbox-overlay,#lightbox-overlay-text-interact').hide();
782			
783			// -------------------
784			// Browser specifics
785			
786			// Handle IE6
787			if ( this.ie6 && this.ie6_support )
788			{	// Support IE6
789				// IE6 does not support fixed positioning so absolute it
790				// ^ This is okay as we disable scrolling
791				$('#lightbox-overlay').css({
792					position:	'absolute',
793					top:		'0px',
794					left:		'0px'
795				});
796			}
797			
798			// -------------------
799			// Preload Images
800			
801			// Cycle and preload
802			$.each(this.files.images, function()
803			{	// Proload the image
804				var preloader = new Image();
805				preloader.onload = function() {
806					preloader.onload = null;
807					preloader = null;
808				};	preloader.src = this;
809			});
810			
811			// -------------------
812			// Apply events
813			
814			// If the window resizes, act appropriatly
815			$(window).unbind('resize').resize(function ()
816			{	// The window has been resized
817				$.Lightbox.resizeBoxes('resized');
818			});
819			
820			// If the window scrolls, act appropriatly
821			if ( this.scroll === 'follow' )
822			{	// We want to
823				$(window).scroll(function ()
824				{	// The window has scrolled
825					$.Lightbox.repositionBoxes();
826				});
827			}
828			
829			// Prev
830			$('#lightbox-nav-btnPrev').unbind().hover(function() { // over
831				$(this).css({ 'background' : 'url(' + $.Lightbox.files.images.prev + ') left 45% no-repeat' });
832			},function() { // out
833				$(this).css({ 'background' : 'transparent url(' + $.Lightbox.files.images.blank + ') no-repeat' });
834			}).click(function() {
835				$.Lightbox.showImage($.Lightbox.images.prev());
836				return false;
837			});
838					
839			// Next
840			$('#lightbox-nav-btnNext').unbind().hover(function() { // over
841				$(this).css({ 'background' : 'url(' + $.Lightbox.files.images.next + ') right 45% no-repeat' });
842			},function() { // out
843				$(this).css({ 'background' : 'transparent url(' + $.Lightbox.files.images.blank + ') no-repeat' });
844			}).click(function() {
845				$.Lightbox.showImage($.Lightbox.images.next());
846				return false;
847			});
848			
849			// Help
850			if ( this.show_linkback )
851			{	// Linkback exists so add handler
852				$('#lightbox-overlay-text-about a').click(function(){window.open($.Lightbox.text.about.link); return false;});
853			}
854			$('#lightbox-overlay-text-close').unbind().hover(
855				function(){
856					$('#lightbox-overlay-text-interact').fadeIn();
857				},
858				function(){
859					$('#lightbox-overlay-text-interact').fadeOut();
860				}
861			);
862			
863			// Image link
864			$('#lightbox-caption-title').click(function(){window.open($(this).attr('href')); return false;});
865			
866			// Assign close clicks
867			$('#lightbox-overlay, #lightbox, #lightbox-loading-link, #lightbox-btnClose').unbind().click(function() {
868				$.Lightbox.finish();
869				return false;	
870			});
871			
872			// -------------------
873			// Finish Up
874			
875			// Relify
876			if ( this.auto_relify )
877			{	// We want to relify, no the user
878				this.relify();
879			}
880			
881			// All good
882			return true;
883		},
884		
885		relify: function ( )
886		{	// Create event
887		
888			//
889			var groups = {};
890			var groups_n = 0;
891			var orig_rel = this.rel;
892			// Create the groups
893			$.each($('[rel*='+orig_rel+']'), function(index, obj){
894				// Get the group
895				var rel = $(obj).attr('rel');
896				// Are we really a group
897				if ( rel === orig_rel )
898				{	// We aren't
899					rel = groups_n; // we are individual
900				}
901				// Does the group exist
902				if ( typeof groups[rel] === 'undefined' )
903				{	// Make the group
904					groups[rel] = [];
905					groups_n++;
906				}
907				// Append the image
908				groups[rel].push(obj);
909			});
910			// Lightbox groups
911			$.each(groups, function(index, group){
912				$(group).lightbox();
913			});
914			// Done
915			return true;
916		},
917		
918		init: function ( image, images )
919		{	// Init a batch of lightboxes
920			
921			// Establish images
922			if ( typeof images === 'undefined' )
923			{
924				images = image;
925				image = 0;
926			}
927			
928			// Clear
929			this.images.clear();
930			
931			// Add images
932			if ( !this.images.add(images) )
933			{	return false;	}
934			
935			// Do we need to bother
936			if ( this.images.empty() )
937			{	// No images
938				$.console.warn('WARNING', 'Lightbox started, but no images: ', image, images);
939				return false;
940			}
941			
942			// Set active
943			if ( !this.images.active(image) )
944			{	return false;	}
945			
946			// Done
947			return true;
948		},
949		
950		start: function ( )
951		{	// Display the lightbox
952				
953			// We are alive
954			this.visible = true;
955			
956			// Adjust scrolling
957			if ( this.scroll === 'disable' )
958			{	// 
959				$(document.body).css('overflow', 'hidden');
960			}
961			
962			// Fix attention seekers
963			$('embed, object, select').css('visibility', 'hidden');//.hide(); - don't use this, give it a go, find out why!
964			
965			// Resize the boxes appropriatly
966			this.resizeBoxes('general');
967			
968			// Reposition the Boxes
969			this.repositionBoxes({'speed':0});
970			
971			// Hide things
972			$('#lightbox-infoFooter').hide(); // we hide this here because it makes the display smoother
973			$('#lightbox-image,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-infoBox').hide();
974					
975			// Display the boxes
976			$('#lightbox-overlay').css('opacity',this.opacity).fadeIn(400, function(){
977				// Show the lightbox
978				$('#lightbox').fadeIn(300);
979				
980				// Display first image
981				if ( !$.Lightbox.showImage($.Lightbox.images.active()) )
982				{	$.Lightbox.finish();	return false;	}
983			});
984			
985			// All done
986			return true;
987		},
988		
989		finish: function ( )
990		{	// Get rid of lightbox
991		
992			// Hide lightbox
993			$('#lightbox').hide();
994			$('#lightbox-overlay').fadeOut(function() { $('#lightbox-overlay').hide(); });
995			
996			// Fix attention seekers
997			$('embed, object, select').css({ 'visibility' : 'visible' });//.show();
998			
999			// Kill active image
1000			this.images.active(false);
1001			
1002			// Adjust scrolling
1003			if ( this.scroll === 'disable' )
1004			{	// 
1005				$(document.body).css('overflow', 'visible');
1006			}
1007			
1008			// We are dead
1009			this.visible = false;
1010			
1011		},
1012		
1013		resizeBoxes: function ( type )
1014		{	// Resize the boxes
1015			// Used on transition or window resize
1016			
1017			// Resize Overlay
1018			if ( type !== 'transition' )
1019			{	// We don't care for transition
1020				var $body = $(this.ie6 ? document.body : document);
1021				$('#lightbox-overlay').css({
1022					width:		$body.width(),
1023					height:		$body.height()
1024				});
1025				delete $body;
1026			}
1027			
1028			// Handle cases
1029			switch ( type )
1030			{
1031				case 'general': // general resize (start of lightbox)
1032					return true;
1033					break;
1034				case 'resized': // window was resized
1035					if ( this.auto_resize === false )
1036					{	// Stop
1037						// Reposition
1038						this.repositionBoxes({'nHeight':nHeight, 'speed':this.speed});
1039						return true;
1040					}
1041				case 'transition': // transition between images
1042				default: // unknown
1043					break;
1044			}
1045			
1046			// Get image
1047			var image = this.images.active();
1048			if ( !image || !image.width || !this.visible )
1049			{	// No image or no visible lightbox, so we don't care
1050				//$.console.warn('A resize occured while no image or no lightbox...');
1051				return false;
1052			}
1053			
1054			// Resize image box
1055			// i:image, w:window, b:box, c:current, n:new, d:difference
1056			
1057			// Get image dimensions
1058			var iWidth  = image.width;
1059			var iHeight = image.height;
1060			
1061			// Get window dimensions
1062			var wWidth  = $(window).width();
1063			var wHeight = $(window).height();
1064			
1065			// Check if we are in size
1066			// Lightbox can take up 4/5 of size
1067			if ( this.auto_resize !== false )
1068			{	// We want to auto resize
1069				var maxWidth  = Math.floor(wWidth*(4/5));
1070				var maxHeight = Math.floor(wHeight*(4/5));
1071				var resizeRatio;
1072				while ( iWidth > maxWidth || iHeight > maxHeight )
1073				{	// We need to resize
1074					if ( iWidth > maxWidth )
1075					{	// Resize width, then height proportionally
1076						resizeRatio = maxWidth/iWidth;
1077						iWidth = maxWidth;
1078						iHeight = Math.floor(iHeight*resizeRatio);
1079					}
1080					if ( iHeight > maxHeight )
1081					{	// Resize height, then width proportionally
1082						resizeRatio = maxHeight/iHeight;
1083						iHeight = maxHeight;
1084						iWidth = Math.floor(iWidth*resizeRatio);
1085					}
1086				}
1087			}
1088			
1089			// Get current width and height
1090			var cWidth  = $('#lightbox-imageBox').width();
1091			var cHeight = $('#lightbox-imageBox').height();
1092	
1093			// Get the width and height of the selected image plus the padding
1094			// padding*2 for both sides (left+right || top+bottom)
1095			var nWidth	= (iWidth  + (this.padding * 2));
1096			var nHeight	= (iHeight + (this.padding * 2));
1097			
1098			// Diferences
1099			var dWidth  = cWidth  - nWidth;
1100			var dHeight = cHeight - nHeight;
1101			
1102			// Set the overlay buttons height and the infobox width
1103			// Other dimensions specified by CSS
1104			$('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css('height', nHeight); 
1105			$('#lightbox-infoBox').css('width', nWidth);
1106			
1107			// Handle final action
1108			if ( type === 'transition' )
1109			{	// We are transition
1110				// Do we need to wait? (just a nice effect to counter the other
1111				if ( dWidth === 0 && dHeight === 0 )
1112				{	// We are the same size
1113					this.pause(this.speed/3);
1114					this.showImage(null, 3);
1115				}
1116				else
1117				{	// We are not the same size
1118					// Animate
1119					$('#lightbox-image').width(iWidth).height(iHeight);
1120					$('#lightbox-imageBox').animate({width: nWidth, height: nHeight}, this.speed, function ( ) { $.Lightbox.showImage(null, 3); } );
1121				}
1122			}
1123			else
1124			{	// We are a resize
1125				// Animate Lightbox
1126				$('#lightbox-image').animate({width:iWidth, height:iHeight}, this.speed);
1127				$('#lightbox-imageBox').animate({width: nWidth, height: nHeight}, this.speed);
1128			}
1129			
1130			// Reposition
1131			this.repositionBoxes({'nHeight':nHeight, 'speed':this.speed});
1132			
1133			// Done
1134			return true;
1135		},
1136		
1137		repositioning:			false,	// are we currently repositioning
1138		reposition_failsafe:	false,	// failsafe
1139		repositionBoxes: function ( options )
1140		{
1141			// Prepare
1142			if ( this.repositioning )
1143			{	// Already here
1144				this.reposition_failsafe = true;
1145				return null;
1146			}
1147			this.repositioning = true;
1148			
1149			// Options
1150			options = $.extend({}, options);
1151			options.callback = options.callback || null;
1152			options.speed = options.speed || 'slow';
1153			
1154			// Get page scroll
1155			var pageScroll = this.getPageScroll();
1156			
1157			// Figure it out
1158			// alert($(window).height()+"\n"+$(document.body).height()+"\n"+$(document).height());
1159			// var nHeight = options.nHeight || parseInt($('#lightbox').height(),10) || $(document).height()/3;
1160			var nHeight = options.nHeight || parseInt($('#lightbox').height(),10);
1161			
1162			// Display lightbox in center
1163			// var nTop = pageScroll.yScroll + ($(document.body).height() /*frame height*/ - nHeight) / 2.5;
1164			var nTop = pageScroll.yScroll + ($(window).height() /*frame height*/ - nHeight) / 2.5;
1165			var nLeft = pageScroll.xScroll;
1166			
1167			// Animate
1168			var css = {
1169				left: nLeft,
1170				top: nTop
1171			};
1172			if (options.speed) {
1173				$('#lightbox').animate(css, 'slow', function(){
1174					if ( $.Lightbox.reposition_failsafe )
1175					{	// Fire again
1176						$.Lightbox.repositioning = $.Lightbox.reposition_failsafe = false;
1177						$.Lightbox.repositionBoxes(options);
1178					}
1179					else
1180					{	// Done
1181						$.Lightbox.repositioning = false;
1182						if ( options.callback )
1183						{	// Call the user callback
1184							options.callback();
1185						}
1186					}
1187				});
1188			}
1189			else
1190			{
1191				$('#lightbox').css(css);
1192				if ( this.reposition_failsafe )
1193				{	// Fire again
1194					this.repositioning = this.reposition_failsafe = false;
1195					this.repositionBoxes(options);
1196				}
1197				else
1198				{	// Done
1199					this.repositioning = false;
1200				}
1201			}
1202			
1203			// Done
1204			return true;
1205		},
1206		
1207		visible: false,
1208		showImage: function ( image, step )
1209		{
1210			// Establish image
1211			image = this.images.get(image);
1212			if ( !image ) { return image; }
1213			
1214			// Default step
1215			step = step || 1;
1216			
1217			// Split up below for jsLint compliance
1218			var skipped_step_1 = step > 1 && this.images.active().src !== image.src;
1219			var skipped_step_2 = step > 2 && $('#lightbox-image').attr('src') !== image.src;
1220			if ( skipped_step_1 || skipped_step_2 )
1221			{	// Force step 1
1222				$.console.info('We wanted to skip a few steps: ', image, step, skipped_step_1, skipped_step_2);
1223				step = 1;
1224			}
1225			
1226			// What do we need to do
1227			switch ( step )
1228			{
1229				// ---------------------------------
1230				// We need to preload
1231				case 1:
1232				
1233					// Disable keyboard nav
1234					this.KeyboardNav_Disable();
1235					
1236					// Show the loading image
1237					$('#lightbox-loading').show();
1238					
1239					// Hide things
1240					$('#lightbox-image,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-infoBox').hide();
1241					
1242					// Remove show info events
1243					$('#lightbox-imageBox').unbind();
1244					// ^ Why? Because otherwise when the image is changing, the info pops out, not good!
1245					
1246					// Make the image the active image
1247					if ( !this.images.active(image) ) { return false; }
1248					
1249					// Check if we need to preload
1250					if ( image.width && image.height )
1251					{	// We don't
1252						// Continue to next step
1253						this.showImage(null, 2);
1254					}
1255					else
1256					{	// We do
1257						// Create preloader
1258						var preloader = new Image();
1259						// Set callback
1260						preloader.onload = function()
1261						{	// We have preloaded the image
1262							// Update image with our new info
1263							image.width  = preloader.width;
1264							image.height = preloader.height;
1265							// Continue to next step
1266							$.Lightbox.showImage(null, 2);
1267							// Kill preloader
1268							preloader.onload = null;
1269							preloader = null;
1270						};
1271						// Start preload
1272						preloader.src = image.src;
1273					}
1274					
1275					// Done
1276					break;
1277				
1278				
1279				// ---------------------------------
1280				// Resize the container
1281				case 2:
1282					
1283					// Apply image changes
1284					$('#lightbox-image').attr('src', image.src);
1285					
1286					// Set container border (Moved here for Konqueror fix - Credits to Blueyed)
1287					if ( typeof this.padding === 'undefined' || this.padding === null || isNaN(this.padding) )
1288					{	// Autodetect
1289						this.padding = parseInt($('#lightbox-imageContainer').css('padding-left'), 10) || parseInt($('#lightbox-imageContainer').css('padding'), 10) || 0;
1290					}
1291					
1292					// Use colorBlend?
1293					if ( this.colorBlend )
1294					{	// We have colorBlend
1295						// Background
1296						$('#lightbox-overlay').animate({'backgroundColor':image.color}, this.speed*2);
1297						// Border
1298						$('#lightbox-imageBox').css('borderColor', image.color);
1299					}
1300					
1301					// Resize boxes
1302					this.resizeBoxes('transition');
1303					// ^ contains callback to next step
1304					
1305					// Done
1306					break;
1307				
1308				
1309				// ---------------------------------
1310				// Display the image
1311				case 3:
1312					
1313					// Hide loading
1314					$('#lightbox-loading').hide();
1315					
1316					// Animate image
1317					$('#lightbox-image').fadeIn(this.speed*1.5, function() {$.Lightbox.showImage(null, 4); });
1318					
1319					// Start the proloading of other images
1320					this.preloadNeighbours();
1321					
1322					// Fire custom handler show
1323					if ( this.handlers.show !== null )
1324					{	// Fire it
1325						this.handlers.show(image);
1326					}
1327					
1328					// Done
1329					break;
1330				
1331				
1332				// ---------------------------------
1333				// Set image info / Set navigation
1334				case 4:
1335					
1336					// ---------------------------------
1337					// Set image info
1338					
1339					// Hide and set image info
1340					var $title = $('#lightbox-caption-title').html(image.title || 'Untitled');
1341					if ( this.download_link )
1342					{	$title.attr('href', this.download_link ? image.src : '');	}
1343					delete $title;
1344					$('#lightbox-caption-seperator').html(image.description ? ': ' : '');
1345					$('#lightbox-caption-description').html(image.description || '&nbsp;');
1346					
1347					// If we have a set, display image position
1348					if ( this.images.size() > 1 )
1349					{	// Display
1350						$('#lightbox-currentNumber').html(this.text.image + '&nbsp;' + ( image.index + 1 ) + '&nbsp;' + this.text.of + '&nbsp;' + this.images.size());
1351					} else
1352					{	// Empty
1353						$('#lightbox-currentNumber').html('&nbsp;');
1354					}
1355					
1356					// ---------------------------------
1357					// Info events
1358					
1359					// Apply event
1360					$('#lightbox-imageBox').unbind('mouseover').mouseover(function(){
1361						$('#lightbox-infoBox:not(:visible)').stop().slideDown('fast');
1362					});
1363					
1364					// Apply event
1365					$('#lightbox-infoBox').unbind('mouseover').mouseover(function(){
1366						$('#lightbox-infoFooter:not(:visible)').stop().slideDown('fast');
1367					});
1368					
1369					// Forced show?
1370					if ( this.show_extended_info === true )
1371					{	// Force show
1372						$('#lightbox-imageBox').trigger('mouseover');
1373						$('#lightbox-infoBox').trigger('mouseover');
1374					}
1375					else if ( this.show_info === true )
1376					{	// Force show
1377						$('#lightbox-imageBox').trigger('mouseover');
1378					}
1379					
1380					// ---------------------------------
1381					// Set navigation
1382		
1383					// Instead to define this configuration in CSS file, we define here. And it's need to IE. Just.
1384					$('#lightbox-nav-btnPrev, #lightbox-nav-btnNext').css({ 'background' : 'transparent url(' + this.files.images.blank + ') no-repeat' });
1385					
1386					// If not first, show previous button
1387					if ( !this.images.first(image) ) {
1388						// Not first, show button
1389						$('#lightbox-nav-btnPrev').show();
1390					}
1391					
1392					// If not last, show next button
1393					if ( !this.images.last(image) ) {
1394						// Not first, show button
1395						$('#lightbox-nav-btnNext').show();
1396					}
1397					
1398					// Make navigation active / show it
1399					$('#lightbox-nav').show();
1400					
1401					// Enable keyboard navigation
1402					this.KeyboardNav_Enable();
1403					
1404					// Done
1405					break;
1406					
1407					
1408				// ---------------------------------
1409				// Error handling
1410				default:
1411					$.console.error('Don\'t know what to do: ', image, step);
1412					return this.showImage(image, 1);
1413					// break;
1414				
1415			}
1416			
1417			// All done
1418			return true;
1419		},
1420		
1421		preloadNeighbours: function ( )
1422		{	// Preload all neighbour images
1423			
1424			// Do we need to do this?
1425			if ( this.images.single() || this.images.empty() )
1426			{	return true;	}
1427			
1428			// Get active image
1429			var image = this.images.active();
1430			if ( !image ) { return image; }
1431			
1432			// Load previous
1433			var prev = this.images.prev(image);
1434			var objNext;
1435			if ( prev ) {
1436				objNext = new Image();
1437				objNext.src = prev.src;
1438			}
1439			
1440			// Load next
1441			var next = this.images.next(image);
1442			if ( next ) {
1443				objNext = new Image();
1444				objNext.src = next.src;
1445			}
1446		},
1447		
1448		// --------------------------------------------------
1449		// Things we don't really care about
1450		
1451		KeyboardNav_Enable: function ( ) {
1452			$(document).keydown(function(objEvent) {
1453				$.Lightbox.KeyboardNav_Action(objEvent);
1454			});
1455		},
1456		
1457		KeyboardNav_Disable: function ( ) {
1458			$(document).unbind('keydown');
1459		},
1460		
1461		KeyboardNav_Action: function ( objEvent ) {
1462			// Prepare
1463			objEvent = objEvent || window.event;
1464			
1465			// Get the keycode
1466			var keycode = objEvent.keyCode;
1467			var escapeKey = objEvent.DOM_VK_ESCAPE /* moz */ || 27;
1468			
1469			// Get key
1470			var key = String.fromCharCode(keycode).toLowerCase();
1471			
1472			// Close?
1473			if ( key === this.keys.close || keycode === escapeKey )
1474			{	return $.Lightbox.finish();		}
1475			
1476			// Prev?
1477			if ( key === this.keys.prev || keycode === 37 )
1478			{	// We want previous
1479				return $.Lightbox.showImage($.Lightbox.images.prev());
1480			}
1481			
1482			// Next?
1483			if ( key === this.keys.next || keycode === 39 )
1484			{	// We want next
1485				return $.Lightbox.showImage($.Lightbox.images.next());
1486			}
1487			
1488			// Unknown
1489			return true;
1490		},
1491		
1492		getPageScroll: function ( ) {
1493			var xScroll, yScroll;
1494			if (self.pageYOffset)
1495			{	// Some browser
1496				yScroll = self.pageYOffset;
1497				xScroll = self.pageXOffset;
1498			} else if (document.documentElement && document.documentElement.scrollTop)
1499			{	// Explorer 6 Strict
1500				yScroll = document.documentElement.scrollTop;
1501				xScroll = document.documentElement.scrollLeft;
1502			} else if (document.body)
1503			{	// All other browsers
1504				yScroll = document.body.scrollTop;
1505				xScroll = document.body.scrollLeft;	
1506			}
1507			var arrayPageScroll = {'xScroll':xScroll,'yScroll':yScroll};
1508			return arrayPageScroll;
1509		},
1510		
1511		pause: function ( ms ) {
1512			var date = new Date();
1513			var curDate = null;
1514			do { curDate = new Date(); }
1515			while ( curDate - date < ms);
1516		}
1517	
1518	}); // We have finished extending/defining our LightboxClass
1519
1520
1521	// --------------------------------------------------
1522	// Finish up
1523	
1524	// Instantiate
1525	if ( typeof $.Lightbox === 'undefined' )
1526	{	// 
1527		$.Lightbox = new $.LightboxClass();
1528	}
1529
1530// Finished definition
1531
1532})(jQuery); // We are done with our plugin, so lets call it with jQuery as the argument

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.