PageSourceSearch

http://elbrusrace.com/plugins/content/joomthumbnail/gallery/highslide/highslide-with-gallery.js

js elbrusrace.com collected 2026-10-02 17:22:04 UTC 101,982 bytes, 2,330 lines download raw bytes

1if (!hs) {
2    var hs = {
3        lang: {
4            cssDirection: 'ltr',
5            loadingText: 'Loading...',
6            loadingTitle: 'Click to cancel',
7            focusTitle: 'Click to bring to front',
8            fullExpandTitle: 'Expand to actual size (f)',
9            creditsText: 'Powered by <i>Highslide JS</i>',
10            creditsTitle: 'Go to the Highslide JS homepage',
11            previousText: 'Previous',
12            nextText: 'Next',
13            moveText: 'Move',
14            closeText: 'Close',
15            closeTitle: 'Close (esc)',
16            resizeTitle: 'Resize',
17            playText: 'Play',
18            playTitle: 'Play slideshow (spacebar)',
19            pauseText: 'Pause',
20            pauseTitle: 'Pause slideshow (spacebar)',
21            previousTitle: 'Previous (arrow left)',
22            nextTitle: 'Next (arrow right)',
23            moveTitle: 'Move',
24            fullExpandText: '1:1',
25            number: 'Image %1 of %2',
26            restoreTitle: 'Click to close image, click and drag to move. Use arrow keys for next and previous.'
27        },
28        graphicsDir: 'highslide/graphics/',
29        expandCursor: 'zoomin.cur',
30        restoreCursor: 'zoomout.cur',
31        expandDuration: 250,
32        restoreDuration: 250,
33        marginLeft: 15,
34        marginRight: 15,
35        marginTop: 15,
36        marginBottom: 15,
37        zIndexCounter: 1001,
38        loadingOpacity: 0.75,
39        allowMultipleInstances: true,
40        numberOfImagesToPreload: 5,
41        outlineWhileAnimating: 2,
42        outlineStartOffset: 3,
43        padToMinWidth: false,
44        fullExpandPosition: 'bottom right',
45        fullExpandOpacity: 1,
46        showCredits: true,
47        creditsHref: 'http://highslide.com/',
48        creditsTarget: '_self',
49        enableKeyListener: true,
50        openerTagNames: ['a'],
51        transitions: [],
52        transitionDuration: 250,
53        dimmingOpacity: 0,
54        dimmingDuration: 50,
55        anchor: 'auto',
56        align: 'auto',
57        targetX: null,
58        targetY: null,
59        dragByHeading: true,
60        minWidth: 200,
61        minHeight: 200,
62        allowSizeReduction: true,
63        outlineType: 'drop-shadow',
64        skin: {
65            controls: '<div class="highslide-controls"><ul>' + '<li class="highslide-previous">' + '<a href="#" title="{hs.lang.previousTitle}">' + '<span>{hs.lang.previousText}</span></a>' + '</li>' + '<li class="highslide-play">' + '<a href="#" title="{hs.lang.playTitle}">' + '<span>{hs.lang.playText}</span></a>' + '</li>' + '<li class="highslide-pause">' + '<a href="#" title="{hs.lang.pauseTitle}">' + '<span>{hs.lang.pauseText}</span></a>' + '</li>' + '<li class="highslide-next">' + '<a href="#" title="{hs.lang.nextTitle}">' + '<span>{hs.lang.nextText}</span></a>' + '</li>' + '<li class="highslide-move">' + '<a href="#" title="{hs.lang.moveTitle}">' + '<span>{hs.lang.moveText}</span></a>' + '</li>' + '<li class="highslide-full-expand">' + '<a href="#" title="{hs.lang.fullExpandTitle}">' + '<span>{hs.lang.fullExpandText}</span></a>' + '</li>' + '<li class="highslide-close">' + '<a href="#" title="{hs.lang.closeTitle}" >' + '<span>{hs.lang.closeText}</span></a>' + '</li>' + '</ul></div>'
66        },
67        preloadTheseImages: [],
68        continuePreloading: true,
69        expanders: [],
70        overrides: ['allowSizeReduction', 'useBox', 'anchor', 'align', 'targetX', 'targetY', 'outlineType', 'outlineWhileAnimating', 'captionId', 'captionText', 'captionEval', 'captionOverlay', 'headingId', 'headingText', 'headingEval', 'headingOverlay', 'creditsPosition', 'dragByHeading', 'autoplay', 'numberPosition', 'transitions', 'dimmingOpacity', 'width', 'height', 'wrapperClassName', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', 'slideshowGroup', 'easing', 'easingClose', 'fadeInOut', 'src'],
71        overlays: [],
72        idCounter: 0,
73        oPos: {
74            x: ['leftpanel', 'left', 'center', 'right', 'rightpanel'],
75            y: ['above', 'top', 'middle', 'bottom', 'below']
76        },
77        mouse: {},
78        headingOverlay: {},
79        captionOverlay: {},
80        timers: [],
81        slideshows: [],
82        pendingOutlines: {},
83        clones: {},
84        onReady: [],
85        uaVersion: /Trident\/4\.0/.test(navigator.userAgent) ? 8 : parseFloat((navigator.userAgent.toLowerCase().match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0, '0'])[1]),
86        ie: (document.all && !window.opera),
87        safari: /Safari/.test(navigator.userAgent),
88        geckoMac: /Macintosh.+rv:1\.[0-8].+Gecko/.test(navigator.userAgent),
89        $: function (id) {
90            if (id) return document.getElementById(id)
91        },
92        push: function (arr, val) {
93            arr[arr.length] = val
94        },
95        createElement: function (tag, attribs, styles, parent, nopad) {
96            var el = document.createElement(tag);
97            if (attribs) hs.extend(el, attribs);
98            if (nopad) hs.setStyles(el, {
99                padding: 0,
100                border: 'none',
101                margin: 0
102            });
103            if (styles) hs.setStyles(el, styles);
104            if (parent) parent.appendChild(el);
105            return el
106        },
107        extend: function (el, attribs) {
108            for (var x in attribs) el[x] = attribs[x];
109            return el
110        },
111        setStyles: function (el, styles) {
112            for (var x in styles) {
113                if (hs.ie && x == 'opacity') {
114                    if (styles[x] > 0.99) el.style.removeAttribute('filter');
115                    else el.style.filter = 'alpha(opacity=' + (styles[x] * 100) + ')'
116                } else el.style[x] = styles[x]
117            }
118        },
119        animate: function (el, prop, opt) {
120            var start, end, unit;
121            if (typeof opt != 'object' || opt === null) {
122                var args = arguments;
123                opt = {
124                    duration: args[2],
125                    easing: args[3],
126                    complete: args[4]
127                }
128            }
129            if (typeof opt.duration != 'number') opt.duration = 250;
130            opt.easing = Math[opt.easing] || Math.easeInQuad;
131            opt.curAnim = hs.extend({},
132            prop);
133            for (var name in prop) {
134                var e = new hs.fx(el, opt, name);
135                start = parseFloat(hs.css(el, name)) || 0;
136                end = parseFloat(prop[name]);
137                unit = name != 'opacity' ? 'px' : '';
138                e.custom(start, end, unit)
139            }
140        },
141        css: function (el, prop) {
142            if (document.defaultView) {
143                return document.defaultView.getComputedStyle(el, null).getPropertyValue(prop)
144            } else {
145                if (prop == 'opacity') prop = 'filter';
146                var val = el.currentStyle[prop.replace(/\-(\w)/g, function (a, b) {
147                    return b.toUpperCase()
148                })];
149                if (prop == 'filter') val = val.replace(/alpha\(opacity=([0-9]+)\)/, function (a, b) {
150                    return b / 100
151                });
152                return val === '' ? 1 : val
153            }
154        },
155        getPageSize: function () {
156            var d = document,
157                w = window,
158                iebody = d.compatMode && d.compatMode != 'BackCompat' ? d.documentElement : d.body;
159            var width = hs.ie ? iebody.clientWidth : (d.documentElement.clientWidth || self.innerWidth),
160            height = hs.ie ? iebody.clientHeight : self.innerHeight;
161            hs.page = {
162                width: width,
163                height: height,
164                scrollLeft: hs.ie ? iebody.scrollLeft : pageXOffset,
165                scrollTop: hs.ie ? iebody.scrollTop : pageYOffset
166            }
167        },
168        getPosition: function (el) {
169            var p = {
170                x: el.offsetLeft,
171                y: el.offsetTop
172            };
173            while (el.offsetParent) {
174                el = el.offsetParent;
175                p.x += el.offsetLeft;
176                p.y += el.offsetTop;
177                if (el != document.body && el != document.documentElement) {
178                    p.x -= el.scrollLeft;
179                    p.y -= el.scrollTop
180                }
181            }
182            return p
183        },
184        expand: function (a, params, custom, type) {
185            if (!a) a = hs.createElement('a', null, {
186                display: 'none'
187            },
188            hs.container);
189            if (typeof a.getParams == 'function') return params;
190            try {
191                new hs.Expander(a, params, custom);
192                return false
193            } catch(e) {
194                return true
195            }
196        },
197        getElementByClass: function (el, tagName, className) {
198            var els = el.getElementsByTagName(tagName);
199            for (var i = 0; i < els.length; i++) {
200                if ((new RegExp(className)).test(els[i].className)) {
201                    return els[i]
202                }
203            }
204            return null
205        },
206        replaceLang: function (s) {
207            s = s.replace(/\s/g, ' ');
208            var re = /{hs\.lang\.([^}]+)\}/g,
209                matches = s.match(re),
210                lang;
211            if (matches) for (var i = 0; i < matches.length; i++) {
212                lang = matches[i].replace(re, "$1");
213                if (typeof hs.lang[lang] != 'undefined') s = s.replace(matches[i], hs.lang[lang])
214            }
215            return s
216        },
217        focusTopmost: function () {
218            var topZ = 0,
219                topmostKey = -1,
220                expanders = hs.expanders,
221                exp, zIndex;
222            for (var i = 0; i < expanders.length; i++) {
223                exp = expanders[i];
224                if (exp) {
225                    zIndex = exp.wrapper.style.zIndex;
226                    if (zIndex && zIndex > topZ) {
227                        topZ = zIndex;
228                        topmostKey = i
229                    }
230                }
231            }
232            if (topmostKey == -1) hs.focusKey = -1;
233            else expanders[topmostKey].focus()
234        },
235        getParam: function (a, param) {
236            a.getParams = a.onclick;
237            var p = a.getParams ? a.getParams() : null;
238            a.getParams = null;
239            return (p && typeof p[param] != 'undefined') ? p[param] : (typeof hs[param] != 'undefined' ? hs[param] : null)
240        },
241        getSrc: function (a) {
242            var src = hs.getParam(a, 'src');
243            if (src) return src;
244            return a.href
245        },
246        getNode: function (id) {
247            var node = hs.$(id),
248                clone = hs.clones[id],
249                a = {};
250            if (!node && !clone) return null;
251            if (!clone) {
252                clone = node.cloneNode(true);
253                clone.id = '';
254                hs.clones[id] = clone;
255                return node
256            } else {
257                return clone.cloneNode(true)
258            }
259        },
260        discardElement: function (d) {
261            if (d) hs.garbageBin.appendChild(d);
262            hs.garbageBin.innerHTML = ''
263        },
264        dim: function (exp) {
265            function fix(prop) {
266                return 'expression( ( ( ignoreMe = document.documentElement.' + prop + ' ? document.documentElement.' + prop + ' : document.body.' + prop + ' ) ) + \'px\' );'
267            }
268            if (!hs.dimmer) {
269                hs.dimmer = hs.createElement('div', {
270                    className: 'highslide-dimming highslide-viewport-size',
271                    owner: '',
272                    onclick: function () {
273                        hs.close()
274                    }
275                },
276                {
277                    visibility: 'visible',
278                    opacity: 0
279                },
280                hs.container, true)
281            }
282            hs.dimmer.style.display = '';
283            hs.dimmer.owner += '|' + exp.key;
284            if (hs.geckoMac && hs.dimmingGeckoFix) hs.setStyles(hs.dimmer, {
285                background: 'url(' + hs.graphicsDir + 'geckodimmer.png)',
286                opacity: 1
287            });
288            else hs.animate(hs.dimmer, {
289                opacity: exp.dimmingOpacity
290            },
291            hs.dimmingDuration)
292        },
293        undim: function (key) {
294            if (!hs.dimmer) return;
295            if (typeof key != 'undefined') hs.dimmer.owner = hs.dimmer.owner.replace('|' + key, '');
296            if ((typeof key != 'undefined' && hs.dimmer.owner != '') || (hs.upcoming && hs.getParam(hs.upcoming, 'dimmingOpacity'))) return;
297            if (hs.geckoMac && hs.dimmingGeckoFix) hs.dimmer.style.display = 'none';
298            else hs.animate(hs.dimmer, {
299                opacity: 0
300            },
301            hs.dimmingDuration, null, function () {
302                hs.dimmer.style.display = 'none'
303            })
304        },
305        transit: function (adj, exp) {
306            var last = exp = exp || hs.getExpander();
307            if (hs.upcoming) return false;
308            else hs.last = last;
309            try {
310                hs.upcoming = adj;
311                adj.onclick()
312            } catch(e) {
313                hs.last = hs.upcoming = null
314            }
315            try {
316                if (!adj || exp.transitions[1] != 'crossfade') exp.close()
317            } catch(e) {}
318            return false
319        },
320        previousOrNext: function (el, op) {
321            var exp = hs.getExpander(el);
322            if (exp) return hs.transit(exp.getAdjacentAnchor(op), exp);
323            else return false
324        },
325        previous: function (el) {
326            return hs.previousOrNext(el, -1)
327        },
328        next: function (el) {
329            return hs.previousOrNext(el, 1)
330        },
331        keyHandler: function (e) {
332            if (!e) e = window.event;
333            if (!e.target) e.target = e.srcElement;
334            if (typeof e.target.form != 'undefined') return true;
335            var exp = hs.getExpander();
336            var op = null;
337            switch (e.keyCode) {
338            case 70:
339                if (exp) exp.doFullExpand();
340                return true;
341            case 32:
342                op = 2;
343                break;
344            case 34:
345            case 39:
346            case 40:
347                op = 1;
348                break;
349            case 8:
350            case 33:
351            case 37:
352            case 38:
353                op = -1;
354                break;
355            case 27:
356            case 13:
357                op = 0
358            }
359            if (op !== null) {
360                if (op != 2) hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
361                if (!hs.enableKeyListener) return true;
362                if (e.preventDefault) e.preventDefault();
363                else e.returnValue = false;
364                if (exp) {
365                    if (op == 0) {
366                        exp.close()
367                    } else if (op == 2) {
368                        if (exp.slideshow) exp.slideshow.hitSpace()
369                    } else {
370                        if (exp.slideshow) exp.slideshow.pause();
371                        hs.previousOrNext(exp.key, op)
372                    }
373                    return false
374                }
375            }
376            return true
377        },
378        registerOverlay: function (overlay) {
379            hs.push(hs.overlays, hs.extend(overlay, {
380                hsId: 'hsId' + hs.idCounter++
381            }))
382        },
383        addSlideshow: function (options) {
384            var sg = options.slideshowGroup;
385            if (typeof sg == 'object') {
386                for (var i = 0; i < sg.length; i++) {
387                    var o = {};
388                    for (var x in options) o[x] = options[x];
389                    o.slideshowGroup = sg[i];
390                    hs.push(hs.slideshows, o)
391                }
392            } else {
393                hs.push(hs.slideshows, options)
394            }
395        },
396        getWrapperKey: function (element, expOnly) {
397            var el, re = /^highslide-wrapper-([0-9]+)$/;
398            el = element;
399            while (el.parentNode) {
400                if (el.hsKey !== undefined) return el.hsKey;
401                if (el.id && re.test(el.id)) return el.id.replace(re, "$1");
402                el = el.parentNode
403            }
404            if (!expOnly) {
405                el = element;
406                while (el.parentNode) {
407                    if (el.tagName && hs.isHsAnchor(el)) {
408                        for (var key = 0; key < hs.expanders.length; key++) {
409                            var exp = hs.expanders[key];
410                            if (exp && exp.a == el) return key
411                        }
412                    }
413                    el = el.parentNode
414                }
415            }
416            return null
417        },
418        getExpander: function (el, expOnly) {
419            if (typeof el == 'undefined') return hs.expanders[hs.focusKey] || null;
420            if (typeof el == 'number') return hs.expanders[el] || null;
421            if (typeof el == 'string') el = hs.$(el);
422            return hs.expanders[hs.getWrapperKey(el, expOnly)] || null
423        },
424        isHsAnchor: function (a) {
425            return (a.onclick && a.onclick.toString().replace(/\s/g, ' ').match(/hs.(htmlE|e)xpand/))
426        },
427        reOrder: function () {
428            for (var i = 0; i < hs.expanders.length;
428 i++) if (hs.expanders[i] && hs.expanders[i].isExpanded) hs.focusTopmost()
429        },
430        mouseClickHandler: function (e) {
431            if (!e) e = window.event;
432            if (e.button > 1) return true;
433            if (!e.target) e.target = e.srcElement;
434            var el = e.target;
435            while (el.parentNode && !(/highslide-(image|move|html|resize)/.test(el.className))) {
436                el = el.parentNode
437            }
438            var exp = hs.getExpander(el);
439            if (exp && (exp.isClosing || !exp.isExpanded)) return true;
440            if (exp && e.type == 'mousedown') {
441                if (e.target.form) return true;
442                var match = el.className.match(/highslide-(image|move|resize)/);
443                if (match) {
444                    hs.dragArgs = {
445                        exp: exp,
446                        type: match[1],
447                        left: exp.x.pos,
448                        width: exp.x.size,
449                        top: exp.y.pos,
450                        height: exp.y.size,
451                        clickX: e.clientX,
452                        clickY: e.clientY
453                    };
454                    hs.addEventListener(document, 'mousemove', hs.dragHandler);
455                    if (e.preventDefault) e.preventDefault();
456                    if (/highslide-(image|html)-blur/.test(exp.content.className)) {
457                        exp.focus();
458                        hs.hasFocused = true
459                    }
460                    return false
461                }
462            } else if (e.type == 'mouseup') {
463                hs.removeEventListener(document, 'mousemove', hs.dragHandler);
464                if (hs.dragArgs) {
465                    if (hs.styleRestoreCursor && hs.dragArgs.type == 'image') hs.dragArgs.exp.content.style.cursor = hs.styleRestoreCursor;
466                    var hasDragged = hs.dragArgs.hasDragged;
467                    if (!hasDragged && !hs.hasFocused && !/(move|resize)/.test(hs.dragArgs.type)) {
468                        exp.close()
469                    } else if (hasDragged || (!hasDragged && hs.hasHtmlExpanders)) {
470                        hs.dragArgs.exp.doShowHide('hidden')
471                    }
472                    hs.hasFocused = false;
473                    hs.dragArgs = null
474                } else if (/highslide-image-blur/.test(el.className)) {
475                    el.style.cursor = hs.styleRestoreCursor
476                }
477            }
478            return false
479        },
480        dragHandler: function (e) {
481            if (!hs.dragArgs) return true;
482            if (!e) e = window.event;
483            var a = hs.dragArgs,
484                exp = a.exp;
485            a.dX = e.clientX - a.clickX;
486            a.dY = e.clientY - a.clickY;
487            var distance = Math.sqrt(Math.pow(a.dX, 2) + Math.pow(a.dY, 2));
488            if (!a.hasDragged) a.hasDragged = (a.type != 'image' && distance > 0) || (distance > (hs.dragSensitivity || 5));
489            if (a.hasDragged && e.clientX > 5 && e.clientY > 5) {
490                if (a.type == 'resize') exp.resize(a);
491                else {
492                    exp.moveTo(a.left + a.dX, a.top + a.dY);
493                    if (a.type == 'image') exp.content.style.cursor = 'move'
494                }
495            }
496            return false
497        },
498        wrapperMouseHandler: function (e) {
499            try {
500                if (!e) e = window.event;
501                var over = /mouseover/i.test(e.type);
502                if (!e.target) e.target = e.srcElement;
503                if (hs.ie) e.relatedTarget = over ? e.fromElement : e.toElement;
504                var exp = hs.getExpander(e.target);
505                if (!exp.isExpanded) return;
506                if (!exp || !e.relatedTarget || hs.getExpander(e.relatedTarget, true) == exp || hs.dragArgs) return;
507                for (var i = 0; i < exp.overlays.length; i++)(function () {
508                    var o = hs.$('hsId' + exp.overlays[i]);
509                    if (o && o.hideOnMouseOut) {
510                        if (over) hs.setStyles(o, {
511                            visibility: 'visible',
512                            display: ''
513                        });
514                        hs.animate(o, {
515                            opacity: over ? o.opacity : 0
516                        },
517                        o.dur)
518                    }
519                })()
520            } catch(e) {}
521        },
522        addEventListener: function (el, event, func) {
523            if (el == document && event == 'ready') hs.push(hs.onReady, func);
524            try {
525                el.addEventListener(event, func, false)
526            } catch(e) {
527                try {
528                    el.detachEvent('on' + event, func);
529                    el.attachEvent('on' + event, func)
530                } catch(e) {
531                    el['on' + event] = func
532                }
533            }
534        },
535        removeEventListener: function (el, event, func) {
536            try {
537                el.removeEventListener(event, func, false)
538            } catch(e) {
539                try {
540                    el.detachEvent('on' + event, func)
541                } catch(e) {
542                    el['on' + event] = null
543                }
544            }
545        },
546        preloadFullImage: function (i) {
547            if (hs.continuePreloading && hs.preloadTheseImages[i] && hs.preloadTheseImages[i] != 'undefined') {
548                var img = document.createElement('img');
549                img.onload = function () {
550                    img = null;
551                    hs.preloadFullImage(i + 1)
552                };
553                img.src = hs.preloadTheseImages[i]
554            }
555        },
556        preloadImages: function (number) {
557            document.getElementsByTagName('body')[0].className+=' highsli
557de-gallery'
558            
559            if (number && typeof number != 'object') hs.numberOfImagesToPreload = number;
560            var arr = hs.getAnchors();
561            for (var i = 0; i < arr.images.length && i < hs.numberOfImagesToPreload; i++) {
562                hs.push(hs.preloadTheseImages, hs.getSrc(arr.images[i]))
563            }
564            if (hs.outlineType) new hs.Outline(hs.outlineType, function () {
565                hs.preloadFullImage(0)
566            });
567            else hs.preloadFullImage(0);
568            if (hs.restoreCursor) var cur = hs.createElement('img', {
569                src: hs.graphicsDir + hs.restoreCursor
570            })
571        },
572        init: function () {
573            if (!hs.container) {
574                hs.getPageSize();
575                hs.ieLt7 = hs.ie && hs.uaVersion < 7;
576                for (var x in hs.langDefaults) {
577                    if (typeof hs[x] != 'undefined') hs.lang[x] = hs[x];
578                    else if (typeof hs.lang[x] == 'undefined' && typeof hs.langDefaults[x] != 'undefined') hs.lang[x] = hs.langDefaults[x]
579                }
580                hs.container = hs.createElement('div', {
581                    className: 'highslide-container'
582                },
583                {
584                    position: 'absolute',
585                    left: 0,
586                    top: 0,
587                    width: '100%',
588                    zIndex: hs.zIndexCounter,
589                    direction: 'ltr'
590                },
591                document.body, true);
592                hs.loading = hs.createElement('a', {
593                    className: 'highslide-loading',
594                    title: hs.lang.loadingTitle,
595                    innerHTML: hs.lang.loadingText,
596                    href: 'javascript:;'
597                },
598                {
599                    position: 'absolute',
600                    top: '-9999px',
601                    opacity: hs.loadingOpacity,
602                    zIndex: 1
603                },
604                hs.container);
605                hs.garbageBin = hs.createElement('div', null, {
606                    display: 'none'
607                },
608                hs.container);
609                hs.viewport = hs.createElement('div', {
610                    className: 'highslide-viewport highslide-viewport-size'
611                },
612                {
613                    visibility: (hs.safari && hs.uaVersion < 525) ? 'visible' : 'hidden'
614                },
615                hs.container, 1);
616                Math.linearTween = function (t, b, c, d) {
617                    return c * t / d + b
618                };
619                Math.easeInQuad = function (t, b, c, d) {
620                    return c * (t /= d) * t + b
621                };
622                Math.easeOutQuad = function (t, b, c, d) {
623                    return -c * (t /= d) * (t - 2) + b
624                };
625                hs.hideSelects = hs.ieLt7;
626                hs.hideIframes = ((window.opera && hs.uaVersion < 9) || navigator.vendor == 'KDE' || (hs.ie && hs.uaVersion < 5.5))
627            }
628        },
629        ready: function () {
630            if (hs.isReady) return;
631            hs.isReady = true;
632            for (var i = 0; i < hs.onReady.length; i++) hs.onReady[i]()
633        },
634        updateAnchors: function () {
635            var el, els, all = [],
636                images = [],
637                groups = {},
638                re;
639            for (var i = 0; i < hs.openerTagNames.length; i++) {
640                els = document.getElementsByTagName(hs.openerTagNames[i]);
641                for (var j = 0; j < els.length; j++) {
642                    el = els[j];
643                    re = hs.isHsAnchor(el);
644                    if (re) {
645                        hs.push(all, el);
646                        if (re[0] == 'hs.expand') hs.push(images, el);
647                        var g = hs.getParam(el, 'slideshowGroup') || 'none';
648                        if (!groups[g]) groups[g] = [];
649                        hs.push(groups[g], el)
650                    }
651                }
652            }
653            hs.anchors = {
654                all: all,
655                groups: groups,
656                images: images
657            };
658            return hs.anchors
659        },
660        getAnchors: function () {
661            return hs.anchors || hs.updateAnchors()
662        },
663        close: function (el) {
664            var exp = hs.getExpander(el);
665            if (exp) exp.close();
666            return false
667        }
668    };
669    hs.fx = function (elem, options, prop) {
670        this.options = options;
671        this.elem = elem;
672        this.prop = prop;
673        if (!options.orig) options.orig = {}
674    };
675    hs.fx.prototype = {
676        update: function () {
677            (hs.fx.step[this.prop] || hs.fx.step._default)(this);
678            if (this.options.step) this.options.step.call(this.elem, this.now, this)
679        },
680        custom: function (from, to, unit) {
681            this.startTime = (new Date()).getTime();
682            this.start = from;
683            this.end = to;
684            this.unit = unit;
685            this.now = this.start;
686            this.pos = this.state = 0;
687            var self = this;
688
689            function t(gotoEnd) {
690                return self.step(gotoEnd)
691            }
692            t.elem = this.elem;
693            if (t() && hs.timers.push(t) == 1) {
694                hs.timerId = setInterval(function () {
695                    var timers = hs.timers;
696                    for (var i = 0; i < timers.length; i++) if (!timers[i]()) timers.splice(i--, 1);
697                    if (!timers.length) {
698                        clearInterval(hs.timerId)
699                    }
700                },
701                13)
702            }
703        },
704        step: function (gotoEnd) {
705            var t = (new Date()).getTime();
706            if (gotoEnd || t >= this.options.duration + this.startTime) {
707                this.now = this.end;
708                this.pos = this.state = 1;
709                this.update();
710                this.options.curAnim[this.prop] = true;
711                var done = true;
712                for (var i in this.options.curAnim) if (this.options.curAnim[i] !== true) done = false;
713                if (done) {
714                    if (this.options.complete) this.options.complete.call(this.elem)
715                }
716                return false
717            } else {
718                var n = t - this.startTime;
719                this.state = n / this.options.duration;
720                this.pos = this.options.easing(n, 0, 1, this.options.duration);
721                this.now = this.start + ((this.end - this.start) * this.pos);
722                this.update()
723            }
724            return true
725        }
726    };
727    hs.extend(hs.fx, {
728        step: {
729            opacity: function (fx) {
730                hs.setStyles(fx.elem, {
731                    opacity: fx.now
732                })
733            },
734            _default: function (fx) {
735                try {
736                    if (fx.elem.style && fx.elem.style[fx.prop] != null) fx.elem.style[fx.prop] = fx.now + fx.unit;
737                    else fx.elem[fx.prop] = fx.now
738                } catch(e) {}
739            }
740        }
741    });
742    hs.Outline = function (outlineType, onLoad) {
743        this.onLoad = onLoad;
744        this.outlineType = outlineType;
745        var v = hs.uaVersion,
746            tr;
747        this.hasAlphaImageLoader = hs.ie && v >= 5.5 && v < 7;
748        if (!outlineType) {
749            if (onLoad) onLoad();
750            return
751        }
752        hs.init();
753        this.table = hs.createElement('table', {
754            cellSpacing: 0
755        },
756        {
757            visibility: 'hidden',
758            position: 'absolute',
759            borderCollapse: 'collapse',
760            width: 0
761        },
762        hs.container, true);
763        var tbody = hs.createElement('tbody', null, null, this.table, 1);
764        this.td = [];
765        for (var i = 0; i <= 8; i++) {
766            if (i % 3 == 0) tr = hs.createElement('tr', null, {
767                height: 'auto'
768            },
769            tbody, true);
770            this.td[i] = hs.createElement('td', null, null, tr, true);
771            var style = i != 4 ? {
772                lineHeight: 0,
773                fontSize: 0
774            } : {
775                position: 'relative'
776            };
777            hs.setStyles(this.td[i], style)
778        }
779        this.td[4].className = outlineType + ' highslide-outline';
780        this.preloadGraphic()
781    };
782    hs.Outline.prototype = {
783        preloadGraphic: function () {
784            var src = hs.graphicsDir + (hs.outlinesDir || "outlines/") + this.outlineType + ".png";
785            var appendTo = hs.safari ? hs.container : null;
786            this.graphic = hs.createElement('img', null, {
787                position: 'absolute',
788                top: '-9999px'
789            },
790            appendTo, true);
791            var pThis = this;
792            this.graphic.onload = function () {
793                pThis.onGraphicLoad()
794            };
795            this.graphic.src = src
796        },
797        onGraphicLoad: function () {
798            var o = this.offset = this.graphic.width / 4,
799                pos = [
800                [0, 0],
801                [0, -4],
802                [-2, 0],
803                [0, -8], 0, [-2, -8],
804                [0, -2],
805                [0, -6],
806                [-2, -2]],
807                dim = {
808                height: (2 * o) + 'px',
809                width: (2 * o) + 'px'
810            };
811            for (var i = 0; i <= 8; i++) {
812                if (pos[i]) {
813                    if (this.hasAlphaImageLoader) {
814                        var w = (i == 1 || i == 7) ? '100%' : this.graphic.width + 'px';
815                        var div = hs.createElement('div', null, {
816                            width: '100%',
817                            height: '100%',
818                            position: 'relative',
819                            overflow: 'hidden'
820                        },
821                        this.td[i], true);
822                        hs.createElement('div', null, {
823                            filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale, src='" + this.graphic.src + "')",
824                            position: 'absolute',
825                            width: w,
826                            height: this.graphic.height + 'px',
827                            left: (pos[i][0] * o) + 'px',
828                            top: (pos[i][1] * o) + 'px'
829                        },
830                        div, true)
831                    } else {
832                        hs.setStyles(this.td[i], {
833                            background: 'url(' + this.graphic.src + ') ' + (pos[i][0] * o) + 'px ' + (pos[i][1] * o) + 'px'
834                        })
835                    }
836                    if (window.opera && (i == 3 || i == 5)) hs.createElement('div', null, dim, this.td[i], true);
837                    hs.setStyles(this.td[i], dim)
838                }
839            }
840            this.graphic = null;
841            if (hs.pendingOutlines[this.outlineType]) hs.pendingOutlines[this.outlineType].destroy();
842            hs.pendingOutlines[this.outlineType] = this;
843            if (this.onLoad) this.onLoad()
844        },
845        setPosition: function (pos, offset, vis, dur, easing) {
846            var exp = this.exp,
847                stl = exp.wrapper.style,
848                offset = offset || 0,
849                pos = pos || {
850                x: exp.x.pos + offset,
851                y: exp.y.pos + offset,
852                w: exp.x.get('wsize') - 2 * offset,
853                h: exp.y.get('wsize') - 2 * offset
854            };
855            if (vis) this.table.style.visibility = (pos.h >= 4 * this.offset) ? 'visible' : 'hidden';
856            hs.setStyles(this.table, {
857                left: (pos.x - this.offset) + 'px',
858                top: (pos.y - this.offset) + 'px',
859                width: (pos.w + 2 * this.offset) + 'px'
860            });
861            pos.w -= 2 * this.offset;
862            pos.h -= 2 * this.offset;
863            hs.setStyles(this.td[4], {
864                width: pos.w >= 0 ? pos.w + 'px' : 0,
865                height: pos.h >= 0 ? pos.h + 'px' : 0
866            });
867            if (this.hasAlphaImageLoader) this.td[3].style.height = this.td[5].style.height = this.td[4].style.height
868        },
869        destroy: function (hide) {
870            if (hide) this.table.style.visibility = 'hidden';
871            else hs.discardElement(this.table)
872        }
873    };
874    hs.Dimension = function (exp, dim) {
875        this.exp = exp;
876        this.dim = dim;
877        this.ucwh = dim == 'x' ? 'Width' : 'Height';
878        this.wh = this.ucwh.toLowerCase();
879        this.uclt = dim == 'x' ? 'Left' : 'Top';
880        this.lt = this.uclt.toLowerCase();
881        this.ucrb = dim == 'x' ? 'Right' : 'Bottom';
882        this.rb = this.ucrb.toLowerCase();
883        this.p1 = this.p2 = 0
884    };
885    hs.Dimension.prototype = {
886        get: function (key) {
887            switch (key) {
888            case 'loadingPos':
889                return this.tpos + this.tb + (this.t - hs.loading['offset' + this.ucwh]) / 2;
890            case 'loadingPosXfade':
891                return this.pos + this.cb + this.p1 + (this.size - hs.loading['offset' + this.ucwh]) / 2;
892            case 'wsize':
893                return this.size + 2 * this.cb + this.p1 + this.p2;
894            case 'fitsize':
895                return this.clientSize - this.marginMin - this.marginMax;
896            case 'maxsize':
897                return this.get('fitsize') - 2 * this.cb - this.p1 - this.p2;
898            case 'opos':
899                return this.pos - (this.exp.outline ? this.exp.outline.offset : 0);
900            case 'osize':
901                return this.get('wsize') + (this.exp.outline ? 2 * this.exp.outline.offset : 0);
902            case 'imgPad':
903                return this.imgSize ? Math.round((this.size - this.imgSize) / 2) : 0
904            }
905        },
906        calcBorders: function () {
907            this.cb = (this.exp.content['offset' + this.ucwh] - this.t) / 2;
908            this.marginMax = hs['margin' + this.ucrb]
909        },
910        calcThumb: function () {
911            this.t = this.exp.el[this.wh] ? parseInt(this.exp.el[this.wh]) : this.exp.el['offset' + this.ucwh];
912            this.tpos = this.exp.tpos[this.dim];
913            this.tb = (this.exp.el['offset' + this.ucwh] - this.t) / 2;
914            if (this.tpos == 0 || this.tpos == -1) {
915                this.tpos = (hs.page[this.wh] / 2) + hs.page['scroll' + this.uclt]
916            }
917        },
918        calcExpanded: function () {
919            var exp = this.exp;
920            this.justify = 'auto';
921            if (exp.align == 'center') this.justify = 'center';
922            else if (new RegExp(this.lt).test(exp.anchor)) this.justify = null;
923            else if (new RegExp(this.rb).test(exp.anchor)) this.justify = 'max';
924            this.pos = this.tpos - this.cb + this.tb;
925            if (this.dim == 'x') exp.maxWidth = Math.min(exp.maxWidth || this.full, exp.maxHeight * this.full / exp.y.full);
926            this.size = Math.min(this.full, exp['max' + this.ucwh] || this.full);
927            this.minSize = exp.allowSizeReduction ? Math.min(exp['min' + this.ucwh], this.full) : this.full;
928            if (exp.isImage && exp.useBox) {
929                this.size = exp[this.wh];
930                this.imgSize = this.full
931            }
932            if (this.dim == 'x' && hs.padToMinWidth) this.minSize = exp.minWidth;
933            this.target = exp['target' + this.dim.toUpperCase()];
934            this.marginMin = hs['margin' + this.uclt];
935            this.scroll = hs.page['scroll' + this.uclt];
936            this.clientSize = hs.page[this.wh]
937        },
938        setSize: function (i) {
939            var exp = this.exp;
940            if (exp.isImage && (exp.useBox || hs.padToMinWidth)) {
941                this.imgSize = i;
942                this.size = Math.max(this.size, this.imgSize);
943                exp.content.style[this.lt] = this.get('imgPad') + 'px'
944            } else this.size = i;
945            exp.content.style[this.wh] = i + 'px';
946            exp.wrapper.style[this.wh] = this.get('wsize') + 'px';
947            if (exp.outline) exp.outline.setPosition();
948            if (this.dim == 'x' && exp.overlayBox) exp.sizeOverlayBox(true);
949            if (this.dim == 'x' && exp.slideshow && exp.isImage) {
950                if (i == this.full) exp.slideshow.disable('full-expand');
951                else exp.slideshow.enable('full-expand')
952            }
953        },
954        setPos: function (i) {
955            this.pos = i;
956            this.exp.wrapper.style[this.lt] = i + 'px';
957            if (this.exp.outline) this.exp.outline.setPosition()
958        }
959    };
960    hs.Expander = function (a, params, custom, contentType) {
961        if (document.readyState && hs.ie && !hs.isReady) {
962            hs.addEventListener(document, 'ready', function () {
963                new hs.Expander(a, params, custom, contentType)
964            });
965            return
966        }
967        this.a = a;
968        this.custom = custom;
969        this.contentType = contentType || 'image';
970        this.isImage = !this.isHtml;
971        hs.continuePreloading = false;
972        this.overlays = [];
973        this.last = hs.last;
974        hs.last = null;
975        hs.init();
976        var key = this.key = hs.expanders.length;
977        for (var i = 0; i < hs.overrides.length; i++) {
978            var name = hs.overrides[i];
979            this[name] = params && typeof params[name] != 'undefined' ? params[name] : hs[name]
980        }
981        if (!this.src) this.src = a.href;
982        var el = (params && params.thumbnailId) ? hs.$(params.thumbnailId) : a;
983        el = this.thumb = el.getElementsByTagName('img')[0] || el;
984        this.thumbsUserSetId = el.id || a.id;
985        for (var i = 0; i < hs.expanders.length; i++) {
986            if (hs.expanders[i] && hs.expanders[i].a == a && !(this.last && this.transitions[1] == 'crossfade')) {
987                hs.expanders[i].focus();
988                return false
989            }
990        }
991        if (!hs.allowSimultaneousLoading) for (var i = 0; i < hs.expanders.length; i++) {
992            if (hs.expanders[i] && hs.expanders[i].thumb != el && !hs.expanders[i].onLoadStarted) {
993                hs.expanders[i].cancelLoading()
994            }
995        }
996        hs.expanders[key] = this;
997        if (!hs.allowMultipleInstances && !hs.upcoming) {
998            if (hs.expanders[key - 1]) hs.expanders[key - 1].close();
999            if (typeof hs.focusKey != 'undefined' && hs.expanders[hs.focusKey]) hs.expanders[hs.focusKey].close()
1000        }
1001        this.el = el;
1002        this.tpos = hs.getPosition(el);
1003        hs.getPageSize();
1004        var x = this.x = new hs.Dimension(this, 'x');
1005        x.calcThumb();
1006        var y = this.y = new hs.Dimension(this, 'y');
1007        y.calcThumb();
1008        this.wrapper = hs.createElement('div', {
1009            id: 'highslide-wrapper-' + this.key,
1010            className: 'highslide-wrapper ' + this.wrapperClassName
1011        },
1012        {
1013            visibility: 'hidden',
1014            position: 'absolute',
1015            zIndex: hs.zIndexCounter += 2
1016        },
1017        null, true);
1018        this.wrapper.onmouseover = this.wrapper.onmouseout = hs.wrapperMouseHandler;
1019        if (this.contentType == 'image' && this.outlineWhileAnimating == 2) this.outlineWhileAnimating = 0;
1020        if (!this.outlineType || (this.last && this.isImage && this.transitions[1] == 'crossfade')) {
1021            this[this.contentType + 'Create']()
1022        } else if (hs.pendingOutlines[this.outlineType]) {
1023            this.connectOutline();
1024            this[this.contentType + 'Create']()
1025        } else {
1026            this.showLoading();
1027            var exp = this;
1028            new hs.Outline(this.outlineType, function () {
1029                exp.connectOutline();
1030                exp[exp.contentType + 'Create']()
1031            })
1032        }
1033        return true
1034    };
1035    hs.Expander.prototype = {
1036        error: function (e) {
1037            window.location.href = this.src
1038        },
1039        connectOutline: function () {
1040            var outline = this.outline = hs.pendingOutlines[this.outlineType];
1041            outline.exp = this;
1042            outline.table.style.zIndex = this.wrapper.style.zIndex - 1;
1043            hs.pendingOutlines[this.outlineType] = null
1044        },
1045        showLoading: function () {
1046            if (this.onLoadStarted || this.loading) return;
1047            this.loading = hs.loading;
1048            var exp = this;
1049            this.loading.onclick = function () {
1050                exp.cancelLoading()
1051            };
1052            var exp = this,
1053                l = this.x.get('loadingPos') + 'px',
1054                t = this.y.get('loadingPos') + 'px';
1055            if (!tgt && this.last && this.transitions[1] == 'crossfade') var tgt = this.last;
1056            if (tgt) {
1057                l = tgt.x.get('loadingPosXfade') + 'px';
1058                t = tgt.y.get('loadingPosXfade') + 'px';
1059                this.loading.style.zIndex = hs.zIndexCounter++
1060            }
1061            setTimeout(function () {
1062                if (exp.loading) hs.setStyles(exp.loading, {
1063                    left: l,
1064                    top: t,
1065                    zIndex: hs.zIndexCounter++
1066                })
1067            },
1068            100)
1069        },
1070        imageCreate: function () {
1071            var exp = this;
1072            var img = document.createElement('img');
1073            this.content = img;
1074            img.onload = function () {
1075                if (hs.expanders[exp.key]) exp.contentLoaded()
1076            };
1077            if (hs.blockRightClick) img.oncontextmenu = function () {
1078                return false
1079            };
1080            img.className = 'highslide-image';
1081            hs.setStyles(img, {
1082                visibility: 'hidden',
1083                display: 'block',
1084                position: 'absolute',
1085                maxWidth: '9999px',
1086                zIndex: 3
1087            });
1088            img.title = hs.lang.restoreTitle;
1089            if (hs.safari) hs.container.appendChild(img);
1090            if (hs.ie && hs.flushImgSize) img.src = null;
1091            img.src = this.src;
1092            this.showLoading()
1093        },
1094        contentLoaded: function () {
1095            try {
1096                if (!this.content) return;
1097                this.content.onload = null;
1098                if (this.onLoadStarted) return;
1099                else this.onLoadStarted = true;
1100                var x = this.x,
1101                    y = this.y;
1102                if (this.loading) {
1103                    hs.setStyles(this.loading, {
1104                        top: '-9999px'
1105                    });
1106                    this.loading = null
1107                }
1108                x.full = this.content.width;
1109                y.full = this.content.height;
1110                hs.setStyles(this.content, {
1111                    width: x.t + 'px',
1112                    height: y.t + 'px'
1113                });
1114                this.wrapper.appendChild(this.content);
1115                hs.container.appendChild(this.wrapper);
1116                x.calcBorders();
1117                y.calcBorders();
1118                hs.setStyles(this.wrapper, {
1119                    left: (x.tpos + x.tb - x.cb) + 'px',
1120                    top: (y.tpos + x.tb - y.cb) + 'px'
1121                });
1122                this.initSlideshow();
1123                this.getOverlays();
1124                var ratio = x.full / y.full;
1125                x.calcExpanded();
1126                this.justify(x);
1127                y.calcExpanded();
1128                this.justify(y);
1129                if (this.overlayBox) this.sizeOverlayBox(0, 1);
1130                if (this.allowSizeReduction) {
1131                    this.correctRatio(ratio);
1132                    var ss = this.slideshow;
1133                    if (ss && this.last && ss.controls && ss.fixedControls) {
1134                        var pos = ss.overlayOptions.position || '',
1135                            p;
1136                        for (var dim in hs.oPos) for (var i = 0; i < 5; i++) {
1137                            p = this[dim];
1138                            if (pos.match(hs.oPos[dim][i])) {
1139                                p.pos = this.last[dim].pos + (this.last[dim].p1 - p.p1) + (this.last[dim].size - p.size) * [0, 0, .5, 1, 1][i];
1140                                if (ss.fixedControls == 'fit') {
1141                                    if (p.pos + p.size + p.p1 + p.p2 > p.scroll + p.clientSize - p.marginMax) p.pos = p.scroll + p.clientSize - p.size - p.marginMin - p.marginMax - p.p1 - p.p2;
1142                                    if (p.pos < p.scroll + p.marginMin) p.pos = p.scroll + p.marginMin
1143                                }
1144                            }
1145                        }
1146                    }
1147                    if (this.isImage && this.x.full > (this.x.imgSize || this.x.size)) {
1148                        this.createFullExpand();
1149                        if (this.overlays.length == 1) this.sizeOverlayBox()
1150                    }
1151                }
1152                this.show()
1153            } catch(e) {
1154                this.error(e)
1155            }
1156        },
1157        justify: function (p, moveOnly) {
1158            var tgtArr, tgt = p.target,
1159                dim = p == this.x ? 'x' : 'y';
1160            if (tgt && tgt.match(/ /)) {
1161                tgtArr = tgt.split(' ');
1162                tgt = tgtArr[0]
1163            }
1164            if (tgt && hs.$(tgt)) {
1165                p.pos = hs.getPosition(hs.$(tgt))[dim];
1166                if (tgtArr && tgtArr[1] && tgtArr[1].match(/^[-]?[0-9]+px$/)) p.pos += parseInt(tgtArr[1]);
1167                if (p.size < p.minSize) p.size = p.minSize
1168            } else if (p.justify == 'auto' || p.justify == 'center') {
1169                var hasMovedMin = false;
1170                var allowReduce = p.exp.allowSizeReduction;
1171                if (p.justify == 'center') p.pos = Math.round(p.scroll + (p.clientSize + p.marginMin - p.marginMax - p.get('wsize')) / 2);
1172                else p.pos = Math.round(p.pos - ((p.get('wsize') - p.t) / 2));
1173                if (p.pos < p.scroll + p.marginMin) {
1174                    p.pos = p.scroll + p.marginMin;
1175                    hasMovedMin = true
1176                }
1177                if (!moveOnly && p.size < p.minSize) {
1178                    p.size = p.minSize;
1179                    allowReduce = false
1180                }
1181                if (p.pos + p.get('wsize') > p.scroll + p.clientSize - p.marginMax) {
1182                    if (!moveOnly && hasMovedMin && allowReduce) {
1183                        p.size = Math.min(p.size, p.get(dim == 'y' ? 'fitsize' : 'maxsize'))
1184                    } else if (p.get('wsize') < p.get('fitsize')) {
1185                        p.pos = p.scroll + p.clientSize - p.marginMax - p.get('wsize')
1186                    } else {
1187                        p.pos = p.scroll + p.marginMin;
1188                        if (!moveOnly && allowReduce) p.size = p.get(dim == 'y' ? 'fitsize' : 'maxsize')
1189                    }
1190                }
1191                if (!moveOnly && p.size < p.minSize) {
1192                    p.size = p.minSize;
1193                    allowReduce = false
1194                }
1195            } else if (p.justify == 'max') {
1196                p.pos = Math.floor(p.pos - p.size + p.t)
1197            }
1198            if (p.pos < p.marginMin) {
1199                var tmpMin = p.pos;
1200                p.pos = p.marginMin;
1201                if (allowReduce && !moveOnly) p.size = p.size - (p.pos - tmpMin)
1202            }
1203        },
1204        correctRatio: function (ratio) {
1205            var x = this.x,
1206                y = this.y,
1207                changed = false,
1208                xSize = Math.min(x.full, x.size),
1209                ySize = Math.min(y.full, y.size),
1210                useBox = (this.useBox || hs.padToMinWidth);
1211            if (xSize / ySize > ratio) {
1212                xSize = ySize * ratio;
1213                if (xSize < x.minSize) {
1214                    xSize = x.minSize;
1215                    ySize = xSize / ratio
1216                }
1217                changed = true
1218            } else if (xSize / ySize < ratio) {
1219                ySize = xSize / ratio;
1220                changed = true
1221            }
1222            if (hs.padToMinWidth && x.full < x.minSize) {
1223                x.imgSize = x.full;
1224                y.size = y.imgSize = y.full
1225            } else if (this.useBox) {
1226                x.imgSize = xSize;
1227                y.imgSize = ySize
1228            } else {
1229                x.size = xSize;
1230                y.size = ySize
1231            }
1232            changed = this.fitOverlayBox(useBox ? null : ratio, changed);
1233            if (useBox && y.size < y.imgSize) {
1234                y.imgSize = y.size;
1235                x.imgSize = y.size * ratio
1236            }
1237            if (changed || useBox) {
1238                x.pos = x.tpos - x.cb + x.tb;
1239                x.minSize = x.size;
1240                this.justify(x, true);
1241                y.pos = y.tpos - y.cb + y.tb;
1242                y.minSize = y.size;
1243                this.justify(y, true);
1244                if (this.overlayBox) this.sizeOverlayBox()
1245            }
1246        },
1247        fitOverlayBox: function (ratio, changed) {
1248            var x = this.x,
1249                y = this.y;
1250            if (this.overlayBox) {
1251                while (y.size > this.minHeight && x.size > this.minWidth && y.get('wsize') > y.get('fitsize')) {
1252                    y.size -= 10;
1253                    if (ratio) x.size = y.size * ratio;
1254                    this.sizeOverlayBox(0, 1);
1255                    changed = true
1256                }
1257            }
1258            return changed
1259        },
1260        show: function () {
1261            var x = this.x,
1262                y = this.y;
1263            this.doShowHide('hidden');
1264            if (this.slideshow && this.slideshow.thumbstrip) this.slideshow.thumbstrip.selectThumb();
1265            this.changeSize(1, {
1266                wrapper: {
1267                    width: x.get('wsize'),
1268                    height: y.get('wsize'),
1269                    left: x.pos,
1270                    top: y.pos
1271                },
1272                content: {
1273                    left: x.p1 + x.get('imgPad'),
1274                    top: y.p1 + y.get('imgPad'),
1275                    width: x.imgSize || x.size,
1276                    height: y.imgSize || y.size
1277                }
1278            },
1279            hs.expandDuration)
1280        },
1281        changeSize: function (up, to, dur) {
1282            var trans = this.transitions,
1283                other = up ? (this.last ? this.last.a : null) : hs.upcoming,
1284            t = (trans[1] && other && hs.getParam(other, 'transitions')[1] == trans[1]) ? trans[1] : trans[0];
1285            if (this[t] && t != 'expand') {
1286                this[t](up, to);
1287                return
1288            }
1289            if (this.outline && !this.outlineWhileAnimating) {
1290                if (up) this.outline.setPosition();
1291                else this.outline.destroy()
1292            }
1293            if (!up) this.destroyOverlays();
1294            var exp = this,
1295                x = exp.x,
1296                y = exp.y,
1297                easing = this.easing;
1298            if (!up) easing = this.easingClose || easing;
1299            var after = up ?
1300            function () {
1301                if (exp.outline) exp.outline.table.style.visibility = "visible";
1302                setTimeout(function () {
1303                    exp.afterExpand()
1304                },
1305                50)
1306            } : function () {
1307                exp.afterClose()
1308            };
1309            if (up) hs.setStyles(this.wrapper, {
1310                width: x.t + 'px',
1311                height: y.t + 'px'
1312            });
1313            if (this.fadeInOut) {
1314                hs.setStyles(this.wrapper, {
1315                    opacity: up ? 0 : 1
1316                });
1317                hs.extend(to.wrapper, {
1318                    opacity: up
1319                })
1320            }
1321            hs.animate(this.wrapper, to.wrapper, {
1322                duration: dur,
1323                easing: easing,
1324                step: function (val, args) {
1325                    if (exp.outline && exp.outlineWhileAnimating && args.prop == 'top') {
1326                        var fac = up ? args.pos : 1 - args.pos;
1327                        var pos = {
1328                            w: x.t + (x.get('wsize') - x.t) * fac,
1329                            h: y.t + (y.get('wsize') - y.t) * fac,
1330                            x: x.tpos + (x.pos - x.tpos) * fac,
1331                            y: y.tpos + (y.pos - y.tpos) * fac
1332                        };
1333                        exp.outline.setPosition(pos, 0, 1)
1334                    }
1335                }
1336            });
1337            hs.animate(this.content, to.content, dur, easing, after);
1338            if (up) {
1339                this.wrapper.style.visibility = 'visible';
1340                this.content.style.visibility = 'visible';
1341                this.a.className += ' highslide-active-anchor'
1342            }
1343        },
1344        fade: function (up, to) {
1345            this.outlineWhileAnimating = false;
1346            var exp = this,
1347                t = up ? hs.expandDuration : 0;
1348            if (up) {
1349                hs.animate(this.wrapper, to.wrapper, 0);
1350                hs.setStyles(this.wrapper, {
1351                    opacity: 0,
1352                    visibility: 'visible'
1353                });
1354                hs.animate(this.content, to.content, 0);
1355                this.content.style.visibility = 'visible';
1356                hs.animate(this.wrapper, {
1357                    opacity: 1
1358                },
1359                t, null, function () {
1360                    exp.afterExpand()
1361                })
1362            }
1363            if (this.outline) {
1364                this.outline.table.style.zIndex = this.wrapper.style.zIndex;
1365                var dir = up || -1,
1366                    offset = this.outline.offset,
1367                    startOff = up ? 3 : offset,
1368                endOff = up ? offset : 3;
1369                for (var i = startOff; dir * i <= dir * endOff; i += dir, t += 25) {
1370                    (function () {
1371                        var o = up ? endOff - i : startOff - i;
1372                        setTimeout(function () {
1373                            exp.outline.setPosition(0, o, 1)
1374                        },
1375                        t)
1376                    })()
1377                }
1378            }
1379            if (up) {} else {
1380                setTimeout(function () {
1381                    if (exp.outline) exp.outline.destroy(exp.preserveContent);
1382                    exp.destroyOverlays();
1383                    hs.animate(exp.wrapper, {
1384                        opacity: 0
1385                    },
1386                    hs.restoreDuration, null, function () {
1387                        exp.afterClose()
1388                    })
1389                },
1390                t)
1391            }
1392        },
1393        crossfade: function (up, to, from) {
1394            if (!up) return;
1395            var exp = this,
1396                last = this.last,
1397                x = this.x,
1398                y = this.y,
1399                lastX = last.x,
1400                lastY = last.y,
1401                wrapper = this.wrapper,
1402                content = this.content,
1403                overlayBox = this.overlayBox;
1404            hs.removeEventListener(document, 'mousemove', hs.dragHandler);
1405            hs.setStyles(content, {
1406                width: (x.imgSize || x.size) + 'px',
1407                height: (y.imgSize || y.size) + 'px'
1408            });
1409            if (overlayBox) overlayBox.style.overflow = 'visible';
1410            this.outline = last.outline;
1411            if (this.outline) this.outline.exp = exp;
1412            last.outline = null;
1413            var fadeBox = hs.createElement('div', {
1414                className: 'highslide-image'
1415            },
1416            {
1417                position: 'absolute',
1418                zIndex: 4,
1419                overflow: 'hidden',
1420                display: 'none'
1421            });
1422            var names = {
1423                oldImg: last,
1424                newImg: this
1425            };
1426            for (var n in names) {
1427                this[n] = names[n].content.cloneNode(1);
1428                hs.setStyles(this[n], {
1429                    position: 'absolute',
1430                    border: 0,
1431                    visibility: 'visible'
1432                });
1433                fadeBox.appendChild(this[n])
1434            }
1435            wrapper.appendChild(fadeBox);
1436            if (overlayBox) {
1437                overlayBox.className = '';
1438                wrapper.appendChild(overlayBox)
1439            }
1440            fadeBox.style.display = '';
1441            last.content.style.display = 'none';
1442            if (hs.safari) {
1443                var match = navigator.userAgent.match(/Safari\/([0-9]{3})/);
1444                if (match && parseInt(match[1]) < 525) this.wrapper.style.visibility = 'visible'
1445            }
1446            hs.animate(wrapper, {
1447                width: x.size
1448            },
1449            {
1450                duration: hs.transitionDuration,
1451                step: function (val, args) {
1452                    var pos = args.pos,
1453                        invPos = 1 - pos;
1454                    var prop, size = {},
1455                        props = ['pos', 'size', 'p1', 'p2'];
1456                    for (var n in props) {
1457                        prop = props[n];
1458                        size['x' + prop] = invPos * lastX[prop] + pos * x[prop];
1459                        size['y' + prop] = invPos * lastY[prop] + pos * y[prop];
1460                        size.ximgSize = invPos * (lastX.imgSize || lastX.size) + pos * (x.imgSize || x.size);
1461                        size.ximgPad = invPos * lastX.get('imgPad') + pos * x.get('imgPad');
1462                        size.yimgSize = invPos * (lastY.imgSize || lastY.size) + pos * (y.imgSize || y.size);
1463                        size.yimgPad = invPos * lastY.get('imgPad') + pos * y.get('imgPad')
1464                    }
1465                    if (exp.outline) exp.outline.setPosition({
1466                        x: size.xpos,
1467                        y: size.ypos,
1468                        w: size.xsize + size.xp1 + size.xp2 + 2 * x.cb,
1469                        h: size.ysize + size.yp1 + size.yp2 + 2 * y.cb
1470                    });
1471                    last.wrapper.style.clip = 'rect(' + (size.ypos - lastY.pos) + 'px, ' + (size.xsize + size.xp1 + size.xp2 + size.xpos + 2 * lastX.cb - lastX.pos) + 'px, ' + (size.ysize + size.yp1 + size.yp2 + size.ypos + 2 * lastY.cb - lastY.pos) + 'px, ' + (size.xpos - lastX.pos) + 'px)';
1472                    hs.setStyles(content, {
1473                        top: (size.yp1 + y.get('imgPad')) + 'px',
1474                        left: (size.xp1 + x.get('imgPad')) + 'px',
1475                        marginTop: (y.pos - size.ypos) + 'px',
1476                        marginLeft: (x.pos - size.xpos) + 'px'
1477                    });
1478                    hs.setStyles(wrapper, {
1479                        top: size.ypos + 'px',
1480                        left: size.xpos + 'px',
1481                        width: (size.xp1 + size.xp2 + size.xsize + 2 * x.cb) + 'px',
1482                        height: (size.yp1 + size.yp2 + size.ysize + 2 * y.cb) + 'px'
1483                    });
1484                    hs.setStyles(fadeBox, {
1485                        width: (size.ximgSize || size.xsize) + 'px',
1486                        height: (size.yimgSize || size.ysize) + 'px',
1487                        left: (size.xp1 + size.ximgPad) + 'px',
1488                        top: (size.yp1 + size.yimgPad) + 'px',
1489                        visibility: 'visible'
1490                    });
1491                    hs.setStyles(exp.oldImg, {
1492                        top: (lastY.pos - size.ypos + lastY.p1 - size.yp1 + lastY.get('imgPad') - size.yimgPad) + 'px',
1493                        left: (lastX.pos - size.xpos + lastX.p1 - size.xp1 + lastX.get('imgPad') - size.ximgPad) + 'px'
1494                    });
1495                    hs.setStyles(exp.newImg, {
1496                        opacity: pos,
1497                        top: (y.pos - size.ypos + y.p1 - size.yp1 + y.get('imgPad') - size.yimgPad) + 'px',
1498                        left: (x.pos - size.xpos + x.p1 - size.xp1 + x.get('imgPad') - size.ximgPad) + 'px'
1499                    });
1500                    if (overlayBox) hs.setStyles(overlayBox, {
1501                        width: size.xsize + 'px',
1502                        height: size.ysize + 'px',
1503                        left: (size.xp1 + x.cb) + 'px',
1504                        top: (size.yp1 + y.cb) + 'px'
1505                    })
1506                },
1507                complete: function () {
1508                    wrapper.style.visibility = content.style.visibility = 'visible';
1509                    content.style.display = 'block';
1510                    fadeBox.style.display = 'none';
1511                    exp.a.className += ' highslide-active-anchor';
1512                    exp.afterExpand();
1513                    last.afterClose();
1514                    exp.last = null
1515                }
1516            })
1517        },
1518        reuseOverlay: function (o, el) {
1519            if (!this.last) return false;
1520            for (var i = 0; i < this.last.overlays.length; i++) {
1521                var oDiv = hs.$('hsId' + this.last.overlays[i]);
1522                if (oDiv && oDiv.hsId == o.hsId) {
1523                    this.genOverlayBox();
1524                    oDiv.reuse = this.key;
1525                    hs.push(this.overlays, this.last.overlays[i]);
1526                    return true
1527                }
1528            }
1529            return false
1530        },
1531        afterExpand: function () {
1532            this.isExpanded = true;
1533            this.focus();
1534            if (this.dimmingOpacity) hs.dim(this);
1535            if (hs.upcoming && hs.upcoming == this.a) hs.upcoming = null;
1536            this.prepareNextOutline();
1537            var p = hs.page,
1538                mX = hs.mouse.x + p.scrollLeft,
1539                mY = hs.mouse.y + p.scrollTop;
1540            this.mouseIsOver = this.x.pos < mX && mX < this.x.pos + this.x.get('wsize') && this.y.pos < mY && mY < this.y.pos + this.y.get('wsize');
1541            if (this.overlayBox) this.showOverlays()
1542        },
1543        prepareNextOutline: function () {
1544            var key = this.key;
1545            var outlineType = this.outlineType;
1546            new hs.Outline(outlineType, function () {
1547                try {
1548                    hs.expanders[key].preloadNext()
1549                } catch(e) {}
1550            })
1551        },
1552        preloadNext: function () {
1553            var next = this.getAdjacentAnchor(1);
1554            if (next && next.onclick.toString().match(/hs\.expand/)) var img = hs.createElement('img', {
1555                src: hs.getSrc(next)
1556            })
1557        },
1558        getAdjacentAnchor: function (op) {
1559            var current = this.getAnchorIndex(),
1560                as = hs.anchors.groups[this.slideshowGroup || 'none'];
1561            if (!as[current + op] && this.slideshow && this.slideshow.repeat) {
1562                if (op == 1) return as[0];
1563                else if (op == -1) return as[as.length - 1]
1564            }
1565            return as[current + op] || null
1566        },
1567        getAnchorIndex: function () {
1568            var arr = hs.getAnchors().groups[this.slideshowGroup || 'none'];
1569            if (arr) for (var i = 0; i < arr.length; i++) {
1570                if (arr[i] == this.a) return i
1571            }
1572            return null
1573        },
1574        getNumber: function () {
1575            if (this[this.numberPosition]) {
1576                var arr = hs.anchors.groups[this.slideshowGroup || 'none'];
1577                if (arr) {
1578                    var s = hs.lang.number.replace('%1', this.getAnchorIndex() + 1).replace('%2', arr.length);
1579                    this[this.numberPosition].innerHTML = '<div class="highsli
1579de-number">' + s + '</div>' + this[this.numberPosition].innerHTML
1580                }
1581            }
1582        },
1583        initSlideshow: function () {
1584            if (!this.last) {
1585                for (var i = 0; i < hs.slideshows.length; i++) {
1586                    var ss = hs.slideshows[i],
1587                        sg = ss.slideshowGroup;
1588                    if (typeof sg == 'undefined' || sg === null || sg === this.slideshowGroup) this.slideshow = new hs.Slideshow(this.key, ss)
1589                }
1590            } else {
1591                this.slideshow = this.last.slideshow
1592            }
1593            var ss = this.slideshow;
1594            if (!ss) return;
1595            var key = ss.expKey = this.key;
1596            ss.checkFirstAndLast();
1597            ss.disable('full-expand');
1598            if (ss.controls) {
1599                var o = ss.overlayOptions || {};
1600                o.overlayId = ss.controls;
1601                o.hsId = 'controls';
1602                this.createOverlay(o)
1603            }
1604            if (ss.thumbstrip) ss.thumbstrip.add(this);
1605            if (!this.last && this.autoplay) ss.play(true);
1606            if (ss.autoplay) {
1607                ss.autoplay = setTimeout(function () {
1608                    hs.next(key)
1609                },
1610                (ss.interval || 500))
1611            }
1612        },
1613        cancelLoading: function () {
1614            hs.discardElement(this.wrapper);
1615            hs.expanders[this.key] = null;
1616            if (hs.upcoming == this.a) hs.upcoming = null;
1617            hs.undim(this.key);
1618            if (this.loading) hs.loading.style.left = '-9999px'
1619        },
1620        writeCredits: function () {
1621            if (this.credits) return;
1622            this.credits = hs.createElement('a', {
1623                href: hs.creditsHref,
1624                target: hs.creditsTarget,
1625                className: 'highslide-credits',
1626                innerHTML: hs.lang.creditsText,
1627                title: hs.lang.creditsTitle
1628            });
1629            this.createOverlay({
1630                overlayId: this.credits,
1631                position: this.creditsPosition || 'top left',
1632                hsId: 'credits'
1633            })
1634        },
1635        getInline: function (types, addOverlay) {
1636            for (var i = 0; i < types.length; i++) {
1637                var type = types[i],
1638                    s = null;
1639                if (!this[type + 'Id'] && this.thumbsUserSetId) this[type + 'Id'] = type + '-for-' + this.thumbsUserSetId;
1640                if (this[type + 'Id']) this[type] = hs.getNode(this[type + 'Id']);
1641                if (!this[type] && !this[type + 'Text'] && this[type + 'Eval']) try {
1642                    s = eval(this[type + 'Eval'])
1643                } catch(e) {}
1644                if (!this[type] && this[type + 'Text']) {
1645                    s = this[type + 'Text']
1646                }
1647                if (!this[type] && !s) {
1648                    this[type] = hs.getNode(this.a['_' + type + 'Id']);
1649                    if (!this[type]) {
1650                        var next = this.a.nextSibling;
1651                        while (next && !hs.isHsAnchor(next)) {
1652                            if ((new RegExp('highslide-' + type)).test(next.className || null)) {
1653                                if (!next.id) this.a['_' + type + 'Id'] = next.id = 'hsId' + hs.idCounter++;
1654                                this[type] = hs.getNode(next.id);
1655                                break
1656                            }
1657                            next = next.nextSibling
1658                        }
1659                    }
1660                }
1661                if (!this[type] && !s && this.numberPosition == type) s = '\n';
1662                if (!this[type] && s) this[type] = hs.createElement('div', {
1663                    className: 'highslide-' + type,
1664                    innerHTML: s
1665                });
1666                if (addOverlay && this[type]) {
1667                    var o = {
1668                        position: (type == 'heading') ? 'above' : 'below'
1669                    };
1670                    for (var x in this[type + 'Overlay']) o[x] = this[type + 'Overlay'][x];
1671                    o.overlayId = this[type];
1672                    this.createOverlay(o)
1673                }
1674            }
1675        },
1676        doShowHide: function (visibility) {
1677            if (hs.hideSelects) this.showHideElements('SELECT', visibility);
1678            if (hs.hideIframes) this.showHideElements('IFRAME', visibility);
1679            if (hs.geckoMac) this.showHideElements('*', visibility)
1680        },
1681        showHideElements: function (tagName, visibility) {
1682            var els = document.getElementsByTagName(tagName);
1683            var prop = tagName == '*' ? 'overflow' : 'visibility';
1684            for (var i = 0; i < els.length; i++) {
1685                if (prop == 'visibility' || (document.defaultView.getComputedStyle(els[i], "").getPropertyValue('overflow') == 'auto' || els[i].getAttribute('hidden-by') != null)) {
1686                    var hiddenBy = els[i].getAttribute('hidden-by');
1687                    if (visibility == 'visible' && hiddenBy) {
1688                        hiddenBy = hiddenBy.replace('[' + this.key + ']', '');
1689                        els[i].setAttribute('hidden-by', hiddenBy);
1690                        if (!hiddenBy) els[i].style[prop] = els[i].origProp
1691                    } else if (visibility == 'hidden') {
1692                        var elPos = hs.getPosition(els[i]);
1693                        elPos.w = els[i].offsetWidth;
1694                        elPos.h = els[i].offsetHeight;
1695                        if (!this.dimmingOpacity) {
1696                            var clearsX = (elPos.x + elPos.w < this.x.get('opos') || elPos.x > this.x.get('opos') + this.x.get('osize'));
1697                            var clearsY = (elPos.y + elPos.h < this.y.get('opos') || elPos.y > this.y.get('opos') + this.y.get('osize'))
1698                        }
1699                        var wrapperKey = hs.getWrapperKey(els[i]);
1700                        if (!clearsX && !clearsY && wrapperKey != this.key) {
1701                            if (!hiddenBy) {
1702                                els[i].setAttribute('hidden-by', '[' + this.key + ']');
1703                                els[i].origProp = els[i].style[prop];
1704                                els[i].style[prop] = 'hidden'
1705                            } else if (hiddenBy.indexOf('[' + this.key + ']') == -1) {
1706                                els[i].setAttribute('hidden-by', hiddenBy + '[' + this.key + ']')
1707                            }
1708                        } else if ((hiddenBy == '[' + this.key + ']' || hs.focusKey == wrapperKey) && wrapperKey != this.key) {
1709                            els[i].setAttribute('hidden-by', '');
1710                            els[i].style[prop] = els[i].origProp || ''
1711                        } else if (hiddenBy && hiddenBy.indexOf('[' + this.key + ']') > -1) {
1712                            els[i].setAttribute('hidden-by', hiddenBy.replace('[' + this.key + ']', ''))
1713                        }
1714                    }
1715                }
1716            }
1717        },
1718        focus: function () {
1719            this.wrapper.style.zIndex = hs.zIndexCounter += 2;
1720            for (var i = 0; i < hs.expanders.length; i++) {
1721                if (hs.expanders[i] && i == hs.focusKey) {
1722                    var blurExp = hs.expanders[i];
1723                    blurExp.content.className += ' highslide-' + blurExp.contentType + '-blur';
1724                    blurExp.content.style.cursor = hs.ie ? 'hand' : 'pointer';
1725                    blurExp.content.title = hs.lang.focusTitle
1726                }
1727            }
1728            if (this.outline) this.outline.table.style.zIndex = this.wrapper.style.zIndex - 1;
1729            this.content.className = 'highslide-' + this.contentType;
1730            this.content.title = hs.lang.restoreTitle;
1731            if (hs.restoreCursor) {
1732                hs.styleRestoreCursor = window.opera ? 'pointer' : 'url(' + hs.graphicsDir + hs.restoreCursor + '), pointer';
1733                if (hs.ie && hs.uaVersion < 6) hs.styleRestoreCursor = 'hand';
1734                this.content.style.cursor = hs.styleRestoreCursor
1735            }
1736            hs.focusKey = this.key;
1737            hs.addEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler)
1738        },
1739        moveTo: function (x, y) {
1740            this.x.setPos(x);
1741            this.y.setPos(y)
1742        },
1743        resize: function (e) {
1744            var w, h, r = e.width / e.height;
1745            w = Math.max(e.width + e.dX, Math.min(this.minWidth, this.x.full));
1746            if (this.isImage && Math.abs(w - this.x.full) < 12) w = this.x.full;
1747            h = w / r;
1748            if (h < Math.min(this.minHeight, this.y.full)) {
1749                h = Math.min(this.minHeight, this.y.full);
1750                if (this.isImage) w = h * r
1751            }
1752            this.resizeTo(w, h)
1753        },
1754        resizeTo: function (w, h) {
1755            this.y.setSize(h);
1756            this.x.setSize(w);
1757            this.wrapper.style.height = this.y.get('wsize') + 'px'
1758        },
1759        close: function () {
1760            if (this.isClosing || !this.isExpanded) return;
1761            if (this.transitions[1] == 'crossfade' && hs.upcoming) {
1762                hs.getExpander(hs.upcoming).cancelLoading();
1763                hs.upcoming = null
1764            }
1765            this.isClosing = true;
1766            if (this.slideshow && !hs.upcoming) this.slideshow.pause();
1767            hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
1768            try {
1769                this.content.style.cursor = 'default';
1770                this.changeSize(0, {
1771                    wrapper: {
1772                        width: this.x.t,
1773                        height: this.y.t,
1774                        left: this.x.tpos - this.x.cb + this.x.tb,
1775                        top: this.y.tpos - this.y.cb + this.y.tb
1776                    },
1777                    content: {
1778                        left: 0,
1779                        top: 0,
1780                        width: this.x.t,
1781                        height: this.y.t
1782                    }
1783                },
1784                hs.restoreDuration)
1785            } catch(e) {
1786                this.afterClose()
1787            }
1788        },
1789        createOverlay: function (o) {
1790            var el = o.overlayId,
1791                relToVP = (o.relativeTo == 'viewport' && !/panel$/.test(o.position));
1792            if (typeof el == 'string') el = hs.getNode(el);
1793            if (o.html) el = hs.createElement('div', {
1794                innerHTML: o.html
1795            });
1796            if (!el || typeof el == 'string') return;
1797            el.style.display = 'block';
1798            o.hsId = o.hsId || o.overlayId;
1799            if (this.transitions[1] == 'crossfade' && this.reuseOverlay(o, el)) return;
1800            this.genOverlayBox();
1801            var width = o.width && /^[0-9]+(px|%)$/.test(o.width) ? o.width : 'auto';
1802            if (/^(left|right)panel$/.test(o.position) && !/^[0-9]+px$/.test(o.width)) width = '200px';
1803            var overlay = hs.createElement('div', {
1804                id: 'hsId' + hs.idCounter++,
1805                hsId: o.hsId
1806            },
1807            {
1808                position: 'absolute',
1809                visibility: 'hidden',
1810                width: width,
1811                direction: hs.lang.cssDirection || '',
1812                opacity: 0
1813            },
1814            relToVP ? hs.viewport : this.overlayBox, true);
1815            if (relToVP) overlay.hsKey = this.key;
1816            overlay.appendChild(el);
1817            hs.extend(overlay, {
1818                opacity: 1,
1819                offsetX: 0,
1820                offsetY: 0,
1821                dur: (o.fade === 0 || o.fade === false || (o.fade == 2 && hs.ie)) ? 0 : 250
1822            });
1823            hs.extend(overlay, o);
1824            if (this.gotOverlays) {
1825                this.positionOverlay(overlay);
1826                if (!overlay.hideOnMouseOut || this.mouseIsOver) hs.animate(overlay, {
1827                    opacity: overlay.opacity
1828                },
1829                overlay.dur)
1830            }
1831            hs.push(this.overlays, hs.idCounter - 1)
1832        },
1833        positionOverlay: function (overlay) {
1834            var p = overlay.position || 'middle center',
1835                relToVP = (overlay.relativeTo == 'viewport'),
1836                offX = overlay.offsetX,
1837                offY = overlay.offsetY;
1838            if (relToVP) {
1839                hs.viewport.style.display = 'block';
1840                overlay.hsKey = this.key;
1841                if (overlay.offsetWidth > overlay.parentNode.offsetWidth) overlay.style.width = '100%'
1842            } else if (overlay.parentNode != this.overlayBox) this.overlayBox.appendChild(overlay);
1843            if (/left$/.test(p)) overlay.style.left = offX + 'px';
1844            if (/center$/.test(p)) hs.setStyles(overlay, {
1845                left: '50%',
1846                marginLeft: (offX - Math.round(overlay.offsetWidth / 2)) + 'px'
1847            });
1848            if (/right$/.test(p)) overlay.style.right = -offX + 'px';
1849            if (/^leftpanel$/.test(p)) {
1850                hs.setStyles(overlay, {
1851                    right: '100%',
1852                    marginRight: this.x.cb + 'px',
1853                    top: -this.y.cb + 'px',
1854                    bottom: -this.y.cb + 'px',
1855                    overflow: 'auto'
1856                });
1857                this.x.p1 = overlay.offsetWidth
1858            } else if (/^rightpanel$/.test(p)) {
1859                hs.setStyles(overlay, {
1860                    left: '100%',
1861                    marginLeft: this.x.cb + 'px',
1862                    top: -this.y.cb + 'px',
1863                    bottom: -this.y.cb + 'px',
1864                    overflow: 'auto'
1865                });
1866                this.x.p2 = overlay.offsetWidth
1867            }
1868            var parOff = overlay.parentNode.offsetHeight;
1869            overlay.style.height = 'auto';
1870            if (relToVP && overlay.offsetHeight > parOff) overlay.style.height = hs.ieLt7 ? parOff + 'px' : '100%';
1871            if (/^top/.test(p)) overlay.style.top = offY + 'px';
1872            if (/^middle/.test(p)) hs.setStyles(overlay, {
1873                top: '50%',
1874                marginTop: (offY - Math.round(overlay.offsetHeight / 2)) + 'px'
1875            });
1876            if (/^bottom/.test(p)) overlay.style.bottom = -offY + 'px';
1877            if (/^above$/.test(p)) {
1878                hs.setStyles(overlay, {
1879                    left: (-this.x.p1 - this.x.cb) + 'px',
1880                    right: (-this.x.p2 - this.x.cb) + 'px',
1881                    bottom: '100%',
1882                    marginBottom: this.y.cb + 'px',
1883                    width: 'auto'
1884                });
1885                this.y.p1 = overlay.offsetHeight
1886            } else if (/^below$/.test(p)) {
1887                hs.setStyles(overlay, {
1888                    position: 'relative',
1889                    left: (-this.x.p1 - this.x.cb) + 'px',
1890                    right: (-this.x.p2 - this.x.cb) + 'px',
1891                    top: '100%',
1892                    marginTop: this.y.cb + 'px',
1893                    width: 'auto'
1894                });
1895                this.y.p2 = overlay.offsetHeight;
1896                overlay.style.position = 'absolute'
1897            }
1898        },
1899        getOverlays: function () {
1900            this.getInline(['heading', 'caption'], true);
1901            this.getNumber();
1902            if (this.heading && this.dragByHeading) this.heading.className += ' highsli
1902de-move';
1903            if (hs.showCredits) this.writeCredits();
1904            for (var i = 0; i < hs.overlays.length; i++) {
1905                var o = hs.overlays[i],
1906                    tId = o.thumbnailId,
1907                    sg = o.slideshowGroup;
1908                if ((!tId && !sg) || (tId && tId == this.thumbsUserSetId) || (sg && sg === this.slideshowGroup)) {
1909                    this.createOverlay(o)
1910                }
1911            }
1912            var os = [];
1913            for (var i = 0; i < this.overlays.length; i++) {
1914                var o = hs.$('hsId' + this.overlays[i]);
1915                if (/panel$/.test(o.position)) this.positionOverlay(o);
1916                else hs.push(os, o)
1917            }
1918            for (var i = 0; i < os.length; i++) this.positionOverlay(os[i]);
1919            this.gotOverlays = true
1920        },
1921        genOverlayBox: function () {
1922            if (!this.overlayBox) this.overlayBox = hs.createElement('div', {
1923                className: this.wrapperClassName
1924            },
1925            {
1926                position: 'absolute',
1927                width: (this.x.size || (this.useBox ? this.width : null) || this.x.full) + 'px',
1928                height: (this.y.size || this.y.full) + 'px',
1929                visibility: 'hidden',
1930                overflow: 'hidden',
1931                zIndex: hs.ie ? 4 : 'auto'
1932            },
1933            hs.container, true)
1934        },
1935        sizeOverlayBox: function (doWrapper, doPanels) {
1936            var overlayBox = this.overlayBox,
1937                x = this.x,
1938                y = this.y;
1939            hs.setStyles(overlayBox, {
1940                width: x.size + 'px',
1941                height: y.size + 'px'
1942            });
1943            if (doWrapper || doPanels) {
1944                for (var i = 0; i < this.overlays.length; i++) {
1945                    var o = hs.$('hsId' + this.overlays[i]);
1946                    var ie6 = (hs.ieLt7 || document.compatMode == 'BackCompat');
1947                    if (o && /^(above|below)$/.test(o.position)) {
1948                        if (ie6) {
1949                            o.style.width = (overlayBox.offsetWidth + 2 * x.cb + x.p1 + x.p2) + 'px'
1950                        }
1951                        y[o.position == 'above' ? 'p1' : 'p2'] = o.offsetHeight
1952                    }
1953                    if (o && ie6 && /^(left|right)panel$/.test(o.position)) {
1954                        o.style.height = (overlayBox.offsetHeight + 2 * y.cb) + 'px'
1955                    }
1956                }
1957            }
1958            if (doWrapper) {
1959                hs.setStyles(this.content, {
1960                    top: y.p1 + 'px'
1961                });
1962                hs.setStyles(overlayBox, {
1963                    top: (y.p1 + y.cb) + 'px'
1964                })
1965            }
1966        },
1967        showOverlays: function () {
1968            var b = this.overlayBox;
1969            b.className = '';
1970            hs.setStyles(b, {
1971                top: (this.y.p1 + this.y.cb) + 'px',
1972                left: (this.x.p1 + this.x.cb) + 'px',
1973                overflow: 'visible'
1974            });
1975            if (hs.safari) b.style.visibility = 'visible';
1976            this.wrapper.appendChild(b);
1977            for (var i = 0; i < this.overlays.length; i++) {
1978                var o = hs.$('hsId' + this.overlays[i]);
1979                o.style.zIndex = o.hsId == 'controls' ? 5 : 4;
1980                if (!o.hideOnMouseOut || this.mouseIsOver) {
1981                    o.style.visibility = 'visible';
1982                    hs.setStyles(o, {
1983                        visibility: 'visible',
1984                        display: ''
1985                    });
1986                    hs.animate(o, {
1987                        opacity: o.opacity
1988                    },
1989                    o.dur)
1990                }
1991            }
1992        },
1993        destroyOverlays: function () {
1994            if (!this.overlays.length) return;
1995            if (this.slideshow) {
1996                var c = this.slideshow.controls;
1997                if (c && hs.getExpander(c) == this) c.parentNode.removeChild(c)
1998            }
1999            for (var i = 0; i < this.overlays.length; i++) {
2000                var o = hs.$('hsId' + this.overlays[i]);
2001                if (o && o.parentNode == hs.viewport && hs.getExpander(o) == this) hs.discardElement(o)
2002            }
2003            hs.discardElement(this.overlayBox)
2004        },
2005        createFullExpand: function () {
2006            if (this.slideshow && this.slideshow.controls) {
2007                this.slideshow.enable('full-expand');
2008                return
2009            }
2010            this.fullExpandLabel = hs.createElement('a', {
2011                href: 'javascript:hs.expanders[' + this.key + '].doFullExpand();',
2012                title: hs.lang.fullExpandTitle,
2013                className: 'highslide-full-expand'
2014            });
2015            this.createOverlay({
2016                overlayId: this.fullExpandLabel,
2017                position: hs.fullExpandPosition,
2018                hideOnMouseOut: true,
2019                opacity: hs.fullExpandOpacity
2020            })
2021        },
2022        doFullExpand: function () {
2023            try {
2024                if (this.fullExpandLabel) hs.discardElement(this.fullExpandLabel);
2025                this.focus();
2026                var xSize = this.x.size;
2027                this.resizeTo(this.x.full, this.y.full);
2028                var xpos = this.x.pos - (this.x.size - xSize) / 2;
2029                if (xpos < hs.marginLeft) xpos = hs.marginLeft;
2030                this.moveTo(xpos, this.y.pos);
2031                this.doShowHide('hidden')
2032            } catch(e) {
2033                this.error(e)
2034            }
2035        },
2036        afterClose: function () {
2037            this.a.className = this.a.className.replace('highsli
2037de-active-anchor', '');
2038            this.doShowHide('visible');
2039            if (this.outline && this.outlineWhileAnimating) this.outline.destroy();
2040            hs.discardElement(this.wrapper);
2041            this.destroyOverlays();
2042            if (!hs.viewport.childNodes.length) hs.viewport.style.display = 'none';
2043            if (this.dimmingOpacity) hs.undim(this.key);
2044            hs.expanders[this.key] = null;
2045            hs.reOrder()
2046        }
2047    };
2048    hs.Slideshow = function (expKey, options) {
2049        if (hs.dynamicallyUpdateAnchors !== false) hs.updateAnchors();
2050        this.expKey = expKey;
2051        for (var x in options) this[x] = options[x];
2052        if (this.useControls) this.getControls();
2053        if (this.thumbstrip) this.thumbstrip = hs.Thumbstrip(this)
2054    };
2055    hs.Slideshow.prototype = {
2056        getControls: function () {
2057            this.controls = hs.createElement('div', {
2058                innerHTML: hs.replaceLang(hs.skin.controls)
2059            },
2060            null, hs.container);
2061            var buttons = ['play', 'pause', 'previous', 'next', 'move', 'full-expand', 'close'];
2062            this.btn = {};
2063            var pThis = this;
2064            for (var i = 0; i < buttons.length; i++) {
2065                this.btn[buttons[i]] = hs.getElementByClass(this.controls, 'li', 'highslide-' + buttons[i]);
2066                this.enable(buttons[i])
2067            }
2068            this.btn.pause.style.display = 'none'
2069        },
2070        checkFirstAndLast: function () {
2071            if (this.repeat || !this.controls) return;
2072            var exp = hs.expanders[this.expKey],
2073                cur = exp.getAnchorIndex(),
2074                re = /disabled$/;
2075            if (cur == 0) this.disable('previous');
2076            else if (re.test(this.btn.previous.getElementsByTagName('a')[0].className)) this.enable('previous');
2077            if (cur + 1 == hs.anchors.groups[exp.slideshowGroup || 'none'].length) {
2078                this.disable('next');
2079                this.disable('play')
2080            } else if (re.test(this.btn.next.getElementsByTagName('a')[0].className)) {
2081                this.enable('next');
2082                this.enable('play')
2083            }
2084        },
2085        enable: function (btn) {
2086            if (!this.btn) return;
2087            var sls = this,
2088                a = this.btn[btn].getElementsByTagName('a')[0],
2089                re = /disabled$/;
2090            a.onclick = function () {
2091                sls[btn]();
2092                return false
2093            };
2094            if (re.test(a.className)) a.className = a.className.replace(re, '')
2095        },
2096        disable: function (btn) {
2097            if (!this.btn) return;
2098            var a = this.btn[btn].getElementsByTagName('a')[0];
2099            a.onclick = function () {
2100                return false
2101            };
2102            if (!/disabled$/.test(a.className)) a.className += ' disabled'
2103        },
2104        hitSpace: function () {
2105            if (this.autoplay) this.pause();
2106            else this.play()
2107        },
2108        play: function (wait) {
2109            if (this.btn) {
2110                this.btn.play.style.display = 'none';
2111                this.btn.pause.style.display = ''
2112            }
2113            this.autoplay = true;
2114            if (!wait) hs.next(this.expKey)
2115        },
2116        pause: function () {
2117            if (this.btn) {
2118                this.btn.pause.style.display = 'none';
2119                this.btn.play.style.display = ''
2120            }
2121            clearTimeout(this.autoplay);
2122            this.autoplay = null
2123        },
2124        previous: function () {
2125            this.pause();
2126            hs.previous(this.btn.previous)
2127        },
2128        next: function () {
2129            this.pause();
2130            hs.next(this.btn.next)
2131        },
2132        move: function () {},
2133        'full-expand': function () {
2134            hs.getExpander().doFullExpand()
2135        },
2136        close: function () {
2137            hs.close(this.btn.close)
2138        }
2139    };
2140    hs.Thumbstrip = function (slideshow) {
2141        function add(exp) {
2142            hs.extend(options || {},
2143            {
2144                overlayId: dom,
2145                hsId: 'thumbstrip',
2146                className: 'highslide-thumbstrip-' + mode + '-overlay ' + (options.className || '')
2147            });
2148            if (hs.ieLt7) options.fade = 0;
2149            exp.createOverlay(options);
2150            hs.setStyles(dom.parentNode, {
2151                overflow: 'hidden'
2152            })
2153        };
2154
2155        function scroll(delta) {
2156            selectThumb(undefined, Math.round(delta * dom[isX ? 'offsetWidth' : 'offsetHeight'] * 0.7))
2157        };
2158
2159        function selectThumb(i, scrollBy) {
2160            if (i === undefined) for (var j = 0; j < group.length; j++) {
2161                if (group[j] == hs.expanders[slideshow.expKey].a) {
2162                    i = j;
2163                    break
2164                }
2165            }
2166            if (i === undefined) return;
2167            var as = dom.getElementsByTagName('a'),
2168                active = as[i],
2169                cell = active.parentNode,
2170                left = isX ? 'Left' : 'Top',
2171            right = isX ? 'Right' : 'Bottom',
2172            width = isX ? 'Width' : 'Height',
2173            offsetLeft = 'offset' + left,
2174            offsetWidth = 'offset' + width,
2175            overlayWidth = div.parentNode.parentNode[offsetWidth],
2176            minTblPos = overlayWidth - table[offsetWidth],
2177            curTblPos = parseInt(table.style[isX ? 'left' : 'top']) || 0,
2178            tblPos = curTblPos,
2179            mgnRight = 20;
2180            if (scrollBy !== undefined) {
2181                tblPos = curTblPos - scrollBy;
2182                if (tblPos > 0) tblPos = 0;
2183                if (tblPos < minTblPos) tblPos = minTblPos
2184            } else {
2185                for (var j = 0; j < as.length; j++) as[j].className = '';
2186                active.className = 'highslide-active-anchor';
2187                var activeLeft = i > 0 ? as[i - 1].parentNode[offsetLeft] : cell[offsetLeft],
2188                activeRight = cell[offsetLeft] + cell[offsetWidth] + (as[i + 1] ? as[i + 1].parentNode[offsetWidth] : 0);
2189                if (activeRight > overlayWidth - curTblPos) tblPos = overlayWidth - activeRight;
2190                else if (activeLeft < -curTblPos) tblPos = -activeLeft
2191            }
2192            var markerPos = cell[offsetLeft] + (cell[offsetWidth] - marker[offsetWidth]) / 2 + tblPos;
2193            hs.animate(table, isX ? {
2194                left: tblPos
2195            } : {
2196                top: tblPos
2197            },
2198            null, 'easeOutQuad');
2199            hs.animate(marker, isX ? {
2200                left: markerPos
2201            } : {
2202                top: markerPos
2203            },
2204            null, 'easeOutQuad');
2205            scrollUp.style.display = tblPos < 0 ? 'block' : 'none';
2206            scrollDown.style.display = (tblPos > minTblPos) ? 'block' : 'none'
2207        };
2208        var group = hs.anchors.groups[hs.expanders[slideshow.expKey].slideshowGroup || 'none'],
2209            options = slideshow.thumbstrip,
2210            mode = options.mode || 'horizontal',
2211            floatMode = (mode == 'float'),
2212            tree = floatMode ? ['div', 'ul', 'li', 'span'] : ['table', 'tbody', 'tr', 'td'],
2213        isX = (mode == 'horizontal'),
2214        dom = hs.createElement('div', {
2215            className: 'highslide-thumbstrip highslide-thumbstrip-' + mode,
2216            innerHTML: '<div class="highslide-thumbstrip-inner">' + '<' + tree[0] + '><' + tree[1] + '></' + tree[1] + '></' + tree[0] + '></div>' + '<div class="highslide-scroll-up"><div></div></div>' + '<div class="highslide-scroll-down"><div></div></div>' + '<div class="highslide-marker"><div></div></div>'
2217        },
2218        {
2219            display: 'none'
2220        },
2221        hs.container),
2222        domCh = dom.childNodes,
2223        div = domCh[0],
2224        scrollUp = domCh[1],
2225        scrollDown = domCh[2],
2226        marker = domCh[3],
2227        table = div.firstChild,
2228        tbody = dom.getElementsByTagName(tree[1])[0],
2229        tr;
2230        for (var i = 0; i < group.length; i++) {
2231            if (i == 0 || !isX) tr = hs.createElement(tree[2], null, null, tbody);
2232            (function () {
2233                var a = group[i],
2234                    cell = hs.createElement(tree[3], null, null, tr),
2235                    pI = i;
2236                hs.createElement('a', {
2237                    href: a.href,
2238                    onclick: function () {
2239                        hs.getExpander(this).focus();
2240                        return hs.transit(a)
2241                    },
2242                    innerHTML: hs.stripItemFormatter ? hs.stripItemFormatter(a) : a.innerHTML
2243                },
2244                null, cell)
2245            })()
2246        }
2247        if (!floatMode) {
2248            scrollUp.onclick = function () {
2249                scroll(-1)
2250            };
2251            scrollDown.onclick = function () {
2252                scroll(1)
2253            };
2254            hs.addEventListener(tbody, document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll', function (e) {
2255                var delta = 0;
2256                e = e || window.event;
2257                if (e.wheelDelta) {
2258                    delta = e.wheelDelta / 120;
2259                    if (hs.opera) delta = -delta
2260                } else if (e.detail) {
2261                    delta = -e.detail / 3
2262                }
2263                if (delta) scroll(-delta * 0.2);
2264                if (e.preventDefault) e.preventDefault();
2265                e.returnValue = false
2266            })
2267        }
2268        return {
2269            add: add,
2270            selectThumb: selectThumb
2271        }
2272    };
2273    hs.langDefaults = hs.lang;
2274    var HsExpander = hs.Expander;
2275    if (hs.ie) {
2276        (function () {
2277            try {
2278                document.documentElement.doScroll('left')
2279            } catch(e) {
2280                setTimeout(arguments.callee, 50);
2281                return
2282            }
2283            hs.ready()
2284        })()
2285    }
2286    hs.addEventListener(document, 'DOMContentLoaded', hs.ready);
2287    hs.addEventListener(window, 'load', hs.ready);
2288    hs.addEventListener(document, 'ready', function () {
2289        if (hs.expandCursor || hs.dimmingOpacity) {
2290            var style = hs.createElement('style', {
2291                type: 'text/css'
2292            },
2293            null, document.getElementsByTagName('HEAD')[0]);
2294
2295            function addRule(sel, dec) {
2296                if (!hs.ie) {
2297                    style.appendChild(document.createTextNode(sel + " {" + dec + "}"))
2298                } else {
2299                    var last = document.styleSheets[document.styleSheets.length - 1];
2300                    if (typeof(last.addRule) == "object") last.addRule(sel, dec)
2301                }
2302            }
2303
2304            function fix(prop) {
2305                return 'expression( ( ( ignoreMe = document.documentElement.' + prop + ' ? document.documentElement.' + prop + ' : document.body.' + prop + ' ) ) + \'px\' );'
2306            }
2307            if (hs.expandCursor) addRule('.highslide img', 'cursor: url(' + hs.graphicsDir + hs.expandCursor + '), pointer !important;');
2308            addRule('.highslide-viewport-size', (hs.ieLt7 || (hs.ie && document.compatMode == 'BackCompat')) ? 'position: absolute; ' + 'left:' + fix('scrollLeft') + 'top:' + fix('scrollTop') + 'width:' + fix('clientWidth') + 'height:' + fix('clientHeight') : 'position: fixed; width: 100%; height: 100%; left: 0; top: 0')
2309        }
2310    });
2311    hs.addEventListener(window, 'resize', function () {
2312        hs.getPageSize();
2313        if (hs.viewport) for (var i = 0; i < hs.viewport.childNodes.length; i++) {
2314            var node = hs.viewport.childNodes[i],
2315                exp = hs.getExpander(node);
2316            exp.positionOverlay(node);
2317            if (node.hsId == 'thumbstrip') exp.slideshow.thumbstrip.selectThumb()
2318        }
2319    });
2320    hs.addEventListener(document, 'mousemove', function (e) {
2321        hs.mouse = {
2322            x: e.clientX,
2323            y: e.clientY
2324        }
2325    });
2326    hs.addEventListener(document, 'mousedown', hs.mouseClickHandler);
2327    hs.addEventListener(document, 'mouseup', hs.mouseClickHandler);
2328    hs.addEventListener(document, 'ready', hs.getAnchors);
2329    hs.addEventListener(window, 'load', hs.preloadImages)
2330}

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.