PageSourceSearch

https://volga-dnepr.com/bitrix/templates/main_eng/js/highslide/highslide.js

js volga-dnepr.com collected 2026-10-02 11:17:48 UTC 50,894 bytes, 1,892 lines download raw bytes

1/** 
2 * Name:    Highslide JS
3 * Version: 4.1.13 (2011-10-06)
4 * Config:  default
5 * Author:  Torstein Hønsi
6 * Support: www.highslide.com/support
7 * License: www.highslide.com/#license
8 */
9if (!hs) { 
10var hs = {
11// Language strings
12lang : {
13	cssDirection: 'ltr',
14	loadingText : 'Loading...',
15	loadingTitle : 'Click to cancel',
16	focusTitle : 'Click to bring to front',
17	fullExpandTitle : 'Expand to actual size (f)',
18	creditsText : 'Powered by <i>Highslide JS</i>',
19	creditsTitle : 'Go to the Highslide JS homepage',
20	restoreTitle : 'Click to close image, click and drag to move. Use arrow keys for next and previous.'
21},
22// See http://highslide.com/ref for examples of settings  
23graphicsDir : 'graphics/',
24expandCursor : 'zoomin.cur', // null disables
25restoreCursor : 'zoomout.cur', // null disables
26expandDuration : 150, // milliseconds
27restoreDuration : 150,
28marginLeft : 15,
29marginRight : 15,
30marginTop : 15,
31marginBottom : 15,
32zIndexCounter : 1001, // adjust to other absolutely positioned elements
33loadingOpacity : 0.75,
34allowMultipleInstances: true,
35numberOfImagesToPreload : 5,
36outlineWhileAnimating : 2, // 0 = never, 1 = always, 2 = HTML only 
37outlineStartOffset : 3, // ends at 10
38padToMinWidth : false, // pad the popup width to make room for wide caption
39fullExpandPosition : 'bottom right',
40fullExpandOpacity : 1,
41showCredits : false, // you can set this to false if you want
42creditsHref : 'http://highslide.com/',
43creditsTarget : '_self',
44enableKeyListener : true,
45openerTagNames : ['a'], // Add more to allow slideshow indexing
46
47dragByHeading: true,
48minWidth: 200,
49minHeight: 200,
50allowSizeReduction: true, // allow the image to reduce to fit client size. If false, this overrides minWidth and minHeight
51outlineType : 'drop-shadow', // set null to disable outlines
52// END OF YOUR SETTINGS
53
54
55// declare internal properties
56preloadTheseImages : [],
57continuePreloading: true,
58expanders : [],
59overrides : [
60	'allowSizeReduction',
61	'useBox',
62	'outlineType',
63	'outlineWhileAnimating',
64	'captionId',
65	'captionText',
66	'captionEval',
67	'captionOverlay',
68	'headingId',
69	'headingText',
70	'headingEval',
71	'headingOverlay',
72	'creditsPosition',
73	'dragByHeading',
74	
75	'width',
76	'height',
77	
78	'wrapperClassName',
79	'minWidth',
80	'minHeight',
81	'maxWidth',
82	'maxHeight',
83	'pageOrigin',
84	'slideshowGroup',
85	'easing',
86	'easingClose',
87	'fadeInOut',
88	'src'
89],
90overlays : [],
91idCounter : 0,
92oPos : {
93	x: ['leftpanel', 'left', 'center', 'right', 'rightpanel'],
94	y: ['above', 'top', 'middle', 'bottom', 'below']
95},
96mouse: {},
97headingOverlay: {},
98captionOverlay: {},
99timers : [],
100
101pendingOutlines : {},
102clones : {},
103onReady: [],
104uaVersion: /Trident\/4\.0/.test(navigator.userAgent) ? 8 :
105	parseFloat((navigator.userAgent.toLowerCase().match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1]),
106ie : (document.all && !window.opera),
107//ie : navigator && /MSIE [678]/.test(navigator.userAgent), // ie9 compliant?
108safari : /Safari/.test(navigator.userAgent),
109geckoMac : /Macintosh.+rv:1\.[0-8].+Gecko/.test(navigator.userAgent),
110
111$ : function (id) {
112	if (id) return document.getElementById(id);
113},
114
115push : function (arr, val) {
116	arr[arr.length] = val;
117},
118
119createElement : function (tag, attribs, styles, parent, nopad) {
120	var el = document.createElement(tag);
121	if (attribs) hs.extend(el, attribs);
122	if (nopad) hs.setStyles(el, {padding: 0, border: 'none', margin: 0});
123	if (styles) hs.setStyles(el, styles);
124	if (parent) parent.appendChild(el);	
125	return el;
126},
127
128extend : function (el, attribs) {
129	for (var x in attribs) el[x] = attribs[x];
130	return el;
131},
132
133setStyles : function (el, styles) {
134	for (var x in styles) {
135		if (hs.ieLt9 && x == 'opacity') {
136			if (styles[x] > 0.99) el.style.removeAttribute('filter');
137			else el.style.filter = 'alpha(opacity='+ (styles[x] * 100) +')';
138		}
139		else el.style[x] = styles[x];		
140	}
141},
142animate: function(el, prop, opt) {
143	var start,
144		end,
145		unit;
146	if (typeof opt != 'object' || opt === null) {
147		var args = arguments;
148		opt = {
149			duration: args[2],
150			easing: args[3],
151			complete: args[4]
152		};
153	}
154	if (typeof opt.duration != 'number') opt.duration = 250;
155	opt.easing = Math[opt.easing] || Math.easeInQuad;
156	opt.curAnim = hs.extend({}
156, prop);
157	for (var name in prop) {
158		var e = new hs.fx(el, opt , name );
159		
160		start = parseFloat(hs.css(el, name)) || 0;
161		end = parseFloat(prop[name]);
162		unit = name != 'opacity' ? 'px' : '';
163		
164		e.custom( start, end, unit );
165	}	
166},
167css: function(el, prop) {
168	if (el.style[prop]) {
169		return el.style[prop];
170	} else if (document.defaultView) {
171		return document.defaultView.getComputedStyle(el, null).getPropertyValue(prop);
172
173	} else {
174		if (prop == 'opacity') prop = 'filter';
175		var val = el.currentStyle[prop.replace(/\-(\w)/g, function (a, b){ return b.toUpperCase(); })];
176		if (prop == 'filter') 
177			val = val.replace(/alpha\(opacity=([0-9]+)\)/, 
178				function (a, b) { return b / 100 });
179		return val === '' ? 1 : val;
180	} 
181},
182
183getPageSize : function () {
184	var d = document, w = window, iebody = d.compatMode && d.compatMode != 'BackCompat' 
185		? d.documentElement : d.body,
186		ieLt9 = hs.ie && (hs.uaVersion < 9 || typeof pageXOffset == 'undefined');
187	
188	var width = ieLt9 ? iebody.clientWidth : 
189			(d.documentElement.clientWidth || self.innerWidth),
190		height = ieLt9 ? iebody.clientHeight : self.innerHeight;
191	hs.page = {
192		width: width,
193		height: height,		
194		scrollLeft: ieLt9 ? iebody.scrollLeft : pageXOffset,
195		scrollTop: ieLt9 ? iebody.scrollTop : pageYOffset
196	};
197	return hs.page;
198},
199
200getPosition : function(el)	{
201	var p = { x: el.offsetLeft, y: el.offsetTop };
202	while (el.offsetParent)	{
203		el = el.offsetParent;
204		p.x += el.offsetLeft;
205		p.y += el.offsetTop;
206		if (el != document.body && el != document.documentElement) {
207			p.x -= el.scrollLeft;
208			p.y -= el.scrollTop;
209		}
210	}
211	return p;
212},
213
214expand : function(a, params, custom, type) {
215	if (!a) a = hs.createElement('a', null, { display: 'none' }, hs.container);
216	if (typeof a.getParams == 'function') return params;	
217	try {	
218		new hs.Expander(a, params, custom);
219		return false;
220	} catch (e) { return true; }
221},
222
223
224focusTopmost : function() {
225	var topZ = 0, 
226		topmostKey = -1,
227		expanders = hs.expanders,
228		exp,
229		zIndex;
230	for (var i = 0; i < expanders.length; i++) {
231		exp = expanders[i];
232		if (exp) {
233			zIndex = exp.wrapper.style.zIndex;
234			if (zIndex && zIndex > topZ) {
235				topZ = zIndex;				
236				topmostKey = i;
237			}
238		}
239	}
240	if (topmostKey == -1) hs.focusKey = -1;
241	else expanders[topmostKey].focus();
242},
243
244getParam : function (a, param) {
245	a.getParams = a.onclick;
246	var p = a.getParams ? a.getParams() : null;
247	a.getParams = null;
248	
249	return (p && typeof p[param] != 'undefined') ? p[param] : 
250		(typeof hs[param] != 'undefined' ? hs[param] : null);
251},
252
253getSrc : function (a) {
254	var src = hs.getParam(a, 'src');
255	if (src) return src;
256	return a.href;
257},
258
259getNode : function (id) {
260	var node = hs.$(id), clone = hs.clones[id], a = {};
261	if (!node && !clone) return null;
262	if (!clone) {
263		clone = node.cloneNode(true);
264		clone.id = '';
265		hs.clones[id] = clone;
266		return node;
267	} else {
268		return clone.cloneNode(true);
269	}
270},
271
272discardElement : function(d) {
273	if (d) hs.garbageBin.appendChild(d);
274	hs.garbageBin.innerHTML = '';
275},
276transit : function (adj, exp) {
277	var last = exp || hs.getExpander();
278	exp = last;
279	if (hs.upcoming) return false;
280	else hs.last = last;
281	hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
282	try {
283		hs.upcoming = adj;
284		adj.onclick(); 		
285	} catch (e){
286		hs.last = hs.upcoming = null;
287	}
288	try {
289		exp.close();
290	} catch (e) {}
291	return false;
292},
293
294previousOrNext : function (el, op) {
295	var exp = hs.getExpander(el);
296	if (exp) return hs.transit(exp.getAdjacentAnchor(op), exp);
297	else return false;
298},
299
300previous : function (el) {
301	return hs.previousOrNext(el, -1);
302},
303
304next : function (el) {
305	return hs.previousOrNext(el, 1);	
306},
307
308keyHandler : function(e) {
309	if (!e) e = window.event;
310	if (!e.target) e.target = e.srcElement; // ie
311	if (typeof e.target.form != 'undefined') return true; // form element has focus
312	var exp = hs.getExpander();
313	
314	var op = null;
315	switch (e.keyCode) {
316		case 70: // f
317			if (exp) exp.doFullExpand();
318			return true;
319		case 32: // Space
320		case 34: // Page Down
321		case 39: // Arrow right
322		case 40: // Arrow down
323			op = 1;
324			break;
325		case 8:  // Backspace
326		case 33: // Page Up
327		case 37: // Arrow left
328		case 38: // Arrow up
329			op = -1;
330			break;
331		case 27: // Escape
332		case 13: // Enter
333			op = 0;
334	}
335	if (op !== null) {hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
336		if (!hs.enableKeyListener) return true;
337		
338		if (e.preventDefault) e.preventDefault();
339    	else e.returnValue = false;
340    	if (exp) {
341			if (op == 0) {
342				exp.close();
343			} else {
344				hs.previousOrNext(exp.key, op);
345			}
346			return false;
347		}
348	}
349	return true;
350},
351
352
353registerOverlay : function (overlay) {
354	hs.push(hs.overlays, hs.extend(overlay, { hsId: 'hsId'+ hs.idCounter++ } ));
355},
356
357
358getWrapperKey : function (element, expOnly) {
359	var el, re = /^highslide-wrapper-([0-9]+)$/;
360	// 1. look in open expanders
361	el = element;
362	while (el.parentNode)	{
363		if (el.id && re.test(el.id)) return el.id.replace(re, "$1");
364		el = el.parentNode;
365	}
366	// 2. look in thumbnail
367	if (!expOnly) {
368		el = element;
369		while (el.parentNode)	{
370			if (el.tagName && hs.isHsAnchor(el)) {
371				for (var key = 0; key < hs.expanders.length; key++) {
372					var exp = hs.expanders[key];
373					if (exp && exp.a == el) return key;
374				}
375			}
376			el = el.parentNode;
377		}
378	}
379	return null; 
380},
381
382getExpander : function (el, expOnly) {
383	if (typeof el == 'undefined') return hs.expanders[hs.focusKey] || null;
384	if (typeof el == 'number') return hs.expanders[el] || null;
385	if (typeof el == 'string') el = hs.$(el);
386	return hs.expanders[hs.getWrapperKey(el, expOnly)] || null;
387},
388
389isHsAnchor : function (a) {
390	return (a.onclick && a.onclick.toString().replace(/\s/g, ' ').match(/hs.(htmlE|e)xpand/));
391},
392
393reOrder : function () {
394	for (var i = 0; i < hs.expanders.length; i++)
395		if (hs.expanders[i] && hs.expanders[i].isExpanded) hs.focusTopmost();
396},
397
398mouseClickHandler : function(e) 
399{	
400	if (!e) e = window.event;
401	if (e.button > 1) return true;
402	if (!e.target) e.target = e.srcElement;
403	
404	var el = e.target;
405	while (el.parentNode
406		&& !(/highslide-(image|move|html|resize)/.test(el.className)))
407	{
408		el = el.parentNode;
409	}
410	var exp = hs.getExpander(el);
411	if (exp && (exp.isClosing || !exp.isExpanded)) return true;
412		
413	if (exp && e.type == 'mousedown') {
414		if (e.target.form) return true;
415		var match = el.className.match(/highslide-(image|move|resize)/);
416		if (match) {
417			hs.dragArgs = { 
418				exp: exp , 
419				type: match[1], 
420				left: exp.x.pos, 
421				width: exp.x.size, 
422				top: exp.y.pos, 
423				height: exp.y.size, 
424				clickX: e.clientX, 
425				clickY: e.clientY
426			};
427			
428			
429			hs.addEventListener(document, 'mousemove', hs.dragHandler);
430			if (e.preventDefault) e.preventDefault(); // FF
431			
432			if (/highslide-(image|html)-blur/.test(exp.content.className)) {
433				exp.focus();
434				hs.hasFocused = true;
435			}
436			return false;
437		}
438	} else if (e.type == 'mouseup') {
439		
440		hs.removeEventListener(document, 'mousemove', hs.dragHandler);
441		
442		if (hs.dragArgs) {
443			if (hs.styleRestoreCursor && hs.dragArgs.type == 'image') 
444				hs.dragArgs.exp.content.style.cursor = hs.styleRestoreCursor;
445			var hasDragged = hs.dragArgs.hasDragged;
446			
447			if (!hasDragged &&!hs.hasFocused && !/(move|resize)/.test(hs.dragArgs.type)) {
448				exp.close();
449			} 
450			else if (hasDragged || (!hasDragged && hs.hasHtmlExpanders)) {
451				hs.dragArgs.exp.doShowHide('hidden');
452			}
453			hs.hasFocused = false;
454			hs.dragArgs = null;
455		
456		} else if (/highslide-image-blur/.test(el.className)) {
457			el.style.cursor = hs.styleRestoreCursor;		
458		}
459	}
460	return false;
461},
462
463dragHandler : function(e)
464{
465	if (!hs.dragArgs) return true;
466	if (!e) e = window.event;
467	var a = hs.dragArgs, exp = a.exp;
468	
469	a.dX = e.clientX - a.clickX;
470	a.dY = e.clientY - a.clickY;	
471	
472	var distance = Math.sqrt(Math.pow(a.dX, 2) + Math.pow(a.dY, 2));
473	if (!a.hasDragged) a.hasDragged = (a.type != 'image' && distance > 0)
474		|| (distance > (hs.dragSensitivity || 5));
475	
476	if (a.hasDragged && e.clientX > 5 && e.clientY > 5) {
477		
478		if (a.type == 'resize') exp.resize(a);
479		else {
480			exp.moveTo(a.left + a.dX, a.top + a.dY);
481			if (a.type == 'image') exp.content.style.cursor = 'move';
482		}
483	}
484	return false;
485},
486
487wrapperMouseHandler : function (e) {
488	try {
489		if (!e) e = window.event;
490		var over = /mouseover/i.test(e.type); 
491		if (!e.target) e.target = e.srcElement; // ie
492		if (!e.relatedTarget) e.relatedTarget = 
493			over ? e.fromElement : e.toElement; // ie
494		var exp = hs.getExpander(e.target);
495		if (!exp.isExpanded) return;
496		if (!exp || !e.relatedTarget || hs.getExpander(e.relatedTarget, true) == exp 
497			|| hs.dragArgs) return;
498		for (var i = 0; i < exp.overlays.length; i++) (function() {
499			var o = hs.$('hsId'+ exp.overlays[i]);
500			if (o && o.hideOnMouseOut) {
501				if (over) hs.setStyles(o, { visibility: 'visible', display: '' });
502				hs.animate(o, { opacity: over ? o.opacity : 0 }, o.dur);
503			}
504		})();	
505	} catch (e) {}
506},
507addEventListener : function (el, event, func) {
508	if (el == document && event == 'ready') {
509		hs.push(hs.onReady, func);
510	}
511	try {
512		el.addEventListener(event, func, false);
513	} catch (e) {
514		try {
515			el.detachEvent('on'+ event, func);
516			el.attachEvent('on'+ event, func);
517		} catch (e) {
518			el['on'+ event] = func;
519		}
520	} 
521},
522
523removeEventListener : function (el, event, func) {
524	try {
525		el.removeEventListener(event, func, false);
526	} catch (e) {
527		try {
528			el.detachEvent('on'+ event, func);
529		} catch (e) {
530			el['on'+ event] = null;
531		}
532	}
533},
534
535preloadFullImage : function (i) {
536	if (hs.continuePreloading && hs.preloadTheseImages[i] && hs.preloadTheseImages[i] != 'undefined') {
537		var img = document.createElement('img');
538		img.onload = function() { 
539			img = null;
540			hs.preloadFullImage(i + 1);
541		};
542		img.src = hs.preloadTheseImages[i];
543	}
544},
545preloadImages : function (number) {
546	if (number && typeof number != 'object') hs.numberOfImagesToPreload = number;
547	
548	var arr = hs.getAnchors();
549	for (var i = 0; i < arr.images.length && i < hs.numberOfImagesToPreload; i++) {
550		hs.push(hs.preloadTheseImages, hs.getSrc(arr.images[i]));
551	}
552	
553	// preload outlines
554	if (hs.outlineType)	new hs.Outline(hs.outlineType, function () { hs.preloadFullImage(0)} );
555	else
556	
557	hs.preloadFullImage(0);
558	
559	// preload cursor
560	if (hs.restoreCursor) var cur = hs.createElement('img', { src: hs.graphicsDir + hs.restoreCursor });
561},
562
563
564init : function () {
565	if (!hs.container) {
566	
567		hs.ieLt7 = hs.ie && hs.uaVersion < 7;
568		hs.ieLt9 = hs.ie && hs.uaVersion < 9;
569		
570		hs.getPageSize();
571		for (var x in hs.langDefaults) {
572			if (typeof hs[x] != 'undefined') hs.lang[x] = hs[x];
573			else if (typeof hs.lang[x] == 'undefined' && typeof hs.langDefaults[x] != 'undefined') 
574				hs.lang[x] = hs.langDefaults[x];
575		}
576		
577		hs.container = hs.createElement('div', {
578				className: 'highslide-container'
579			}, {
580				position: 'absolute',
581				left: 0, 
582				top: 0, 
583				width: '100%', 
584				zIndex: hs.zIndexCounter,
585				direction: 'ltr'
586			}, 
587			document.body,
588			true
589		);
590		hs.loading = hs.createElement('a', {
591				className: 'highslide-loading',
592				title: hs.lang.loadingTitle,
593				innerHTML: hs.lang.loadingText,
594				href: 'javascript:;'
595			}, {
596				position: 'absolute',
597				top: '-9999px',
598				opacity: hs.loadingOpacity,
599				zIndex: 1
600			}, hs.container
601		);
602		hs.garbageBin = hs.createElement('div', null, { display: 'none' }, hs.container);
603		
604		// http://www.robertpenner.com/easing/ 
605		Math.linearTween = function (t, b, c, d) {
606			return c*t/d + b;
607		};
608		Math.easeInQuad = function (t, b, c, d) {
609			return c*(t/=d)*t + b;
610		};
611		
612		hs.hideSelects = hs.ieLt7;
613		hs.hideIframes = ((window.opera && hs.uaVersion < 9) || navigator.vendor == 'KDE' 
614			|| (hs.ieLt7 && hs.uaVersion < 5.5));
615	}
616},
617ready : function() {
618	if (hs.isReady) return;
619	hs.isReady = true;
620	for (var i = 0; i < hs.onReady.length; i++) hs.onReady[i]();
621},
622
623updateAnchors : function() {
624	var el, els, all = [], images = [],groups = {}, re;
625		
626	for (var i = 0; i < hs.openerTagNames.length; i++) {
627		els = document.getElementsByTagName(hs.openerTagNames[i]);
628		for (var j = 0; j < els.length; j++) {
629			el = els[j];
630			re = hs.isHsAnchor(el);
631			if (re) {
632				hs.push(all, el);
633				if (re[0] == 'hs.expand') hs.push(images, el);
634				var g = hs.getParam(el, 'slideshowGroup') || 'none';
635				if (!groups[g]) groups[g] = [];
636				hs.push(groups[g], el);
637			}
638		}
639	}
640	hs.anchors = { all: all, groups: groups, images: images };
641	return hs.anchors;
642	
643},
644
645getAnchors : function() {
646	return hs.anchors || hs.updateAnchors();
647},
648
649
650close : function(el) {
651	var exp = hs.getExpander(el);
652	if (exp) exp.close();
653	return false;
654}
655}; // end hs object
656hs.fx = function( elem, options, prop ){
657	this.options = options;
658	this.elem = elem;
659	this.prop = prop;
660
661	if (!options.orig) options.orig = {};
662};
663hs.fx.prototype = {
664	update: function(){
665		(hs.fx.step[this.prop] || hs.fx.step._default)(this);
666		
667		if (this.options.step)
668			this.options.step.call(this.elem, this.now, this);
669
670	},
671	custom: function(from, to, unit){
672		this.startTime = (new Date()).getTime();
673		this.start = from;
674		this.end = to;
675		this.unit = unit;// || this.unit || "px";
676		this.now = this.start;
677		this.pos = this.state = 0;
678
679		var self = this;
680		function t(gotoEnd){
681			return self.step(gotoEnd);
682		}
683
684		t.elem = this.elem;
685
686		if ( t() && hs.timers.push(t) == 1 ) {
687			hs.timerId = setInterval(function(){
688				var timers = hs.timers;
689
690				for ( var i = 0; i < timers.length; i++ )
691					if ( !timers[i]() )
692						timers.splice(i--, 1);
693
694				if ( !timers.length ) {
695					clearInterval(hs.timerId);
696				}
697			}, 13);
698		}
699	},
700	step: function(gotoEnd){
701		var t = (new Date()).getTime();
702		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
703			this.now = this.end;
704			this.pos = this.state = 1;
705			this.update();
706
707			this.options.curAnim[ this.prop ] = true;
708
709			var done = true;
710			for ( var i in this.options.curAnim )
711				if ( this.options.curAnim[i] !== true )
712					done = false;
713
714			if ( done ) {
715				if (this.options.complete) this.options.complete.call(this.elem);
716			}
717			return false;
718		} else {
719			var n = t - this.startTime;
720			this.state = n / this.options.duration;
721			this.pos = this.options.easing(n, 0, 1, this.options.duration);
722			this.now = this.start + ((this.end - this.start) * this.pos);
723			this.update();
724		}
725		return true;
726	}
727
728};
729
730hs.extend( hs.fx, {
731	step: {
732
733		opacity: function(fx){
734			hs.setStyles(fx.elem, { opacity: fx.now });
735		},
736
737		_default: function(fx){
738			try {
739				if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
740					fx.elem.style[ fx.prop ] = fx.now + fx.unit;
741				else
742					fx.elem[ fx.prop ] = fx.now;
743			} catch (e) {}
744		}
745	}
746});
747
748hs.Outline =  function (outlineType, onLoad) {
749	this.onLoad = onLoad;
750	this.outlineType = outlineType;
751	var v = hs.uaVersion, tr;
752	
753	this.hasAlphaImageLoader = hs.ie && hs.uaVersion < 7;
754	if (!outlineType) {
755		if (onLoad) onLoad();
756		return;
757	}
758	
759	hs.init();
760	this.table = hs.createElement(
761		'table', { 
762			cellSpacing: 0 
763		}, {
764			visibility: 'hidden',
765			position: 'absolute',
766			borderCollapse: 'collapse',
767			width: 0
768		},
769		hs.container,
770		true
771	);
772	var tbody = hs.createElement('tbody', null, null, this.table, 1);
773	
774	this.td = [];
775	for (var i = 0; i <= 8; i++) {
776		if (i % 3 == 0) tr = hs.createElement('tr', null, { height: 'auto' }, tbody, true);
777		this.td[i] = hs.createElement('td', null, null, tr, true);
778		var style = i != 4 ? { lineHeight: 0, fontSize: 0} : { position : 'relative' };
779		hs.setStyles(this.td[i], style);
780	}
781	this.td[4].className = outlineType +' highslide-outline';
782	
783	this.preloadGraphic(); 
784};
785
786hs.Outline.prototype = {
787preloadGraphic : function () {
788	var src = hs.graphicsDir + (hs.outlinesDir || "outlines/")+ this.outlineType +".png";
789				
790	var appendTo = hs.safari && hs.uaVersion < 525 ? hs.container : null;
791	this.graphic = hs.createElement('img', null, { position: 'absolute', 
792		top: '-9999px' }, appendTo, true); // for onload trigger
793	
794	var pThis = this;
795	this.graphic.onload = function() { pThis.onGraphicLoad(); };
796	
797	this.graphic.src = src;
798},
799
800onGraphicLoad : function () {
801	var o = this.offset = this.graphic.width / 4,
802		pos = [[0,0],[0,-4],[-2,0],[0,-8],0,[-2,-8],[0,-2],[0,-6],[-2,-2]],
803		dim = { height: (2*o) +'px', width: (2*o) +'px' };
804	for (var i = 0; i <= 8; i++) {
805		if (pos[i]) {
806			if (this.hasAlphaImageLoader) {
807				var w = (i == 1 || i == 7) ? '100%' : this.graphic.width +'px';
808				var div = hs.createElement('div', null, { width: '100%', height: '100%', position: 'relative', overflow: 'hidden'}, this.td[i], true);
809				hs.createElement ('div', null, { 
810						filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale, src='"+ this.graphic.src + "')", 
811						position: 'absolute',
812						width: w, 
813						height: this.graphic.height +'px',
814						left: (pos[i][0]*o)+'px',
815						top: (pos[i][1]*o)+'px'
816					}, 
817				div,
818				true);
819			} else {
820				hs.setStyles(this.td[i], { background: 'url('+ this.graphic.src +') '+ (pos[i][0]*o)+'px '+(pos[i][1]*o)+'px'});
821			}
822			
823			if (window.opera && (i == 3 || i ==5)) 
824				hs.createElement('div', null, dim, this.td[i], true);
825			
826			hs.setStyles (this.td[i], dim);
827		}
828	}
829	this.graphic = null;
830	if (hs.pendingOutlines[this.outlineType]) hs.pendingOutlines[this.outlineType].destroy();
831	hs.pendingOutlines[this.outlineType] = this;
832	if (this.onLoad) this.onLoad();
833},
834	
835setPosition : function (pos, offset, vis, dur, easing) {
836	var exp = this.exp,
837		stl = exp.wrapper.style,
838		offset = offset || 0,
839		pos = pos || {
840			x: exp.x.pos + offset,
841			y: exp.y.pos + offset,
842			w: exp.x.get('wsize') - 2 * offset,
843			h: exp.y.get('wsize') - 2 * offset
844		};
845	if (vis) this.table.style.visibility = (pos.h >= 4 * this.offset) 
846		? 'visible' : 'hidden';
847	hs.setStyles(this.table, {
848		left: (pos.x - this.offset) +'px',
849		top: (pos.y - this.offset) +'px',
850		width: (pos.w + 2 * this.offset) +'px'
851	});
852	
853	pos.w -= 2 * this.offset;
854	pos.h -= 2 * this.offset;
855	hs.setStyles (this.td[4], {
856		width: pos.w >= 0 ? pos.w +'px' : 0,
857		height: pos.h >= 0 ? pos.h +'px' : 0
858	});
859	if (this.hasAlphaImageLoader) this.td[3].style.height 
860		= this.td[5].style.height = this.td[4].style.height;	
861	
862},
863	
864destroy : function(hide) {
865	if (hide) this.table.style.visibility = 'hidden';
866	else hs.discardElement(this.table);
867}
868};
869
870hs.Dimension = function(exp, dim) {
871	this.exp = exp;
872	this.dim = dim;
873	this.ucwh = dim == 'x' ? 'Width' : 'Height';
874	this.wh = this.ucwh.toLowerCase();
875	this.uclt = dim == 'x' ? 'Left' : 'Top';
876	this.lt = this.uclt.toLowerCase();
877	this.ucrb = dim == 'x' ? 'Right' : 'Bottom';
878	this.rb = this.ucrb.toLowerCase();
879	this.p1 = this.p2 = 0;
880};
881hs.Dimension.prototype = {
882get : function(key) {
883	switch (key) {
884		case 'loadingPos':
885			return this.tpos + this.tb + (this.t - hs.loading['offset'+ this.ucwh]) / 2;
886		case 'wsize':
887			return this.size + 2 * this.cb + this.p1 + this.p2;
888		case 'fitsize':
889			return this.clientSize - this.marginMin - this.marginMax;
890		case 'maxsize':
891			return this.get('fitsize') - 2 * this.cb - this.p1 - this.p2 ;
892		case 'opos':
893			return this.pos - (this.exp.outline ? this.exp.outline.offset : 0);
894		case 'osize':
895			return this.get('wsize') + (this.exp.outline ? 2*this.exp.outline.offset : 0);
896		case 'imgPad':
897			return this.imgSize ? Math.round((this.size - this.imgSize) / 2) : 0;
898		
899	}
900},
901calcBorders: function() {
902	// correct for borders
903	this.cb = (this.exp.content['offset'+ this.ucwh] - this.t) / 2;
904	
905	this.marginMax = hs['margin'+ this.ucrb];
906},
907calcThumb: function() {
908	this.t = this.exp.el[this.wh] ? parseInt(this.exp.el[this.wh]) : 
909		this.exp.el['offset'+ this.ucwh];
910	this.tpos = this.exp.tpos[this.dim];
911	this.tb = (this.exp.el['offset'+ this.ucwh] - this.t) / 2;
912	if (this.tpos == 0 || this.tpos == -1) {
913		this.tpos = (hs.page[this.wh] / 2) + hs.page['scroll'+ this.uclt];		
914	};
915},
916calcExpanded: function() {
917	var exp = this.exp;
918	this.justify = 'auto';
919	
920	
921	// size and position
922	this.pos = this.tpos - this.cb + this.tb;
923	
924	if (this.maxHeight && this.dim == 'x')
925		exp.maxWidth = Math.min(exp.maxWidth || this.full, exp.maxHeight * this.full / exp.y.full); 
926		
927	this.size = Math.min(this.full, exp['max'+ this.ucwh] || this.full);
928	this.minSize = exp.allowSizeReduction ? 
929		Math.min(exp['min'+ this.ucwh], this.full) :this.full;
930	if (exp.isImage && exp.useBox)	{
931		this.size = exp[this.wh];
932		this.imgSize = this.full;
933	}
934	if (this.dim == 'x' && hs.padToMinWidth) this.minSize = exp.minWidth;
935	this.marginMin = hs['margin'+ this.uclt];
936	this.scroll = hs.page['scroll'+ this.uclt];
937	this.clientSize = hs.page[this.wh];
938},
939setSize: function(i) {
940	var exp = this.exp;
941	if (exp.isImage && (exp.useBox || hs.padToMinWidth)) {
942		this.imgSize = i;
943		this.size = Math.max(this.size, this.imgSize);
944		exp.content.style[this.lt] = this.get('imgPad')+'px';
945	} else
946	this.size = i;
947	
948	exp.content.style[this.wh] = i +'px';
949	exp.wrapper.style[this.wh] = this.get('wsize') +'px';
950	if (exp.outline) exp.outline.setPosition();
951	if (this.dim == 'x' && exp.overlayBox) exp.sizeOverlayBox(true);
952},
953setPos: function(i) {
954	this.pos = i;
955	this.exp.wrapper.style[this.lt] = i +'px';	
956	
957	if (this.exp.outline) this.exp.outline.setPosition();
958	
959}
960};
961
962hs.Expander = function(a, params, custom, contentType) {
963	if (document.readyState && hs.ie && !hs.isReady) {
964		hs.addEventListener(document, 'ready', function() {
965			new hs.Expander(a, params, custom, contentType);
966		});
967		return;
968	} 
969	this.a = a;
970	this.custom = custom;
971	this.contentType = contentType || 'image';
972	this.isImage = !this.isHtml;
973	
974	hs.continuePreloading = false;
975	this.overlays = [];
976	hs.init();
977	var key = this.key = hs.expanders.length;
978	// override inline parameters
979	for (var i = 0; i < hs.overrides.length; i++) {
980		var name = hs.overrides[i];
981		this[name] = params && typeof params[name] != 'undefined' ?
982			params[name] : hs[name];
983	}
984	if (!this.src) this.src = a.href;
985	
986	// get thumb
987	var el = (params && params.thumbnailId) ? hs.$(params.thumbnailId) : a;
988	el = this.thumb = el.getElementsByTagName('img')[0] || el;
989	this.thumbsUserSetId = el.id || a.id;
990	
991	// check if already open
992	for (var i = 0; i < hs.expanders.length; i++) {
993		if (hs.expanders[i] && hs.expanders[i].a == a) {
994			hs.expanders[i].focus();
995			return false;
996		}
997	}	
998
999	// cancel other
1000	if (!hs.allowSimultaneousLoading) for (var i = 0; i < hs.expanders.length; i++) {
1001		if (hs.expanders[i] && hs.expanders[i].thumb != el && !hs.expanders[i].onLoadStarted) {
1002			hs.expanders[i].cancelLoading();
1003		}
1004	}
1005	hs.expanders[key] = this;
1006	if (!hs.allowMultipleInstances && !hs.upcoming) {
1007		if (hs.expanders[key-1]) hs.expanders[key-1].close();
1008		if (typeof hs.focusKey != 'undefined' && hs.expanders[hs.focusKey])
1009			hs.expanders[hs.focusKey].close();
1010	}
1011	
1012	// initiate metrics
1013	this.el = el;
1014	this.tpos = this.pageOrigin || hs.getPosition(el);
1015	hs.getPageSize();
1016	var x = this.x = new hs.Dimension(this, 'x');
1017	x.calcThumb();
1018	var y = this.y = new hs.Dimension(this, 'y');
1019	y.calcThumb();
1020	this.wrapper = hs.createElement(
1021		'div', {
1022			id: 'highslide-wrapper-'+ this.key,
1023			className: 'highslide-wrapper '+ this.wrapperClassName
1024		}, {
1025			visibility: 'hidden',
1026			position: 'absolute',
1027			zIndex: hs.zIndexCounter += 2
1028		}, null, true );
1029	
1030	this.wrapper.onmouseover = this.wrapper.onmouseout = hs.wrapperMouseHandler;
1031	if (this.contentType == 'image' && this.outlineWhileAnimating == 2)
1032		this.outlineWhileAnimating = 0;
1033	
1034	// get the outline
1035	if (!this.outlineType) {
1036		this[this.contentType +'Create']();
1037	
1038	} else if (hs.pendingOutlines[this.outlineType]) {
1039		this.connectOutline();
1040		this[this.contentType +'Create']();
1041	
1042	} else {
1043		this.showLoading();
1044		var exp = this;
1045		new hs.Outline(this.outlineType, 
1046			function () {
1047				exp.connectOutline();
1048				exp[exp.contentType +'Create']();
1049			} 
1050		);
1051	}
1052	return true;
1053};
1054
1055hs.Expander.prototype = {
1056error : function(e) {
1057	if (hs.debug) alert ('Line '+ e.lineNumber +': '+ e.message);
1058	else window.location.href = this.src;
1059},
1060
1061connectOutline : function() {
1062	var outline = this.outline = hs.pendingOutlines[this.outlineType];
1063	outline.exp = this;
1064	outline.table.style.zIndex = this.wrapper.style.zIndex - 1;
1065	hs.pendingOutlines[this.outlineType] = null;
1066},
1067
1068showLoading : function() {
1069	if (this.onLoadStarted || this.loading) return;
1070	
1071	this.loading = hs.loading;
1072	var exp = this;
1073	this.loading.onclick = function() {
1074		exp.cancelLoading();
1075	};
1076	var exp = this, 
1077		l = this.x.get('loadingPos') +'px',
1078		t = this.y.get('loadingPos') +'px';
1079	setTimeout(function () { 
1080		if (exp.loading) hs.setStyles(exp.loading, { left: l, top: t, zIndex: hs.zIndexCounter++ })}
1081	, 100);
1082},
1083
1084imageCreate : function() {
1085	var exp = this;
1086	
1087	var img = document.createElement('img');
1088    this.content = img;
1089    img.onload = function () {
1090    	if (hs.expanders[exp.key]) exp.contentLoaded(); 
1091	};
1092    if (hs.blockRightClick) img.oncontextmenu = function() { return false; };
1093    img.className = 'highslide-image';
1094    hs.setStyles(img, {
1095    	visibility: 'hidden',
1096    	display: 'block',
1097    	position: 'absolute',
1098		maxWidth: '9999px',
1099		zIndex: 3
1100	});
1101    img.title = hs.lang.restoreTitle;
1102	if (hs.safari && hs.uaVersion < 525) hs.container.appendChild(img);
1103    if (hs.ie && hs.flushImgSize) img.src = null;
1104	img.src = this.src;
1105	
1106	this.showLoading();
1107},
1108
1109contentLoaded : function() {
1110	try {	
1111		if (!this.content) return;
1112		this.content.onload = null;
1113		if (this.onLoadStarted) return;
1114		else this.onLoadStarted = true;
1115		
1116		var x = this.x, y = this.y;
1117		
1118		if (this.loading) {
1119			hs.setStyles(this.loading, { top: '-9999px' });
1120			this.loading = null;
1121		}	
1122			x.full = this.content.width;
1123			y.full = this.content.height;
1124			
1125			hs.setStyles(this.content, {
1126				width: x.t +'px',
1127				height: y.t +'px'
1128			});
1129			this.wrapper.appendChild(this.content);
1130			hs.container.appendChild(this.wrapper);
1131		
1132		x.calcBorders();
1133		y.calcBorders();
1134		
1135		hs.setStyles (this.wrapper, {
1136			left: (x.tpos + x.tb - x.cb) +'px',
1137			top: (y.tpos + x.tb - y.cb) +'px'
1138		});
1139		this.getOverlays();
1140		
1141		var ratio = x.full / y.full;
1142		x.calcExpanded();
1143		this.justify(x);
1144		
1145		y.calcExpanded();
1146		this.justify(y);
1147		if (this.overlayBox) this.sizeOverlayBox(0, 1);
1148
1149		
1150		if (this.allowSizeReduction) {
1151				this.correctRatio(ratio);
1152			if (this.isImage && this.x.full > (this.x.imgSize || this.x.size)) {
1153				this.createFullExpand();
1154				if (this.overlays.length == 1) this.sizeOverlayBox();
1155			}
1156		}
1157		this.show();
1158		
1159	} catch (e) {
1160		this.error(e);
1161	}
1162},
1163
1164justify : function (p, moveOnly) {
1165	var tgtArr, tgt = p.target, dim = p == this.x ? 'x' : 'y';
1166	
1167		var hasMovedMin = false;
1168		
1169		var allowReduce = p.exp.allowSizeReduction;
1170			p.pos = Math.round(p.pos - ((p.get('wsize') - p.t) / 2));
1171		if (p.pos < p.scroll + p.marginMin) {
1172			p.pos = p.scroll + p.marginMin;
1173			hasMovedMin = true;		
1174		}
1175		if (!moveOnly && p.size < p.minSize) {
1176			p.size = p.minSize;
1177			allowReduce = false;
1178		}
1179		if (p.pos + p.get('wsize') > p.scroll + p.clientSize - p.marginMax) {
1180			if (!moveOnly && hasMovedMin && allowReduce) {
1181				p.size = Math.min(p.size, p.get(dim == 'y' ? 'fitsize' : 'maxsize'));
1182			} else if (p.get('wsize') < p.get('fitsize')) {
1183				p.pos = p.scroll + p.clientSize - p.marginMax - p.get('wsize');
1184			} else { // image larger than viewport
1185				p.pos = p.scroll + p.marginMin;
1186				if (!moveOnly && allowReduce) p.size = p.get(dim == 'y' ? 'fitsize' : 'maxsize');
1187			}			
1188		}
1189		
1190		if (!moveOnly && p.size < p.minSize) {
1191			p.size = p.minSize;
1192			allowReduce = false;
1193		}
1194		
1195	
1196		
1197	if (p.pos < p.marginMin) {
1198		var tmpMin = p.pos;
1199		p.pos = p.marginMin; 
1200		
1201		if (allowReduce && !moveOnly) p.size = p.size - (p.pos - tmpMin);
1202		
1203	}
1204},
1205
1206correctRatio : function(ratio) {
1207	var x = this.x, 
1208		y = this.y,
1209		changed = false,
1210		xSize = Math.min(x.full, x.size),
1211		ySize = Math.min(y.full, y.size),
1212		useBox = (this.useBox || hs.padToMinWidth);
1213	
1214	if (xSize / ySize > ratio) { // width greater
1215		xSize = ySize * ratio;
1216		if (xSize < x.minSize) { // below minWidth
1217			xSize = x.minSize;
1218			ySize = xSize / ratio;
1219		}
1220		changed = true;
1221	
1222	} else if (xSize / ySize < ratio) { // height greater
1223		ySize = xSize / ratio;
1224		changed = true;
1225	}
1226	
1227	if (hs.padToMinWidth && x.full < x.minSize) {
1228		x.imgSize = x.full;
1229		y.size = y.imgSize = y.full;
1230	} else if (this.useBox) {
1231		x.imgSize = xSize;
1232		y.imgSize = ySize;
1233	} else {
1234		x.size = xSize;
1235		y.size = ySize;
1236	}
1237	changed = this.fitOverlayBox(this.useBox ? null : ratio, changed);
1238	if (useBox && y.size < y.imgSize) {
1239		y.imgSize = y.size;
1240		x.imgSize = y.size * ratio;
1241	}
1242	if (changed || useBox) {
1243		x.pos = x.tpos - x.cb + x.tb;
1244		x.minSize = x.size;
1245		this.justify(x, true);
1246	
1247		y.pos = y.tpos - y.cb + y.tb;
1248		y.minSize = y.size;
1249		this.justify(y, true);
1250		if (this.overlayBox) this.sizeOverlayBox();
1251	}
1252	
1253	
1254},
1255fitOverlayBox : function(ratio, changed) {
1256	var x = this.x, y = this.y;
1257	if (this.overlayBox) {
1258		while (y.size > this.minHeight && x.size > this.minWidth 
1259				&&  y.get('wsize') > y.get('fitsize')) {
1260			y.size -= 10;
1261			if (ratio) x.size = y.size * ratio;
1262			this.sizeOverlayBox(0, 1);
1263			changed = true;
1264		}
1265	}
1266	return changed;
1267},
1268
1269show : function () {
1270	var x = this.x, y = this.y;
1271	this.doShowHide('hidden');
1272	
1273	// Apply size change
1274	this.changeSize(
1275		1, {
1276			wrapper: {
1277				width : x.get('wsize'),
1278				height : y.get('wsize'),
1279				left: x.pos,
1280				top: y.pos
1281			},
1282			content: {
1283				left: x.p1 + x.get('imgPad'),
1284				top: y.p1 + y.get('imgPad'),
1285				width:x.imgSize ||x.size,
1286				height:y.imgSize ||y.size
1287			}
1288		},
1289		hs.expandDuration
1290	);
1291},
1292
1293changeSize : function(up, to, dur) {
1294	
1295	if (this.outline && !this.outlineWhileAnimating) {
1296		if (up) this.outline.setPosition();
1297		else this.outline.destroy();
1298	}
1299	
1300	
1301	if (!up) this.destroyOverlays();
1302	
1303	var exp = this,
1304		x = exp.x,
1305		y = exp.y,
1306		easing = this.easing;
1307	if (!up) easing = this.easingClose || easing;
1308	var after = up ?
1309		function() {
1310				
1311			if (exp.outline) exp.outline.table.style.visibility = "visible";
1312			setTimeout(function() {
1313				exp.afterExpand();
1314			}, 50);
1315		} :
1316		function() {
1317			exp.afterClose();
1318		};
1319	if (up) hs.setStyles( this.wrapper, {
1320		width: x.t +'px',
1321		height: y.t +'px'
1322	});
1323	if (this.fadeInOut) {
1324		hs.setStyles(this.wrapper, { opacity: up ? 0 : 1 });
1325		hs.extend(to.wrapper, { opacity: up });
1326	}
1327	hs.animate( this.wrapper, to.wrapper, {
1328		duration: dur,
1329		easing: easing,
1330		step: function(val, args) {
1331			if (exp.outline && exp.outlineWhileAnimating && args.prop == 'top') {
1332				var fac = up ? args.pos : 1 - args.pos;
1333				var pos = {
1334					w: x.t + (x.get('wsize') - x.t) * fac,
1335					h: y.t + (y.get('wsize') - y.t) * fac,
1336					x: x.tpos + (x.pos - x.tpos) * fac,
1337					y: y.tpos + (y.pos - y.tpos) * fac
1338				};
1339				exp.outline.setPosition(pos, 0, 1);				
1340			}
1341		}
1342	});
1343	hs.animate( this.content, to.content, dur, easing, after);
1344	if (up) {
1345		this.wrapper.style.visibility = 'visible';
1346		this.content.style.visibility = 'visible';
1347		this.a.className += ' highslide-active-anchor';
1348	}
1349},
1350
1351
1352
1353
1354afterExpand : function() {
1355	this.isExpanded = true;	
1356	this.focus();
1357	if (hs.upcoming && hs.upcoming == this.a) hs.upcoming = null;
1358	this.prepareNextOutline();
1359	var p = hs.page, mX = hs.mouse.x + p.scrollLeft, mY = hs.mouse.y + p.scrollTop;
1360	this.mouseIsOver = this.x.pos < mX && mX < this.x.pos + this.x.get('wsize')
1361		&& this.y.pos < mY && mY < this.y.pos + this.y.get('wsize');	
1362	if (this.overlayBox) this.showOverlays();
1363	
1364},
1365
1366
1367prepareNextOutline : function() {
1368	var key = this.key;
1369	var outlineType = this.outlineType;
1370	new hs.Outline(outlineType, 
1371		function () { try { hs.expanders[key].preloadNext(); } catch (e) {} });
1372},
1373
1374
1375preloadNext : function() {
1376	var next = this.getAdjacentAnchor(1);
1377	if (next && next.onclick.toString().match(/hs\.expand/)) 
1378		var img = hs.createElement('img', { src: hs.getSrc(next) });
1379},
1380
1381
1382getAdjacentAnchor : function(op) {
1383	var current = this.getAnchorIndex(), as = hs.anchors.groups[this.slideshowGroup || 'none'];
1384	return (as && as[current + op]) || null;
1385},
1386
1387getAnchorIndex : function() {
1388	var arr = hs.getAnchors().groups[this.slideshowGroup || 'none'];
1389	if (arr) for (var i = 0; i < arr.length; i++) {
1390		if (arr[i] == this.a) return i; 
1391	}
1392	return null;
1393},
1394
1395
1396cancelLoading : function() {
1397	hs.discardElement (this.wrapper);
1398	hs.expanders[this.key] = null;
1399	if (this.loading) hs.loading.style.left = '-9999px';
1400},
1401
1402writeCredits : function () {
1403	this.credits = hs.createElement('a', {
1404		href: hs.creditsHref,
1405		target: hs.creditsTarget,
1406		className: 'highslide-credits',
1407		innerHTML: hs.lang.creditsText,
1408		title: hs.lang.creditsTitle
1409	});
1410	this.createOverlay({ 
1411		overlayId: this.credits, 
1412		position: this.creditsPosition || 'top left' 
1413	});
1414},
1415
1416getInline : function(types, addOverlay) {
1417	for (var i = 0; i < types.length; i++) {
1418		var type = types[i], s = null;
1419		if (!this[type +'Id'] && this.thumbsUserSetId)  
1420			this[type +'Id'] = type +'-for-'+ this.thumbsUserSetId;
1421		if (this[type +'Id']) this[type] = hs.getNode(this[type +'Id']);
1422		if (!this[type] && !this[type +'Text'] && this[type +'Eval']) try {
1423			s = eval(this[type +'Eval']);
1424		} catch (e) {}
1425		if (!this[type] && this[type +'Text']) {
1426			s = this[type +'Text'];
1427		}
1428		if (!this[type] && !s) {
1429			this[type] = hs.getNode(this.a['_'+ type + 'Id']);
1430			if (!this[type]) {
1431				var next = this.a.nextSibling;
1432				while (next && !hs.isHsAnchor(next)) {
1433					if ((new RegExp('highslide-'+ type)).test(next.className || null)) {
1434						if (!next.id) this.a['_'+ type + 'Id'] = next.id = 'hsId'+ hs.idCounter++;
1435						this[type] = hs.getNode(next.id);
1436						break;
1437					}
1438					next = next.nextSibling;
1439				}
1440			}
1441		}
1442		
1443		if (!this[type] && s) this[type] = hs.createElement('div', 
1444				{ className: 'highslide-'+ type, innerHTML: s } );
1445		
1446		if (addOverlay && this[type]) {
1447			var o = { position: (type == 'heading') ? 'above' : 'below' };
1448			for (var x in this[type+'Overlay']) o[x] = this[type+'Overlay'][x];
1449			o.overlayId = this[type];
1450			this.createOverlay(o);
1451		}
1452	}
1453},
1454
1455
1456// on end move and resize
1457doShowHide : function(visibility) {
1458	if (hs.hideSelects) this.showHideElements('SELECT', visibility);
1459	if (hs.hideIframes) this.showHideElements('IFRAME', visibility);
1460	if (hs.geckoMac) this.showHideElements('*', visibility);
1461},
1462showHideElements : function (tagName, visibility) {
1463	var els = document.getElementsByTagName(tagName);
1464	var prop = tagName == '*' ? 'overflow' : 'visibility';
1465	for (var i = 0; i < els.length; i++) {
1466		if (prop == 'visibility' || (document.defaultView.getComputedStyle(
1467				els[i], "").getPropertyValue('overflow') == 'auto'
1468				|| els[i].getAttribute('hidden-by') != null)) {
1469			var hiddenBy = els[i].getAttribute('hidden-by');
1470			if (visibility == 'visible' && hiddenBy) {
1471				hiddenBy = hiddenBy.replace('['+ this.key +']', '');
1472				els[i].setAttribute('hidden-by', hiddenBy);
1473				if (!hiddenBy) els[i].style[prop] = els[i].origProp;
1474			} else if (visibility == 'hidden') { // hide if behind
1475				var elPos = hs.getPosition(els[i]);
1476				elPos.w = els[i].offsetWidth;
1477				elPos.h = els[i].offsetHeight;
1478			
1479				
1480					var clearsX = (elPos.x + elPos.w < this.x.get('opos') 
1481						|| elPos.x > this.x.get('opos') + this.x.get('osize'));
1482					var clearsY = (elPos.y + elPos.h < this.y.get('opos') 
1483						|| elPos.y > this.y.get('opos') + this.y.get('osize'));
1484				var wrapperKey = hs.getWrapperKey(els[i]);
1485				if (!clearsX && !clearsY && wrapperKey != this.key) { // element falls behind image
1486					if (!hiddenBy) {
1487						els[i].setAttribute('hidden-by', '['+ this.key +']');
1488						els[i].origProp = els[i].style[prop];
1489						els[i].style[prop] = 'hidden';
1490						
1491					} else if (hiddenBy.indexOf('['+ this.key +']') == -1) {
1492						els[i].setAttribute('hidden-by', hiddenBy + '['+ this.key +']');
1493					}
1494				} else if ((hiddenBy == '['+ this.key +']' || hs.focusKey == wrapperKey)
1495						&& wrapperKey != this.key) { // on move
1496					els[i].setAttribute('hidden-by', '');
1497					els[i].style[prop] = els[i].origProp || '';
1498				} else if (hiddenBy && hiddenBy.indexOf('['+ this.key +']') > -1) {
1499					els[i].setAttribute('hidden-by', hiddenBy.replace('['+ this.key +']', ''));
1500				}
1501						
1502			}
1503		}
1504	}
1505},
1506
1507focus : function() {
1508	this.wrapper.style.zIndex = hs.zIndexCounter += 2;
1509	// blur others
1510	for (var i = 0; i < hs.expanders.length; i++) {
1511		if (hs.expanders[i] && i == hs.focusKey) {
1512			var blurExp = hs.expanders[i];
1513			blurExp.content.className += ' highslide-'+ blurExp.contentType +'-blur';
1514				blurExp.content.style.cursor = hs.ieLt7 ? 'hand' : 'pointer';
1515				blurExp.content.title = hs.lang.focusTitle;
1516		}
1517	}
1518	
1519	// focus this
1520	if (this.outline) this.outline.table.style.zIndex 
1521		= this.wrapper.style.zIndex - 1;
1522	this.content.className = 'highslide-'+ this.contentType;
1523		this.content.title = hs.lang.restoreTitle;
1524		
1525		if (hs.restoreCursor) {
1526			hs.styleRestoreCursor = window.opera ? 'pointer' : 'url('+ hs.graphicsDir + hs.restoreCursor +'), pointer';
1527			if (hs.ieLt7 && hs.uaVersion < 6) hs.styleRestoreCursor = 'hand';
1528			this.content.style.cursor = hs.styleRestoreCursor;
1529		}
1530		
1531	hs.focusKey = this.key;	
1532	hs.addEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);	
1533},
1534moveTo: function(x, y) {
1535	this.x.setPos(x);
1536	this.y.setPos(y);
1537},
1538resize : function (e) {
1539	var w, h, r = e.width / e.height;
1540	w = Math.max(e.width + e.dX, Math.min(this.minWidth, this.x.full));
1541	if (this.isImage && Math.abs(w - this.x.full) < 12) w = this.x.full;
1542	h = w / r;
1543	if (h < Math.min(this.minHeight, this.y.full)) {
1544		h = Math.min(this.minHeight, this.y.full);
1545		if (this.isImage) w = h * r;
1546	}
1547	this.resizeTo(w, h);
1548},
1549resizeTo: function(w, h) {
1550	this.y.setSize(h);
1551	this.x.setSize(w);
1552	this.wrapper.style.height = this.y.get('wsize') +'px';
1553},
1554
1555close : function() {
1556	if (this.isClosing || !this.isExpanded) return;
1557	this.isClosing = true;
1558	
1559	hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
1560	
1561	try {
1562		this.content.style.cursor = 'default';
1563		this.changeSize(
1564			0, {
1565				wrapper: {
1566					width : this.x.t,
1567					height : this.y.t,
1568					left: this.x.tpos - this.x.cb + this.x.tb,
1569					top: this.y.tpos - this.y.cb + this.y.tb
1570				},
1571				content: {
1572					left: 0,
1573					top: 0,
1574					width: this.x.t,
1575					height: this.y.t
1576				}
1577			}, hs.restoreDuration
1578		);
1579	} catch (e) { this.afterClose(); }
1580},
1581
1582createOverlay : function (o) {
1583	var el = o.overlayId;
1584	if (typeof el == 'string') el = hs.getNode(el);
1585	if (o.html) el = hs.createElement('div', { innerHTML: o.html });
1586	if (!el || typeof el == 'string') return;
1587	el.style.display = 'block';
1588	this.genOverlayBox();
1589	var width = o.width && /^[0-9]+(px|%)$/.test(o.width) ? o.width : 'auto';
1590	if (/^(left|right)panel$/.test(o.position) && !/^[0-9]+px$/.test(o.width)) width = '200px';
1591	var overlay = hs.createElement(
1592		'div', {
1593			id: 'hsId'+ hs.idCounter++,
1594			hsId: o.hsId
1595		}, {
1596			position: 'absolute',
1597			visibility: 'hidden',
1598			width: width,
1599			direction: hs.lang.cssDirection || '',
1600			opacity: 0
1601		},this.overlayBox,
1602		true
1603	);
1604	
1605	overlay.appendChild(el);
1606	hs.extend(overlay, {
1607		opacity: 1,
1608		offsetX: 0,
1609		offsetY: 0,
1610		dur: (o.fade === 0 || o.fade === false || (o.fade == 2 && hs.ie)) ? 0 : 250
1611	});
1612	hs.extend(overlay, o);
1613	
1614		
1615	if (this.gotOverlays) {
1616		this.positionOverlay(overlay);
1617		if (!overlay.hideOnMouseOut || this.mouseIsOver) 
1618			hs.animate(overlay, { opacity: overlay.opacity }, overlay.dur);
1619	}
1620	hs.push(this.overlays, hs.idCounter - 1);
1621},
1622positionOverlay : function(overlay) {
1623	var p = overlay.position || 'middle center',
1624		offX = overlay.offsetX,
1625		offY = overlay.offsetY;
1626	if (overlay.parentNode != this.overlayBox) this.overlayBox.appendChild(overlay);
1627	if (/left$/.test(p)) overlay.style.left = offX +'px'; 
1628	
1629	if (/center$/.test(p))	hs.setStyles (overlay, { 
1630		left: '50%',
1631		marginLeft: (offX - Math.round(overlay.offsetWidth / 2)) +'px'
1632	});	
1633	
1634	if (/right$/.test(p)) overlay.style.right = - offX +'px';
1635		
1636	if (/^leftpanel$/.test(p)) { 
1637		hs.setStyles(overlay, {
1638			right: '100%',
1639			marginRight: this.x.cb +'px',
1640			top: - this.y.cb +'px',
1641			bottom: - this.y.cb +'px',
1642			overflow: 'auto'
1643		});		 
1644		this.x.p1 = overlay.offsetWidth;
1645	
1646	} else if (/^rightpanel$/.test(p)) {
1647		hs.setStyles(overlay, {
1648			left: '100%',
1649			marginLeft: this.x.cb +'px',
1650			top: - this.y.cb +'px',
1651			bottom: - this.y.cb +'px',
1652			overflow: 'auto'
1653		});
1654		this.x.p2 = overlay.offsetWidth;
1655	}
1656
1657	if (/^top/.test(p)) overlay.style.top = offY +'px'; 
1658	if (/^middle/.test(p))	hs.setStyles (overlay, { 
1659		top: '50%', 
1660		marginTop: (offY - Math.round(overlay.offsetHeight / 2)) +'px'
1661	});	
1662	if (/^bottom/.test(p)) overlay.style.bottom = - offY +'px';
1663	if (/^above$/.test(p)) {
1664		hs.setStyles(overlay, {
1665			left: (- this.x.p1 - this.x.cb) +'px',
1666			right: (- this.x.p2 - this.x.cb) +'px',
1667			bottom: '100%',
1668			marginBottom: this.y.cb +'px',
1669			width: 'auto'
1670		});
1671		this.y.p1 = overlay.offsetHeight;
1672	
1673	} else if (/^below$/.test(p)) {
1674		hs.setStyles(overlay, {
1675			position: 'relative',
1676			left: (- this.x.p1 - this.x.cb) +'px',
1677			right: (- this.x.p2 - this.x.cb) +'px',
1678			top: '100%',
1679			marginTop: this.y.cb +'px',
1680			width: 'auto'
1681		});
1682		this.y.p2 = overlay.offsetHeight;
1683		overlay.style.position = 'absolute';
1684	}
1685},
1686
1687getOverlays : function() {	
1688	this.getInline(['heading', 'caption'], true);
1689	if (this.heading && this.dragByHeading) this.heading.className += ' highsli
1689de-move';
1690	if (hs.showCredits) this.writeCredits();
1691	for (var i = 0; i < hs.overlays.length; i++) {
1692		var o = hs.overlays[i], tId = o.thumbnailId, sg = o.slideshowGroup;
1693		if ((!tId && !sg) || (tId && tId == this.thumbsUserSetId)
1694				|| (sg && sg === this.slideshowGroup)) {
1695			this.createOverlay(o);
1696		}
1697	}
1698	var os = [];
1699	for (var i = 0; i < this.overlays.length; i++) {
1700		var o = hs.$('hsId'+ this.overlays[i]);
1701		if (/panel$/.test(o.position)) this.positionOverlay(o);
1702		else hs.push(os, o);
1703	}
1704	for (var i = 0; i < os.length; i++) this.positionOverlay(os[i]);
1705	this.gotOverlays = true;
1706},
1707genOverlayBox : function() {
1708	if (!this.overlayBox) this.overlayBox = hs.createElement (
1709		'div', {
1710			className: this.wrapperClassName
1711		}, {
1712			position : 'absolute',
1713			width: (this.x.size || (this.useBox ? this.width : null) 
1714				|| this.x.full) +'px',
1715			height: (this.y.size || this.y.full) +'px',
1716			visibility : 'hidden',
1717			overflow : 'hidden',
1718			zIndex : hs.ie ? 4 : 'auto'
1719		},
1720		hs.container,
1721		true
1722	);
1723},
1724sizeOverlayBox : function(doWrapper, doPanels) {
1725	var overlayBox = this.overlayBox, 
1726		x = this.x,
1727		y = this.y;
1728	hs.setStyles( overlayBox, {
1729		width: x.size +'px', 
1730		height: y.size +'px'
1731	});
1732	if (doWrapper || doPanels) {
1733		for (var i = 0; i < this.overlays.length; i++) {
1734			var o = hs.$('hsId'+ this.overlays[i]);
1735			var ie6 = (hs.ieLt7 || document.compatMode == 'BackCompat');
1736			if (o && /^(above|below)$/.test(o.position)) {
1737				if (ie6) {
1738					o.style.width = (overlayBox.offsetWidth + 2 * x.cb
1739						+ x.p1 + x.p2) +'px';
1740				}
1741				y[o.position == 'above' ? 'p1' : 'p2'] = o.offsetHeight;
1742			}
1743			if (o && ie6 && /^(left|right)panel$/.test(o.position)) {
1744				o.style.height = (overlayBox.offsetHeight + 2* y.cb) +'px';
1745			}
1746		}
1747	}
1748	if (doWrapper) {
1749		hs.setStyles(this.content, {
1750			top: y.p1 +'px'
1751		});
1752		hs.setStyles(overlayBox, {
1753			top: (y.p1 + y.cb) +'px'
1754		});
1755	}
1756},
1757
1758showOverlays : function() {
1759	var b = this.overlayBox;
1760	b.className = '';
1761	hs.setStyles(b, {
1762		top: (this.y.p1 + this.y.cb) +'px',
1763		left: (this.x.p1 + this.x.cb) +'px',
1764		overflow : 'visible'
1765	});
1766	if (hs.safari) b.style.visibility = 'visible';
1767	this.wrapper.appendChild (b);
1768	for (var i = 0; i < this.overlays.length; i++) {
1769		var o = hs.$('hsId'+ this.overlays[i]);
1770		o.style.zIndex = o.zIndex || 4;
1771		if (!o.hideOnMouseOut || this.mouseIsOver) {
1772			o.style.visibility = 'visible';
1773			hs.setStyles(o, { visibility: 'visible', display: '' });
1774			hs.animate(o, { opacity: o.opacity }, o.dur);
1775		}
1776	}
1777},
1778
1779destroyOverlays : function() {
1780	if (!this.overlays.length) return;
1781	hs.discardElement(this.overlayBox);
1782},
1783
1784
1785
1786createFullExpand : function () {
1787	this.fullExpandLabel = hs.createElement(
1788		'a', {
1789			href: 'javascript:hs.expanders['+ this.key +'].doFullExpand();',
1790			title: hs.lang.fullExpandTitle,
1791			className: 'highslide-full-expand'
1792		}
1793	);
1794	
1795	this.createOverlay({ 
1796		overlayId: this.fullExpandLabel, 
1797		position: hs.fullExpandPosition, 
1798		hideOnMouseOut: true, 
1799		opacity: hs.fullExpandOpacity
1800	});
1801},
1802
1803doFullExpand : function () {
1804	try {
1805		if (this.fullExpandLabel) hs.discardElement(this.fullExpandLabel);
1806		
1807		this.focus();
1808		var xSize = this.x.size,
1809        	ySize = this.y.size;
1810        this.resizeTo(this.x.full, this.y.full);
1811       
1812        var xpos = this.x.pos - (this.x.size - xSize) / 2;
1813        if (xpos < hs.marginLeft) xpos = hs.marginLeft;
1814       
1815        var ypos = this.y.pos - (this.y.size - ySize) / 2;
1816        if (ypos < hs.marginTop) ypos = hs.marginTop;
1817       
1818        this.moveTo(xpos, ypos);
1819		this.doShowHide('hidden');
1820	
1821	} catch (e) {
1822		this.error(e);
1823	}
1824},
1825
1826
1827afterClose : function () {
1828	this.a.className = this.a.className.replace('highslide-active-anchor', '');
1829	
1830	this.doShowHide('visible');
1831		if (this.outline && this.outlineWhileAnimating) this.outline.destroy();
1832	
1833		hs.discardElement(this.wrapper);
1834	
1835	hs.expanders[this.key] = null;		
1836	hs.reOrder();
1837}
1838
1839};
1840hs.langDefaults = hs.lang;
1841// history
1842var HsExpander = hs.Expander;
1843if (hs.ie && window == window.top) {
1844	(function () {
1845		try {
1846			document.documentElement.doScroll('left');
1847		} catch (e) {
1848			setTimeout(arguments.callee, 50);
1849			return;
1850		}
1851		hs.ready();
1852	})();
1853}
1854hs.addEventListener(document, 'DOMContentLoaded', hs.ready);
1855hs.addEventListener(window, 'load', hs.ready);
1856
1857// set handlers
1858hs.addEventListener(document, 'ready', function() {
1859	if (hs.expandCursor) {
1860		var style = hs.createElement('style', { type: 'text/css' }, null, 
1861			document.getElementsByTagName('HEAD')[0]), 
1862			backCompat = document.compatMode == 'BackCompat';
1863			
1864		
1865		function addRule(sel, dec) {
1866			if (hs.ie && (hs.uaVersion < 9 || backCompat)) {
1867				var last = document.styleSheets[document.styleSheets.length - 1];
1868				if (typeof(last.addRule) == "object") last.addRule(sel, dec);
1869			} else {
1870				style.appendChild(document.createTextNode(sel + " {" + dec + "}"));
1871			}
1872		}
1873		function fix(prop) {
1874			return 'expression( ( ( ignoreMe = document.documentElement.'+ prop +
1875				' ? document.documentElement.'+ prop +' : document.body.'+ prop +' ) ) + \'px\' );';
1876		}
1877		if (hs.expandCursor) addRule ('.highslide img', 
1878			'cursor: url('+ hs.graphicsDir + hs.expandCursor +'), pointer !important;');
1879	}
1880});
1881hs.addEventListener(window, 'resize', function() {
1882	hs.getPageSize();
1883});
1884hs.addEventListener(document, 'mousemove', function(e) {
1885	hs.mouse = { x: e.clientX, y: e.clientY	};
1886});
1887hs.addEventListener(document, 'mousedown', hs.mouseClickHandler);
1888hs.addEventListener(document, 'mouseup', hs.mouseClickHandler);
1889
1890hs.addEventListener(document, 'ready', hs.getAnchors);
1891hs.addEventListener(window, 'load', hs.preloadImages);
1892}

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.