[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/highslide/ -> highslide-full.js (source)

   1  /** 

   2   * Name:    Highslide JS

   3   * Version: 4.1.12 (2011-03-28)

   4   * Config:  default +events +unobtrusive +imagemap +slideshow +positioning +transitions +viewport +thumbstrip +inline +ajax +iframe +flash
   5   * Author:  Torstein Hønsi

   6   * Support: www.highslide.com/support

   7   * License: www.highslide.com/#license

   8   */
   9  if (!hs) { var hs = {
  10  // Language strings

  11  lang : {
  12      cssDirection: 'ltr',
  13      loadingText : 'Loading...',
  14      loadingTitle : 'Click to cancel',
  15      focusTitle : 'Click to bring to front',
  16      fullExpandTitle : 'Expand to actual size (f)',
  17      creditsText : 'Powered by <i>Highslide JS</i>',
  18      creditsTitle : 'Go to the Highslide JS homepage',
  19      previousText : 'Previous',
  20      nextText : 'Next', 
  21      moveText : 'Move',
  22      closeText : 'Close', 
  23      closeTitle : 'Close (esc)', 
  24      resizeTitle : 'Resize',
  25      playText : 'Play',
  26      playTitle : 'Play slideshow (spacebar)',
  27      pauseText : 'Pause',
  28      pauseTitle : 'Pause slideshow (spacebar)',
  29      previousTitle : 'Previous (arrow left)',
  30      nextTitle : 'Next (arrow right)',
  31      moveTitle : 'Move',
  32      fullExpandText : '1:1',
  33      number: 'Image %1 of %2',
  34      restoreTitle : 'Click to close image, click and drag to move. Use arrow keys for next and previous.'
  35  },
  36  // See http://highslide.com/ref for examples of settings  

  37  graphicsDir : 'highslide/graphics/',
  38  expandCursor : 'zoomin.cur', // null disables
  39  restoreCursor : 'zoomout.cur', // null disables
  40  expandDuration : 250, // milliseconds
  41  restoreDuration : 250,
  42  marginLeft : 15,
  43  marginRight : 15,
  44  marginTop : 15,
  45  marginBottom : 15,
  46  zIndexCounter : 1001, // adjust to other absolutely positioned elements
  47  loadingOpacity : 0.75,
  48  allowMultipleInstances: true,
  49  numberOfImagesToPreload : 5,
  50  outlineWhileAnimating : 2, // 0 = never, 1 = always, 2 = HTML only 
  51  outlineStartOffset : 3, // ends at 10
  52  padToMinWidth : false, // pad the popup width to make room for wide caption
  53  fullExpandPosition : 'bottom right',
  54  fullExpandOpacity : 1,
  55  showCredits : true, // you can set this to false if you want
  56  creditsHref : 'http://highslide.com/',
  57  creditsTarget : '_self',
  58  enableKeyListener : true,
  59  openerTagNames : ['a', 'area'], // Add more to allow slideshow indexing
  60  transitions : [],
  61  transitionDuration: 250,
  62  dimmingOpacity: 0, // Lightbox style dimming background
  63  dimmingDuration: 50, // 0 for instant dimming
  64  
  65  allowWidthReduction : false,
  66  allowHeightReduction : true,
  67  preserveContent : true, // Preserve changes made to the content and position of HTML popups.
  68  objectLoadTime : 'before', // Load iframes 'before' or 'after' expansion.
  69  cacheAjax : true, // Cache ajax popups for instant display. Can be overridden for each popup.
  70  anchor : 'auto', // where the image expands from
  71  align : 'auto', // position in the client (overrides anchor)
  72  targetX: null, // the id of a target element
  73  targetY: null,
  74  dragByHeading: true,
  75  minWidth: 200,
  76  minHeight: 200,
  77  allowSizeReduction: true, // allow the image to reduce to fit client size. If false, this overrides minWidth and minHeight
  78  outlineType : 'drop-shadow', // set null to disable outlines
  79  skin : {
  80      controls:
  81          '<div class="highslide-controls"><ul>'+
  82              '<li class="highslide-previous">'+
  83                  '<a href="#" title="{hs.lang.previousTitle}">'+
  84                  '<span>{hs.lang.previousText}</span></a>'+
  85              '</li>'+
  86              '<li class="highslide-play">'+
  87                  '<a href="#" title="{hs.lang.playTitle}">'+
  88                  '<span>{hs.lang.playText}</span></a>'+
  89              '</li>'+
  90              '<li class="highslide-pause">'+
  91                  '<a href="#" title="{hs.lang.pauseTitle}">'+
  92                  '<span>{hs.lang.pauseText}</span></a>'+
  93              '</li>'+
  94              '<li class="highslide-next">'+
  95                  '<a href="#" title="{hs.lang.nextTitle}">'+
  96                  '<span>{hs.lang.nextText}</span></a>'+
  97              '</li>'+
  98              '<li class="highslide-move">'+
  99                  '<a href="#" title="{hs.lang.moveTitle}">'+
 100                  '<span>{hs.lang.moveText}</span></a>'+
 101              '</li>'+
 102              '<li class="highslide-full-expand">'+
 103                  '<a href="#" title="{hs.lang.fullExpandTitle}">'+
 104                  '<span>{hs.lang.fullExpandText}</span></a>'+
 105              '</li>'+
 106              '<li class="highslide-close">'+
 107                  '<a href="#" title="{hs.lang.closeTitle}" >'+
 108                  '<span>{hs.lang.closeText}</span></a>'+
 109              '</li>'+
 110          '</ul></div>'
 111      ,
 112      contentWrapper:
 113          '<div class="highslide-header"><ul>'+
 114              '<li class="highslide-previous">'+
 115                  '<a href="#" title="{hs.lang.previousTitle}" onclick="return hs.previous(this)">'+
 116                  '<span>{hs.lang.previousText}</span></a>'+
 117              '</li>'+
 118              '<li class="highslide-next">'+
 119                  '<a href="#" title="{hs.lang.nextTitle}" onclick="return hs.next(this)">'+
 120                  '<span>{hs.lang.nextText}</span></a>'+
 121              '</li>'+
 122              '<li class="highslide-move">'+
 123                  '<a href="#" title="{hs.lang.moveTitle}" onclick="return false">'+
 124                  '<span>{hs.lang.moveText}</span></a>'+
 125              '</li>'+
 126              '<li class="highslide-close">'+
 127                  '<a href="#" title="{hs.lang.closeTitle}" onclick="return hs.close(this)">'+
 128                  '<span>{hs.lang.closeText}</span></a>'+
 129              '</li>'+
 130          '</ul></div>'+
 131          '<div class="highslide-body"></div>'+
 132          '<div class="highslide-footer"><div>'+
 133              '<span class="highslide-resize" title="{hs.lang.resizeTitle}"><span></span></span>'+
 134          '</div></div>'
 135  },
 136  // END OF YOUR SETTINGS

 137  
 138  
 139  // declare internal properties

 140  preloadTheseImages : [],
 141  continuePreloading: true,
 142  expanders : [],
 143  overrides : [
 144      'allowSizeReduction',
 145      'useBox',
 146      'anchor',
 147      'align',
 148      'targetX',
 149      'targetY',
 150      'outlineType',
 151      'outlineWhileAnimating',
 152      'captionId',
 153      'captionText',
 154      'captionEval',
 155      'captionOverlay',
 156      'headingId',
 157      'headingText',
 158      'headingEval',
 159      'headingOverlay',
 160      'creditsPosition',
 161      'dragByHeading',
 162      'autoplay',
 163      'numberPosition',
 164      'transitions',
 165      'dimmingOpacity',
 166      
 167      'width',
 168      'height',
 169      
 170      'contentId',
 171      'allowWidthReduction',
 172      'allowHeightReduction',
 173      'preserveContent',
 174      'maincontentId',
 175      'maincontentText',
 176      'maincontentEval',
 177      'objectType',    
 178      'cacheAjax',    
 179      'objectWidth',
 180      'objectHeight',
 181      'objectLoadTime',    
 182      'swfOptions',
 183      'wrapperClassName',
 184      'minWidth',
 185      'minHeight',
 186      'maxWidth',
 187      'maxHeight',
 188      'pageOrigin',
 189      'slideshowGroup',
 190      'easing',
 191      'easingClose',
 192      'fadeInOut',
 193      'src'
 194  ],
 195  overlays : [],
 196  idCounter : 0,
 197  oPos : {
 198      x: ['leftpanel', 'left', 'center', 'right', 'rightpanel'],
 199      y: ['above', 'top', 'middle', 'bottom', 'below']
 200  },
 201  mouse: {},
 202  headingOverlay: {},
 203  captionOverlay: {},
 204  swfOptions: { flashvars: {}, params: {}, attributes: {} },
 205  timers : [],
 206  
 207  slideshows : [],
 208  
 209  pendingOutlines : {},
 210  sleeping : [],
 211  preloadTheseAjax : [],
 212  cacheBindings : [],
 213  cachedGets : {},
 214  clones : {},
 215  onReady: [],
 216  uaVersion: /Trident\/4\.0/.test(navigator.userAgent) ? 8 :
 217      parseFloat((navigator.userAgent.toLowerCase().match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1]),
 218  ie : (document.all && !window.opera),
 219  //ie : navigator && /MSIE [678]/.test(navigator.userAgent), // ie9 compliant?

 220  safari : /Safari/.test(navigator.userAgent),
 221  geckoMac : /Macintosh.+rv:1\.[0-8].+Gecko/.test(navigator.userAgent),
 222  
 223  $ : function (id) {
 224      if (id) return document.getElementById(id);
 225  },
 226  
 227  push : function (arr, val) {
 228      arr[arr.length] = val;
 229  },
 230  
 231  createElement : function (tag, attribs, styles, parent, nopad) {
 232      var el = document.createElement(tag);
 233      if (attribs) hs.extend(el, attribs);
 234      if (nopad) hs.setStyles(el, {padding: 0, border: 'none', margin: 0});
 235      if (styles) hs.setStyles(el, styles);
 236      if (parent) parent.appendChild(el);    
 237      return el;
 238  },
 239  
 240  extend : function (el, attribs) {
 241      for (var x in attribs) el[x] = attribs[x];
 242      return el;
 243  },
 244  
 245  setStyles : function (el, styles) {
 246      for (var x in styles) {
 247          if (hs.ieLt9 && x == 'opacity') {
 248              if (styles[x] > 0.99) el.style.removeAttribute('filter');
 249              else el.style.filter = 'alpha(opacity='+ (styles[x] * 100) +')';
 250          }
 251          else el.style[x] = styles[x];        
 252      }
 253  },
 254  animate: function(el, prop, opt) {
 255      var start,
 256          end,
 257          unit;
 258      if (typeof opt != 'object' || opt === null) {
 259          var args = arguments;
 260          opt = {
 261              duration: args[2],
 262              easing: args[3],
 263              complete: args[4]
 264          };
 265      }
 266      if (typeof opt.duration != 'number') opt.duration = 250;
 267      opt.easing = Math[opt.easing] || Math.easeInQuad;
 268      opt.curAnim = hs.extend({}, prop);
 269      for (var name in prop) {
 270          var e = new hs.fx(el, opt , name );
 271          
 272          start = parseFloat(hs.css(el, name)) || 0;
 273          end = parseFloat(prop[name]);
 274          unit = name != 'opacity' ? 'px' : '';
 275          
 276          e.custom( start, end, unit );
 277      }    
 278  },
 279  css: function(el, prop) {
 280      if (el.style[prop]) {
 281          return el.style[prop];
 282      } else if (document.defaultView) {
 283          return document.defaultView.getComputedStyle(el, null).getPropertyValue(prop);
 284  
 285      } else {
 286          if (prop == 'opacity') prop = 'filter';
 287          var val = el.currentStyle[prop.replace(/\-(\w)/g, function (a, b){ return b.toUpperCase(); })];
 288          if (prop == 'filter') 
 289              val = val.replace(/alpha\(opacity=([0-9]+)\)/, 
 290                  function (a, b) { return b / 100 });
 291          return val === '' ? 1 : val;
 292      } 
 293  },
 294  
 295  getPageSize : function () {
 296      var d = document, w = window, iebody = d.compatMode && d.compatMode != 'BackCompat' 
 297          ? d.documentElement : d.body;
 298      
 299      var width = hs.ieLt9 ? iebody.clientWidth : 
 300              (d.documentElement.clientWidth || self.innerWidth),
 301          height = hs.ieLt9 ? iebody.clientHeight : self.innerHeight;
 302      
 303      hs.page = {
 304          width: width,
 305          height: height,        
 306          scrollLeft: hs.ieLt9 ? iebody.scrollLeft : pageXOffset,
 307          scrollTop: hs.ieLt9 ? iebody.scrollTop : pageYOffset
 308      };
 309      return hs.page;
 310  },
 311  
 312  getPosition : function(el)    {
 313      if (/area/i.test(el.tagName)) {
 314          var imgs = document.getElementsByTagName('img');
 315          for (var i = 0; i < imgs.length; i++) {
 316              var u = imgs[i].useMap;
 317              if (u && u.replace(/^.*?#/, '') == el.parentNode.name) {
 318                  el = imgs[i];
 319                  break;
 320              }
 321          }
 322      }
 323      var p = { x: el.offsetLeft, y: el.offsetTop };
 324      while (el.offsetParent)    {
 325          el = el.offsetParent;
 326          p.x += el.offsetLeft;
 327          p.y += el.offsetTop;
 328          if (el != document.body && el != document.documentElement) {
 329              p.x -= el.scrollLeft;
 330              p.y -= el.scrollTop;
 331          }
 332      }
 333      return p;
 334  },
 335  
 336  expand : function(a, params, custom, type) {
 337      if (!a) a = hs.createElement('a', null, { display: 'none' }, hs.container);
 338      if (typeof a.getParams == 'function') return params;
 339      if (type == 'html') {
 340          for (var i = 0; i < hs.sleeping.length; i++) {
 341              if (hs.sleeping[i] && hs.sleeping[i].a == a) {
 342                  hs.sleeping[i].awake();
 343                  hs.sleeping[i] = null;
 344                  return false;
 345              }
 346          }
 347          hs.hasHtmlExpanders = true;
 348      }    
 349      try {    
 350          new hs.Expander(a, params, custom, type);
 351          return false;
 352      } catch (e) { return true; }
 353  },
 354  
 355  htmlExpand : function(a, params, custom) {
 356      return hs.expand(a, params, custom, 'html');
 357  },
 358  
 359  getSelfRendered : function() {
 360      return hs.createElement('div', { 
 361          className: 'highslide-html-content', 
 362          innerHTML: hs.replaceLang(hs.skin.contentWrapper) 
 363      });
 364  },
 365  getElementByClass : function (el, tagName, className) {
 366      var els = el.getElementsByTagName(tagName);
 367      for (var i = 0; i < els.length; i++) {
 368          if ((new RegExp(className)).test(els[i].className)) {
 369              return els[i];
 370          }
 371      }
 372      return null;
 373  },
 374  replaceLang : function(s) {
 375      s = s.replace(/\s/g, ' ');
 376      var re = /{hs\.lang\.([^}]+)\}/g,
 377          matches = s.match(re),
 378          lang;
 379      if (matches) for (var i = 0; i < matches.length; i++) {
 380          lang = matches[i].replace(re, "$1");
 381          if (typeof hs.lang[lang] != 'undefined') s = s.replace(matches[i], hs.lang[lang]);
 382      }
 383      return s;
 384  },
 385  
 386  
 387  setClickEvents : function () {
 388      var els = document.getElementsByTagName('a');
 389      for (var i = 0; i < els.length; i++) {
 390          var type = hs.isUnobtrusiveAnchor(els[i]);
 391          if (type && !els[i].hsHasSetClick) {
 392              (function(){
 393                  var t = type;
 394                  if (hs.fireEvent(hs, 'onSetClickEvent', { element: els[i], type: t })) {
 395                      els[i].onclick =(type == 'image') ?function() { return hs.expand(this) }:
 396                          function() { return hs.htmlExpand(this, { objectType: t } );};
 397                  }
 398              })();
 399              els[i].hsHasSetClick = true;    
 400          }
 401      }
 402      hs.getAnchors();
 403  },
 404  isUnobtrusiveAnchor: function(el) {
 405      if (el.rel == 'highslide') return 'image';
 406      else if (el.rel == 'highslide-ajax') return 'ajax';
 407      else if (el.rel == 'highslide-iframe') return 'iframe';
 408      else if (el.rel == 'highslide-swf') return 'swf';
 409  },
 410  
 411  getCacheBinding : function (a) {
 412      for (var i = 0; i < hs.cacheBindings.length; i++) {
 413          if (hs.cacheBindings[i][0] == a) {
 414              var c = hs.cacheBindings[i][1];
 415              hs.cacheBindings[i][1] = c.cloneNode(1);
 416              return c;
 417          }
 418      }
 419      return null;
 420  },
 421  
 422  preloadAjax : function (e) {
 423      var arr = hs.getAnchors();
 424      for (var i = 0; i < arr.htmls.length; i++) {
 425          var a = arr.htmls[i];
 426          if (hs.getParam(a, 'objectType') == 'ajax' && hs.getParam(a, 'cacheAjax'))
 427              hs.push(hs.preloadTheseAjax, a);
 428      }
 429      
 430      hs.preloadAjaxElement(0);
 431  },
 432  
 433  preloadAjaxElement : function (i) {
 434      if (!hs.preloadTheseAjax[i]) return;
 435      var a = hs.preloadTheseAjax[i];
 436      var cache = hs.getNode(hs.getParam(a, 'contentId'));
 437      if (!cache) cache = hs.getSelfRendered();
 438      var ajax = new hs.Ajax(a, cache, 1);    
 439         ajax.onError = function () { };
 440         ajax.onLoad = function () {
 441             hs.push(hs.cacheBindings, [a, cache]);
 442             hs.preloadAjaxElement(i + 1);
 443         };
 444         ajax.run();
 445  },
 446  
 447  focusTopmost : function() {
 448      var topZ = 0, 
 449          topmostKey = -1,
 450          expanders = hs.expanders,
 451          exp,
 452          zIndex;
 453      for (var i = 0; i < expanders.length; i++) {
 454          exp = expanders[i];
 455          if (exp) {
 456              zIndex = exp.wrapper.style.zIndex;
 457              if (zIndex && zIndex > topZ) {
 458                  topZ = zIndex;                
 459                  topmostKey = i;
 460              }
 461          }
 462      }
 463      if (topmostKey == -1) hs.focusKey = -1;
 464      else expanders[topmostKey].focus();
 465  },
 466  
 467  getParam : function (a, param) {
 468      a.getParams = a.onclick;
 469      var p = a.getParams ? a.getParams() : null;
 470      a.getParams = null;
 471      
 472      return (p && typeof p[param] != 'undefined') ? p[param] : 
 473          (typeof hs[param] != 'undefined' ? hs[param] : null);
 474  },
 475  
 476  getSrc : function (a) {
 477      var src = hs.getParam(a, 'src');
 478      if (src) return src;
 479      return a.href;
 480  },
 481  
 482  getNode : function (id) {
 483      var node = hs.$(id), clone = hs.clones[id], a = {};
 484      if (!node && !clone) return null;
 485      if (!clone) {
 486          clone = node.cloneNode(true);
 487          clone.id = '';
 488          hs.clones[id] = clone;
 489          return node;
 490      } else {
 491          return clone.cloneNode(true);
 492      }
 493  },
 494  
 495  discardElement : function(d) {
 496      if (d) hs.garbageBin.appendChild(d);
 497      hs.garbageBin.innerHTML = '';
 498  },
 499  dim : function(exp) {
 500      if (!hs.dimmer) {
 501          isNew = true;
 502          hs.dimmer = hs.createElement ('div', {
 503                  className: 'highslide-dimming highslide-viewport-size',
 504                  owner: '',
 505                  onclick: function() {
 506                      if (hs.fireEvent(hs, 'onDimmerClick'))
 507                      
 508                          hs.close();
 509                  }
 510              }, {
 511                  visibility: 'visible',
 512                  opacity: 0
 513              }, hs.container, true);
 514      }
 515      hs.dimmer.style.display = '';
 516  
 517      var isNew = hs.dimmer.owner == '';
 518      hs.dimmer.owner += '|'+ exp.key;
 519      
 520      if (isNew) {
 521          if (hs.geckoMac && hs.dimmingGeckoFix)
 522              hs.setStyles(hs.dimmer, {
 523                  background: 'url('+ hs.graphicsDir + 'geckodimmer.png)',
 524                  opacity: 1
 525              });
 526          else
 527              hs.animate(hs.dimmer, { opacity: exp.dimmingOpacity }, hs.dimmingDuration);
 528      }
 529  },
 530  undim : function(key) {
 531      if (!hs.dimmer) return;
 532      if (typeof key != 'undefined') hs.dimmer.owner = hs.dimmer.owner.replace('|'+ key, '');
 533  
 534      if (
 535          (typeof key != 'undefined' && hs.dimmer.owner != '')
 536          || (hs.upcoming && hs.getParam(hs.upcoming, 'dimmingOpacity'))
 537      ) return;
 538  
 539      if (hs.geckoMac && hs.dimmingGeckoFix) hs.dimmer.style.display = 'none';
 540      else hs.animate(hs.dimmer, { opacity: 0 }, hs.dimmingDuration, null, function() {
 541          hs.dimmer.style.display = 'none';
 542      });
 543  },
 544  transit : function (adj, exp) {
 545      var last = exp || hs.getExpander();
 546      exp = last;
 547      if (hs.upcoming) return false;
 548      else hs.last = last;
 549      hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
 550      try {
 551          hs.upcoming = adj;
 552          adj.onclick();         
 553      } catch (e){
 554          hs.last = hs.upcoming = null;
 555      }
 556      try {
 557          if (!adj || exp.transitions[1] != 'crossfade')
 558          exp.close();
 559      } catch (e) {}
 560      return false;
 561  },
 562  
 563  previousOrNext : function (el, op) {
 564      var exp = hs.getExpander(el);
 565      if (exp) return hs.transit(exp.getAdjacentAnchor(op), exp);
 566      else return false;
 567  },
 568  
 569  previous : function (el) {
 570      return hs.previousOrNext(el, -1);
 571  },
 572  
 573  next : function (el) {
 574      return hs.previousOrNext(el, 1);    
 575  },
 576  
 577  keyHandler : function(e) {
 578      if (!e) e = window.event;
 579      if (!e.target) e.target = e.srcElement; // ie

 580      if (typeof e.target.form != 'undefined') return true; // form element has focus

 581      if (!hs.fireEvent(hs, 'onKeyDown', e)) return true;
 582      var exp = hs.getExpander();
 583      
 584      var op = null;
 585      switch (e.keyCode) {
 586          case 70: // f
 587              if (exp) exp.doFullExpand();
 588              return true;
 589          case 32: // Space
 590              op = 2;
 591              break;
 592          case 34: // Page Down
 593          case 39: // Arrow right
 594          case 40: // Arrow down
 595              op = 1;
 596              break;
 597          case 8:  // Backspace
 598          case 33: // Page Up
 599          case 37: // Arrow left
 600          case 38: // Arrow up
 601              op = -1;
 602              break;
 603          case 27: // Escape
 604          case 13: // Enter
 605              op = 0;
 606      }
 607      if (op !== null) {
 608          hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
 609          if (!hs.enableKeyListener) return true;
 610          
 611          if (e.preventDefault) e.preventDefault();
 612          else e.returnValue = false;
 613          if (exp) {
 614              if (op == 0) {
 615                  exp.close();
 616              } else if (op == 2) {
 617                  if (exp.slideshow) exp.slideshow.hitSpace();
 618              } else {
 619                  if (exp.slideshow) exp.slideshow.pause();
 620                  hs.previousOrNext(exp.key, op);
 621              }
 622              return false;
 623          }
 624      }
 625      return true;
 626  },
 627  
 628  
 629  registerOverlay : function (overlay) {
 630      hs.push(hs.overlays, hs.extend(overlay, { hsId: 'hsId'+ hs.idCounter++ } ));
 631  },
 632  
 633  
 634  addSlideshow : function (options) {
 635      var sg = options.slideshowGroup;
 636      if (typeof sg == 'object') {
 637          for (var i = 0; i < sg.length; i++) {
 638              var o = {};
 639              for (var x in options) o[x] = options[x];
 640              o.slideshowGroup = sg[i];
 641              hs.push(hs.slideshows, o);
 642          }
 643      } else {
 644          hs.push(hs.slideshows, options);
 645      }
 646  },
 647  
 648  getWrapperKey : function (element, expOnly) {
 649      var el, re = /^highslide-wrapper-([0-9]+)$/;
 650      // 1. look in open expanders

 651      el = element;
 652      while (el.parentNode)    {
 653          if (el.hsKey !== undefined) return el.hsKey;
 654          if (el.id && re.test(el.id)) return el.id.replace(re, "$1");
 655          el = el.parentNode;
 656      }
 657      // 2. look in thumbnail

 658      if (!expOnly) {
 659          el = element;
 660          while (el.parentNode)    {
 661              if (el.tagName && hs.isHsAnchor(el)) {
 662                  for (var key = 0; key < hs.expanders.length; key++) {
 663                      var exp = hs.expanders[key];
 664                      if (exp && exp.a == el) return key;
 665                  }
 666              }
 667              el = el.parentNode;
 668          }
 669      }
 670      return null; 
 671  },
 672  
 673  getExpander : function (el, expOnly) {
 674      if (typeof el == 'undefined') return hs.expanders[hs.focusKey] || null;
 675      if (typeof el == 'number') return hs.expanders[el] || null;
 676      if (typeof el == 'string') el = hs.$(el);
 677      return hs.expanders[hs.getWrapperKey(el, expOnly)] || null;
 678  },
 679  
 680  isHsAnchor : function (a) {
 681      return (a.onclick && a.onclick.toString().replace(/\s/g, ' ').match(/hs.(htmlE|e)xpand/));
 682  },
 683  
 684  reOrder : function () {
 685      for (var i = 0; i < hs.expanders.length; i++)
 686          if (hs.expanders[i] && hs.expanders[i].isExpanded) hs.focusTopmost();
 687  },
 688  fireEvent : function (obj, evt, args) {
 689      return obj && obj[evt] ? (obj[evt](obj, args) !== false) : true;
 690  },
 691  
 692  mouseClickHandler : function(e) 
 693  {    
 694      if (!e) e = window.event;
 695      if (e.button > 1) return true;
 696      if (!e.target) e.target = e.srcElement;
 697      
 698      var el = e.target;
 699      while (el.parentNode
 700          && !(/highslide-(image|move|html|resize)/.test(el.className)))
 701      {
 702          el = el.parentNode;
 703      }
 704      var exp = hs.getExpander(el);
 705      if (exp && (exp.isClosing || !exp.isExpanded)) return true;
 706          
 707      if (exp && e.type == 'mousedown') {
 708          if (e.target.form) return true;
 709          var match = el.className.match(/highslide-(image|move|resize)/);
 710          if (match) {
 711              hs.dragArgs = { 
 712                  exp: exp , 
 713                  type: match[1], 
 714                  left: exp.x.pos, 
 715                  width: exp.x.size, 
 716                  top: exp.y.pos, 
 717                  height: exp.y.size, 
 718                  clickX: e.clientX, 
 719                  clickY: e.clientY
 720              };
 721              
 722              
 723              hs.addEventListener(document, 'mousemove', hs.dragHandler);
 724              if (e.preventDefault) e.preventDefault(); // FF

 725              
 726              if (/highslide-(image|html)-blur/.test(exp.content.className)) {
 727                  exp.focus();
 728                  hs.hasFocused = true;
 729              }
 730              return false;
 731          }
 732          else if (/highslide-html/.test(el.className) && hs.focusKey != exp.key) {
 733              exp.focus();
 734              exp.doShowHide('hidden');
 735          }
 736      } else if (e.type == 'mouseup') {
 737          
 738          hs.removeEventListener(document, 'mousemove', hs.dragHandler);
 739          
 740          if (hs.dragArgs) {
 741              if (hs.styleRestoreCursor && hs.dragArgs.type == 'image') 
 742                  hs.dragArgs.exp.content.style.cursor = hs.styleRestoreCursor;
 743              var hasDragged = hs.dragArgs.hasDragged;
 744              
 745              if (!hasDragged &&!hs.hasFocused && !/(move|resize)/.test(hs.dragArgs.type)) {
 746                  if (hs.fireEvent(exp, 'onImageClick'))
 747                  exp.close();
 748              } 
 749              else if (hasDragged || (!hasDragged && hs.hasHtmlExpanders)) {
 750                  hs.dragArgs.exp.doShowHide('hidden');
 751              }
 752              
 753              if (hs.dragArgs.exp.releaseMask) 
 754                  hs.dragArgs.exp.releaseMask.style.display = 'none';
 755              
 756              if (hasDragged) hs.fireEvent(hs.dragArgs.exp, 'onDrop', hs.dragArgs);
 757              hs.hasFocused = false;
 758              hs.dragArgs = null;
 759          
 760          } else if (/highslide-image-blur/.test(el.className)) {
 761              el.style.cursor = hs.styleRestoreCursor;        
 762          }
 763      }
 764      return false;
 765  },
 766  
 767  dragHandler : function(e)
 768  {
 769      if (!hs.dragArgs) return true;
 770      if (!e) e = window.event;
 771      var a = hs.dragArgs, exp = a.exp;
 772      if (exp.iframe) {        
 773          if (!exp.releaseMask) exp.releaseMask = hs.createElement('div', null, 
 774              { position: 'absolute', width: exp.x.size+'px', height: exp.y.size+'px', 
 775                  left: exp.x.cb+'px', top: exp.y.cb+'px', zIndex: 4,    background: (hs.ieLt9 ? 'white' : 'none'), 
 776                  opacity: 0.01 }, 
 777              exp.wrapper, true);
 778          if (exp.releaseMask.style.display == 'none')
 779              exp.releaseMask.style.display = '';
 780      }
 781      
 782      a.dX = e.clientX - a.clickX;
 783      a.dY = e.clientY - a.clickY;    
 784      
 785      var distance = Math.sqrt(Math.pow(a.dX, 2) + Math.pow(a.dY, 2));
 786      if (!a.hasDragged) a.hasDragged = (a.type != 'image' && distance > 0)
 787          || (distance > (hs.dragSensitivity || 5));
 788      
 789      if (a.hasDragged && e.clientX > 5 && e.clientY > 5) {
 790          if (!hs.fireEvent(exp, 'onDrag', a)) return false;
 791          
 792          if (a.type == 'resize') exp.resize(a);
 793          else {
 794              exp.moveTo(a.left + a.dX, a.top + a.dY);
 795              if (a.type == 'image') exp.content.style.cursor = 'move';
 796          }
 797      }
 798      return false;
 799  },
 800  
 801  wrapperMouseHandler : function (e) {
 802      try {
 803          if (!e) e = window.event;
 804          var over = /mouseover/i.test(e.type); 
 805          if (!e.target) e.target = e.srcElement; // ie

 806          if (!e.relatedTarget) e.relatedTarget = 
 807              over ? e.fromElement : e.toElement; // ie

 808          var exp = hs.getExpander(e.target);
 809          if (!exp.isExpanded) return;
 810          if (!exp || !e.relatedTarget || hs.getExpander(e.relatedTarget, true) == exp 
 811              || hs.dragArgs) return;
 812          hs.fireEvent(exp, over ? 'onMouseOver' : 'onMouseOut', e);
 813          for (var i = 0; i < exp.overlays.length; i++) (function() {
 814              var o = hs.$('hsId'+ exp.overlays[i]);
 815              if (o && o.hideOnMouseOut) {
 816                  if (over) hs.setStyles(o, { visibility: 'visible', display: '' });
 817                  hs.animate(o, { opacity: over ? o.opacity : 0 }, o.dur);
 818              }
 819          })();    
 820      } catch (e) {}
 821  },
 822  addEventListener : function (el, event, func) {
 823      if (el == document && event == 'ready') {
 824          hs.push(hs.onReady, func);
 825      }
 826      try {
 827          el.addEventListener(event, func, false);
 828      } catch (e) {
 829          try {
 830              el.detachEvent('on'+ event, func);
 831              el.attachEvent('on'+ event, func);
 832          } catch (e) {
 833              el['on'+ event] = func;
 834          }
 835      } 
 836  },
 837  
 838  removeEventListener : function (el, event, func) {
 839      try {
 840          el.removeEventListener(event, func, false);
 841      } catch (e) {
 842          try {
 843              el.detachEvent('on'+ event, func);
 844          } catch (e) {
 845              el['on'+ event] = null;
 846          }
 847      }
 848  },
 849  
 850  preloadFullImage : function (i) {
 851      if (hs.continuePreloading && hs.preloadTheseImages[i] && hs.preloadTheseImages[i] != 'undefined') {
 852          var img = document.createElement('img');
 853          img.onload = function() { 
 854              img = null;
 855              hs.preloadFullImage(i + 1);
 856          };
 857          img.src = hs.preloadTheseImages[i];
 858      }
 859  },
 860  preloadImages : function (number) {
 861      if (number && typeof number != 'object') hs.numberOfImagesToPreload = number;
 862      
 863      var arr = hs.getAnchors();
 864      for (var i = 0; i < arr.images.length && i < hs.numberOfImagesToPreload; i++) {
 865          hs.push(hs.preloadTheseImages, hs.getSrc(arr.images[i]));
 866      }
 867      
 868      // preload outlines

 869      if (hs.outlineType)    new hs.Outline(hs.outlineType, function () { hs.preloadFullImage(0)} );
 870      else
 871      
 872      hs.preloadFullImage(0);
 873      
 874      // preload cursor

 875      if (hs.restoreCursor) var cur = hs.createElement('img', { src: hs.graphicsDir + hs.restoreCursor });
 876  },
 877  
 878  
 879  init : function () {
 880      if (!hs.container) {
 881      
 882          hs.ieLt7 = hs.ie && hs.uaVersion < 7;
 883          hs.ieLt9 = hs.ie && hs.uaVersion < 9;
 884          
 885          hs.getPageSize();
 886          hs.ie6SSL = hs.ieLt7 && location.protocol == 'https:';
 887          for (var x in hs.langDefaults) {
 888              if (typeof hs[x] != 'undefined') hs.lang[x] = hs[x];
 889              else if (typeof hs.lang[x] == 'undefined' && typeof hs.langDefaults[x] != 'undefined') 
 890                  hs.lang[x] = hs.langDefaults[x];
 891          }
 892          
 893          hs.container = hs.createElement('div', {
 894                  className: 'highslide-container'
 895              }, {
 896                  position: 'absolute',
 897                  left: 0, 
 898                  top: 0, 
 899                  width: '100%', 
 900                  zIndex: hs.zIndexCounter,
 901                  direction: 'ltr'
 902              }, 
 903              document.body,
 904              true
 905          );
 906          hs.loading = hs.createElement('a', {
 907                  className: 'highslide-loading',
 908                  title: hs.lang.loadingTitle,
 909                  innerHTML: hs.lang.loadingText,
 910                  href: 'javascript:;'
 911              }, {
 912                  position: 'absolute',
 913                  top: '-9999px',
 914                  opacity: hs.loadingOpacity,
 915                  zIndex: 1
 916              }, hs.container
 917          );
 918          hs.garbageBin = hs.createElement('div', null, { display: 'none' }, hs.container);
 919          hs.viewport = hs.createElement('div', {
 920                  className: 'highslide-viewport highslide-viewport-size'
 921              }, {
 922                  visibility: (hs.safari && hs.uaVersion < 525) ? 'visible' : 'hidden'
 923              }, hs.container, 1
 924          );
 925          hs.clearing = hs.createElement('div', null, 
 926              { clear: 'both', paddingTop: '1px' }, null, true);
 927          
 928          // http://www.robertpenner.com/easing/ 

 929          Math.linearTween = function (t, b, c, d) {
 930              return c*t/d + b;
 931          };
 932          Math.easeInQuad = function (t, b, c, d) {
 933              return c*(t/=d)*t + b;
 934          };
 935          Math.easeOutQuad = function (t, b, c, d) {
 936              return -c *(t/=d)*(t-2) + b;
 937          };
 938          
 939          hs.hideSelects = hs.ieLt7;
 940          hs.hideIframes = ((window.opera && hs.uaVersion < 9) || navigator.vendor == 'KDE' 
 941              || (hs.ieLt7 && hs.uaVersion < 5.5));
 942          hs.fireEvent(this, 'onActivate');
 943      }
 944  },
 945  ready : function() {
 946      if (hs.isReady) return;
 947      hs.isReady = true;
 948      for (var i = 0; i < hs.onReady.length; i++) hs.onReady[i]();
 949  },
 950  
 951  updateAnchors : function() {
 952      var el, els, all = [], images = [], htmls = [],groups = {}, re;
 953          
 954      for (var i = 0; i < hs.openerTagNames.length; i++) {
 955          els = document.getElementsByTagName(hs.openerTagNames[i]);
 956          for (var j = 0; j < els.length; j++) {
 957              el = els[j];
 958              re = hs.isHsAnchor(el);
 959              if (re) {
 960                  hs.push(all, el);
 961                  if (re[0] == 'hs.expand') hs.push(images, el);
 962                  else if (re[0] == 'hs.htmlExpand') hs.push(htmls, el);
 963                  var g = hs.getParam(el, 'slideshowGroup') || 'none';
 964                  if (!groups[g]) groups[g] = [];
 965                  hs.push(groups[g], el);
 966              }
 967          }
 968      }
 969      hs.anchors = { all: all, groups: groups, images: images, htmls: htmls };
 970      return hs.anchors;
 971      
 972  },
 973  
 974  getAnchors : function() {
 975      return hs.anchors || hs.updateAnchors();
 976  },
 977  
 978  
 979  close : function(el) {
 980      var exp = hs.getExpander(el);
 981      if (exp) exp.close();
 982      return false;
 983  }
 984  }; // end hs object
 985  hs.fx = function( elem, options, prop ){
 986      this.options = options;
 987      this.elem = elem;
 988      this.prop = prop;
 989  
 990      if (!options.orig) options.orig = {};
 991  };
 992  hs.fx.prototype = {
 993      update: function(){
 994          (hs.fx.step[this.prop] || hs.fx.step._default)(this);
 995          
 996          if (this.options.step)
 997              this.options.step.call(this.elem, this.now, this);
 998  
 999      },
1000      custom: function(from, to, unit){
1001          this.startTime = (new Date()).getTime();
1002          this.start = from;
1003          this.end = to;
1004          this.unit = unit;// || this.unit || "px";

1005          this.now = this.start;
1006          this.pos = this.state = 0;
1007  
1008          var self = this;
1009          function t(gotoEnd){
1010              return self.step(gotoEnd);
1011          }
1012  
1013          t.elem = this.elem;
1014  
1015          if ( t() && hs.timers.push(t) == 1 ) {
1016              hs.timerId = setInterval(function(){
1017                  var timers = hs.timers;
1018  
1019                  for ( var i = 0; i < timers.length; i++ )
1020                      if ( !timers[i]() )
1021                          timers.splice(i--, 1);
1022  
1023                  if ( !timers.length ) {
1024                      clearInterval(hs.timerId);
1025                  }
1026              }, 13);
1027          }
1028      },
1029      step: function(gotoEnd){
1030          var t = (new Date()).getTime();
1031          if ( gotoEnd || t >= this.options.duration + this.startTime ) {
1032              this.now = this.end;
1033              this.pos = this.state = 1;
1034              this.update();
1035  
1036              this.options.curAnim[ this.prop ] = true;
1037  
1038              var done = true;
1039              for ( var i in this.options.curAnim )
1040                  if ( this.options.curAnim[i] !== true )
1041                      done = false;
1042  
1043              if ( done ) {
1044                  if (this.options.complete) this.options.complete.call(this.elem);
1045              }
1046              return false;
1047          } else {
1048              var n = t - this.startTime;
1049              this.state = n / this.options.duration;
1050              this.pos = this.options.easing(n, 0, 1, this.options.duration);
1051              this.now = this.start + ((this.end - this.start) * this.pos);
1052              this.update();
1053          }
1054          return true;
1055      }
1056  
1057  };
1058  
1059  hs.extend( hs.fx, {
1060      step: {
1061  
1062          opacity: function(fx){
1063              hs.setStyles(fx.elem, { opacity: fx.now });
1064          },
1065  
1066          _default: function(fx){
1067              try {
1068                  if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
1069                      fx.elem.style[ fx.prop ] = fx.now + fx.unit;
1070                  else
1071                      fx.elem[ fx.prop ] = fx.now;
1072              } catch (e) {}
1073          }
1074      }
1075  });
1076  
1077  hs.Outline =  function (outlineType, onLoad) {
1078      this.onLoad = onLoad;
1079      this.outlineType = outlineType;
1080      var v = hs.uaVersion, tr;
1081      
1082      this.hasAlphaImageLoader = hs.ie && hs.uaVersion < 7;
1083      if (!outlineType) {
1084          if (onLoad) onLoad();
1085          return;
1086      }
1087      
1088      hs.init();
1089      this.table = hs.createElement(
1090          'table', { 
1091              cellSpacing: 0 
1092          }, {
1093              visibility: 'hidden',
1094              position: 'absolute',
1095              borderCollapse: 'collapse',
1096              width: 0
1097          },
1098          hs.container,
1099          true
1100      );
1101      var tbody = hs.createElement('tbody', null, null, this.table, 1);
1102      
1103      this.td = [];
1104      for (var i = 0; i <= 8; i++) {
1105          if (i % 3 == 0) tr = hs.createElement('tr', null, { height: 'auto' }, tbody, true);
1106          this.td[i] = hs.createElement('td', null, null, tr, true);
1107          var style = i != 4 ? { lineHeight: 0, fontSize: 0} : { position : 'relative' };
1108          hs.setStyles(this.td[i], style);
1109      }
1110      this.td[4].className = outlineType +' highslide-outline';
1111      
1112      this.preloadGraphic(); 
1113  };
1114  
1115  hs.Outline.prototype = {
1116  preloadGraphic : function () {
1117      var src = hs.graphicsDir + (hs.outlinesDir || "outlines/")+ this.outlineType +".png";
1118                  
1119      var appendTo = hs.safari && hs.uaVersion < 525 ? hs.container : null;
1120      this.graphic = hs.createElement('img', null, { position: 'absolute', 
1121          top: '-9999px' }, appendTo, true); // for onload trigger

1122      
1123      var pThis = this;
1124      this.graphic.onload = function() { pThis.onGraphicLoad(); };
1125      
1126      this.graphic.src = src;
1127  },
1128  
1129  onGraphicLoad : function () {
1130      var o = this.offset = this.graphic.width / 4,
1131          pos = [[0,0],[0,-4],[-2,0],[0,-8],0,[-2,-8],[0,-2],[0,-6],[-2,-2]],
1132          dim = { height: (2*o) +'px', width: (2*o) +'px' };
1133      for (var i = 0; i <= 8; i++) {
1134          if (pos[i]) {
1135              if (this.hasAlphaImageLoader) {
1136                  var w = (i == 1 || i == 7) ? '100%' : this.graphic.width +'px';
1137                  var div = hs.createElement('div', null, { width: '100%', height: '100%', position: 'relative', overflow: 'hidden'}, this.td[i], true);
1138                  hs.createElement ('div', null, { 
1139                          filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale, src='"+ this.graphic.src + "')", 
1140                          position: 'absolute',
1141                          width: w, 
1142                          height: this.graphic.height +'px',
1143                          left: (pos[i][0]*o)+'px',
1144                          top: (pos[i][1]*o)+'px'
1145                      }, 
1146                  div,
1147                  true);
1148              } else {
1149                  hs.setStyles(this.td[i], { background: 'url('+ this.graphic.src +') '+ (pos[i][0]*o)+'px '+(pos[i][1]*o)+'px'});
1150              }
1151              
1152              if (window.opera && (i == 3 || i ==5)) 
1153                  hs.createElement('div', null, dim, this.td[i], true);
1154              
1155              hs.setStyles (this.td[i], dim);
1156          }
1157      }
1158      this.graphic = null;
1159      if (hs.pendingOutlines[this.outlineType]) hs.pendingOutlines[this.outlineType].destroy();
1160      hs.pendingOutlines[this.outlineType] = this;
1161      if (this.onLoad) this.onLoad();
1162  },
1163      
1164  setPosition : function (pos, offset, vis, dur, easing) {
1165      var exp = this.exp,
1166          stl = exp.wrapper.style,
1167          offset = offset || 0,
1168          pos = pos || {
1169              x: exp.x.pos + offset,
1170              y: exp.y.pos + offset,
1171              w: exp.x.get('wsize') - 2 * offset,
1172              h: exp.y.get('wsize') - 2 * offset
1173          };
1174      if (vis) this.table.style.visibility = (pos.h >= 4 * this.offset) 
1175          ? 'visible' : 'hidden';
1176      hs.setStyles(this.table, {
1177          left: (pos.x - this.offset) +'px',
1178          top: (pos.y - this.offset) +'px',
1179          width: (pos.w + 2 * this.offset) +'px'
1180      });
1181      
1182      pos.w -= 2 * this.offset;
1183      pos.h -= 2 * this.offset;
1184      hs.setStyles (this.td[4], {
1185          width: pos.w >= 0 ? pos.w +'px' : 0,
1186          height: pos.h >= 0 ? pos.h +'px' : 0
1187      });
1188      if (this.hasAlphaImageLoader) this.td[3].style.height 
1189          = this.td[5].style.height = this.td[4].style.height;    
1190      
1191  },
1192      
1193  destroy : function(hide) {
1194      if (hide) this.table.style.visibility = 'hidden';
1195      else hs.discardElement(this.table);
1196  }
1197  };
1198  
1199  hs.Dimension = function(exp, dim) {
1200      this.exp = exp;
1201      this.dim = dim;
1202      this.ucwh = dim == 'x' ? 'Width' : 'Height';
1203      this.wh = this.ucwh.toLowerCase();
1204      this.uclt = dim == 'x' ? 'Left' : 'Top';
1205      this.lt = this.uclt.toLowerCase();
1206      this.ucrb = dim == 'x' ? 'Right' : 'Bottom';
1207      this.rb = this.ucrb.toLowerCase();
1208      this.p1 = this.p2 = 0;
1209  };
1210  hs.Dimension.prototype = {
1211  get : function(key) {
1212      switch (key) {
1213          case 'loadingPos':
1214              return this.tpos + this.tb + (this.t - hs.loading['offset'+ this.ucwh]) / 2;
1215          case 'loadingPosXfade':
1216              return this.pos + this.cb+ this.p1 + (this.size - hs.loading['offset'+ this.ucwh]) / 2;
1217          case 'wsize':
1218              return this.size + 2 * this.cb + this.p1 + this.p2;
1219          case 'fitsize':
1220              return this.clientSize - this.marginMin - this.marginMax;
1221          case 'maxsize':
1222              return this.get('fitsize') - 2 * this.cb - this.p1 - this.p2 ;
1223          case 'opos':
1224              return this.pos - (this.exp.outline ? this.exp.outline.offset : 0);
1225          case 'osize':
1226              return this.get('wsize') + (this.exp.outline ? 2*this.exp.outline.offset : 0);
1227          case 'imgPad':
1228              return this.imgSize ? Math.round((this.size - this.imgSize) / 2) : 0;
1229          
1230      }
1231  },
1232  calcBorders: function() {
1233      // correct for borders

1234      this.cb = (this.exp.content['offset'+ this.ucwh] - this.t) / 2;
1235      
1236      this.marginMax = hs['margin'+ this.ucrb];
1237  },
1238  calcThumb: function() {
1239      this.t = this.exp.el[this.wh] ? parseInt(this.exp.el[this.wh]) : 
1240          this.exp.el['offset'+ this.ucwh];
1241      this.tpos = this.exp.tpos[this.dim];
1242      this.tb = (this.exp.el['offset'+ this.ucwh] - this.t) / 2;
1243      if (this.tpos == 0 || this.tpos == -1) {
1244          this.tpos = (hs.page[this.wh] / 2) + hs.page['scroll'+ this.uclt];        
1245      };
1246  },
1247  calcExpanded: function() {
1248      var exp = this.exp;
1249      this.justify = 'auto';
1250      
1251      // get alignment

1252      if (exp.align == 'center') this.justify = 'center';
1253      else if (new RegExp(this.lt).test(exp.anchor)) this.justify = null;
1254      else if (new RegExp(this.rb).test(exp.anchor)) this.justify = 'max';
1255      
1256      
1257      // size and position

1258      this.pos = this.tpos - this.cb + this.tb;
1259      
1260      if (this.maxHeight && this.dim == 'x')
1261          exp.maxWidth = Math.min(exp.maxWidth || this.full, exp.maxHeight * this.full / exp.y.full); 
1262          
1263      this.size = Math.min(this.full, exp['max'+ this.ucwh] || this.full);
1264      this.minSize = exp.allowSizeReduction ? 
1265          Math.min(exp['min'+ this.ucwh], this.full) :this.full;
1266      if (exp.isImage && exp.useBox)    {
1267          this.size = exp[this.wh];
1268          this.imgSize = this.full;
1269      }
1270      if (this.dim == 'x' && hs.padToMinWidth) this.minSize = exp.minWidth;
1271      this.target = exp['target'+ this.dim.toUpperCase()];
1272      this.marginMin = hs['margin'+ this.uclt];
1273      this.scroll = hs.page['scroll'+ this.uclt];
1274      this.clientSize = hs.page[this.wh];
1275  },
1276  setSize: function(i) {
1277      var exp = this.exp;
1278      if (exp.isImage && (exp.useBox || hs.padToMinWidth)) {
1279          this.imgSize = i;
1280          this.size = Math.max(this.size, this.imgSize);
1281          exp.content.style[this.lt] = this.get('imgPad')+'px';
1282      } else
1283      this.size = i;
1284      
1285      exp.content.style[this.wh] = i +'px';
1286      exp.wrapper.style[this.wh] = this.get('wsize') +'px';
1287      if (exp.outline) exp.outline.setPosition();
1288      if (exp.releaseMask) exp.releaseMask.style[this.wh] = i +'px';
1289      if (this.dim == 'y' && exp.iDoc && exp.body.style.height != 'auto') try {
1290          exp.iDoc.body.style.overflow = 'auto';
1291      } catch (e) {}
1292      if (exp.isHtml) {
1293          var d = exp.scrollerDiv;
1294          if (this.sizeDiff === undefined)
1295              this.sizeDiff = exp.innerContent['offset'+ this.ucwh] - d['offset'+ this.ucwh];
1296          d.style[this.wh] = (this.size - this.sizeDiff) +'px';
1297              
1298          if (this.dim == 'x') exp.mediumContent.style.width = 'auto';
1299          if (exp.body) exp.body.style[this.wh] = 'auto';
1300      }
1301      if (this.dim == 'x' && exp.overlayBox) exp.sizeOverlayBox(true);
1302      if (this.dim == 'x' && exp.slideshow && exp.isImage) {
1303          if (i == this.full) exp.slideshow.disable('full-expand');
1304          else exp.slideshow.enable('full-expand');
1305      }
1306  },
1307  setPos: function(i) {
1308      this.pos = i;
1309      this.exp.wrapper.style[this.lt] = i +'px';    
1310      
1311      if (this.exp.outline) this.exp.outline.setPosition();
1312      
1313  }
1314  };
1315  
1316  hs.Expander = function(a, params, custom, contentType) {
1317      if (document.readyState && hs.ie && !hs.isReady) {
1318          hs.addEventListener(document, 'ready', function() {
1319              new hs.Expander(a, params, custom, contentType);
1320          });
1321          return;
1322      } 
1323      this.a = a;
1324      this.custom = custom;
1325      this.contentType = contentType || 'image';
1326      this.isHtml = (contentType == 'html');
1327      this.isImage = !this.isHtml;
1328      
1329      hs.continuePreloading = false;
1330      this.overlays = [];
1331      this.last = hs.last;
1332      hs.last = null;
1333      hs.init();
1334      var key = this.key = hs.expanders.length;
1335      // override inline parameters

1336      for (var i = 0; i < hs.overrides.length; i++) {
1337          var name = hs.overrides[i];
1338          this[name] = params && typeof params[name] != 'undefined' ?
1339              params[name] : hs[name];
1340      }
1341      if (!this.src) this.src = a.href;
1342      
1343      // get thumb

1344      var el = (params && params.thumbnailId) ? hs.$(params.thumbnailId) : a;
1345      el = this.thumb = el.getElementsByTagName('img')[0] || el;
1346      this.thumbsUserSetId = el.id || a.id;
1347      if (!hs.fireEvent(this, 'onInit')) return true;
1348      
1349      // check if already open

1350      for (var i = 0; i < hs.expanders.length; i++) {
1351          if (hs.expanders[i] && hs.expanders[i].a == a 
1352              && !(this.last && this.transitions[1] == 'crossfade')) {
1353              hs.expanders[i].focus();
1354              return false;
1355          }
1356      }    
1357  
1358      // cancel other

1359      if (!hs.allowSimultaneousLoading) for (var i = 0; i < hs.expanders.length; i++) {
1360          if (hs.expanders[i] && hs.expanders[i].thumb != el && !hs.expanders[i].onLoadStarted) {
1361              hs.expanders[i].cancelLoading();
1362          }
1363      }
1364      hs.expanders[key] = this;
1365      if (!hs.allowMultipleInstances && !hs.upcoming) {
1366          if (hs.expanders[key-1]) hs.expanders[key-1].close();
1367          if (typeof hs.focusKey != 'undefined' && hs.expanders[hs.focusKey])
1368              hs.expanders[hs.focusKey].close();
1369      }
1370      
1371      // initiate metrics

1372      this.el = el;
1373      this.tpos = this.pageOrigin || hs.getPosition(el);
1374      hs.getPageSize();
1375      var x = this.x = new hs.Dimension(this, 'x');
1376      x.calcThumb();
1377      var y = this.y = new hs.Dimension(this, 'y');
1378      y.calcThumb();
1379      if (/area/i.test(el.tagName)) this.getImageMapAreaCorrection(el);
1380      this.wrapper = hs.createElement(
1381          'div', {
1382              id: 'highslide-wrapper-'+ this.key,
1383              className: 'highslide-wrapper '+ this.wrapperClassName
1384          }, {
1385              visibility: 'hidden',
1386              position: 'absolute',
1387              zIndex: hs.zIndexCounter += 2
1388          }, null, true );
1389      
1390      this.wrapper.onmouseover = this.wrapper.onmouseout = hs.wrapperMouseHandler;
1391      if (this.contentType == 'image' && this.outlineWhileAnimating == 2)
1392          this.outlineWhileAnimating = 0;
1393      
1394      // get the outline

1395      if (!this.outlineType 
1396          || (this.last && this.isImage && this.transitions[1] == 'crossfade')) {
1397          this[this.contentType +'Create']();
1398      
1399      } else if (hs.pendingOutlines[this.outlineType]) {
1400          this.connectOutline();
1401          this[this.contentType +'Create']();
1402      
1403      } else {
1404          this.showLoading();
1405          var exp = this;
1406          new hs.Outline(this.outlineType, 
1407              function () {
1408                  exp.connectOutline();
1409                  exp[exp.contentType +'Create']();
1410              } 
1411          );
1412      }
1413      return true;
1414  };
1415  
1416  hs.Expander.prototype = {
1417  error : function(e) {
1418      if (hs.debug) alert ('Line '+ e.lineNumber +': '+ e.message);
1419      else window.location.href = this.src;
1420  },
1421  
1422  connectOutline : function() {
1423      var outline = this.outline = hs.pendingOutlines[this.outlineType];
1424      outline.exp = this;
1425      outline.table.style.zIndex = this.wrapper.style.zIndex - 1;
1426      hs.pendingOutlines[this.outlineType] = null;
1427  },
1428  
1429  showLoading : function() {
1430      if (this.onLoadStarted || this.loading) return;
1431      
1432      this.loading = hs.loading;
1433      var exp = this;
1434      this.loading.onclick = function() {
1435          exp.cancelLoading();
1436      };
1437      
1438      
1439      if (!hs.fireEvent(this, 'onShowLoading')) return;
1440      var exp = this, 
1441          l = this.x.get('loadingPos') +'px',
1442          t = this.y.get('loadingPos') +'px';
1443      if (!tgt && this.last && this.transitions[1] == 'crossfade') 
1444          var tgt = this.last; 
1445      if (tgt) {
1446          l = tgt.x.get('loadingPosXfade') +'px';
1447          t = tgt.y.get('loadingPosXfade') +'px';
1448          this.loading.style.zIndex = hs.zIndexCounter++;
1449      }
1450      setTimeout(function () { 
1451          if (exp.loading) hs.setStyles(exp.loading, { left: l, top: t, zIndex: hs.zIndexCounter++ })}
1452      , 100);
1453  },
1454  
1455  imageCreate : function() {
1456      var exp = this;
1457      
1458      var img = document.createElement('img');
1459      this.content = img;
1460      img.onload = function () {
1461          if (hs.expanders[exp.key]) exp.contentLoaded(); 
1462      };
1463      if (hs.blockRightClick) img.oncontextmenu = function() { return false; };
1464      img.className = 'highslide-image';
1465      hs.setStyles(img, {
1466          visibility: 'hidden',
1467          display: 'block',
1468          position: 'absolute',
1469          maxWidth: '9999px',
1470          zIndex: 3
1471      });
1472      img.title = hs.lang.restoreTitle;
1473      if (hs.safari && hs.uaVersion < 525) hs.container.appendChild(img);
1474      if (hs.ie && hs.flushImgSize) img.src = null;
1475      img.src = this.src;
1476      
1477      this.showLoading();
1478  },
1479  
1480  htmlCreate : function () {
1481      if (!hs.fireEvent(this, 'onBeforeGetContent')) return;
1482      
1483      this.content = hs.getCacheBinding(this.a);
1484      if (!this.content) 
1485          this.content = hs.getNode(this.contentId);
1486      if (!this.content) 
1487          this.content = hs.getSelfRendered();
1488      this.getInline(['maincontent']);
1489      if (this.maincontent) {
1490          var body = hs.getElementByClass(this.content, 'div', 'highslide-body');
1491          if (body) body.appendChild(this.maincontent);
1492          this.maincontent.style.display = 'block';
1493      }
1494      hs.fireEvent(this, 'onAfterGetContent');
1495      
1496      var innerContent = this.innerContent = this.content;
1497      
1498      if (/(swf|iframe)/.test(this.objectType)) this.setObjContainerSize(innerContent);
1499      
1500      // the content tree

1501      hs.container.appendChild(this.wrapper);
1502      hs.setStyles( this.wrapper, { 
1503          position: 'static',
1504          padding: '0 '+ hs.marginRight +'px 0 '+ hs.marginLeft +'px'
1505      });
1506      this.content = hs.createElement(
1507          'div', {
1508              className: 'highslide-html' 
1509          }, {
1510              position: 'relative',
1511              zIndex: 3,
1512              height: 0,
1513              overflow: 'hidden'
1514          },
1515          this.wrapper
1516      );
1517      this.mediumContent = hs.createElement('div', null, null, this.content, 1);
1518      this.mediumContent.appendChild(innerContent);
1519      
1520      hs.setStyles (innerContent, { 
1521          position: 'relative',
1522          display: 'block',
1523          direction: hs.lang.cssDirection || ''
1524      });
1525      if (this.width) innerContent.style.width = this.width +'px';
1526      if (this.height) hs.setStyles(innerContent, {
1527          height: this.height +'px',
1528          overflow: 'hidden'
1529      });
1530      if (innerContent.offsetWidth < this.minWidth)
1531          innerContent.style.width = this.minWidth +'px';
1532          
1533      
1534      
1535      if (this.objectType == 'ajax' && !hs.getCacheBinding(this.a)) {
1536          this.showLoading();
1537          var exp = this;
1538          var ajax = new hs.Ajax(this.a, innerContent);
1539          ajax.src = this.src;
1540          ajax.onLoad = function () {    if (hs.expanders[exp.key]) exp.contentLoaded(); };
1541          ajax.onError = function () { location.href = exp.src; };
1542          ajax.run();
1543      }
1544      else
1545      
1546      if (this.objectType == 'iframe' && this.objectLoadTime == 'before') {
1547          this.writeExtendedContent();
1548      }
1549      else
1550          this.contentLoaded();
1551  },
1552  
1553  contentLoaded : function() {
1554      try {    
1555          if (!this.content) return;
1556          this.content.onload = null;
1557          if (this.onLoadStarted) return;
1558          else this.onLoadStarted = true;
1559          
1560          var x = this.x, y = this.y;
1561          
1562          if (this.loading) {
1563              hs.setStyles(this.loading, { top: '-9999px' });
1564              this.loading = null;
1565              hs.fireEvent(this, 'onHideLoading');
1566          }
1567          if (this.isImage) {    
1568              x.full = this.content.width;
1569              y.full = this.content.height;
1570              
1571              hs.setStyles(this.content, {
1572                  width: x.t +'px',
1573                  height: y.t +'px'
1574              });
1575              this.wrapper.appendChild(this.content);
1576              hs.container.appendChild(this.wrapper);
1577          } else if (this.htmlGetSize) this.htmlGetSize();
1578          
1579          x.calcBorders();
1580          y.calcBorders();
1581          
1582          hs.setStyles (this.wrapper, {
1583              left: (x.tpos + x.tb - x.cb) +'px',
1584              top: (y.tpos + x.tb - y.cb) +'px'
1585          });
1586          
1587          
1588          this.initSlideshow();
1589          this.getOverlays();
1590          
1591          var ratio = x.full / y.full;
1592          x.calcExpanded();
1593          this.justify(x);
1594          
1595          y.calcExpanded();
1596          this.justify(y);
1597          if (this.isHtml) this.htmlSizeOperations();
1598          if (this.overlayBox) this.sizeOverlayBox(0, 1);
1599  
1600          
1601          if (this.allowSizeReduction) {
1602              if (this.isImage)
1603                  this.correctRatio(ratio);
1604              else this.fitOverlayBox();
1605              var ss = this.slideshow;            
1606              if (ss && this.last && ss.controls && ss.fixedControls) {
1607                  var pos = ss.overlayOptions.position || '', p;
1608                  for (var dim in hs.oPos) for (var i = 0; i < 5; i++) {
1609                      p = this[dim];
1610                      if (pos.match(hs.oPos[dim][i])) {
1611                          p.pos = this.last[dim].pos 
1612                              + (this.last[dim].p1 - p.p1)
1613                              + (this.last[dim].size - p.size) * [0, 0, .5, 1, 1][i];
1614                          if (ss.fixedControls == 'fit') {
1615                              if (p.pos + p.size + p.p1 + p.p2 > p.scroll + p.clientSize - p.marginMax)
1616                                  p.pos = p.scroll + p.clientSize - p.size - p.marginMin - p.marginMax - p.p1 - p.p2;
1617                              if (p.pos < p.scroll + p.marginMin) p.pos = p.scroll + p.marginMin; 
1618                          } 
1619                      }
1620                  }
1621              }
1622              if (this.isImage && this.x.full > (this.x.imgSize || this.x.size)) {
1623                  this.createFullExpand();
1624                  if (this.overlays.length == 1) this.sizeOverlayBox();
1625              }
1626          }
1627          this.show();
1628          
1629      } catch (e) {
1630          this.error(e);
1631      }
1632  },
1633  
1634  
1635  setObjContainerSize : function(parent, auto) {
1636      var c = hs.getElementByClass(parent, 'DIV', 'highslide-body');
1637      if (/(iframe|swf)/.test(this.objectType)) {
1638          if (this.objectWidth) c.style.width = this.objectWidth +'px';
1639          if (this.objectHeight) c.style.height = this.objectHeight +'px';
1640      }
1641  },
1642  
1643  writeExtendedContent : function () {
1644      if (this.hasExtendedContent) return;
1645      var exp = this;
1646      this.body = hs.getElementByClass(this.innerContent, 'DIV', 'highslide-body');
1647      if (this.objectType == 'iframe') {
1648          this.showLoading();
1649          var ruler = hs.clearing.cloneNode(1);
1650          this.body.appendChild(ruler);
1651          this.newWidth = this.innerContent.offsetWidth;
1652          if (!this.objectWidth) this.objectWidth = ruler.offsetWidth;
1653          var hDiff = this.innerContent.offsetHeight - this.body.offsetHeight,
1654              h = this.objectHeight || hs.page.height - hDiff - hs.marginTop - hs.marginBottom,
1655              onload = this.objectLoadTime == 'before' ? 
1656                  ' onload="if (hs.expanders['+ this.key +']) hs.expanders['+ this.key +'].contentLoaded()" ' : '';
1657          this.body.innerHTML += '<iframe name="hs'+ (new Date()).getTime() +'" frameborder="0" key="'+ this.key +'" '
1658              +' style="width:'+ this.objectWidth +'px; height:'+ h +'px" '
1659              + onload +' src="'+ this.src +'" ></iframe>';
1660          this.ruler = this.body.getElementsByTagName('div')[0];
1661          this.iframe = this.body.getElementsByTagName('iframe')[0];
1662          
1663          if (this.objectLoadTime == 'after') this.correctIframeSize();
1664          
1665      }
1666      if (this.objectType == 'swf') {
1667          this.body.id = this.body.id || 'hs-flash-id-' + this.key;
1668          var a = this.swfOptions;
1669          if (!a.params) a.params = {};
1670          if (typeof a.params.wmode == 'undefined') a.params.wmode = 'transparent';
1671          if (swfobject) swfobject.embedSWF(this.src, this.body.id, this.objectWidth, this.objectHeight, 
1672              a.version || '7', a.expressInstallSwfurl, a.flashvars, a.params, a.attributes);
1673      }
1674      this.hasExtendedContent = true;
1675  },
1676  htmlGetSize : function() {
1677      if (this.iframe && !this.objectHeight) { // loadtime before
1678          this.iframe.style.height = this.body.style.height = this.getIframePageHeight() +'px';
1679      }
1680      this.innerContent.appendChild(hs.clearing);
1681      if (!this.x.full) this.x.full = this.innerContent.offsetWidth;
1682      this.y.full = this.innerContent.offsetHeight;
1683      this.innerContent.removeChild(hs.clearing);
1684      if (hs.ie && this.newHeight > parseInt(this.innerContent.currentStyle.height)) { // ie css bug
1685          this.newHeight = parseInt(this.innerContent.currentStyle.height);
1686      }
1687      hs.setStyles( this.wrapper, { position: 'absolute',    padding: '0'});
1688      hs.setStyles( this.content, { width: this.x.t +'px', height: this.y.t +'px'});
1689      
1690  },
1691  
1692  getIframePageHeight : function() {
1693      var h;
1694      try {
1695          var doc = this.iDoc = this.iframe.contentDocument || this.iframe.contentWindow.document;
1696          var clearing = doc.createElement('div');
1697          clearing.style.clear = 'both';
1698          doc.body.appendChild(clearing);
1699          h = clearing.offsetTop;
1700          if (hs.ie) h += parseInt(doc.body.currentStyle.marginTop) 
1701              + parseInt(doc.body.currentStyle.marginBottom) - 1;
1702      } catch (e) { // other domain
1703          h = 300;
1704      }
1705      return h;
1706  },
1707  correctIframeSize : function () {
1708      var wDiff = this.innerContent.offsetWidth - this.ruler.offsetWidth;
1709      hs.discardElement(this.ruler);
1710      if (wDiff < 0) wDiff = 0;
1711      
1712      var hDiff = this.innerContent.offsetHeight - this.iframe.offsetHeight;
1713      if (this.iDoc && !this.objectHeight && !this.height && this.y.size == this.y.full) try {
1714          this.iDoc.body.style.overflow = 'hidden';
1715      } catch (e) {}
1716      hs.setStyles(this.iframe, { 
1717          width: Math.abs(this.x.size - wDiff) +'px', 
1718          height: Math.abs(this.y.size - hDiff) +'px'
1719      });
1720      hs.setStyles(this.body, { 
1721          width: this.iframe.style.width, 
1722          height: this.iframe.style.height
1723      });
1724          
1725      this.scrollingContent = this.iframe;
1726      this.scrollerDiv = this.scrollingContent;
1727      
1728  },
1729  htmlSizeOperations : function () {
1730      
1731      this.setObjContainerSize(this.innerContent);
1732      
1733      
1734      if (this.objectType == 'swf' && this.objectLoadTime == 'before') this.writeExtendedContent();    
1735      
1736      // handle minimum size

1737      if (this.x.size < this.x.full && !this.allowWidthReduction) this.x.size = this.x.full;
1738      if (this.y.size < this.y.full && !this.allowHeightReduction) this.y.size = this.y.full;
1739      this.scrollerDiv = this.innerContent;
1740      hs.setStyles(this.mediumContent, { 
1741          position: 'relative',
1742          width: this.x.size +'px'
1743      });
1744      hs.setStyles(this.innerContent, { 
1745          border: 'none',
1746          width: 'auto',
1747          height: 'auto'
1748      });
1749      var node = hs.getElementByClass(this.innerContent, 'DIV', 'highslide-body');
1750      if (node && !/(iframe|swf)/.test(this.objectType)) {
1751          var cNode = node; // wrap to get true size

1752          node = hs.createElement(cNode.nodeName, null, {overflow: 'hidden'}, null, true);
1753          cNode.parentNode.insertBefore(node, cNode);
1754          node.appendChild(hs.clearing); // IE6

1755          node.appendChild(cNode);
1756          
1757          var wDiff = this.innerContent.offsetWidth - node.offsetWidth;
1758          var hDiff = this.innerContent.offsetHeight - node.offsetHeight;
1759          node.removeChild(hs.clearing);
1760          
1761          var kdeBugCorr = hs.safari || navigator.vendor == 'KDE' ? 1 : 0; // KDE repainting bug

1762          hs.setStyles(node, { 
1763                  width: (this.x.size - wDiff - kdeBugCorr) +'px', 
1764                  height: (this.y.size - hDiff) +'px',
1765                  overflow: 'auto', 
1766                  position: 'relative' 
1767              } 
1768          );
1769          if (kdeBugCorr && cNode.offsetHeight > node.offsetHeight)    {
1770              node.style.width = (parseInt(node.style.width) + kdeBugCorr) + 'px';
1771          }
1772          this.scrollingContent = node;
1773          this.scrollerDiv = this.scrollingContent;
1774      }
1775      if (this.iframe && this.objectLoadTime == 'before') this.correctIframeSize();
1776      if (!this.scrollingContent && this.y.size < this.mediumContent.offsetHeight) this.scrollerDiv = this.content;
1777      
1778      if (this.scrollerDiv == this.content && !this.allowWidthReduction && !/(iframe|swf)/.test(this.objectType)) {
1779          this.x.size += 17; // room for scrollbars

1780      }
1781      if (this.scrollerDiv && this.scrollerDiv.offsetHeight > this.scrollerDiv.parentNode.offsetHeight) {
1782          setTimeout("try { hs.expanders["+ this.key +"].scrollerDiv.style.overflow = 'auto'; } catch(e) {}",
1783               hs.expandDuration);
1784      }
1785  },
1786  
1787  getImageMapAreaCorrection : function(area) {
1788      var c = area.coords.split(',');
1789      for (var i = 0; i < c.length; i++) c[i] = parseInt(c[i]);
1790      
1791      if (area.shape.toLowerCase() == 'circle') {
1792          this.x.tpos += c[0] - c[2];
1793          this.y.tpos += c[1] - c[2];
1794          this.x.t = this.y.t = 2 * c[2];
1795      } else {
1796          var maxX, maxY, minX = maxX = c[0], minY = maxY = c[1];
1797          for (var i = 0; i < c.length; i++) {
1798              if (i % 2 == 0) {
1799                  minX = Math.min(minX, c[i]);
1800                  maxX = Math.max(maxX, c[i]);
1801              } else {
1802                  minY = Math.min(minY, c[i]);
1803                  maxY = Math.max(maxY, c[i]);
1804              }
1805          }
1806          this.x.tpos += minX;
1807          this.x.t = maxX - minX;
1808          this.y.tpos += minY;
1809          this.y.t = maxY - minY;
1810      }
1811  },
1812  justify : function (p, moveOnly) {
1813      var tgtArr, tgt = p.target, dim = p == this.x ? 'x' : 'y';
1814      
1815      if (tgt && tgt.match(/ /)) {
1816          tgtArr = tgt.split(' ');
1817          tgt = tgtArr[0];
1818      }
1819      if (tgt && hs.$(tgt)) {
1820          p.pos = hs.getPosition(hs.$(tgt))[dim];
1821          if (tgtArr && tgtArr[1] && tgtArr[1].match(/^[-]?[0-9]+px$/)) 
1822              p.pos += parseInt(tgtArr[1]);
1823          if (p.size < p.minSize) p.size = p.minSize;
1824          
1825      } else if (p.justify == 'auto' || p.justify == 'center') {
1826      
1827          var hasMovedMin = false;
1828          
1829          var allowReduce = p.exp.allowSizeReduction;
1830          if (p.justify == 'center')
1831              p.pos = Math.round(p.scroll + (p.clientSize + p.marginMin - p.marginMax - p.get('wsize')) / 2);
1832          else
1833              p.pos = Math.round(p.pos - ((p.get('wsize') - p.t) / 2));
1834          if (p.pos < p.scroll + p.marginMin) {
1835              p.pos = p.scroll + p.marginMin;
1836              hasMovedMin = true;        
1837          }
1838          if (!moveOnly && p.size < p.minSize) {
1839              p.size = p.minSize;
1840              allowReduce = false;
1841          }
1842          if (p.pos + p.get('wsize') > p.scroll + p.clientSize - p.marginMax) {
1843              if (!moveOnly && hasMovedMin && allowReduce) {
1844                  p.size = Math.min(p.size, p.get(dim == 'y' ? 'fitsize' : 'maxsize'));
1845              } else if (p.get('wsize') < p.get('fitsize')) {
1846                  p.pos = p.scroll + p.clientSize - p.marginMax - p.get('wsize');
1847              } else { // image larger than viewport
1848                  p.pos = p.scroll + p.marginMin;
1849                  if (!moveOnly && allowReduce) p.size = p.get(dim == 'y' ? 'fitsize' : 'maxsize');
1850              }            
1851          }
1852          
1853          if (!moveOnly && p.size < p.minSize) {
1854              p.size = p.minSize;
1855              allowReduce = false;
1856          }
1857          
1858      
1859      } else if (p.justify == 'max') {
1860          p.pos = Math.floor(p.pos - p.size + p.t);
1861      }
1862      
1863          
1864      if (p.pos < p.marginMin) {
1865          var tmpMin = p.pos;
1866          p.pos = p.marginMin; 
1867          
1868          if (allowReduce && !moveOnly) p.size = p.size - (p.pos - tmpMin);
1869          
1870      }
1871  },
1872  
1873  correctRatio : function(ratio) {
1874      var x = this.x, 
1875          y = this.y,
1876          changed = false,
1877          xSize = Math.min(x.full, x.size),
1878          ySize = Math.min(y.full, y.size),
1879          useBox = (this.useBox || hs.padToMinWidth);
1880      
1881      if (xSize / ySize > ratio) { // width greater
1882          xSize = ySize * ratio;
1883          if (xSize < x.minSize) { // below minWidth
1884              xSize = x.minSize;
1885              ySize = xSize / ratio;
1886          }
1887          changed = true;
1888      
1889      } else if (xSize / ySize < ratio) { // height greater
1890          ySize = xSize / ratio;
1891          changed = true;
1892      }
1893      
1894      if (hs.padToMinWidth && x.full < x.minSize) {
1895          x.imgSize = x.full;
1896          y.size = y.imgSize = y.full;
1897      } else if (this.useBox) {
1898          x.imgSize = xSize;
1899          y.imgSize = ySize;
1900      } else {
1901          x.size = xSize;
1902          y.size = ySize;
1903      }
1904      changed = this.fitOverlayBox(this.useBox ? null : ratio, changed);
1905      if (useBox && y.size < y.imgSize) {
1906          y.imgSize = y.size;
1907          x.imgSize = y.size * ratio;
1908      }
1909      if (changed || useBox) {
1910          x.pos = x.tpos - x.cb + x.tb;
1911          x.minSize = x.size;
1912          this.justify(x, true);
1913      
1914          y.pos = y.tpos - y.cb + y.tb;
1915          y.minSize = y.size;
1916          this.justify(y, true);
1917          if (this.overlayBox) this.sizeOverlayBox();
1918      }
1919      
1920      
1921  },
1922  fitOverlayBox : function(ratio, changed) {
1923      var x = this.x, y = this.y;
1924      if (this.overlayBox && (this.isImage || this.allowHeightReduction)) {
1925          while (y.size > this.minHeight && x.size > this.minWidth 
1926                  &&  y.get('wsize') > y.get('fitsize')) {
1927              y.size -= 10;
1928              if (ratio) x.size = y.size * ratio;
1929              this.sizeOverlayBox(0, 1);
1930              changed = true;
1931          }
1932      }
1933      return changed;
1934  },
1935  
1936  reflow : function () {
1937      if (this.scrollerDiv) {
1938          var h = /iframe/i.test(this.scrollerDiv.tagName) ? (this.getIframePageHeight() + 1) +'px' : 'auto';
1939          if (this.body) this.body.style.height = h;
1940          this.scrollerDiv.style.height = h;
1941          this.y.setSize(this.innerContent.offsetHeight);
1942      }
1943  },
1944  
1945  show : function () {
1946      var x = this.x, y = this.y;
1947      this.doShowHide('hidden');
1948      hs.fireEvent(this, 'onBeforeExpand');
1949      if (this.slideshow && this.slideshow.thumbstrip) this.slideshow.thumbstrip.selectThumb();
1950      
1951      // Apply size change

1952      this.changeSize(
1953          1, {
1954              wrapper: {
1955                  width : x.get('wsize'),
1956                  height : y.get('wsize'),
1957                  left: x.pos,
1958                  top: y.pos
1959              },
1960              content: {
1961                  left: x.p1 + x.get('imgPad'),
1962                  top: y.p1 + y.get('imgPad'),
1963                  width:x.imgSize ||x.size,
1964                  height:y.imgSize ||y.size
1965              }
1966          },
1967          hs.expandDuration
1968      );
1969  },
1970  
1971  changeSize : function(up, to, dur) {
1972      // transition

1973      var trans = this.transitions,
1974      other = up ? (this.last ? this.last.a : null) : hs.upcoming,
1975      t = (trans[1] && other 
1976              && hs.getParam(other, 'transitions')[1] == trans[1]) ?
1977          trans[1] : trans[0];
1978          
1979      if (this[t] && t != 'expand') {
1980          this[t](up, to);
1981          return;
1982      }
1983      
1984      if (this.outline && !this.outlineWhileAnimating) {
1985          if (up) this.outline.setPosition();
1986          else this.outline.destroy(
1987                  (this.isHtml && this.preserveContent));
1988      }
1989      
1990      
1991      if (!up) this.destroyOverlays();
1992      
1993      var exp = this,
1994          x = exp.x,
1995          y = exp.y,
1996          easing = this.easing;
1997      if (!up) easing = this.easingClose || easing;
1998      var after = up ?
1999          function() {
2000                  
2001              if (exp.outline) exp.outline.table.style.visibility = "visible";
2002              setTimeout(function() {
2003                  exp.afterExpand();
2004              }, 50);
2005          } :
2006          function() {
2007              exp.afterClose();
2008          };
2009      if (up) hs.setStyles( this.wrapper, {
2010          width: x.t +'px',
2011          height: y.t +'px'
2012      });
2013      if (up && this.isHtml) {
2014          hs.setStyles(this.wrapper, {
2015              left: (x.tpos - x.cb + x.tb) +'px',
2016              top: (y.tpos - y.cb + y.tb) +'px'
2017          });
2018      }
2019      if (this.fadeInOut) {
2020          hs.setStyles(this.wrapper, { opacity: up ? 0 : 1 });
2021          hs.extend(to.wrapper, { opacity: up });
2022      }
2023      hs.animate( this.wrapper, to.wrapper, {
2024          duration: dur,
2025          easing: easing,
2026          step: function(val, args) {
2027              if (exp.outline && exp.outlineWhileAnimating && args.prop == 'top') {
2028                  var fac = up ? args.pos : 1 - args.pos;
2029                  var pos = {
2030                      w: x.t + (x.get('wsize') - x.t) * fac,
2031                      h: y.t + (y.get('wsize') - y.t) * fac,
2032                      x: x.tpos + (x.pos - x.tpos) * fac,
2033                      y: y.tpos + (y.pos - y.tpos) * fac
2034                  };
2035                  exp.outline.setPosition(pos, 0, 1);                
2036              }
2037              if (exp.isHtml) {    
2038                  if (args.prop == 'left') 
2039                      exp.mediumContent.style.left = (x.pos - val) +'px';
2040                  if (args.prop == 'top') 
2041                      exp.mediumContent.style.top = (y.pos - val) +'px';
2042              }
2043          }
2044      });
2045      hs.animate( this.content, to.content, dur, easing, after);
2046      if (up) {
2047          this.wrapper.style.visibility = 'visible';
2048          this.content.style.visibility = 'visible';
2049          if (this.isHtml) this.innerContent.style.visibility = 'visible';
2050          this.a.className += ' highslide-active-anchor';
2051      }
2052  },
2053  
2054  
2055  
2056  fade : function(up, to) {
2057      this.outlineWhileAnimating = false;
2058      var exp = this,    t = up ? hs.expandDuration : 0;
2059      
2060      if (up) {
2061          hs.animate(this.wrapper, to.wrapper, 0);
2062          hs.setStyles(this.wrapper, { opacity: 0, visibility: 'visible' });
2063          hs.animate(this.content, to.content, 0);
2064          this.content.style.visibility = 'visible';
2065  
2066          hs.animate(this.wrapper, { opacity: 1 }, t, null, 
2067              function() { exp.afterExpand(); });
2068      }
2069      
2070      if (this.outline) {
2071          this.outline.table.style.zIndex = this.wrapper.style.zIndex;
2072          var dir = up || -1, 
2073              offset = this.outline.offset,
2074              startOff = up ? 3 : offset,
2075              endOff = up? offset : 3;
2076          for (var i = startOff; dir * i <= dir * endOff; i += dir, t += 25) {
2077              (function() {
2078                  var o = up ? endOff - i : startOff - i;
2079                  setTimeout(function() {
2080                      exp.outline.setPosition(0, o, 1);
2081                  }, t);
2082              })();
2083          }
2084      }
2085      
2086      
2087      if (up) {}//setTimeout(function() { exp.afterExpand(); }, t+50);

2088      else {
2089          setTimeout( function() {
2090              if (exp.outline) exp.outline.destroy(exp.preserveContent);
2091              
2092              exp.destroyOverlays();
2093      
2094              hs.animate( exp.wrapper, { opacity: 0 }, hs.restoreDuration, null, function(){
2095                  exp.afterClose();
2096              });
2097          }, t);        
2098      }
2099  },
2100  crossfade : function (up, to, from) {
2101      if (!up) return;
2102      var exp = this, 
2103          last = this.last,
2104          x = this.x,
2105          y = this.y,
2106          lastX = last.x,
2107          lastY = last.y,
2108          wrapper = this.wrapper,
2109          content = this.content,
2110          overlayBox = this.overlayBox;
2111      hs.removeEventListener(document, 'mousemove', hs.dragHandler);
2112      
2113      hs.setStyles(content, { 
2114          width: (x.imgSize || x.size) +'px', 
2115          height: (y.imgSize || y.size) +'px'        
2116      });
2117      if (overlayBox) overlayBox.style.overflow = 'visible';
2118      this.outline = last.outline;
2119      if (this.outline) this.outline.exp = exp;
2120      last.outline = null;
2121      var fadeBox = hs.createElement('div', {
2122              className: 'highslide-'+ this.contentType
2123          }, { 
2124              position: 'absolute', 
2125              zIndex: 4,
2126              overflow: 'hidden',
2127              display: 'none'
2128          }
2129      );
2130      var names = { oldImg: last, newImg: this };
2131      for (var n in names) {     
2132          this[n] = names[n].content.cloneNode(1);
2133          hs.setStyles(this[n], {
2134              position: 'absolute',
2135              border: 0,
2136              visibility: 'visible'
2137          });
2138          fadeBox.appendChild(this[n]);
2139      }
2140      wrapper.appendChild(fadeBox);
2141      if (this.isHtml) hs.setStyles(this.mediumContent, { 
2142          left: 0,
2143          top: 0
2144      });
2145      if (overlayBox) {
2146          overlayBox.className = '';
2147          wrapper.appendChild(overlayBox);
2148      }
2149      fadeBox.style.display = '';
2150      last.content.style.display = 'none';
2151      
2152      
2153      if (hs.safari && hs.uaVersion < 525) {
2154          this.wrapper.style.visibility = 'visible';
2155      }
2156      hs.animate(wrapper, {
2157          width: x.size
2158      }, {
2159          duration: hs.transitionDuration, 
2160          step: function(val, args) {
2161              var pos = args.pos,
2162                  invPos = 1 - pos;
2163              var prop,
2164                  size = {}, 
2165                  props = ['pos', 'size', 'p1', 'p2'];
2166              for (var n in props) {
2167                  prop = props[n];
2168                  size['x'+ prop] = Math.round(invPos * lastX[prop] + pos * x[prop]);
2169                  size['y'+ prop] = Math.round(invPos * lastY[prop] + pos * y[prop]);
2170                  size.ximgSize = Math.round(
2171                      invPos * (lastX.imgSize || lastX.size) + pos * (x.imgSize || x.size));
2172                  size.ximgPad = Math.round(invPos * lastX.get('imgPad') + pos * x.get('imgPad'));
2173                  size.yimgSize = Math.round(
2174                      invPos * (lastY.imgSize || lastY.size) + pos * (y.imgSize || y.size));
2175                  size.yimgPad = Math.round(invPos * lastY.get('imgPad') + pos * y.get('imgPad'));
2176              }
2177              if (exp.outline) exp.outline.setPosition({ 
2178                  x: size.xpos, 
2179                  y: size.ypos, 
2180                  w: size.xsize + size.xp1 + size.xp2 + 2 * x.cb, 
2181                  h: size.ysize + size.yp1 + size.yp2 + 2 * y.cb
2182              });
2183              last.wrapper.style.clip = 'rect('
2184                  + (size.ypos - lastY.pos)+'px, '
2185                  + (size.xsize + size.xp1 + size.xp2 + size.xpos + 2 * lastX.cb - lastX.pos) +'px, '
2186                  + (size.ysize + size.yp1 + size.yp2 + size.ypos + 2 * lastY.cb - lastY.pos) +'px, '
2187                  + (size.xpos - lastX.pos)+'px)';
2188                  
2189              hs.setStyles(content, {
2190                  top: (size.yp1 + y.get('imgPad')) +'px',
2191                  left: (size.xp1 + x.get('imgPad')) +'px',
2192                  marginTop: (y.pos - size.ypos) +'px',
2193                  marginLeft: (x.pos - size.xpos) +'px'
2194              });
2195              hs.setStyles(wrapper, {
2196                  top: size.ypos +'px',
2197                  left: size.xpos +'px',
2198                  width: (size.xp1 + size.xp2 + size.xsize + 2 * x.cb)+ 'px',
2199                  height: (size.yp1 + size.yp2 + size.ysize + 2 * y.cb) + 'px'
2200              });
2201              hs.setStyles(fadeBox, {
2202                  width: (size.ximgSize || size.xsize) + 'px',
2203                  height: (size.yimgSize || size.ysize) +'px',
2204                  left: (size.xp1 + size.ximgPad)  +'px',
2205                  top: (size.yp1 + size.yimgPad) +'px',
2206                  visibility: 'visible'
2207              });
2208              
2209              hs.setStyles(exp.oldImg, {
2210                  top: (lastY.pos - size.ypos + lastY.p1 - size.yp1 + lastY.get('imgPad') - size.yimgPad)+'px',
2211                  left: (lastX.pos - size.xpos + lastX.p1 - size.xp1 + lastX.get('imgPad') - size.ximgPad)+'px'
2212              });        
2213              
2214              hs.setStyles(exp.newImg, {
2215                  opacity: pos,
2216                  top: (y.pos - size.ypos + y.p1 - size.yp1 + y.get('imgPad') - size.yimgPad) +'px',
2217                  left: (x.pos - size.xpos + x.p1 - size.xp1 + x.get('imgPad') - size.ximgPad) +'px'
2218              });
2219              if (overlayBox) hs.setStyles(overlayBox, {
2220                  width: size.xsize + 'px',
2221                  height: size.ysize +'px',
2222                  left: (size.xp1 + x.cb)  +'px',
2223                  top: (size.yp1 + y.cb) +'px'
2224              });
2225          },
2226          complete: function () {
2227              wrapper.style.visibility = content.style.visibility = 'visible';
2228              content.style.display = 'block';
2229              hs.discardElement(fadeBox);
2230              exp.afterExpand();
2231              last.afterClose();
2232              exp.last = null;
2233          }
2234          
2235      });
2236  },
2237  reuseOverlay : function(o, el) {
2238      if (!this.last) return false;
2239      for (var i = 0; i < this.last.overlays.length; i++) {
2240          var oDiv = hs.$('hsId'+ this.last.overlays[i]);
2241          if (oDiv && oDiv.hsId == o.hsId) {
2242              this.genOverlayBox();
2243              oDiv.reuse = this.key;
2244              hs.push(this.overlays, this.last.overlays[i]);
2245              return true;
2246          }
2247      }
2248      return false;
2249  },
2250  
2251  
2252  afterExpand : function() {
2253      this.isExpanded = true;    
2254      this.focus();
2255      
2256      if (this.isHtml && this.objectLoadTime == 'after') this.writeExtendedContent();
2257      if (this.iframe) {
2258          try {
2259              var exp = this,
2260                  doc = this.iframe.contentDocument || this.iframe.contentWindow.document;
2261              hs.addEventListener(doc, 'mousedown', function () {
2262                  if (hs.focusKey != exp.key) exp.focus();
2263              });
2264          } catch(e) {}
2265          if (hs.ie && typeof this.isClosing != 'boolean') // first open 
2266              this.iframe.style.width = (this.objectWidth - 1) +'px'; // hasLayout

2267      }
2268      if (this.dimmingOpacity) hs.dim(this);
2269      if (hs.upcoming && hs.upcoming == this.a) hs.upcoming = null;
2270      this.prepareNextOutline();
2271      var p = hs.page, mX = hs.mouse.x + p.scrollLeft, mY = hs.mouse.y + p.scrollTop;
2272      this.mouseIsOver = this.x.pos < mX && mX < this.x.pos + this.x.get('wsize')
2273          && this.y.pos < mY && mY < this.y.pos + this.y.get('wsize');    
2274      if (this.overlayBox) this.showOverlays();
2275      hs.fireEvent(this, 'onAfterExpand');
2276      
2277  },
2278  
2279  
2280  prepareNextOutline : function() {
2281      var key = this.key;
2282      var outlineType = this.outlineType;
2283      new hs.Outline(outlineType, 
2284          function () { try { hs.expanders[key].preloadNext(); } catch (e) {} });
2285  },
2286  
2287  
2288  preloadNext : function() {
2289      var next = this.getAdjacentAnchor(1);
2290      if (next && next.onclick.toString().match(/hs\.expand/)) 
2291          var img = hs.createElement('img', { src: hs.getSrc(next) });
2292  },
2293  
2294  
2295  getAdjacentAnchor : function(op) {
2296      var current = this.getAnchorIndex(), as = hs.anchors.groups[this.slideshowGroup || 'none'];
2297      if (as && !as[current + op] && this.slideshow && this.slideshow.repeat) {
2298          if (op == 1) return as[0];
2299          else if (op == -1) return as[as.length-1];
2300      }
2301      return (as && as[current + op]) || null;
2302  },
2303  
2304  getAnchorIndex : function() {
2305      var arr = hs.getAnchors().groups[this.slideshowGroup || 'none'];
2306      if (arr) for (var i = 0; i < arr.length; i++) {
2307          if (arr[i] == this.a) return i; 
2308      }
2309      return null;
2310  },
2311  
2312  
2313  getNumber : function() {
2314      if (this[this.numberPosition]) {
2315          var arr = hs.anchors.groups[this.slideshowGroup || 'none'];
2316          if (arr) {
2317              var s = hs.lang.number.replace('%1', this.getAnchorIndex() + 1).replace('%2', arr.length);
2318              this[this.numberPosition].innerHTML = 
2319                  '<div class="highslide-number">'+ s +'</div>'+ this[this.numberPosition].innerHTML;
2320          }
2321      }
2322  },
2323  initSlideshow : function() {
2324      if (!this.last) {
2325          for (var i = 0; i < hs.slideshows.length; i++) {
2326              var ss = hs.slideshows[i], sg = ss.slideshowGroup;
2327              if (typeof sg == 'undefined' || sg === null || sg === this.slideshowGroup) 
2328                  this.slideshow = new hs.Slideshow(this.key, ss);
2329          } 
2330      } else {
2331          this.slideshow = this.last.slideshow;
2332      }
2333      var ss = this.slideshow;
2334      if (!ss) return;
2335      var key = ss.expKey = this.key;
2336      
2337      ss.checkFirstAndLast();
2338      ss.disable('full-expand');
2339      if (ss.controls) {
2340          this.createOverlay(hs.extend(ss.overlayOptions || {}, {
2341              overlayId: ss.controls,
2342              hsId: 'controls',
2343              zIndex: 5
2344          }));
2345      }
2346      if (ss.thumbstrip) ss.thumbstrip.add(this);
2347      if (!this.last && this.autoplay) ss.play(true);
2348      if (ss.autoplay) {
2349          ss.autoplay = setTimeout(function() {
2350              hs.next(key);
2351          }, (ss.interval || 500));
2352      }
2353  },
2354  
2355  cancelLoading : function() {
2356      hs.discardElement (this.wrapper);
2357      hs.expanders[this.key] = null;
2358      if (hs.upcoming == this.a) hs.upcoming = null;
2359      hs.undim(this.key);
2360      if (this.loading) hs.loading.style.left = '-9999px';
2361      hs.fireEvent(this, 'onHideLoading');
2362  },
2363  
2364  writeCredits : function () {
2365      if (this.credits) return;
2366      this.credits = hs.createElement('a', {
2367          href: hs.creditsHref,
2368          target: hs.creditsTarget,
2369          className: 'highslide-credits',
2370          innerHTML: hs.lang.creditsText,
2371          title: hs.lang.creditsTitle
2372      });
2373      this.createOverlay({ 
2374          overlayId: this.credits, 
2375          position: this.creditsPosition || 'top left', 
2376          hsId: 'credits' 
2377      });
2378  },
2379  
2380  getInline : function(types, addOverlay) {
2381      for (var i = 0; i < types.length; i++) {
2382          var type = types[i], s = null;
2383          if (type == 'caption' && !hs.fireEvent(this, 'onBeforeGetCaption')) return;
2384          else if (type == 'heading' && !hs.fireEvent(this, 'onBeforeGetHeading')) return;
2385          if (!this[type +'Id'] && this.thumbsUserSetId)  
2386              this[type +'Id'] = type +'-for-'+ this.thumbsUserSetId;
2387          if (this[type +'Id']) this[type] = hs.getNode(this[type +'Id']);
2388          if (!this[type] && !this[type +'Text'] && this[type +'Eval']) try {
2389              s = eval(this[type +'Eval']);
2390          } catch (e) {}
2391          if (!this[type] && this[type +'Text']) {
2392              s = this[type +'Text'];
2393          }
2394          if (!this[type] && !s) {
2395              this[type] = hs.getNode(this.a['_'+ type + 'Id']);
2396              if (!this[type]) {
2397                  var next = this.a.nextSibling;
2398                  while (next && !hs.isHsAnchor(next)) {
2399                      if ((new RegExp('highslide-'+ type)).test(next.className || null)) {
2400                          if (!next.id) this.a['_'+ type + 'Id'] = next.id = 'hsId'+ hs.idCounter++;
2401                          this[type] = hs.getNode(next.id);
2402                          break;
2403                      }
2404                      next = next.nextSibling;
2405                  }
2406              }
2407          }
2408          if (!this[type] && !s && this.numberPosition == type) s = '\n';
2409          
2410          if (!this[type] && s) this[type] = hs.createElement('div', 
2411                  { className: 'highslide-'+ type, innerHTML: s } );
2412          
2413          if (addOverlay && this[type]) {
2414              var o = { position: (type == 'heading') ? 'above' : 'below' };
2415              for (var x in this[type+'Overlay']) o[x] = this[type+'Overlay'][x];
2416              o.overlayId = this[type];
2417              this.createOverlay(o);
2418          }
2419      }
2420  },
2421  
2422  
2423  // on end move and resize

2424  doShowHide : function(visibility) {
2425      if (hs.hideSelects) this.showHideElements('SELECT', visibility);
2426      if (hs.hideIframes) this.showHideElements('IFRAME', visibility);
2427      if (hs.geckoMac) this.showHideElements('*', visibility);
2428  },
2429  showHideElements : function (tagName, visibility) {
2430      var els = document.getElementsByTagName(tagName);
2431      var prop = tagName == '*' ? 'overflow' : 'visibility';
2432      for (var i = 0; i < els.length; i++) {
2433          if (prop == 'visibility' || (document.defaultView.getComputedStyle(
2434                  els[i], "").getPropertyValue('overflow') == 'auto'
2435                  || els[i].getAttribute('hidden-by') != null)) {
2436              var hiddenBy = els[i].getAttribute('hidden-by');
2437              if (visibility == 'visible' && hiddenBy) {
2438                  hiddenBy = hiddenBy.replace('['+ this.key +']', '');
2439                  els[i].setAttribute('hidden-by', hiddenBy);
2440                  if (!hiddenBy) els[i].style[prop] = els[i].origProp;
2441              } else if (visibility == 'hidden') { // hide if behind
2442                  var elPos = hs.getPosition(els[i]);
2443                  elPos.w = els[i].offsetWidth;
2444                  elPos.h = els[i].offsetHeight;
2445                  if (!this.dimmingOpacity) { // hide all if dimming
2446                  
2447                      var clearsX = (elPos.x + elPos.w < this.x.get('opos') 
2448                          || elPos.x > this.x.get('opos') + this.x.get('osize'));
2449                      var clearsY = (elPos.y + elPos.h < this.y.get('opos') 
2450                          || elPos.y > this.y.get('opos') + this.y.get('osize'));
2451                  }
2452                  var wrapperKey = hs.getWrapperKey(els[i]);
2453                  if (!clearsX && !clearsY && wrapperKey != this.key) { // element falls behind image
2454                      if (!hiddenBy) {
2455                          els[i].setAttribute('hidden-by', '['+ this.key +']');
2456                          els[i].origProp = els[i].style[prop];
2457                          els[i].style[prop] = 'hidden';
2458                          
2459                      } else if (hiddenBy.indexOf('['+ this.key +']') == -1) {
2460                          els[i].setAttribute('hidden-by', hiddenBy + '['+ this.key +']');
2461                      }
2462                  } else if ((hiddenBy == '['+ this.key +']' || hs.focusKey == wrapperKey)
2463                          && wrapperKey != this.key) { // on move
2464                      els[i].setAttribute('hidden-by', '');
2465                      els[i].style[prop] = els[i].origProp || '';
2466                  } else if (hiddenBy && hiddenBy.indexOf('['+ this.key +']') > -1) {
2467                      els[i].setAttribute('hidden-by', hiddenBy.replace('['+ this.key +']', ''));
2468                  }
2469                          
2470              }
2471          }
2472      }
2473  },
2474  
2475  focus : function() {
2476      this.wrapper.style.zIndex = hs.zIndexCounter += 2;
2477      // blur others

2478      for (var i = 0; i < hs.expanders.length; i++) {
2479          if (hs.expanders[i] && i == hs.focusKey) {
2480              var blurExp = hs.expanders[i];
2481              blurExp.content.className += ' highslide-'+ blurExp.contentType +'-blur';
2482              if (blurExp.isImage) {
2483                  blurExp.content.style.cursor = hs.ieLt7 ? 'hand' : 'pointer';
2484                  blurExp.content.title = hs.lang.focusTitle;    
2485              }    
2486              hs.fireEvent(blurExp, 'onBlur');
2487          }
2488      }
2489      
2490      // focus this

2491      if (this.outline) this.outline.table.style.zIndex 
2492          = this.wrapper.style.zIndex - 1;
2493      this.content.className = 'highslide-'+ this.contentType;
2494      if (this.isImage) {
2495          this.content.title = hs.lang.restoreTitle;
2496          
2497          if (hs.restoreCursor) {
2498              hs.styleRestoreCursor = window.opera ? 'pointer' : 'url('+ hs.graphicsDir + hs.restoreCursor +'), pointer';
2499              if (hs.ieLt7 && hs.uaVersion < 6) hs.styleRestoreCursor = 'hand';
2500              this.content.style.cursor = hs.styleRestoreCursor;
2501          }
2502      }
2503      hs.focusKey = this.key;    
2504      hs.addEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);    
2505      hs.fireEvent(this, 'onFocus');    
2506  },
2507  moveTo: function(x, y) {
2508      this.x.setPos(x);
2509      this.y.setPos(y);
2510  },
2511  resize : function (e) {
2512      var w, h, r = e.width / e.height;
2513      w = Math.max(e.width + e.dX, Math.min(this.minWidth, this.x.full));
2514      if (this.isImage && Math.abs(w - this.x.full) < 12) w = this.x.full;
2515      h = this.isHtml ? e.height + e.dY : w / r;
2516      if (h < Math.min(this.minHeight, this.y.full)) {
2517          h = Math.min(this.minHeight, this.y.full);
2518          if (this.isImage) w = h * r;
2519      }
2520      this.resizeTo(w, h);
2521  },
2522  resizeTo: function(w, h) {
2523      this.y.setSize(h);
2524      this.x.setSize(w);
2525      this.wrapper.style.height = this.y.get('wsize') +'px';
2526  },
2527  
2528  close : function() {
2529      if (this.isClosing || !this.isExpanded) return;
2530      if (this.transitions[1] == 'crossfade' && hs.upcoming) {
2531          hs.getExpander(hs.upcoming).cancelLoading();
2532          hs.upcoming = null;
2533      }
2534      if (!hs.fireEvent(this, 'onBeforeClose')) return;
2535      this.isClosing = true;
2536      if (this.slideshow && !hs.upcoming) this.slideshow.pause();
2537      
2538      hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
2539      
2540      try {
2541          if (this.isHtml) this.htmlPrepareClose();
2542          this.content.style.cursor = 'default';
2543          this.changeSize(
2544              0, {
2545                  wrapper: {
2546                      width : this.x.t,
2547                      height : this.y.t,
2548                      left: this.x.tpos - this.x.cb + this.x.tb,
2549                      top: this.y.tpos - this.y.cb + this.y.tb
2550                  },
2551                  content: {
2552                      left: 0,
2553                      top: 0,
2554                      width: this.x.t,
2555                      height: this.y.t
2556                  }
2557              }, hs.restoreDuration
2558          );
2559      } catch (e) { this.afterClose(); }
2560  },
2561  
2562  htmlPrepareClose : function() {
2563      if (hs.geckoMac) { // bad redraws
2564          if (!hs.mask) hs.mask = hs.createElement('div', null, 
2565              { position: 'absolute' }, hs.container);
2566          hs.setStyles(hs.mask, { width: this.x.size +'px', height: this.y.size +'px', 
2567              left: this.x.pos +'px', top: this.y.pos +'px', display: 'block' });            
2568      }
2569      if (this.objectType == 'swf') try { hs.$(this.body.id).StopPlay(); } catch (e) {}
2570      
2571      if (this.objectLoadTime == 'after' && !this.preserveContent) this.destroyObject();        
2572      if (this.scrollerDiv && this.scrollerDiv != this.scrollingContent) 
2573          this.scrollerDiv.style.overflow = 'hidden';
2574  },
2575  
2576  destroyObject : function () {
2577      if (hs.ie && this.iframe)
2578          try { this.iframe.contentWindow.document.body.innerHTML = ''; } catch (e) {}
2579      if (this.objectType == 'swf') swfobject.removeSWF(this.body.id);
2580      this.body.innerHTML = '';
2581  },
2582  
2583  sleep : function() {
2584      if (this.outline) this.outline.table.style.display = 'none';
2585      this.releaseMask = null;
2586      this.wrapper.style.display = 'none';
2587      this.isExpanded = false;
2588      hs.push(hs.sleeping, this);
2589  },
2590  
2591  awake : function() {try {
2592      
2593      hs.expanders[this.key] = this;
2594      
2595      if (!hs.allowMultipleInstances &&hs.focusKey != this.key) {    
2596          try { hs.expanders[hs.focusKey].close(); } catch (e){}
2597      }
2598      
2599      var z = hs.zIndexCounter++, stl = { display: '', zIndex: z };
2600      hs.setStyles (this.wrapper, stl);
2601      this.isClosing = false;
2602      
2603      var o = this.outline || 0;
2604      if (o) {
2605          if (!this.outlineWhileAnimating) stl.visibility = 'hidden';
2606          hs.setStyles (o.table, stl);        
2607      }
2608      if (this.slideshow) {
2609          this.initSlideshow();
2610      }
2611          
2612      this.show();
2613  } catch (e) {}
2614  
2615  
2616  },
2617  
2618  createOverlay : function (o) {
2619      var el = o.overlayId, 
2620          relToVP = (o.relativeTo == 'viewport' && !/panel$/.test(o.position));
2621      if (typeof el == 'string') el = hs.getNode(el);
2622      if (o.html) el = hs.createElement('div', { innerHTML: o.html });
2623      if (!el || typeof el == 'string') return;
2624      if (!hs.fireEvent(this, 'onCreateOverlay', { overlay: el })) return;
2625      el.style.display = 'block';
2626      o.hsId = o.hsId || o.overlayId; 
2627      if (this.transitions[1] == 'crossfade' && this.reuseOverlay(o, el)) return;
2628      this.genOverlayBox();
2629      var width = o.width && /^[0-9]+(px|%)$/.test(o.width) ? o.width : 'auto';
2630      if (/^(left|right)panel$/.test(o.position) && !/^[0-9]+px$/.test(o.width)) width = '200px';
2631      var overlay = hs.createElement(
2632          'div', {
2633              id: 'hsId'+ hs.idCounter++,
2634              hsId: o.hsId
2635          }, {
2636              position: 'absolute',
2637              visibility: 'hidden',
2638              width: width,
2639              direction: hs.lang.cssDirection || '',
2640              opacity: 0
2641          },
2642          relToVP ? hs.viewport :this.overlayBox,
2643          true
2644      );
2645      if (relToVP) overlay.hsKey = this.key;
2646      
2647      overlay.appendChild(el);
2648      hs.extend(overlay, {
2649          opacity: 1,
2650          offsetX: 0,
2651          offsetY: 0,
2652          dur: (o.fade === 0 || o.fade === false || (o.fade == 2 && hs.ie)) ? 0 : 250
2653      });
2654      hs.extend(overlay, o);
2655      
2656          
2657      if (this.gotOverlays) {
2658          this.positionOverlay(overlay);
2659          if (!overlay.hideOnMouseOut || this.mouseIsOver) 
2660              hs.animate(overlay, { opacity: overlay.opacity }, overlay.dur);
2661      }
2662      hs.push(this.overlays, hs.idCounter - 1);
2663  },
2664  positionOverlay : function(overlay) {
2665      var p = overlay.position || 'middle center',
2666          relToVP = (overlay.relativeTo == 'viewport'),
2667          offX = overlay.offsetX,
2668          offY = overlay.offsetY;
2669      if (relToVP) {
2670          hs.viewport.style.display = 'block';
2671          overlay.hsKey = this.key;
2672          if (overlay.offsetWidth > overlay.parentNode.offsetWidth)
2673              overlay.style.width = '100%';
2674      } else
2675      if (overlay.parentNode != this.overlayBox) this.overlayBox.appendChild(overlay);
2676      if (/left$/.test(p)) overlay.style.left = offX +'px'; 
2677      
2678      if (/center$/.test(p))    hs.setStyles (overlay, { 
2679          left: '50%',
2680          marginLeft: (offX - Math.round(overlay.offsetWidth / 2)) +'px'
2681      });    
2682      
2683      if (/right$/.test(p)) overlay.style.right = - offX +'px';
2684          
2685      if (/^leftpanel$/.test(p)) { 
2686          hs.setStyles(overlay, {
2687              right: '100%',
2688              marginRight: this.x.cb +'px',
2689              top: - this.y.cb +'px',
2690              bottom: - this.y.cb +'px',
2691              overflow: 'auto'
2692          });         
2693          this.x.p1 = overlay.offsetWidth;
2694      
2695      } else if (/^rightpanel$/.test(p)) {
2696          hs.setStyles(overlay, {
2697              left: '100%',
2698              marginLeft: this.x.cb +'px',
2699              top: - this.y.cb +'px',
2700              bottom: - this.y.cb +'px',
2701              overflow: 'auto'
2702          });
2703          this.x.p2 = overlay.offsetWidth;
2704      }
2705      var parOff = overlay.parentNode.offsetHeight;
2706      overlay.style.height = 'auto';
2707      if (relToVP && overlay.offsetHeight > parOff)
2708          overlay.style.height = hs.ieLt7 ? parOff +'px' : '100%';
2709  
2710      if (/^top/.test(p)) overlay.style.top = offY +'px'; 
2711      if (/^middle/.test(p))    hs.setStyles (overlay, { 
2712          top: '50%', 
2713          marginTop: (offY - Math.round(overlay.offsetHeight / 2)) +'px'
2714      });    
2715      if (/^bottom/.test(p)) overlay.style.bottom = - offY +'px';
2716      if (/^above$/.test(p)) {
2717          hs.setStyles(overlay, {
2718              left: (- this.x.p1 - this.x.cb) +'px',
2719              right: (- this.x.p2 - this.x.cb) +'px',
2720              bottom: '100%',
2721              marginBottom: this.y.cb +'px',
2722              width: 'auto'
2723          });
2724          this.y.p1 = overlay.offsetHeight;
2725      
2726      } else if (/^below$/.test(p)) {
2727          hs.setStyles(overlay, {
2728              position: 'relative',
2729              left: (- this.x.p1 - this.x.cb) +'px',
2730              right: (- this.x.p2 - this.x.cb) +'px',
2731              top: '100%',
2732              marginTop: this.y.cb +'px',
2733              width: 'auto'
2734          });
2735          this.y.p2 = overlay.offsetHeight;
2736          overlay.style.position = 'absolute';
2737      }
2738  },
2739  
2740  getOverlays : function() {    
2741      this.getInline(['heading', 'caption'], true);
2742      this.getNumber();
2743      if (this.caption) hs.fireEvent(this, 'onAfterGetCaption');
2744      if (this.heading) hs.fireEvent(this, 'onAfterGetHeading');
2745      if (this.heading && this.dragByHeading) this.heading.className += ' highslide-move';
2746      if (hs.showCredits) this.writeCredits();
2747      for (var i = 0; i < hs.overlays.length; i++) {
2748          var o = hs.overlays[i], tId = o.thumbnailId, sg = o.slideshowGroup;
2749          if ((!tId && !sg) || (tId && tId == this.thumbsUserSetId)
2750                  || (sg && sg === this.slideshowGroup)) {
2751              if (this.isImage || (this.isHtml && o.useOnHtml))
2752              this.createOverlay(o);
2753          }
2754      }
2755      var os = [];
2756      for (var i = 0; i < this.overlays.length; i++) {
2757          var o = hs.$('hsId'+ this.overlays[i]);
2758          if (/panel$/.test(o.position)) this.positionOverlay(o);
2759          else hs.push(os, o);
2760      }
2761      for (var i = 0; i < os.length; i++) this.positionOverlay(os[i]);
2762      this.gotOverlays = true;
2763  },
2764  genOverlayBox : function() {
2765      if (!this.overlayBox) this.overlayBox = hs.createElement (
2766          'div', {
2767              className: this.wrapperClassName
2768          }, {
2769              position : 'absolute',
2770              width: (this.x.size || (this.useBox ? this.width : null) 
2771                  || this.x.full) +'px',
2772              height: (this.y.size || this.y.full) +'px',
2773              visibility : 'hidden',
2774              overflow : 'hidden',
2775              zIndex : hs.ie ? 4 : 'auto'
2776          },
2777          hs.container,
2778          true
2779      );
2780  },
2781  sizeOverlayBox : function(doWrapper, doPanels) {
2782      var overlayBox = this.overlayBox, 
2783          x = this.x,
2784          y = this.y;
2785      hs.setStyles( overlayBox, {
2786          width: x.size +'px', 
2787          height: y.size +'px'
2788      });
2789      if (doWrapper || doPanels) {
2790          for (var i = 0; i < this.overlays.length; i++) {
2791              var o = hs.$('hsId'+ this.overlays[i]);
2792              var ie6 = (hs.ieLt7 || document.compatMode == 'BackCompat');
2793              if (o && /^(above|below)$/.test(o.position)) {
2794                  if (ie6) {
2795                      o.style.width = (overlayBox.offsetWidth + 2 * x.cb
2796                          + x.p1 + x.p2) +'px';
2797                  }
2798                  y[o.position == 'above' ? 'p1' : 'p2'] = o.offsetHeight;
2799              }
2800              if (o && ie6 && /^(left|right)panel$/.test(o.position)) {
2801                  o.style.height = (overlayBox.offsetHeight + 2* y.cb) +'px';
2802              }
2803          }
2804      }
2805      if (doWrapper) {
2806          hs.setStyles(this.content, {
2807              top: y.p1 +'px'
2808          });
2809          hs.setStyles(overlayBox, {
2810              top: (y.p1 + y.cb) +'px'
2811          });
2812      }
2813  },
2814  
2815  showOverlays : function() {
2816      var b = this.overlayBox;
2817      b.className = '';
2818      hs.setStyles(b, {
2819          top: (this.y.p1 + this.y.cb) +'px',
2820          left: (this.x.p1 + this.x.cb) +'px',
2821          overflow : 'visible'
2822      });
2823      if (hs.safari) b.style.visibility = 'visible';
2824      this.wrapper.appendChild (b);
2825      for (var i = 0; i < this.overlays.length; i++) {
2826          var o = hs.$('hsId'+ this.overlays[i]);
2827          o.style.zIndex = o.zIndex || 4;
2828          if (!o.hideOnMouseOut || this.mouseIsOver) {
2829              o.style.visibility = 'visible';
2830              hs.setStyles(o, { visibility: 'visible', display: '' });
2831              hs.animate(o, { opacity: o.opacity }, o.dur);
2832          }
2833      }
2834  },
2835  
2836  destroyOverlays : function() {
2837      if (!this.overlays.length) return;
2838      if (this.slideshow) {
2839          var c = this.slideshow.controls;
2840          if (c && hs.getExpander(c) == this) c.parentNode.removeChild(c);
2841      }
2842      for (var i = 0; i < this.overlays.length; i++) {
2843          var o = hs.$('hsId'+ this.overlays[i]);
2844          if (o && o.parentNode == hs.viewport && hs.getExpander(o) == this) hs.discardElement(o);
2845      }
2846      if (this.isHtml && this.preserveContent) {
2847          this.overlayBox.style.top = '-9999px';
2848          hs.container.appendChild(this.overlayBox);
2849      } else
2850      hs.discardElement(this.overlayBox);
2851  },
2852  
2853  
2854  
2855  createFullExpand : function () {
2856      if (this.slideshow && this.slideshow.controls) {
2857          this.slideshow.enable('full-expand');
2858          return;
2859      }
2860      this.fullExpandLabel = hs.createElement(
2861          'a', {
2862              href: 'javascript:hs.expanders['+ this.key +'].doFullExpand();',
2863              title: hs.lang.fullExpandTitle,
2864              className: 'highslide-full-expand'
2865          }
2866      );
2867      if (!hs.fireEvent(this, 'onCreateFullExpand')) return;
2868      
2869      this.createOverlay({ 
2870          overlayId: this.fullExpandLabel, 
2871          position: hs.fullExpandPosition, 
2872          hideOnMouseOut: true, 
2873          opacity: hs.fullExpandOpacity
2874      });
2875  },
2876  
2877  doFullExpand : function () {
2878      try {
2879          if (!hs.fireEvent(this, 'onDoFullExpand')) return;
2880          if (this.fullExpandLabel) hs.discardElement(this.fullExpandLabel);
2881          
2882          this.focus();
2883          var xSize = this.x.size;
2884          this.resizeTo(this.x.full, this.y.full);
2885          
2886          var xpos = this.x.pos - (this.x.size - xSize) / 2;
2887          if (xpos < hs.marginLeft) xpos = hs.marginLeft;
2888          
2889          this.moveTo(xpos, this.y.pos);
2890          this.doShowHide('hidden');
2891      
2892      } catch (e) {
2893          this.error(e);
2894      }
2895  },
2896  
2897  
2898  afterClose : function () {
2899      this.a.className = this.a.className.replace('highslide-active-anchor', '');
2900      
2901      this.doShowHide('visible');    
2902      
2903      if (this.isHtml && this.preserveContent
2904               && this.transitions[1] != 'crossfade') {
2905          this.sleep();
2906      } else {
2907          if (this.outline && this.outlineWhileAnimating) this.outline.destroy();
2908      
2909          hs.discardElement(this.wrapper);
2910      }
2911      if (hs.mask) hs.mask.style.display = 'none';
2912      this.destroyOverlays();
2913      if (!hs.viewport.childNodes.length) hs.viewport.style.display = 'none';
2914      
2915      if (this.dimmingOpacity) hs.undim(this.key);
2916      hs.fireEvent(this, 'onAfterClose');
2917      hs.expanders[this.key] = null;        
2918      hs.reOrder();
2919  }
2920  
2921  };
2922  
2923  
2924  // hs.Ajax object prototype

2925  hs.Ajax = function (a, content, pre) {
2926      this.a = a;
2927      this.content = content;
2928      this.pre = pre;
2929  };
2930  
2931  hs.Ajax.prototype = {
2932  run : function () {
2933      var xhr;
2934      if (!this.src) this.src = hs.getSrc(this.a);
2935      if (this.src.match('#')) {
2936          var arr = this.src.split('#');
2937          this.src = arr[0];
2938          this.id = arr[1];
2939      }
2940      if (hs.cachedGets[this.src]) {
2941          this.cachedGet = hs.cachedGets[this.src];
2942          if (this.id) this.getElementContent();
2943          else this.loadHTML();
2944          return;
2945      }
2946      try { xhr = new XMLHttpRequest(); }
2947      catch (e) {
2948          try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); }
2949          catch (e) {
2950              try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
2951              catch (e) { this.onError(); }
2952          }
2953      }
2954      var pThis = this; 
2955      xhr.onreadystatechange = function() {
2956          if(pThis.xhr.readyState == 4) {
2957              if (pThis.id) pThis.getElementContent();
2958              else pThis.loadHTML();
2959          }
2960      };
2961      var src = this.src;
2962      this.xhr = xhr;
2963      if (hs.forceAjaxReload) 
2964          src = src.replace(/$/, (/\?/.test(src) ? '&' : '?') +'dummy='+ (new Date()).getTime());
2965      xhr.open('GET', src, true);
2966      xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
2967      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
2968      xhr.send(null);
2969  },
2970  
2971  getElementContent : function() {
2972      hs.init();
2973      var attribs = window.opera || hs.ie6SSL ? { src: 'about:blank' } : null;
2974      
2975      this.iframe = hs.createElement('iframe', attribs, 
2976          { position: 'absolute', top: '-9999px' }, hs.container);
2977          
2978      this.loadHTML();
2979  },
2980  
2981  loadHTML : function() {
2982      var s = this.cachedGet || this.xhr.responseText,
2983          regBody;
2984      if (this.pre) hs.cachedGets[this.src] = s;
2985      if (!hs.ie || hs.uaVersion >= 5.5) {
2986          s = s.replace(new RegExp('<link[^>]*>', 'gi'), '')
2987              .replace(new RegExp('<script[^>]*>.*?</script>', 'gi'), '');
2988          if (this.iframe) {
2989              var doc = this.iframe.contentDocument;
2990              if (!doc && this.iframe.contentWindow) doc = this.iframe.contentWindow.document;
2991              if (!doc) { // Opera
2992                  var pThis = this;
2993                  setTimeout(function() {    pThis.loadHTML(); }, 25);
2994                  return;
2995              }
2996              doc.open();
2997              doc.write(s);
2998              doc.close();
2999              try { s = doc.getElementById(this.id).innerHTML; } catch (e) {
3000                  try { s = this.iframe.document.getElementById(this.id).innerHTML; } catch (e) {} // opera

3001              }
3002              hs.discardElement(this.iframe);
3003          } else {
3004              regBody = /(<body[^>]*>|<\/body>)/ig;
3005              if (regBody.test(s)) s = s.split(regBody)[hs.ieLt9 ? 1 : 2];
3006              
3007          }
3008      }
3009      hs.getElementByClass(this.content, 'DIV', 'highslide-body').innerHTML = s;
3010      this.onLoad();
3011      for (var x in this) this[x] = null;
3012  }
3013  };
3014  
3015  
3016  hs.Slideshow = function (expKey, options) {
3017      if (hs.dynamicallyUpdateAnchors !== false) hs.updateAnchors();
3018      this.expKey = expKey;
3019      for (var x in options) this[x] = options[x];
3020      if (this.useControls) this.getControls();
3021      if (this.thumbstrip) this.thumbstrip = hs.Thumbstrip(this);
3022  };
3023  hs.Slideshow.prototype = {
3024  getControls: function() {
3025      this.controls = hs.createElement('div', { innerHTML: hs.replaceLang(hs.skin.controls) }, 
3026          null, hs.container);
3027      
3028      var buttons = ['play', 'pause', 'previous', 'next', 'move', 'full-expand', 'close'];
3029      this.btn = {};
3030      var pThis = this;
3031      for (var i = 0; i < buttons.length; i++) {
3032          this.btn[buttons[i]] = hs.getElementByClass(this.controls, 'li', 'highslide-'+ buttons[i]);
3033          this.enable(buttons[i]);
3034      }
3035      this.btn.pause.style.display = 'none';
3036      //this.disable('full-expand');

3037  },
3038  checkFirstAndLast: function() {
3039      if (this.repeat || !this.controls) return;
3040      var exp = hs.expanders[this.expKey],
3041          cur = exp.getAnchorIndex(), 
3042          re = /disabled$/;
3043      if (cur == 0) 
3044          this.disable('previous');
3045      else if (re.test(this.btn.previous.getElementsByTagName('a')[0].className))
3046          this.enable('previous');
3047      if (cur + 1 == hs.anchors.groups[exp.slideshowGroup || 'none'].length) {
3048          this.disable('next');
3049          this.disable('play');
3050      } else if (re.test(this.btn.next.getElementsByTagName('a')[0].className)) {
3051          this.enable('next');
3052          this.enable('play');
3053      }
3054  },
3055  enable: function(btn) {
3056      if (!this.btn) return;
3057      var sls = this, a = this.btn[btn].getElementsByTagName('a')[0], re = /disabled$/;
3058      a.onclick = function() {
3059          sls[btn]();
3060          return false;
3061      };
3062      if (re.test(a.className)) a.className = a.className.replace(re, '');
3063  },
3064  disable: function(btn) {
3065      if (!this.btn) return;
3066      var a = this.btn[btn].getElementsByTagName('a')[0];
3067      a.onclick = function() { return false; };
3068      if (!/disabled$/.test(a.className)) a.className += ' disabled';
3069  },
3070  hitSpace: function() {
3071      if (this.autoplay) this.pause();
3072      else this.play();
3073  },
3074  play: function(wait) {
3075      if (this.btn) {
3076          this.btn.play.style.display = 'none';
3077          this.btn.pause.style.display = '';
3078      }
3079      
3080      this.autoplay = true;    
3081      if (!wait) hs.next(this.expKey);
3082  },
3083  pause: function() {
3084      if (this.btn) {
3085          this.btn.pause.style.display = 'none';
3086          this.btn.play.style.display = '';
3087      }
3088      
3089      clearTimeout(this.autoplay);
3090      this.autoplay = null;
3091  },
3092  previous: function() {
3093      this.pause();
3094      hs.previous(this.btn.previous);
3095  },
3096  next: function() {
3097      this.pause();
3098      hs.next(this.btn.next);
3099  },
3100  move: function() {},
3101  'full-expand': function() {
3102      hs.getExpander().doFullExpand();
3103  },
3104  close: function() {
3105      hs.close(this.btn.close);
3106  }
3107  };
3108  hs.Thumbstrip = function(slideshow) {
3109  	function add (exp) {
3110          hs.extend(options || {}, {
3111              overlayId: dom,
3112              hsId: 'thumbstrip',
3113              className: 'highslide-thumbstrip-'+ mode +'-overlay ' + (options.className || '')
3114          });
3115          if (hs.ieLt7) options.fade = 0;
3116          exp.createOverlay(options);
3117          hs.setStyles(dom.parentNode, { overflow: 'hidden' });
3118      };
3119      
3120  	function scroll (delta) {    
3121          selectThumb(undefined, Math.round(delta * dom[isX ? 'offsetWidth' : 'offsetHeight'] * 0.7));
3122      };
3123      
3124  	function selectThumb (i, scrollBy) {
3125          if (i === undefined) for (var j = 0; j < group.length; j++) {
3126              if (group[j] == hs.expanders[slideshow.expKey].a) {
3127                  i = j;
3128                  break;
3129              }
3130          }
3131          if (i === undefined) return;
3132          var as = dom.getElementsByTagName('a'),
3133              active = as[i],
3134              cell = active.parentNode,
3135              left = isX ? 'Left' : 'Top',
3136              right = isX ? 'Right' : 'Bottom',
3137              width = isX ? 'Width' : 'Height',
3138              offsetLeft = 'offset' + left,
3139              offsetWidth = 'offset' + width,
3140              overlayWidth = div.parentNode.parentNode[offsetWidth],
3141              minTblPos = overlayWidth - table[offsetWidth],
3142              curTblPos = parseInt(table.style[isX ? 'left' : 'top']) || 0,
3143              tblPos = curTblPos,
3144              mgnRight = 20;
3145          if (scrollBy !== undefined) {
3146              tblPos = curTblPos - scrollBy;
3147              
3148              if (minTblPos > 0) minTblPos = 0;
3149              if (tblPos > 0) tblPos = 0;
3150              if (tblPos < minTblPos) tblPos = minTblPos;
3151              
3152      
3153          } else {
3154              for (var j = 0; j < as.length; j++) as[j].className = '';
3155              active.className = 'highslide-active-anchor';
3156              var activeLeft = i > 0 ? as[i - 1].parentNode[offsetLeft] : cell[offsetLeft],
3157                  activeRight = cell[offsetLeft] + cell[offsetWidth] + 
3158                      (as[i + 1] ? as[i + 1].parentNode[offsetWidth] : 0);
3159              if (activeRight > overlayWidth - curTblPos) tblPos = overlayWidth - activeRight;
3160              else if (activeLeft < -curTblPos) tblPos = -activeLeft;
3161          }
3162          var markerPos = cell[offsetLeft] + (cell[offsetWidth] - marker[offsetWidth]) / 2 + tblPos;
3163          hs.animate(table, isX ? { left: tblPos } : { top: tblPos }, null, 'easeOutQuad');
3164          hs.animate(marker, isX ? { left: markerPos } : { top: markerPos }, null, 'easeOutQuad');
3165          scrollUp.style.display = tblPos < 0 ? 'block' : 'none';
3166          scrollDown.style.display = (tblPos > minTblPos)  ? 'block' : 'none';
3167          
3168      };
3169      
3170  
3171      // initialize

3172      var group = hs.anchors.groups[hs.expanders[slideshow.expKey].slideshowGroup || 'none'],
3173          options = slideshow.thumbstrip,
3174          mode = options.mode || 'horizontal',
3175          floatMode = (mode == 'float'),
3176          tree = floatMode ? ['div', 'ul', 'li', 'span'] : ['table', 'tbody', 'tr', 'td'],
3177          isX = (mode == 'horizontal'),
3178          dom = hs.createElement('div', {
3179                  className: 'highslide-thumbstrip highslide-thumbstrip-'+ mode,
3180                  innerHTML:
3181                      '<div class="highslide-thumbstrip-inner">'+
3182                      '<'+ tree[0] +'><'+ tree[1] +'></'+ tree[1] +'></'+ tree[0] +'></div>'+
3183                      '<div class="highslide-scroll-up"><div></div></div>'+
3184                      '<div class="highslide-scroll-down"><div></div></div>'+
3185                      '<div class="highslide-marker"><div></div></div>'
3186              }, {
3187                  display: 'none'
3188              }, hs.container),
3189          domCh = dom.childNodes,
3190          div = domCh[0],
3191          scrollUp = domCh[1],
3192          scrollDown = domCh[2],
3193          marker = domCh[3],
3194          table = div.firstChild,
3195          tbody = dom.getElementsByTagName(tree[1])[0],
3196          tr;
3197      for (var i = 0; i < group.length; i++) {
3198          if (i == 0 || !isX) tr = hs.createElement(tree[2], null, null, tbody);
3199          (function(){
3200              var a = group[i],
3201                  cell = hs.createElement(tree[3], null, null, tr),
3202                  pI = i;
3203              hs.createElement('a', {
3204                  href: a.href,
3205                  onclick: function() {
3206                      if (/highslide-active-anchor/.test(this.className)) return false;
3207                      hs.getExpander(this).focus();
3208                      return hs.transit(a);
3209                  },
3210                  innerHTML: hs.stripItemFormatter ? hs.stripItemFormatter(a) : a.innerHTML
3211              }, null, cell);
3212          })();
3213      }
3214      if (!floatMode) {
3215          scrollUp.onclick = function () { scroll(-1); };
3216          scrollDown.onclick = function() { scroll(1); };
3217          hs.addEventListener(tbody, document.onmousewheel !== undefined ? 
3218                  'mousewheel' : 'DOMMouseScroll', function(e) {        
3219              var delta = 0;
3220              e = e || window.event;
3221              if (e.wheelDelta) {
3222                  delta = e.wheelDelta/120;
3223                  if (hs.opera) delta = -delta;
3224              } else if (e.detail) {
3225                  delta = -e.detail/3;
3226              }
3227              if (delta) scroll(-delta * 0.2);
3228              if (e.preventDefault) e.preventDefault();
3229              e.returnValue = false;
3230          });
3231      }
3232      
3233      return {
3234          add: add,
3235          selectThumb: selectThumb
3236      }
3237  };
3238  hs.langDefaults = hs.lang;
3239  // history

3240  var HsExpander = hs.Expander;
3241  if (hs.ie && window == window.top) {
3242      (function () {
3243          try {
3244              document.documentElement.doScroll('left');
3245          } catch (e) {
3246              setTimeout(arguments.callee, 50);
3247              return;
3248          }
3249          hs.ready();
3250      })();
3251  }
3252  hs.addEventListener(document, 'DOMContentLoaded', hs.ready);
3253  hs.addEventListener(window, 'load', hs.ready);
3254  
3255  // set handlers
3256  hs.addEventListener(document, 'ready', function() {
3257      if (hs.expandCursor || hs.dimmingOpacity) {
3258          var style = hs.createElement('style', { type: 'text/css' }, null, 
3259              document.getElementsByTagName('HEAD')[0]);
3260              
3261  		function addRule(sel, dec) {        
3262              if (hs.ie && hs.uaVersion < 9) {
3263                  var last = document.styleSheets[document.styleSheets.length - 1];
3264                  if (typeof(last.addRule) == "object") last.addRule(sel, dec);
3265              } else {
3266                  style.appendChild(document.createTextNode(sel + " {" + dec + "}"));
3267              }
3268          }
3269  		function fix(prop) {
3270              return 'expression( ( ( ignoreMe = document.documentElement.'+ prop +
3271                  ' ? document.documentElement.'+ prop +' : document.body.'+ prop +' ) ) + \'px\' );';
3272          }
3273          if (hs.expandCursor) addRule ('.highslide img', 
3274              'cursor: url('+ hs.graphicsDir + hs.expandCursor +'), pointer !important;');
3275          addRule ('.highslide-viewport-size',
3276              hs.ie && (hs.uaVersion < 7 || document.compatMode == 'BackCompat') ?
3277                  'position: absolute; '+
3278                  'left:'+ fix('scrollLeft') +
3279                  'top:'+ fix('scrollTop') +
3280                  'width:'+ fix('clientWidth') +
3281                  'height:'+ fix('clientHeight') :
3282                  'position: fixed; width: 100%; height: 100%; left: 0; top: 0');
3283      }
3284  });
3285  hs.addEventListener(window, 'resize', function() {
3286      hs.getPageSize();
3287      if (hs.viewport) for (var i = 0; i < hs.viewport.childNodes.length; i++) {
3288          var node = hs.viewport.childNodes[i],
3289              exp = hs.getExpander(node);
3290          exp.positionOverlay(node);
3291          if (node.hsId == 'thumbstrip') exp.slideshow.thumbstrip.selectThumb();
3292      }
3293  });
3294  hs.addEventListener(document, 'mousemove', function(e) {
3295      hs.mouse = { x: e.clientX, y: e.clientY    };
3296  });
3297  hs.addEventListener(document, 'mousedown', hs.mouseClickHandler);
3298  hs.addEventListener(document, 'mouseup', hs.mouseClickHandler);
3299  hs.addEventListener(document, 'ready', hs.setClickEvents);
3300  hs.addEventListener(window, 'load', hs.preloadImages);
3301  hs.addEventListener(window, 'load', hs.preloadAjax);
3302  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7