
    /*  Prototype JavaScript framework, version 1.6.1
 *  (c) 2005-2009 Sam Stephenson
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://www.prototypejs.org/
 *
 *  Bugfix: Issue found and corrected in getOffsetParent() by Jake 011019
 *  See ticket for more info: 
 *  https://prototype.lighthouseapp.com/projects/8886/tickets/365-elementgetstyle-problem-with-ie-6-7
 *--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.6.1',

  Browser: (function(){
    var ua = navigator.userAgent;
    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
    return {
      IE:             !!window.attachEvent && !isOpera,
      Opera:          isOpera,
      WebKit:         ua.indexOf('AppleWebKit/') > -1,
      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
      MobileSafari:   /Apple.*Mobile.*Safari/.test(ua)
    }
  })(),

  BrowserFeatures: {
    XPath: !!document.evaluate,
    SelectorsAPI: !!document.querySelector,
    ElementExtensions: (function() {
      var constructor = window.Element || window.HTMLElement;
      return !!(constructor && constructor.prototype);
    })(),
    SpecificElementExtensions: (function() {
      if (typeof window.HTMLDivElement !== 'undefined')
        return true;

      var div = document.createElement('div');
      var form = document.createElement('form');
      var isSupported = false;

      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
        isSupported = true;
      }

      div = form = null;

      return isSupported;
    })()
  },

  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

  emptyFunction: function() { },
  K: function(x) { return x }
};

if (Prototype.Browser.MobileSafari)
  Prototype.BrowserFeatures.SpecificElementExtensions = false;


var Abstract = { };


var Try = {
  these: function() {
    var returnValue;

    for (var i = 0, length = arguments.length; i < length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) { }
    }

    return returnValue;
  }
};

/* Based on Alex Arnell's inheritance implementation. */

var Class = (function() {
  function subclass() {};
  function create() {
    var parent = null, properties = $A(arguments);
    if (Object.isFunction(properties[0]))
      parent = properties.shift();

    function klass() {
      this.initialize.apply(this, arguments);
    }

    Object.extend(klass, Class.Methods);
    klass.superclass = parent;
    klass.subclasses = [];

    if (parent) {
      subclass.prototype = parent.prototype;
      klass.prototype = new subclass;
      parent.subclasses.push(klass);
    }

    for (var i = 0; i < properties.length; i++)
      klass.addMethods(properties[i]);

    if (!klass.prototype.initialize)
      klass.prototype.initialize = Prototype.emptyFunction;

    klass.prototype.constructor = klass;
    return klass;
  }

  function addMethods(source) {
    var ancestor   = this.superclass && this.superclass.prototype;
    var properties = Object.keys(source);

    if (!Object.keys({ toString: true }).length) {
      if (source.toString != Object.prototype.toString)
        properties.push("toString");
      if (source.valueOf != Object.prototype.valueOf)
        properties.push("valueOf");
    }

    for (var i = 0, length = properties.length; i < length; i++) {
      var property = properties[i], value = source[property];
      if (ancestor && Object.isFunction(value) &&
          value.argumentNames().first() == "$super") {
        var method = value;
        value = (function(m) {
          return function() { return ancestor[m].apply(this, arguments); };
        })(property).wrap(method);

        value.valueOf = method.valueOf.bind(method);
        value.toString = method.toString.bind(method);
      }
      this.prototype[property] = value;
    }

    return this;
  }

  return {
    create: create,
    Methods: {
      addMethods: addMethods
    }
  };
})();
(function() {

  var _toString = Object.prototype.toString;

  function extend(destination, source) {
    for (var property in source)
      destination[property] = source[property];
    return destination;
  }

  function inspect(object) {
    try {
      if (isUndefined(object)) return 'undefined';
      if (object === null) return 'null';
      return object.inspect ? object.inspect() : String(object);
    } catch (e) {
      if (e instanceof RangeError) return '...';
      throw e;
    }
  }

  function toJSON(object) {
    var type = typeof object;
    switch (type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }

    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (isElement(object)) return;

    var results = [];
    for (var property in object) {
      var value = toJSON(object[property]);
      if (!isUndefined(value))
        results.push(property.toJSON() + ': ' + value);
    }

    return '{' + results.join(', ') + '}';
  }

  function toQueryString(object) {
    return $H(object).toQueryString();
  }

  function toHTML(object) {
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
  }

  function keys(object) {
    var results = [];
    for (var property in object)
      results.push(property);
    return results;
  }

  function values(object) {
    var results = [];
    for (var property in object)
      results.push(object[property]);
    return results;
  }

  function clone(object) {
    return extend({ }, object);
  }

  function isElement(object) {
    return !!(object && object.nodeType == 1);
  }

  function isArray(object) {
    return _toString.call(object) == "[object Array]";
  }


  function isHash(object) {
    return object instanceof Hash;
  }

  function isFunction(object) {
    return typeof object === "function";
  }

  function isString(object) {
    return _toString.call(object) == "[object String]";
  }

  function isNumber(object) {
    return _toString.call(object) == "[object Number]";
  }

  function isUndefined(object) {
    return typeof object === "undefined";
  }

  extend(Object, {
    extend:        extend,
    inspect:       inspect,
    toJSON:        toJSON,
    toQueryString: toQueryString,
    toHTML:        toHTML,
    keys:          keys,
    values:        values,
    clone:         clone,
    isElement:     isElement,
    isArray:       isArray,
    isHash:        isHash,
    isFunction:    isFunction,
    isString:      isString,
    isNumber:      isNumber,
    isUndefined:   isUndefined
  });
})();
Object.extend(Function.prototype, (function() {
  var slice = Array.prototype.slice;

  function update(array, args) {
    var arrayLength = array.length, length = args.length;
    while (length--) array[arrayLength + length] = args[length];
    return array;
  }

  function merge(array, args) {
    array = slice.call(array, 0);
    return update(array, args);
  }

  function argumentNames() {
    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
      .replace(/\s+/g, '').split(',');
    return names.length == 1 && !names[0] ? [] : names;
  }

  function bind(context) {
    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
    var __method = this, args = slice.call(arguments, 1);
    return function() {
      var a = merge(args, arguments);
      return __method.apply(context, a);
    }
  }

  function bindAsEventListener(context) {
    var __method = this, args = slice.call(arguments, 1);
    return function(event) {
      var a = update([event || window.event], args);
      return __method.apply(context, a);
    }
  }

  function curry() {
    if (!arguments.length) return this;
    var __method = this, args = slice.call(arguments, 0);
    return function() {
      var a = merge(args, arguments);
      return __method.apply(this, a);
    }
  }

  function delay(timeout) {
    var __method = this, args = slice.call(arguments, 1);
    timeout = timeout * 1000
    return window.setTimeout(function() {
      return __method.apply(__method, args);
    }, timeout);
  }

  function defer() {
    var args = update([0.01], arguments);
    return this.delay.apply(this, args);
  }

  function wrap(wrapper) {
    var __method = this;
    return function() {
      var a = update([__method.bind(this)], arguments);
      return wrapper.apply(this, a);
    }
  }

  function methodize() {
    if (this._methodized) return this._methodized;
    var __method = this;
    return this._methodized = function() {
      var a = update([this], arguments);
      return __method.apply(null, a);
    };
  }

  return {
    argumentNames:       argumentNames,
    bind:                bind,
    bindAsEventListener: bindAsEventListener,
    curry:               curry,
    delay:               delay,
    defer:               defer,
    wrap:                wrap,
    methodize:           methodize
  }
})());


Date.prototype.toJSON = function() {
  return '"' + this.getUTCFullYear() + '-' +
    (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
    this.getUTCDate().toPaddedString(2) + 'T' +
    this.getUTCHours().toPaddedString(2) + ':' +
    this.getUTCMinutes().toPaddedString(2) + ':' +
    this.getUTCSeconds().toPaddedString(2) + 'Z"';
};


RegExp.prototype.match = RegExp.prototype.test;

RegExp.escape = function(str) {
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
var PeriodicalExecuter = Class.create({
  initialize: function(callback, frequency) {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;

    this.registerCallback();
  },

  registerCallback: function() {
    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  execute: function() {
    this.callback(this);
  },

  stop: function() {
    if (!this.timer) return;
    clearInterval(this.timer);
    this.timer = null;
  },

  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.execute();
        this.currentlyExecuting = false;
      } catch(e) {
        this.currentlyExecuting = false;
        throw e;
      }
    }
  }
});
Object.extend(String, {
  interpret: function(value) {
    return value == null ? '' : String(value);
  },
  specialChar: {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '\\': '\\\\'
  }
});

Object.extend(String.prototype, (function() {

  function prepareReplacement(replacement) {
    if (Object.isFunction(replacement)) return replacement;
    var template = new Template(replacement);
    return function(match) { return template.evaluate(match) };
  }

  function gsub(pattern, replacement) {
    var result = '', source = this, match;
    replacement = prepareReplacement(replacement);

    if (Object.isString(pattern))
      pattern = RegExp.escape(pattern);

    if (!(pattern.length || pattern.source)) {
      replacement = replacement('');
      return replacement + source.split('').join(replacement) + replacement;
    }

    while (source.length > 0) {
      if (match = source.match(pattern)) {
        result += source.slice(0, match.index);
        result += String.interpret(replacement(match));
        source  = source.slice(match.index + match[0].length);
      } else {
        result += source, source = '';
      }
    }
    return result;
  }

  function sub(pattern, replacement, count) {
    replacement = prepareReplacement(replacement);
    count = Object.isUndefined(count) ? 1 : count;

    return this.gsub(pattern, function(match) {
      if (--count < 0) return match[0];
      return replacement(match);
    });
  }

  function scan(pattern, iterator) {
    this.gsub(pattern, iterator);
    return String(this);
  }

  function truncate(length, truncation) {
    length = length || 30;
    truncation = Object.isUndefined(truncation) ? '...' : truncation;
    return this.length > length ?
      this.slice(0, length - truncation.length) + truncation : String(this);
  }

  function strip() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
  }

  function stripTags() {
    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
  }

  function stripScripts() {
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
  }

  function extractScripts() {
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
    return (this.match(matchAll) || []).map(function(scriptTag) {
      return (scriptTag.match(matchOne) || ['', ''])[1];
    });
  }

  function evalScripts() {
    return this.extractScripts().map(function(script) { return eval(script) });
  }

  function escapeHTML() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  }

  function unescapeHTML() {
    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
  }


  function toQueryParams(separator) {
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
    if (!match) return { };

    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
      if ((pair = pair.split('='))[0]) {
        var key = decodeURIComponent(pair.shift());
        var value = pair.length > 1 ? pair.join('=') : pair[0];
        if (value != undefined) value = decodeURIComponent(value);

        if (key in hash) {
          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
          hash[key].push(value);
        }
        else hash[key] = value;
      }
      return hash;
    });
  }

  function toArray() {
    return this.split('');
  }

  function succ() {
    return this.slice(0, this.length - 1) +
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  }

  function times(count) {
    return count < 1 ? '' : new Array(count + 1).join(this);
  }

  function camelize() {
    var parts = this.split('-'), len = parts.length;
    if (len == 1) return parts[0];

    var camelized = this.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
  }

  function capitalize() {
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  }

  function underscore() {
    return this.replace(/::/g, '/')
               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
               .replace(/([a-z\d])([A-Z])/g, '$1_$2')
               .replace(/-/g, '_')
               .toLowerCase();
  }

  function dasherize() {
    return this.replace(/_/g, '-');
  }

  function inspect(useDoubleQuotes) {
    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
      if (character in String.specialChar) {
        return String.specialChar[character];
      }
      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
    });
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  }

  function toJSON() {
    return this.inspect(true);
  }

  function unfilterJSON(filter) {
    return this.replace(filter || Prototype.JSONFilter, '$1');
  }

  function isJSON() {
    var str = this;
    if (str.blank()) return false;
    str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
  }

  function evalJSON(sanitize) {
    var json = this.unfilterJSON();
    try {
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
    } catch (e) { }
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
  }

  function include(pattern) {
    return this.indexOf(pattern) > -1;
  }

  function startsWith(pattern) {
    return this.indexOf(pattern) === 0;
  }

  function endsWith(pattern) {
    var d = this.length - pattern.length;
    return d >= 0 && this.lastIndexOf(pattern) === d;
  }

  function empty() {
    return this == '';
  }

  function blank() {
    return /^\s*$/.test(this);
  }

  function interpolate(object, pattern) {
    return new Template(this, pattern).evaluate(object);
  }

  return {
    gsub:           gsub,
    sub:            sub,
    scan:           scan,
    truncate:       truncate,
    strip:          String.prototype.trim ? String.prototype.trim : strip,
    stripTags:      stripTags,
    stripScripts:   stripScripts,
    extractScripts: extractScripts,
    evalScripts:    evalScripts,
    escapeHTML:     escapeHTML,
    unescapeHTML:   unescapeHTML,
    toQueryParams:  toQueryParams,
    parseQuery:     toQueryParams,
    toArray:        toArray,
    succ:           succ,
    times:          times,
    camelize:       camelize,
    capitalize:     capitalize,
    underscore:     underscore,
    dasherize:      dasherize,
    inspect:        inspect,
    toJSON:         toJSON,
    unfilterJSON:   unfilterJSON,
    isJSON:         isJSON,
    evalJSON:       evalJSON,
    include:        include,
    startsWith:     startsWith,
    endsWith:       endsWith,
    empty:          empty,
    blank:          blank,
    interpolate:    interpolate
  };
})());

var Template = Class.create({
  initialize: function(template, pattern) {
    this.template = template.toString();
    this.pattern = pattern || Template.Pattern;
  },

  evaluate: function(object) {
    if (object && Object.isFunction(object.toTemplateReplacements))
      object = object.toTemplateReplacements();

    return this.template.gsub(this.pattern, function(match) {
      if (object == null) return (match[1] + '');

      var before = match[1] || '';
      if (before == '\\') return match[2];

      var ctx = object, expr = match[3];
      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
      match = pattern.exec(expr);
      if (match == null) return before;

      while (match != null) {
        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
        ctx = ctx[comp];
        if (null == ctx || '' == match[3]) break;
        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
        match = pattern.exec(expr);
      }

      return before + String.interpret(ctx);
    });
  }
});
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;

var $break = { };

var Enumerable = (function() {
  function each(iterator, context) {
    var index = 0;
    try {
      this._each(function(value) {
        iterator.call(context, value, index++);
      });
    } catch (e) {
      if (e != $break) throw e;
    }
    return this;
  }

  function eachSlice(number, iterator, context) {
    var index = -number, slices = [], array = this.toArray();
    if (number < 1) return array;
    while ((index += number) < array.length)
      slices.push(array.slice(index, index+number));
    return slices.collect(iterator, context);
  }

  function all(iterator, context) {
    iterator = iterator || Prototype.K;
    var result = true;
    this.each(function(value, index) {
      result = result && !!iterator.call(context, value, index);
      if (!result) throw $break;
    });
    return result;
  }

  function any(iterator, context) {
    iterator = iterator || Prototype.K;
    var result = false;
    this.each(function(value, index) {
      if (result = !!iterator.call(context, value, index))
        throw $break;
    });
    return result;
  }

  function collect(iterator, context) {
    iterator = iterator || Prototype.K;
    var results = [];
    this.each(function(value, index) {
      results.push(iterator.call(context, value, index));
    });
    return results;
  }

  function detect(iterator, context) {
    var result;
    this.each(function(value, index) {
      if (iterator.call(context, value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  }

  function findAll(iterator, context) {
    var results = [];
    this.each(function(value, index) {
      if (iterator.call(context, value, index))
        results.push(value);
    });
    return results;
  }

  function grep(filter, iterator, context) {
    iterator = iterator || Prototype.K;
    var results = [];

    if (Object.isString(filter))
      filter = new RegExp(RegExp.escape(filter));

    this.each(function(value, index) {
      if (filter.match(value))
        results.push(iterator.call(context, value, index));
    });
    return results;
  }

  function include(object) {
    if (Object.isFunction(this.indexOf))
      if (this.indexOf(object) != -1) return true;

    var found = false;
    this.each(function(value) {
      if (value == object) {
        found = true;
        throw $break;
      }
    });
    return found;
  }

  function inGroupsOf(number, fillWith) {
    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
    return this.eachSlice(number, function(slice) {
      while(slice.length < number) slice.push(fillWith);
      return slice;
    });
  }

  function inject(memo, iterator, context) {
    this.each(function(value, index) {
      memo = iterator.call(context, memo, value, index);
    });
    return memo;
  }

  function invoke(method) {
    var args = $A(arguments).slice(1);
    return this.map(function(value) {
      return value[method].apply(value, args);
    });
  }

  function max(iterator, context) {
    iterator = iterator || Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator.call(context, value, index);
      if (result == null || value >= result)
        result = value;
    });
    return result;
  }

  function min(iterator, context) {
    iterator = iterator || Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator.call(context, value, index);
      if (result == null || value < result)
        result = value;
    });
    return result;
  }

  function partition(iterator, context) {
    iterator = iterator || Prototype.K;
    var trues = [], falses = [];
    this.each(function(value, index) {
      (iterator.call(context, value, index) ?
        trues : falses).push(value);
    });
    return [trues, falses];
  }

  function pluck(property) {
    var results = [];
    this.each(function(value) {
      results.push(value[property]);
    });
    return results;
  }

  function reject(iterator, context) {
    var results = [];
    this.each(function(value, index) {
      if (!iterator.call(context, value, index))
        results.push(value);
    });
    return results;
  }

  function sortBy(iterator, context) {
    return this.map(function(value, index) {
      return {
        value: value,
        criteria: iterator.call(context, value, index)
      };
    }).sort(function(left, right) {
      var a = left.criteria, b = right.criteria;
      return a < b ? -1 : a > b ? 1 : 0;
    }).pluck('value');
  }

  function toArray() {
    return this.map();
  }

  function zip() {
    var iterator = Prototype.K, args = $A(arguments);
    if (Object.isFunction(args.last()))
      iterator = args.pop();

    var collections = [this].concat(args).map($A);
    return this.map(function(value, index) {
      return iterator(collections.pluck(index));
    });
  }

  function size() {
    return this.toArray().length;
  }

  function inspect() {
    return '#<Enumerable:' + this.toArray().inspect() + '>';
  }









  return {
    each:       each,
    eachSlice:  eachSlice,
    all:        all,
    every:      all,
    any:        any,
    some:       any,
    collect:    collect,
    map:        collect,
    detect:     detect,
    findAll:    findAll,
    select:     findAll,
    filter:     findAll,
    grep:       grep,
    include:    include,
    member:     include,
    inGroupsOf: inGroupsOf,
    inject:     inject,
    invoke:     invoke,
    max:        max,
    min:        min,
    partition:  partition,
    pluck:      pluck,
    reject:     reject,
    sortBy:     sortBy,
    toArray:    toArray,
    entries:    toArray,
    zip:        zip,
    size:       size,
    inspect:    inspect,
    find:       detect
  };
})();
function $A(iterable) {
  if (!iterable) return [];
  if ('toArray' in Object(iterable)) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

function $w(string) {
  if (!Object.isString(string)) return [];
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

Array.from = $A;


(function() {
  var arrayProto = Array.prototype,
      slice = arrayProto.slice,
      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available

  function each(iterator) {
    for (var i = 0, length = this.length; i < length; i++)
      iterator(this[i]);
  }
  if (!_each) _each = each;

  function clear() {
    this.length = 0;
    return this;
  }

  function first() {
    return this[0];
  }

  function last() {
    return this[this.length - 1];
  }

  function compact() {
    return this.select(function(value) {
      return value != null;
    });
  }

  function flatten() {
    return this.inject([], function(array, value) {
      if (Object.isArray(value))
        return array.concat(value.flatten());
      array.push(value);
      return array;
    });
  }

  function without() {
    var values = slice.call(arguments, 0);
    return this.select(function(value) {
      return !values.include(value);
    });
  }

  function reverse(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  }

  function uniq(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  }

  function intersect(array) {
    return this.uniq().findAll(function(item) {
      return array.detect(function(value) { return item === value });
    });
  }


  function clone() {
    return slice.call(this, 0);
  }

  function size() {
    return this.length;
  }

  function inspect() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  }

  function toJSON() {
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (!Object.isUndefined(value)) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }

  function indexOf(item, i) {
    i || (i = 0);
    var length = this.length;
    if (i < 0) i = length + i;
    for (; i < length; i++)
      if (this[i] === item) return i;
    return -1;
  }

  function lastIndexOf(item, i) {
    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
    var n = this.slice(0, i).reverse().indexOf(item);
    return (n < 0) ? n : i - n - 1;
  }

  function concat() {
    var array = slice.call(this, 0), item;
    for (var i = 0, length = arguments.length; i < length; i++) {
      item = arguments[i];
      if (Object.isArray(item) && !('callee' in item)) {
        for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
          array.push(item[j]);
      } else {
        array.push(item);
      }
    }
    return array;
  }

  Object.extend(arrayProto, Enumerable);

  if (!arrayProto._reverse)
    arrayProto._reverse = arrayProto.reverse;

  Object.extend(arrayProto, {
    _each:     _each,
    clear:     clear,
    first:     first,
    last:      last,
    compact:   compact,
    flatten:   flatten,
    without:   without,
    reverse:   reverse,
    uniq:      uniq,
    intersect: intersect,
    clone:     clone,
    toArray:   clone,
    size:      size,
    inspect:   inspect,
    toJSON:    toJSON
  });

  var CONCAT_ARGUMENTS_BUGGY = (function() {
    return [].concat(arguments)[0][0] !== 1;
  })(1,2)

  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;

  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
})();
function $H(object) {
  return new Hash(object);
};

var Hash = Class.create(Enumerable, (function() {
  function initialize(object) {
    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
  }

  function _each(iterator) {
    for (var key in this._object) {
      var value = this._object[key], pair = [key, value];
      pair.key = key;
      pair.value = value;
      iterator(pair);
    }
  }

  function set(key, value) {
    return this._object[key] = value;
  }

  function get(key) {
    if (this._object[key] !== Object.prototype[key])
      return this._object[key];
  }

  function unset(key) {
    var value = this._object[key];
    delete this._object[key];
    return value;
  }

  function toObject() {
    return Object.clone(this._object);
  }

  function keys() {
    return this.pluck('key');
  }

  function values() {
    return this.pluck('value');
  }

  function index(value) {
    var match = this.detect(function(pair) {
      return pair.value === value;
    });
    return match && match.key;
  }

  function merge(object) {
    return this.clone().update(object);
  }

  function update(object) {
    return new Hash(object).inject(this, function(result, pair) {
      result.set(pair.key, pair.value);
      return result;
    });
  }

  function toQueryPair(key, value) {
    if (Object.isUndefined(value)) return key;
    return key + '=' + encodeURIComponent(String.interpret(value));
  }

  function toQueryString() {
    return this.inject([], function(results, pair) {
      var key = encodeURIComponent(pair.key), values = pair.value;

      if (values && typeof values == 'object') {
        if (Object.isArray(values))
          return results.concat(values.map(toQueryPair.curry(key)));
      } else results.push(toQueryPair(key, values));
      return results;
    }).join('&');
  }

  function inspect() {
    return '#<Hash:{' + this.map(function(pair) {
      return pair.map(Object.inspect).join(': ');
    }).join(', ') + '}>';
  }

  function toJSON() {
    return Object.toJSON(this.toObject());
  }

  function clone() {
    return new Hash(this);
  }

  return {
    initialize:             initialize,
    _each:                  _each,
    set:                    set,
    get:                    get,
    unset:                  unset,
    toObject:               toObject,
    toTemplateReplacements: toObject,
    keys:                   keys,
    values:                 values,
    index:                  index,
    merge:                  merge,
    update:                 update,
    toQueryString:          toQueryString,
    inspect:                inspect,
    toJSON:                 toJSON,
    clone:                  clone
  };
})());

Hash.from = $H;
Object.extend(Number.prototype, (function() {
  function toColorPart() {
    return this.toPaddedString(2, 16);
  }

  function succ() {
    return this + 1;
  }

  function times(iterator, context) {
    $R(0, this, true).each(iterator, context);
    return this;
  }

  function toPaddedString(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
  }

  function toJSON() {
    return isFinite(this) ? this.toString() : 'null';
  }

  function abs() {
    return Math.abs(this);
  }

  function round() {
    return Math.round(this);
  }

  function ceil() {
    return Math.ceil(this);
  }

  function floor() {
    return Math.floor(this);
  }

  return {
    toColorPart:    toColorPart,
    succ:           succ,
    times:          times,
    toPaddedString: toPaddedString,
    toJSON:         toJSON,
    abs:            abs,
    round:          round,
    ceil:           ceil,
    floor:          floor
  };
})());

function $R(start, end, exclusive) {
  return new ObjectRange(start, end, exclusive);
}

var ObjectRange = Class.create(Enumerable, (function() {
  function initialize(start, end, exclusive) {
    this.start = start;
    this.end = end;
    this.exclusive = exclusive;
  }

  function _each(iterator) {
    var value = this.start;
    while (this.include(value)) {
      iterator(value);
      value = value.succ();
    }
  }

  function include(value) {
    if (value < this.start)
      return false;
    if (this.exclusive)
      return value < this.end;
    return value <= this.end;
  }

  return {
    initialize: initialize,
    _each:      _each,
    include:    include
  };
})());



var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
  },

  activeRequestCount: 0
};

Ajax.Responders = {
  responders: [],

  _each: function(iterator) {
    this.responders._each(iterator);
  },

  register: function(responder) {
    if (!this.include(responder))
      this.responders.push(responder);
  },

  unregister: function(responder) {
    this.responders = this.responders.without(responder);
  },

  dispatch: function(callback, request, transport, json) {
    this.each(function(responder) {
      if (Object.isFunction(responder[callback])) {
        try {
          responder[callback].apply(responder, [request, transport, json]);
        } catch (e) { }
      }
    });
  }
};

Object.extend(Ajax.Responders, Enumerable);

Ajax.Responders.register({
  onCreate:   function() { Ajax.activeRequestCount++ },
  onComplete: function() { Ajax.activeRequestCount-- }
});
Ajax.Base = Class.create({
  initialize: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      contentType:  'application/x-www-form-urlencoded',
      encoding:     'UTF-8',
      parameters:   '',
      evalJSON:     true,
      evalJS:       true
    };
    Object.extend(this.options, options || { });

    this.options.method = this.options.method.toLowerCase();

    if (Object.isString(this.options.parameters))
      this.options.parameters = this.options.parameters.toQueryParams();
    else if (Object.isHash(this.options.parameters))
      this.options.parameters = this.options.parameters.toObject();
  }
});
Ajax.Request = Class.create(Ajax.Base, {
  _complete: false,

  initialize: function($super, url, options) {
    $super(options);
    this.transport = Ajax.getTransport();
    this.request(url);
  },

  request: function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = Object.clone(this.options.parameters);

    if (!['get', 'post'].include(this.method)) {
      params['_method'] = this.method;
      this.method = 'post';
    }

    this.parameters = params;

    if (params = Object.toQueryString(params)) {
      if (this.method == 'get')
        this.url += (this.url.include('?') ? '&' : '?') + params;
      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
        params += '&_=';
    }

    try {
      var response = new Ajax.Response(this);
      if (this.options.onCreate) this.options.onCreate(response);
      Ajax.Responders.dispatch('onCreate', this, response);

      this.transport.open(this.method.toUpperCase(), this.url,
        this.options.asynchronous);

      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);

      this.transport.onreadystatechange = this.onStateChange.bind(this);
      this.setRequestHeaders();

      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
      this.transport.send(this.body);

      /* Force Firefox to handle ready state 4 for synchronous requests */
      if (!this.options.asynchronous && this.transport.overrideMimeType)
        this.onStateChange();

    }
    catch (e) {
      this.dispatchException(e);
    }
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState > 1 && !((readyState == 4) && this._complete))
      this.respondToReadyState(this.transport.readyState);
  },

  setRequestHeaders: function() {
    var headers = {
      'X-Requested-With': 'XMLHttpRequest',
      'X-Prototype-Version': Prototype.Version,
      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
    };

    if (this.method == 'post') {
      headers['Content-type'] = this.options.contentType +
        (this.options.encoding ? '; charset=' + this.options.encoding : '');

      /* Force "Connection: close" for older Mozilla browsers to work
       * around a bug where XMLHttpRequest sends an incorrect
       * Content-length header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType &&
          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
            headers['Connection'] = 'close';
    }

    if (typeof this.options.requestHeaders == 'object') {
      var extras = this.options.requestHeaders;

      if (Object.isFunction(extras.push))
        for (var i = 0, length = extras.length; i < length; i += 2)
          headers[extras[i]] = extras[i+1];
      else
        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
    }

    for (var name in headers)
      this.transport.setRequestHeader(name, headers[name]);
  },

  success: function() {
    var status = this.getStatus();
    return !status || (status >= 200 && status < 300);
  },

  getStatus: function() {
    try {
      return this.transport.status || 0;
    } catch (e) { return 0 }
  },

  respondToReadyState: function(readyState) {
    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);

    if (state == 'Complete') {
      try {
        this._complete = true;
        (this.options['on' + response.status]
         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(response, response.headerJSON);
      } catch (e) {
        this.dispatchException(e);
      }

      var contentType = response.getHeader('Content-type');
      if (this.options.evalJS == 'force'
          || (this.options.evalJS && this.isSameOrigin() && contentType
          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
        this.evalResponse();
    }

    try {
      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
    } catch (e) {
      this.dispatchException(e);
    }

    if (state == 'Complete') {
      this.transport.onreadystatechange = Prototype.emptyFunction;
    }
  },

  isSameOrigin: function() {
    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
      protocol: location.protocol,
      domain: document.domain,
      port: location.port ? ':' + location.port : ''
    }));
  },

  getHeader: function(name) {
    try {
      return this.transport.getResponseHeader(name) || null;
    } catch (e) { return null; }
  },

  evalResponse: function() {
    try {
      return eval((this.transport.responseText || '').unfilterJSON());
    } catch (e) {
      this.dispatchException(e);
    }
  },

  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
    Ajax.Responders.dispatch('onException', this, exception);
  }
});

Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];








Ajax.Response = Class.create({
  initialize: function(request){
    this.request = request;
    var transport  = this.transport  = request.transport,
        readyState = this.readyState = transport.readyState;

    if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
      this.status       = this.getStatus();
      this.statusText   = this.getStatusText();
      this.responseText = String.interpret(transport.responseText);
      this.headerJSON   = this._getHeaderJSON();
    }

    if(readyState == 4) {
      var xml = transport.responseXML;
      this.responseXML  = Object.isUndefined(xml) ? null : xml;
      this.responseJSON = this._getResponseJSON();
    }
  },

  status:      0,

  statusText: '',

  getStatus: Ajax.Request.prototype.getStatus,

  getStatusText: function() {
    try {
      return this.transport.statusText || '';
    } catch (e) { return '' }
  },

  getHeader: Ajax.Request.prototype.getHeader,

  getAllHeaders: function() {
    try {
      return this.getAllResponseHeaders();
    } catch (e) { return null }
  },

  getResponseHeader: function(name) {
    return this.transport.getResponseHeader(name);
  },

  getAllResponseHeaders: function() {
    return this.transport.getAllResponseHeaders();
  },

  _getHeaderJSON: function() {
    var json = this.getHeader('X-JSON');
    if (!json) return null;
    json = decodeURIComponent(escape(json));
    try {
      return json.evalJSON(this.request.options.sanitizeJSON ||
        !this.request.isSameOrigin());
    } catch (e) {
      this.request.dispatchException(e);
    }
  },

  _getResponseJSON: function() {
    var options = this.request.options;
    if (!options.evalJSON || (options.evalJSON != 'force' &&
      !(this.getHeader('Content-type') || '').include('application/json')) ||
        this.responseText.blank())
          return null;
    try {
      return this.responseText.evalJSON(options.sanitizeJSON ||
        !this.request.isSameOrigin());
    } catch (e) {
      this.request.dispatchException(e);
    }
  }
});

Ajax.Updater = Class.create(Ajax.Request, {
  initialize: function($super, container, url, options) {
    this.container = {
      success: (container.success || container),
      failure: (container.failure || (container.success ? null : container))
    };

    options = Object.clone(options);
    var onComplete = options.onComplete;
    options.onComplete = (function(response, json) {
      this.updateContent(response.responseText);
      if (Object.isFunction(onComplete)) onComplete(response, json);
    }).bind(this);

    $super(url, options);
  },

  updateContent: function(responseText) {
    var receiver = this.container[this.success() ? 'success' : 'failure'],
        options = this.options;

    if (!options.evalScripts) responseText = responseText.stripScripts();

    if (receiver = $(receiver)) {
      if (options.insertion) {
        if (Object.isString(options.insertion)) {
          var insertion = { }; insertion[options.insertion] = responseText;
          receiver.insert(insertion);
        }
        else options.insertion(receiver, responseText);
      }
      else receiver.update(responseText);
    }
  }
});

Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
  initialize: function($super, container, url, options) {
    $super(options);
    this.onComplete = this.options.onComplete;

    this.frequency = (this.options.frequency || 2);
    this.decay = (this.options.decay || 1);

    this.updater = { };
    this.container = container;
    this.url = url;

    this.start();
  },

  start: function() {
    this.options.onComplete = this.updateComplete.bind(this);
    this.onTimerEvent();
  },

  stop: function() {
    this.updater.options.onComplete = undefined;
    clearTimeout(this.timer);
    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
  },

  updateComplete: function(response) {
    if (this.options.decay) {
      this.decay = (response.responseText == this.lastText ?
        this.decay * this.options.decay : 1);

      this.lastText = response.responseText;
    }
    this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
  },

  onTimerEvent: function() {
    this.updater = new Ajax.Updater(this.container, this.url, this.options);
  }
});



function $(element) {
  if (arguments.length > 1) {
    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
      elements.push($(arguments[i]));
    return elements;
  }
  if (Object.isString(element))
    element = document.getElementById(element);
  return Element.extend(element);
}

if (Prototype.BrowserFeatures.XPath) {
  document._getElementsByXPath = function(expression, parentElement) {
    var results = [];
    var query = document.evaluate(expression, $(parentElement) || document,
      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0, length = query.snapshotLength; i < length; i++)
      results.push(Element.extend(query.snapshotItem(i)));
    return results;
  };
}

/*--------------------------------------------------------------------------*/

if (!window.Node) var Node = { };

if (!Node.ELEMENT_NODE) {
  Object.extend(Node, {
    ELEMENT_NODE: 1,
    ATTRIBUTE_NODE: 2,
    TEXT_NODE: 3,
    CDATA_SECTION_NODE: 4,
    ENTITY_REFERENCE_NODE: 5,
    ENTITY_NODE: 6,
    PROCESSING_INSTRUCTION_NODE: 7,
    COMMENT_NODE: 8,
    DOCUMENT_NODE: 9,
    DOCUMENT_TYPE_NODE: 10,
    DOCUMENT_FRAGMENT_NODE: 11,
    NOTATION_NODE: 12
  });
}


(function(global) {

  var SETATTRIBUTE_IGNORES_NAME = (function(){
    var elForm = document.createElement("form");
    var elInput = document.createElement("input");
    var root = document.documentElement;
    elInput.setAttribute("name", "test");
    elForm.appendChild(elInput);
    root.appendChild(elForm);
    var isBuggy = elForm.elements
      ? (typeof elForm.elements.test == "undefined")
      : null;
    root.removeChild(elForm);
    elForm = elInput = null;
    return isBuggy;
  })();

  var element = global.Element;
  global.Element = function(tagName, attributes) {
    attributes = attributes || { };
    tagName = tagName.toLowerCase();
    var cache = Element.cache;
    if (SETATTRIBUTE_IGNORES_NAME && attributes.name) {
      tagName = '<' + tagName + ' name="' + attributes.name + '">';
      delete attributes.name;
      return Element.writeAttribute(document.createElement(tagName), attributes);
    }
    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
  };
  Object.extend(global.Element, element || { });
  if (element) global.Element.prototype = element.prototype;
})(this);

Element.cache = { };
Element.idCounter = 1;

Element.Methods = {
  visible: function(element) {
    return $(element).style.display != 'none';
  },

  toggle: function(element) {
    element = $(element);
    Element[Element.visible(element) ? 'hide' : 'show'](element);
    return element;
  },


  hide: function(element) {
    element = $(element);
    element.style.display = 'none';
    return element;
  },

  show: function(element) {
    element = $(element);
    element.style.display = '';
    return element;
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
    return element;
  },

  update: (function(){

    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
      var el = document.createElement("select"),
          isBuggy = true;
      el.innerHTML = "<option value=\"test\">test</option>";
      if (el.options && el.options[0]) {
        isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
      }
      el = null;
      return isBuggy;
    })();

    var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
      try {
        var el = document.createElement("table");
        if (el && el.tBodies) {
          el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
          var isBuggy = typeof el.tBodies[0] == "undefined";
          el = null;
          return isBuggy;
        }
      } catch (e) {
        return true;
      }
    })();

    var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
      var s = document.createElement("script"),
          isBuggy = false;
      try {
        s.appendChild(document.createTextNode(""));
        isBuggy = !s.firstChild ||
          s.firstChild && s.firstChild.nodeType !== 3;
      } catch (e) {
        isBuggy = true;
      }
      s = null;
      return isBuggy;
    })();

    function update(element, content) {
      element = $(element);

      if (content && content.toElement)
        content = content.toElement();

      if (Object.isElement(content))
        return element.update().insert(content);

      content = Object.toHTML(content);

      var tagName = element.tagName.toUpperCase();

      if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
        element.text = content;
        return element;
      }

      if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
        if (tagName in Element._insertionTranslations.tags) {
          while (element.firstChild) {
            element.removeChild(element.firstChild);
          }
          Element._getContentFromAnonymousElement(tagName, content.stripScripts())
            .each(function(node) {
              element.appendChild(node)
            });
        }
        else {
          element.innerHTML = content.stripScripts();
        }
      }
      else {
        element.innerHTML = content.stripScripts();
      }

      content.evalScripts.bind(content).defer();
      return element;
    }

    return update;
  })(),

  replace: function(element, content) {
    element = $(element);
    if (content && content.toElement) content = content.toElement();
    else if (!Object.isElement(content)) {
      content = Object.toHTML(content);
      var range = element.ownerDocument.createRange();
      range.selectNode(element);
      content.evalScripts.bind(content).defer();
      content = range.createContextualFragment(content.stripScripts());
    }
    element.parentNode.replaceChild(content, element);
    return element;
  },

  insert: function(element, insertions) {
    element = $(element);

    if (Object.isString(insertions) || Object.isNumber(insertions) ||
        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
          insertions = {bottom:insertions};

    var content, insert, tagName, childNodes;

    for (var position in insertions) {
      content  = insertions[position];
      position = position.toLowerCase();
      insert = Element._insertionTranslations[position];

      if (content && content.toElement) content = content.toElement();
      if (Object.isElement(content)) {
        insert(element, content);
        continue;
      }

      content = Object.toHTML(content);

      tagName = ((position == 'before' || position == 'after')
        ? element.parentNode : element).tagName.toUpperCase();

      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());

      if (position == 'top' || position == 'after') childNodes.reverse();
      childNodes.each(insert.curry(element));

      content.evalScripts.bind(content).defer();
    }

    return element;
  },

  wrap: function(element, wrapper, attributes) {
    element = $(element);
    if (Object.isElement(wrapper))
      $(wrapper).writeAttribute(attributes || { });
    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
    else wrapper = new Element('div', wrapper);
    if (element.parentNode)
      element.parentNode.replaceChild(wrapper, element);
    wrapper.appendChild(element);
    return wrapper;
  },

  inspect: function(element) {
    element = $(element);
    var result = '<' + element.tagName.toLowerCase();
    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
      var property = pair.first(), attribute = pair.last();
      var value = (element[property] || '').toString();
      if (value) result += ' ' + attribute + '=' + value.inspect(true);
    });
    return result + '>';
  },

  recursivelyCollect: function(element, property) {
    element = $(element);
    var elements = [];
    while (element = element[property])
      if (element.nodeType == 1)
        elements.push(Element.extend(element));
    return elements;
  },

  ancestors: function(element) {
    return Element.recursivelyCollect(element, 'parentNode');
  },

  descendants: function(element) {
    return Element.select(element, "*");
  },

  firstDescendant: function(element) {
    element = $(element).firstChild;
    while (element && element.nodeType != 1) element = element.nextSibling;
    return $(element);
  },

  immediateDescendants: function(element) {
    if (!(element = $(element).firstChild)) return [];
    while (element && element.nodeType != 1) element = element.nextSibling;
    if (element) return [element].concat($(element).nextSiblings());
    return [];
  },

  previousSiblings: function(element) {
    return Element.recursivelyCollect(element, 'previousSibling');
  },

  nextSiblings: function(element) {
    return Element.recursivelyCollect(element, 'nextSibling');
  },

  siblings: function(element) {
    element = $(element);
    return Element.previousSiblings(element).reverse()
      .concat(Element.nextSiblings(element));
  },

  match: function(element, selector) {
    if (Object.isString(selector))
      selector = new Selector(selector);
    return selector.match($(element));
  },

  up: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(element.parentNode);
    var ancestors = Element.ancestors(element);
    return Object.isNumber(expression) ? ancestors[expression] :
      Selector.findElement(ancestors, expression, index);
  },

  down: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return Element.firstDescendant(element);
    return Object.isNumber(expression) ? Element.descendants(element)[expression] :
      Element.select(element, expression)[index || 0];
  },

  previous: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
    var previousSiblings = Element.previousSiblings(element);
    return Object.isNumber(expression) ? previousSiblings[expression] :
      Selector.findElement(previousSiblings, expression, index);
  },

  next: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
    var nextSiblings = Element.nextSiblings(element);
    return Object.isNumber(expression) ? nextSiblings[expression] :
      Selector.findElement(nextSiblings, expression, index);
  },


  select: function(element) {
    var args = Array.prototype.slice.call(arguments, 1);
    return Selector.findChildElements(element, args);
  },

  adjacent: function(element) {
    var args = Array.prototype.slice.call(arguments, 1);
    return Selector.findChildElements(element.parentNode, args).without(element);
  },

  identify: function(element) {
    element = $(element);
    var id = Element.readAttribute(element, 'id');
    if (id) return id;
    do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
    Element.writeAttribute(element, 'id', id);
    return id;
  },

  readAttribute: function(element, name) {
    element = $(element);
    if (Prototype.Browser.IE) {
      var t = Element._attributeTranslations.read;
      if (t.values[name]) return t.values[name](element, name);
      if (t.names[name]) name = t.names[name];
      if (name.include(':')) {
        return (!element.attributes || !element.attributes[name]) ? null :
         element.attributes[name].value;
      }
    }
    return element.getAttribute(name);
  },

  writeAttribute: function(element, name, value) {
    element = $(element);
    var attributes = { }, t = Element._attributeTranslations.write;

    if (typeof name == 'object') attributes = name;
    else attributes[name] = Object.isUndefined(value) ? true : value;

    for (var attr in attributes) {
      name = t.names[attr] || attr;
      value = attributes[attr];
      if (t.values[attr]) name = t.values[attr](element, value);
      if (value === false || value === null)
        element.removeAttribute(name);
      else if (value === true)
        element.setAttribute(name, name);
      else element.setAttribute(name, value);
    }
    return element;
  },

  getHeight: function(element) {
    return Element.getDimensions(element).height;
  },

  getWidth: function(element) {
    return Element.getDimensions(element).width;
  },

  classNames: function(element) {
    return new Element.ClassNames(element);
  },

  hasClassName: function(element, className) {
    if (!(element = $(element))) return;
    var elementClassName = element.className;
    return (elementClassName.length > 0 && (elementClassName == className ||
      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
  },

  addClassName: function(element, className) {
    if (!(element = $(element))) return;
    if (!Element.hasClassName(element, className))
      element.className += (element.className ? ' ' : '') + className;
    return element;
  },

  removeClassName: function(element, className) {
    if (!(element = $(element))) return;
    element.className = element.className.replace(
      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
    return element;
  },

  toggleClassName: function(element, className) {
    if (!(element = $(element))) return;
    return Element[Element.hasClassName(element, className) ?
      'removeClassName' : 'addClassName'](element, className);
  },

  cleanWhitespace: function(element) {
    element = $(element);
    var node = element.firstChild;
    while (node) {
      var nextNode = node.nextSibling;
      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
        element.removeChild(node);
      node = nextNode;
    }
    return element;
  },

  empty: function(element) {
    return $(element).innerHTML.blank();
  },

  descendantOf: function(element, ancestor) {
    element = $(element), ancestor = $(ancestor);

    if (element.compareDocumentPosition)
      return (element.compareDocumentPosition(ancestor) & 8) === 8;

    if (ancestor.contains)
      return ancestor.contains(element) && ancestor !== element;

    while (element = element.parentNode)
      if (element == ancestor) return true;

    return false;
  },

  scrollTo: function(element) {
    element = $(element);
    var pos = Element.cumulativeOffset(element);
    window.scrollTo(pos[0], pos[1]);
    return element;
  },

  getStyle: function(element, style) {
    element = $(element);
    style = style == 'float' ? 'cssFloat' : style.camelize();
    var value = element.style[style];
    if (!value || value == 'auto') {
      var css = document.defaultView.getComputedStyle(element, null);
      value = css ? css[style] : null;
    }
    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
    return value == 'auto' ? null : value;
  },

  getOpacity: function(element) {
    return $(element).getStyle('opacity');
  },

  setStyle: function(element, styles) {
    element = $(element);
    var elementStyle = element.style, match;
    if (Object.isString(styles)) {
      element.style.cssText += ';' + styles;
      return styles.include('opacity') ?
        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
    }
    for (var property in styles)
      if (property == 'opacity') element.setOpacity(styles[property]);
      else
        elementStyle[(property == 'float' || property == 'cssFloat') ?
          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
            property] = styles[property];

    return element;
  },

  setOpacity: function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;
    return element;
  },

  getDimensions: function(element) {
    element = $(element);
    var display = Element.getStyle(element, 'display');
    if (display != 'none' && display != null) // Safari bug
      return {width: element.offsetWidth, height: element.offsetHeight};

    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari
      els.position = 'absolute';
    els.display = 'block';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = originalDisplay;
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
  },

  makePositioned: function(element) {
    element = $(element);
    var pos = Element.getStyle(element, 'position');
    if (pos == 'static' || !pos) {
      element._madePositioned = true;
      element.style.position = 'relative';
      if (Prototype.Browser.Opera) {
        element.style.top = 0;
        element.style.left = 0;
      }
    }
    return element;
  },

  undoPositioned: function(element) {
    element = $(element);
    if (element._madePositioned) {
      element._madePositioned = undefined;
      element.style.position =
        element.style.top =
        element.style.left =
        element.style.bottom =
        element.style.right = '';
    }
    return element;
  },

  makeClipping: function(element) {
    element = $(element);
    if (element._overflow) return element;
    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
    if (element._overflow !== 'hidden')
      element.style.overflow = 'hidden';
    return element;
  },

  undoClipping: function(element) {
    element = $(element);
    if (!element._overflow) return element;
    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
    element._overflow = null;
    return element;
  },

  cumulativeOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  positionedOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
      if (element) {
        if (element.tagName.toUpperCase() == 'BODY') break;
        var p = Element.getStyle(element, 'position');
        if (p !== 'static') break;
      }
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  absolutize: function(element) {
    element = $(element);
    if (Element.getStyle(element, 'position') == 'absolute') return element;

    var offsets = Element.positionedOffset(element);
    var top     = offsets[1];
    var left    = offsets[0];
    var width   = element.clientWidth;
    var height  = element.clientHeight;

    element._originalLeft   = left - parseFloat(element.style.left  || 0);
    element._originalTop    = top  - parseFloat(element.style.top || 0);
    element._originalWidth  = element.style.width;
    element._originalHeight = element.style.height;

    element.style.position = 'absolute';
    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.width  = width + 'px';
    element.style.height = height + 'px';
    return element;
  },

  relativize: function(element) {
    element = $(element);
    if (Element.getStyle(element, 'position') == 'relative') return element;

    element.style.position = 'relative';
    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.height = element._originalHeight;
    element.style.width  = element._originalWidth;
    return element;
  },

  cumulativeScrollOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.scrollTop  || 0;
      valueL += element.scrollLeft || 0;
      element = element.parentNode;
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  getOffsetParent: function(element) {
    if (element.offsetParent) return $(element.offsetParent);
    if (element == document.body) return $(element);

    if(element.tagName.toUpperCase()=='HTML') //for IE6,7      
      return $(document.body); // 
    while ((element = element.parentNode) && element != document.body)
      if (Element.getStyle(element, 'position') != 'static')
        return $(element);

    return $(document.body);
  },

  viewportOffset: function(forElement) {
    var valueT = 0, valueL = 0;

    var element = forElement;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;

      if (element.offsetParent == document.body &&
        Element.getStyle(element, 'position') == 'absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
        valueT -= element.scrollTop  || 0;
        valueL -= element.scrollLeft || 0;
      }
    } while (element = element.parentNode);

    return Element._returnOffset(valueL, valueT);
  },

  clonePosition: function(element, source) {
    var options = Object.extend({
      setLeft:    true,
      setTop:     true,
      setWidth:   true,
      setHeight:  true,
      offsetTop:  0,
      offsetLeft: 0
    }, arguments[2] || { });

    source = $(source);
    var p = Element.viewportOffset(source);

    element = $(element);
    var delta = [0, 0];
    var parent = null;
    if (Element.getStyle(element, 'position') == 'absolute') {
      parent = Element.getOffsetParent(element);
      delta = Element.viewportOffset(parent);
    }

    if (parent == document.body) {
      delta[0] -= document.body.offsetLeft;
      delta[1] -= document.body.offsetTop;
    }

    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
    return element;
  }
};

Object.extend(Element.Methods, {
  getElementsBySelector: Element.Methods.select,

  childElements: Element.Methods.immediateDescendants
});

Element._attributeTranslations = {
  write: {
    names: {
      className: 'class',
      htmlFor:   'for'
    },
    values: { }
  }
};

if (Prototype.Browser.Opera) {
  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
    function(proceed, element, style) {
      switch (style) {
        case 'left': case 'top': case 'right': case 'bottom':
          if (proceed(element, 'position') === 'static') return null;
        case 'height': case 'width':
          if (!Element.visible(element)) return null;

          var dim = parseInt(proceed(element, style), 10);

          if (dim !== element['offset' + style.capitalize()])
            return dim + 'px';

          var properties;
          if (style === 'height') {
            properties = ['border-top-width', 'padding-top',
             'padding-bottom', 'border-bottom-width'];
          }
          else {
            properties = ['border-left-width', 'padding-left',
             'padding-right', 'border-right-width'];
          }
          return properties.inject(dim, function(memo, property) {
            var val = proceed(element, property);
            return val === null ? memo : memo - parseInt(val, 10);
          }) + 'px';
        default: return proceed(element, style);
      }
    }
  );

  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
    function(proceed, element, attribute) {
      if (attribute === 'title') return element.title;
      return proceed(element, attribute);
    }
  );
}

else if (Prototype.Browser.IE) {
  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
    function(proceed, element) {
      element = $(element);
      try { element.offsetParent }
      catch(e) { return $(document.body) }
      var position = element.getStyle('position');
      if (position !== 'static') return proceed(element);
      element.setStyle({ position: 'relative' });
      var value = proceed(element);
      element.setStyle({ position: position });
      return value;
    }
  );

  $w('positionedOffset viewportOffset').each(function(method) {
    Element.Methods[method] = Element.Methods[method].wrap(
      function(proceed, element) {
        element = $(element);
        try { element.offsetParent }
        catch(e) { return Element._returnOffset(0,0) }
        var position = element.getStyle('position');
        if (position !== 'static') return proceed(element);
        var offsetParent = element.getOffsetParent();
        if (offsetParent && offsetParent.getStyle('position') === 'fixed')
          offsetParent.setStyle({ zoom: 1 });
        element.setStyle({ position: 'relative' });
        var value = proceed(element);
        element.setStyle({ position: position });
        return value;
      }
    );
  });

  Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
    function(proceed, element) {
      try { element.offsetParent }
      catch(e) { return Element._returnOffset(0,0) }
      return proceed(element);
    }
  );

  Element.Methods.getStyle = function(element, style) {
    element = $(element);
    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
    var value = element.style[style];
    if (!value && element.currentStyle) value = element.currentStyle[style];

    if (style == 'opacity') {
      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        if (value[1]) return parseFloat(value[1]) / 100;
      return 1.0;
    }

    if (value == 'auto') {
      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
        return element['offset' + style.capitalize()] + 'px';
      return null;
    }
    return value;
  };

  Element.Methods.setOpacity = function(element, value) {
    function stripAlpha(filter){
      return filter.replace(/alpha\([^\)]*\)/gi,'');
    }
    element = $(element);
    var currentStyle = element.currentStyle;
    if ((currentStyle && !currentStyle.hasLayout) ||
      (!currentStyle && element.style.zoom == 'normal'))
        element.style.zoom = 1;

    var filter = element.getStyle('filter'), style = element.style;
    if (value == 1 || value === '') {
      (filter = stripAlpha(filter)) ?
        style.filter = filter : style.removeAttribute('filter');
      return element;
    } else if (value < 0.00001) value = 0;
    style.filter = stripAlpha(filter) +
      'alpha(opacity=' + (value * 100) + ')';
    return element;
  };

  Element._attributeTranslations = (function(){

    var classProp = 'className';
    var forProp = 'for';

    var el = document.createElement('div');

    el.setAttribute(classProp, 'x');

    if (el.className !== 'x') {
      el.setAttribute('class', 'x');
      if (el.className === 'x') {
        classProp = 'class';
      }
    }
    el = null;

    el = document.createElement('label');
    el.setAttribute(forProp, 'x');
    if (el.htmlFor !== 'x') {
      el.setAttribute('htmlFor', 'x');
      if (el.htmlFor === 'x') {
        forProp = 'htmlFor';
      }
    }
    el = null;

    return {
      read: {
        names: {
          'class':      classProp,
          'className':  classProp,
          'for':        forProp,
          'htmlFor':    forProp
        },
        values: {
          _getAttr: function(element, attribute) {
            return element.getAttribute(attribute);
          },
          _getAttr2: function(element, attribute) {
            return element.getAttribute(attribute, 2);
          },
          _getAttrNode: function(element, attribute) {
            var node = element.getAttributeNode(attribute);
            return node ? node.value : "";
          },
          _getEv: (function(){

            var el = document.createElement('div');
            el.onclick = Prototype.emptyFunction;
            var value = el.getAttribute('onclick');
            var f;

            if (String(value).indexOf('{') > -1) {
              f = function(element, attribute) {
                attribute = element.getAttribute(attribute);
                if (!attribute) return null;
                attribute = attribute.toString();
                attribute = attribute.split('{')[1];
                attribute = attribute.split('}')[0];
                return attribute.strip();
              };
            }
            else if (value === '') {
              f = function(element, attribute) {
                attribute = element.getAttribute(attribute);
                if (!attribute) return null;
                return attribute.strip();
              };
            }
            el = null;
            return f;
          })(),
          _flag: function(element, attribute) {
            return $(element).hasAttribute(attribute) ? attribute : null;
          },
          style: function(element) {
            return element.style.cssText.toLowerCase();
          },
          title: function(element) {
            return element.title;
          }
        }
      }
    }
  })();

  Element._attributeTranslations.write = {
    names: Object.extend({
      cellpadding: 'cellPadding',
      cellspacing: 'cellSpacing'
    }, Element._attributeTranslations.read.names),
    values: {
      checked: function(element, value) {
        element.checked = !!value;
      },

      style: function(element, value) {
        element.style.cssText = value ? value : '';
      }
    }
  };

  Element._attributeTranslations.has = {};

  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
  });

  (function(v) {
    Object.extend(v, {
      href:        v._getAttr2,
      src:         v._getAttr2,
      type:        v._getAttr,
      action:      v._getAttrNode,
      disabled:    v._flag,
      checked:     v._flag,
      readonly:    v._flag,
      multiple:    v._flag,
      onload:      v._getEv,
      onunload:    v._getEv,
      onclick:     v._getEv,
      ondblclick:  v._getEv,
      onmousedown: v._getEv,
      onmouseup:   v._getEv,
      onmouseover: v._getEv,
      onmousemove: v._getEv,
      onmouseout:  v._getEv,
      onfocus:     v._getEv,
      onblur:      v._getEv,
      onkeypress:  v._getEv,
      onkeydown:   v._getEv,
      onkeyup:     v._getEv,
      onsubmit:    v._getEv,
      onreset:     v._getEv,
      onselect:    v._getEv,
      onchange:    v._getEv
    });
  })(Element._attributeTranslations.read.values);

  if (Prototype.BrowserFeatures.ElementExtensions) {
    (function() {
      function _descendants(element) {
        var nodes = element.getElementsByTagName('*'), results = [];
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.tagName !== "!") // Filter out comment nodes.
            results.push(node);
        return results;
      }

      Element.Methods.down = function(element, expression, index) {
        element = $(element);
        if (arguments.length == 1) return element.firstDescendant();
        return Object.isNumber(expression) ? _descendants(element)[expression] :
          Element.select(element, expression)[index || 0];
      }
    })();
  }

}

else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1) ? 0.999999 :
      (value === '') ? '' : (value < 0.00001) ? 0 : value;
    return element;
  };
}

else if (Prototype.Browser.WebKit) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;

    if (value == 1)
      if(element.tagName.toUpperCase() == 'IMG' && element.width) {
        element.width++; element.width--;
      } else try {
        var n = document.createTextNode(' ');
        element.appendChild(n);
        element.removeChild(n);
      } catch (e) { }

    return element;
  };

  Element.Methods.cumulativeOffset = function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      if (element.offsetParent == document.body)
        if (Element.getStyle(element, 'position') == 'absolute') break;

      element = element.offsetParent;
    } while (element);

    return Element._returnOffset(valueL, valueT);
  };
}

if ('outerHTML' in document.documentElement) {
  Element.Methods.replace = function(element, content) {
    element = $(element);

    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) {
      element.parentNode.replaceChild(content, element);
      return element;
    }

    content = Object.toHTML(content);
    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();

    if (Element._insertionTranslations.tags[tagName]) {
      var nextSibling = element.next();
      var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
      parent.removeChild(element);
      if (nextSibling)
        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
      else
        fragments.each(function(node) { parent.appendChild(node) });
    }
    else element.outerHTML = content.stripScripts();

    content.evalScripts.bind(content).defer();
    return element;
  };
}

Element._returnOffset = function(l, t) {
  var result = [l, t];
  result.left = l;
  result.top = t;
  return result;
};

Element._getContentFromAnonymousElement = function(tagName, html) {
  var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
  if (t) {
    div.innerHTML = t[0] + html + t[1];
    t[2].times(function() { div = div.firstChild });
  } else div.innerHTML = html;
  return $A(div.childNodes);
};

Element._insertionTranslations = {
  before: function(element, node) {
    element.parentNode.insertBefore(node, element);
  },
  top: function(element, node) {
    element.insertBefore(node, element.firstChild);
  },
  bottom: function(element, node) {
    element.appendChild(node);
  },
  after: function(element, node) {
    element.parentNode.insertBefore(node, element.nextSibling);
  },
  tags: {
    TABLE:  ['<table>',                '</table>',                   1],
    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
    SELECT: ['<select>',               '</select>',                  1]
  }
};

(function() {
  var tags = Element._insertionTranslations.tags;
  Object.extend(tags, {
    THEAD: tags.TBODY,
    TFOOT: tags.TBODY,
    TH:    tags.TD
  });
})();

Element.Methods.Simulated = {
  hasAttribute: function(element, attribute) {
    attribute = Element._attributeTranslations.has[attribute] || attribute;
    var node = $(element).getAttributeNode(attribute);
    return !!(node && node.specified);
  }
};

Element.Methods.ByTag = { };

Object.extend(Element, Element.Methods);

(function(div) {

  if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
    window.HTMLElement = { };
    window.HTMLElement.prototype = div['__proto__'];
    Prototype.BrowserFeatures.ElementExtensions = true;
  }

  div = null;

})(document.createElement('div'))

Element.extend = (function() {

  function checkDeficiency(tagName) {
    if (typeof window.Element != 'undefined') {
      var proto = window.Element.prototype;
      if (proto) {
        var id = '_' + (Math.random()+'').slice(2);
        var el = document.createElement(tagName);
        proto[id] = 'x';
        var isBuggy = (el[id] !== 'x');
        delete proto[id];
        el = null;
        return isBuggy;
      }
    }
    return false;
  }

  function extendElementWith(element, methods) {
    for (var property in methods) {
      var value = methods[property];
      if (Object.isFunction(value) && !(property in element))
        element[property] = value.methodize();
    }
  }

  var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');

  if (Prototype.BrowserFeatures.SpecificElementExtensions) {
    if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
      return function(element) {
        if (element && typeof element._extendedByPrototype == 'undefined') {
          var t = element.tagName;
          if (t && (/^(?:object|applet|embed)$/i.test(t))) {
            extendElementWith(element, Element.Methods);
            extendElementWith(element, Element.Methods.Simulated);
            extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
          }
        }
        return element;
      }
    }
    return Prototype.K;
  }

  var Methods = { }, ByTag = Element.Methods.ByTag;

  var extend = Object.extend(function(element) {
    if (!element || typeof element._extendedByPrototype != 'undefined' ||
        element.nodeType != 1 || element == window) return element;

    var methods = Object.clone(Methods),
        tagName = element.tagName.toUpperCase();

    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);

    extendElementWith(element, methods);

    element._extendedByPrototype = Prototype.emptyFunction;
    return element;

  }, {
    refresh: function() {
      if (!Prototype.BrowserFeatures.ElementExtensions) {
        Object.extend(Methods, Element.Methods);
        Object.extend(Methods, Element.Methods.Simulated);
      }
    }
  });

  extend.refresh();
  return extend;
})();

Element.hasAttribute = function(element, attribute) {
  if (element.hasAttribute) return element.hasAttribute(attribute);
  return Element.Methods.Simulated.hasAttribute(element, attribute);
};

Element.addMethods = function(methods) {
  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;

  if (!methods) {
    Object.extend(Form, Form.Methods);
    Object.extend(Form.Element, Form.Element.Methods);
    Object.extend(Element.Methods.ByTag, {
      "FORM":     Object.clone(Form.Methods),
      "INPUT":    Object.clone(Form.Element.Methods),
      "SELECT":   Object.clone(Form.Element.Methods),
      "TEXTAREA": Object.clone(Form.Element.Methods)
    });
  }

  if (arguments.length == 2) {
    var tagName = methods;
    methods = arguments[1];
  }

  if (!tagName) Object.extend(Element.Methods, methods || { });
  else {
    if (Object.isArray(tagName)) tagName.each(extend);
    else extend(tagName);
  }

  function extend(tagName) {
    tagName = tagName.toUpperCase();
    if (!Element.Methods.ByTag[tagName])
      Element.Methods.ByTag[tagName] = { };
    Object.extend(Element.Methods.ByTag[tagName], methods);
  }

  function copy(methods, destination, onlyIfAbsent) {
    onlyIfAbsent = onlyIfAbsent || false;
    for (var property in methods) {
      var value = methods[property];
      if (!Object.isFunction(value)) continue;
      if (!onlyIfAbsent || !(property in destination))
        destination[property] = value.methodize();
    }
  }

  function findDOMClass(tagName) {
    var klass;
    var trans = {
      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
      "FrameSet", "IFRAME": "IFrame"
    };
    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName.capitalize() + 'Element';
    if (window[klass]) return window[klass];

    var element = document.createElement(tagName);
    var proto = element['__proto__'] || element.constructor.prototype;
    element = null;
    return proto;
  }

  var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
   Element.prototype;

  if (F.ElementExtensions) {
    copy(Element.Methods, elementPrototype);
    copy(Element.Methods.Simulated, elementPrototype, true);
  }

  if (F.SpecificElementExtensions) {
    for (var tag in Element.Methods.ByTag) {
      var klass = findDOMClass(tag);
      if (Object.isUndefined(klass)) continue;
      copy(T[tag], klass.prototype);
    }
  }

  Object.extend(Element, Element.Methods);
  delete Element.ByTag;

  if (Element.extend.refresh) Element.extend.refresh();
  Element.cache = { };
};


document.viewport = {

  getDimensions: function() {
    return { width: this.getWidth(), height: this.getHeight() };
  },

  getScrollOffsets: function() {
    return Element._returnOffset(
      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
      window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop);
  }
};

(function(viewport) {
  var B = Prototype.Browser, doc = document, element, property = {};

  function getRootElement() {
    if (B.WebKit && !doc.evaluate)
      return document;

    if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
      return document.body;

    return document.documentElement;
  }

  function define(D) {
    if (!element) element = getRootElement();

    property[D] = 'client' + D;

    viewport['get' + D] = function() { return element[property[D]] };
    return viewport['get' + D]();
  }

  viewport.getWidth  = define.curry('Width');

  viewport.getHeight = define.curry('Height');
})(document.viewport);


Element.Storage = {
  UID: 1
};

Element.addMethods({
  getStorage: function(element) {
    if (!(element = $(element))) return;

    var uid;
    if (element === window) {
      uid = 0;
    } else {
      if (typeof element._prototypeUID === "undefined")
        element._prototypeUID = [Element.Storage.UID++];
      uid = element._prototypeUID[0];
    }

    if (!Element.Storage[uid])
      Element.Storage[uid] = $H();

    return Element.Storage[uid];
  },

  store: function(element, key, value) {
    if (!(element = $(element))) return;

    if (arguments.length === 2) {
      Element.getStorage(element).update(key);
    } else {
      Element.getStorage(element).set(key, value);
    }

    return element;
  },

  retrieve: function(element, key, defaultValue) {
    if (!(element = $(element))) return;
    var hash = Element.getStorage(element), value = hash.get(key);

    if (Object.isUndefined(value)) {
      hash.set(key, defaultValue);
      value = defaultValue;
    }

    return value;
  },

  clone: function(element, deep) {
    if (!(element = $(element))) return;
    var clone = element.cloneNode(deep);
    clone._prototypeUID = void 0;
    if (deep) {
      var descendants = Element.select(clone, '*'),
          i = descendants.length;
      while (i--) {
        descendants[i]._prototypeUID = void 0;
      }
    }
    return Element.extend(clone);
  }
});
/* Portions of the Selector class are derived from Jack Slocum's DomQuery,
 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
 * license.  Please see http://www.yui-ext.com/ for more information. */

var Selector = Class.create({
  initialize: function(expression) {
    this.expression = expression.strip();

    if (this.shouldUseSelectorsAPI()) {
      this.mode = 'selectorsAPI';
    } else if (this.shouldUseXPath()) {
      this.mode = 'xpath';
      this.compileXPathMatcher();
    } else {
      this.mode = "normal";
      this.compileMatcher();
    }

  },

  shouldUseXPath: (function() {

    var IS_DESCENDANT_SELECTOR_BUGGY = (function(){
      var isBuggy = false;
      if (document.evaluate && window.XPathResult) {
        var el = document.createElement('div');
        el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';

        var xpath = ".//*[local-name()='ul' or local-name()='UL']" +
          "//*[local-name()='li' or local-name()='LI']";

        var result = document.evaluate(xpath, el, null,
          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

        isBuggy = (result.snapshotLength !== 2);
        el = null;
      }
      return isBuggy;
    })();

    return function() {
      if (!Prototype.BrowserFeatures.XPath) return false;

      var e = this.expression;

      if (Prototype.Browser.WebKit &&
       (e.include("-of-type") || e.include(":empty")))
        return false;

      if ((/(\[[\w-]*?:|:checked)/).test(e))
        return false;

      if (IS_DESCENDANT_SELECTOR_BUGGY) return false;

      return true;
    }

  })(),

  shouldUseSelectorsAPI: function() {
    if (!Prototype.BrowserFeatures.SelectorsAPI) return false;

    if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false;

    if (!Selector._div) Selector._div = new Element('div');

    try {
      Selector._div.querySelector(this.expression);
    } catch(e) {
      return false;
    }

    return true;
  },

  compileMatcher: function() {
    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
        c = Selector.criteria, le, p, m, len = ps.length, name;

    if (Selector._cache[e]) {
      this.matcher = Selector._cache[e];
      return;
    }

    this.matcher = ["this.matcher = function(root) {",
                    "var r = root, h = Selector.handlers, c = false, n;"];

    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i = 0; i<len; i++) {
        p = ps[i].re;
        name = ps[i].name;
        if (m = e.match(p)) {
          this.matcher.push(Object.isFunction(c[name]) ? c[name](m) :
            new Template(c[name]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.matcher.push("return h.unique(n);\n}");
    eval(this.matcher.join('\n'));
    Selector._cache[this.expression] = this.matcher;
  },

  compileXPathMatcher: function() {
    var e = this.expression, ps = Selector.patterns,
        x = Selector.xpath, le, m, len = ps.length, name;

    if (Selector._cache[e]) {
      this.xpath = Selector._cache[e]; return;
    }

    this.matcher = ['.//*'];
    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i = 0; i<len; i++) {
        name = ps[i].name;
        if (m = e.match(ps[i].re)) {
          this.matcher.push(Object.isFunction(x[name]) ? x[name](m) :
            new Template(x[name]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.xpath = this.matcher.join('');
    Selector._cache[this.expression] = this.xpath;
  },

  findElements: function(root) {
    root = root || document;
    var e = this.expression, results;

    switch (this.mode) {
      case 'selectorsAPI':
        if (root !== document) {
          var oldId = root.id, id = $(root).identify();
          id = id.replace(/([\.:])/g, "\\$1");
          e = "#" + id + " " + e;
        }

        results = $A(root.querySelectorAll(e)).map(Element.extend);
        root.id = oldId;

        return results;
      case 'xpath':
        return document._getElementsByXPath(this.xpath, root);
      default:
       return this.matcher(root);
    }
  },

  match: function(element) {
    this.tokens = [];

    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
    var le, p, m, len = ps.length, name;

    while (e && le !== e && (/\S/).test(e)) {
      le = e;
      for (var i = 0; i<len; i++) {
        p = ps[i].re;
        name = ps[i].name;
        if (m = e.match(p)) {
          if (as[name]) {
            this.tokens.push([name, Object.clone(m)]);
            e = e.replace(m[0], '');
          } else {
            return this.findElements(document).include(element);
          }
        }
      }
    }

    var match = true, name, matches;
    for (var i = 0, token; token = this.tokens[i]; i++) {
      name = token[0], matches = token[1];
      if (!Selector.assertions[name](element, matches)) {
        match = false; break;
      }
    }

    return match;
  },

  toString: function() {
    return this.expression;
  },

  inspect: function() {
    return "#<Selector:" + this.expression.inspect() + ">";
  }
});

if (Prototype.BrowserFeatures.SelectorsAPI &&
 document.compatMode === 'BackCompat') {
  Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){
    var div = document.createElement('div'),
     span = document.createElement('span');

    div.id = "prototype_test_id";
    span.className = 'Test';
    div.appendChild(span);
    var isIgnored = (div.querySelector('#prototype_test_id .test') !== null);
    div = span = null;
    return isIgnored;
  })();
}

Object.extend(Selector, {
  _cache: { },

  xpath: {
    descendant:   "//*",
    child:        "/*",
    adjacent:     "/following-sibling::*[1]",
    laterSibling: '/following-sibling::*',
    tagName:      function(m) {
      if (m[1] == '*') return '';
      return "[local-name()='" + m[1].toLowerCase() +
             "' or local-name()='" + m[1].toUpperCase() + "']";
    },
    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
    id:           "[@id='#{1}']",
    attrPresence: function(m) {
      m[1] = m[1].toLowerCase();
      return new Template("[@#{1}]").evaluate(m);
    },
    attr: function(m) {
      m[1] = m[1].toLowerCase();
      m[3] = m[5] || m[6];
      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
    },
    pseudo: function(m) {
      var h = Selector.xpath.pseudos[m[1]];
      if (!h) return '';
      if (Object.isFunction(h)) return h(m);
      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
    },
    operators: {
      '=':  "[@#{1}='#{3}']",
      '!=': "[@#{1}!='#{3}']",
      '^=': "[starts-with(@#{1}, '#{3}')]",
      '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
      '*=': "[contains(@#{1}, '#{3}')]",
      '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
      '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
    },
    pseudos: {
      'first-child': '[not(preceding-sibling::*)]',
      'last-child':  '[not(following-sibling::*)]',
      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
      'empty':       "[count(*) = 0 and (count(text()) = 0)]",
      'checked':     "[@checked]",
      'disabled':    "[(@disabled) and (@type!='hidden')]",
      'enabled':     "[not(@disabled) and (@type!='hidden')]",
      'not': function(m) {
        var e = m[6], p = Selector.patterns,
            x = Selector.xpath, le, v, len = p.length, name;

        var exclusion = [];
        while (e && le != e && (/\S/).test(e)) {
          le = e;
          for (var i = 0; i<len; i++) {
            name = p[i].name
            if (m = e.match(p[i].re)) {
              v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m);
              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
              e = e.replace(m[0], '');
              break;
            }
          }
        }
        return "[not(" + exclusion.join(" and ") + ")]";
      },
      'nth-child':      function(m) {
        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
      },
      'nth-last-child': function(m) {
        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
      },
      'nth-of-type':    function(m) {
        return Selector.xpath.pseudos.nth("position() ", m);
      },
      'nth-last-of-type': function(m) {
        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
      },
      'first-of-type':  function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
      },
      'last-of-type':   function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
      },
      'only-of-type':   function(m) {
        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
      },
      nth: function(fragment, m) {
        var mm, formula = m[6], predicate;
        if (formula == 'even') formula = '2n+0';
        if (formula == 'odd')  formula = '2n+1';
        if (mm = formula.match(/^(\d+)$/)) // digit only
          return '[' + fragment + "= " + mm[1] + ']';
        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
          if (mm[1] == "-") mm[1] = -1;
          var a = mm[1] ? Number(mm[1]) : 1;
          var b = mm[2] ? Number(mm[2]) : 0;
          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
          "((#{fragment} - #{b}) div #{a} >= 0)]";
          return new Template(predicate).evaluate({
            fragment: fragment, a: a, b: b });
        }
      }
    }
  },

  criteria: {
    tagName:      'n = h.tagName(n, r, "#{1}", c);      c = false;',
    className:    'n = h.className(n, r, "#{1}", c);    c = false;',
    id:           'n = h.id(n, r, "#{1}", c);           c = false;',
    attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
    attr: function(m) {
      m[3] = (m[5] || m[6]);
      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
    },
    pseudo: function(m) {
      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
    },
    descendant:   'c = "descendant";',
    child:        'c = "child";',
    adjacent:     'c = "adjacent";',
    laterSibling: 'c = "laterSibling";'
  },

  patterns: [
    { name: 'laterSibling', re: /^\s*~\s*/ },
    { name: 'child',        re: /^\s*>\s*/ },
    { name: 'adjacent',     re: /^\s*\+\s*/ },
    { name: 'descendant',   re: /^\s/ },

    { name: 'tagName',      re: /^\s*(\*|[\w\-]+)(\b|$)?/ },
    { name: 'id',           re: /^#([\w\-\*]+)(\b|$)/ },
    { name: 'className',    re: /^\.([\w\-\*]+)(\b|$)/ },
    { name: 'pseudo',       re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ },
    { name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ },
    { name: 'attr',         re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ }
  ],

  assertions: {
    tagName: function(element, matches) {
      return matches[1].toUpperCase() == element.tagName.toUpperCase();
    },

    className: function(element, matches) {
      return Element.hasClassName(element, matches[1]);
    },

    id: function(element, matches) {
      return element.id === matches[1];
    },

    attrPresence: function(element, matches) {
      return Element.hasAttribute(element, matches[1]);
    },

    attr: function(element, matches) {
      var nodeValue = Element.readAttribute(element, matches[1]);
      return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
    }
  },

  handlers: {
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        a.push(node);
      return a;
    },

    mark: function(nodes) {
      var _true = Prototype.emptyFunction;
      for (var i = 0, node; node = nodes[i]; i++)
        node._countedByPrototype = _true;
      return nodes;
    },

    unmark: (function(){

      var PROPERTIES_ATTRIBUTES_MAP = (function(){
        var el = document.createElement('div'),
            isBuggy = false,
            propName = '_countedByPrototype',
            value = 'x'
        el[propName] = value;
        isBuggy = (el.getAttribute(propName) === value);
        el = null;
        return isBuggy;
      })();

      return PROPERTIES_ATTRIBUTES_MAP ?
        function(nodes) {
          for (var i = 0, node; node = nodes[i]; i++)
            node.removeAttribute('_countedByPrototype');
          return nodes;
        } :
        function(nodes) {
          for (var i = 0, node; node = nodes[i]; i++)
            node._countedByPrototype = void 0;
          return nodes;
        }
    })(),

    index: function(parentNode, reverse, ofType) {
      parentNode._countedByPrototype = Prototype.emptyFunction;
      if (reverse) {
        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
          var node = nodes[i];
          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
        }
      } else {
        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
      }
    },

    unique: function(nodes) {
      if (nodes.length == 0) return nodes;
      var results = [], n;
      for (var i = 0, l = nodes.length; i < l; i++)
        if (typeof (n = nodes[i])._countedByPrototype == 'undefined') {
          n._countedByPrototype = Prototype.emptyFunction;
          results.push(Element.extend(n));
        }
      return Selector.handlers.unmark(results);
    },

    descendant: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, node.getElementsByTagName('*'));
      return results;
    },

    child: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        for (var j = 0, child; child = node.childNodes[j]; j++)
          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
      }
      return results;
    },

    adjacent: function(nodes) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        var next = this.nextElementSibling(node);
        if (next) results.push(next);
      }
      return results;
    },

    laterSibling: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, Element.nextSiblings(node));
      return results;
    },

    nextElementSibling: function(node) {
      while (node = node.nextSibling)
        if (node.nodeType == 1) return node;
      return null;
    },

    previousElementSibling: function(node) {
      while (node = node.previousSibling)
        if (node.nodeType == 1) return node;
      return null;
    },

    tagName: function(nodes, root, tagName, combinator) {
      var uTagName = tagName.toUpperCase();
      var results = [], h = Selector.handlers;
      if (nodes) {
        if (combinator) {
          if (combinator == "descendant") {
            for (var i = 0, node; node = nodes[i]; i++)
              h.concat(results, node.getElementsByTagName(tagName));
            return results;
          } else nodes = this[combinator](nodes);
          if (tagName == "*") return nodes;
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.tagName.toUpperCase() === uTagName) results.push(node);
        return results;
      } else return root.getElementsByTagName(tagName);
    },

    id: function(nodes, root, id, combinator) {
      var targetNode = $(id), h = Selector.handlers;

      if (root == document) {
        if (!targetNode) return [];
        if (!nodes) return [targetNode];
      } else {
        if (!root.sourceIndex || root.sourceIndex < 1) {
          var nodes = root.getElementsByTagName('*');
          for (var j = 0, node; node = nodes[j]; j++) {
            if (node.id === id) return [node];
          }
        }
      }

      if (nodes) {
        if (combinator) {
          if (combinator == 'child') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (targetNode.parentNode == node) return [targetNode];
          } else if (combinator == 'descendant') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Element.descendantOf(targetNode, node)) return [targetNode];
          } else if (combinator == 'adjacent') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Selector.handlers.previousElementSibling(targetNode) == node)
                return [targetNode];
          } else nodes = h[combinator](nodes);
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node == targetNode) return [targetNode];
        return [];
      }
      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
    },

    className: function(nodes, root, className, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      return Selector.handlers.byClassName(nodes, root, className);
    },

    byClassName: function(nodes, root, className) {
      if (!nodes) nodes = Selector.handlers.descendant([root]);
      var needle = ' ' + className + ' ';
      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
        nodeClassName = node.className;
        if (nodeClassName.length == 0) continue;
        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
          results.push(node);
      }
      return results;
    },

    attrPresence: function(nodes, root, attr, combinator) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      if (nodes && combinator) nodes = this[combinator](nodes);
      var results = [];
      for (var i = 0, node; node = nodes[i]; i++)
        if (Element.hasAttribute(node, attr)) results.push(node);
      return results;
    },

    attr: function(nodes, root, attr, value, operator, combinator) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      if (nodes && combinator) nodes = this[combinator](nodes);
      var handler = Selector.operators[operator], results = [];
      for (var i = 0, node; node = nodes[i]; i++) {
        var nodeValue = Element.readAttribute(node, attr);
        if (nodeValue === null) continue;
        if (handler(nodeValue, value)) results.push(node);
      }
      return results;
    },

    pseudo: function(nodes, name, value, root, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      if (!nodes) nodes = root.getElementsByTagName("*");
      return Selector.pseudos[name](nodes, value, root);
    }
  },

  pseudos: {
    'first-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.previousElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'last-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.nextElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'only-child': function(nodes, value, root) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
          results.push(node);
      return results;
    },
    'nth-child':        function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root);
    },
    'nth-last-child':   function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true);
    },
    'nth-of-type':      function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, false, true);
    },
    'nth-last-of-type': function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true, true);
    },
    'first-of-type':    function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, false, true);
    },
    'last-of-type':     function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, true, true);
    },
    'only-of-type':     function(nodes, formula, root) {
      var p = Selector.pseudos;
      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
    },

    getIndices: function(a, b, total) {
      if (a == 0) return b > 0 ? [b] : [];
      return $R(1, total).inject([], function(memo, i) {
        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
        return memo;
      });
    },

    nth: function(nodes, formula, root, reverse, ofType) {
      if (nodes.length == 0) return [];
      if (formula == 'even') formula = '2n+0';
      if (formula == 'odd')  formula = '2n+1';
      var h = Selector.handlers, results = [], indexed = [], m;
      h.mark(nodes);
      for (var i = 0, node; node = nodes[i]; i++) {
        if (!node.parentNode._countedByPrototype) {
          h.index(node.parentNode, reverse, ofType);
          indexed.push(node.parentNode);
        }
      }
      if (formula.match(/^\d+$/)) { // just a number
        formula = Number(formula);
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.nodeIndex == formula) results.push(node);
      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
        if (m[1] == "-") m[1] = -1;
        var a = m[1] ? Number(m[1]) : 1;
        var b = m[2] ? Number(m[2]) : 0;
        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
          for (var j = 0; j < l; j++)
            if (node.nodeIndex == indices[j]) results.push(node);
        }
      }
      h.unmark(nodes);
      h.unmark(indexed);
      return results;
    },

    'empty': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (node.tagName == '!' || node.firstChild) continue;
        results.push(node);
      }
      return results;
    },

    'not': function(nodes, selector, root) {
      var h = Selector.handlers, selectorType, m;
      var exclusions = new Selector(selector).findElements(root);
      h.mark(exclusions);
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node._countedByPrototype) results.push(node);
      h.unmark(exclusions);
      return results;
    },

    'enabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node.disabled && (!node.type || node.type !== 'hidden'))
          results.push(node);
      return results;
    },

    'disabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.disabled) results.push(node);
      return results;
    },

    'checked': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.checked) results.push(node);
      return results;
    }
  },

  operators: {
    '=':  function(nv, v) { return nv == v; },
    '!=': function(nv, v) { return nv != v; },
    '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
    '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
    '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
    '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
     '-').include('-' + (v || "").toUpperCase() + '-'); }
  },

  split: function(expression) {
    var expressions = [];
    expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
      expressions.push(m[1].strip());
    });
    return expressions;
  },

  matchElements: function(elements, expression) {
    var matches = $$(expression), h = Selector.handlers;
    h.mark(matches);
    for (var i = 0, results = [], element; element = elements[i]; i++)
      if (element._countedByPrototype) results.push(element);
    h.unmark(matches);
    return results;
  },

  findElement: function(elements, expression, index) {
    if (Object.isNumber(expression)) {
      index = expression; expression = false;
    }
    return Selector.matchElements(elements, expression || '*')[index || 0];
  },

  findChildElements: function(element, expressions) {
    expressions = Selector.split(expressions.join(','));
    var results = [], h = Selector.handlers;
    for (var i = 0, l = expressions.length, selector; i < l; i++) {
      selector = new Selector(expressions[i].strip());
      h.concat(results, selector.findElements(element));
    }
    return (l > 1) ? h.unique(results) : results;
  }
});

if (Prototype.Browser.IE) {
  Object.extend(Selector.handlers, {
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        if (node.tagName !== "!") a.push(node);
      return a;
    }
  });
}

function $$() {
  return Selector.findChildElements(document, $A(arguments));
}

var Form = {
  reset: function(form) {
    form = $(form);
    form.reset();
    return form;
  },

  serializeElements: function(elements, options) {
    if (typeof options != 'object') options = { hash: !!options };
    else if (Object.isUndefined(options.hash)) options.hash = true;
    var key, value, submitted = false, submit = options.submit;

    var data = elements.inject({ }, function(result, element) {
      if (!element.disabled && element.name) {
        key = element.name; value = $(element).getValue();
        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
            submit !== false && (!submit || key == submit) && (submitted = true)))) {
          if (key in result) {
            if (!Object.isArray(result[key])) result[key] = [result[key]];
            result[key].push(value);
          }
          else result[key] = value;
        }
      }
      return result;
    });

    return options.hash ? data : Object.toQueryString(data);
  }
};

Form.Methods = {
  serialize: function(form, options) {
    return Form.serializeElements(Form.getElements(form), options);
  },

  getElements: function(form) {
    var elements = $(form).getElementsByTagName('*'),
        element,
        arr = [ ],
        serializers = Form.Element.Serializers;
    for (var i = 0; element = elements[i]; i++) {
      arr.push(element);
    }
    return arr.inject([], function(elements, child) {
      if (serializers[child.tagName.toLowerCase()])
        elements.push(Element.extend(child));
      return elements;
    })
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name) return $A(inputs).map(Element.extend);

    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) || (name && input.name != name))
        continue;
      matchingInputs.push(Element.extend(input));
    }

    return matchingInputs;
  },

  disable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('disable');
    return form;
  },

  enable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('enable');
    return form;
  },

  findFirstElement: function(form) {
    var elements = $(form).getElements().findAll(function(element) {
      return 'hidden' != element.type && !element.disabled;
    });
    var firstByIndex = elements.findAll(function(element) {
      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
    }).sortBy(function(element) { return element.tabIndex }).first();

    return firstByIndex ? firstByIndex : elements.find(function(element) {
      return /^(?:input|select|textarea)$/i.test(element.tagName);
    });
  },

  focusFirstElement: function(form) {
    form = $(form);
    form.findFirstElement().activate();
    return form;
  },

  request: function(form, options) {
    form = $(form), options = Object.clone(options || { });

    var params = options.parameters, action = form.readAttribute('action') || '';
    if (action.blank()) action = window.location.href;
    options.parameters = form.serialize(true);

    if (params) {
      if (Object.isString(params)) params = params.toQueryParams();
      Object.extend(options.parameters, params);
    }

    if (form.hasAttribute('method') && !options.method)
      options.method = form.method;

    return new Ajax.Request(action, options);
  }
};

/*--------------------------------------------------------------------------*/


Form.Element = {
  focus: function(element) {
    $(element).focus();
    return element;
  },

  select: function(element) {
    $(element).select();
    return element;
  }
};

Form.Element.Methods = {

  serialize: function(element) {
    element = $(element);
    if (!element.disabled && element.name) {
      var value = element.getValue();
      if (value != undefined) {
        var pair = { };
        pair[element.name] = value;
        return Object.toQueryString(pair);
      }
    }
    return '';
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    return Form.Element.Serializers[method](element);
  },

  setValue: function(element, value) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    Form.Element.Serializers[method](element, value);
    return element;
  },

  clear: function(element) {
    $(element).value = '';
    return element;
  },

  present: function(element) {
    return $(element).value != '';
  },

  activate: function(element) {
    element = $(element);
    try {
      element.focus();
      if (element.select && (element.tagName.toLowerCase() != 'input' ||
          !(/^(?:button|reset|submit)$/i.test(element.type))))
        element.select();
    } catch (e) { }
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.disabled = true;
    return element;
  },

  enable: function(element) {
    element = $(element);
    element.disabled = false;
    return element;
  }
};

/*--------------------------------------------------------------------------*/

var Field = Form.Element;

var $F = Form.Element.Methods.getValue;

/*--------------------------------------------------------------------------*/

Form.Element.Serializers = {
  input: function(element, value) {
    switch (element.type.toLowerCase()) {
      case 'checkbox':
      case 'radio':
        return Form.Element.Serializers.inputSelector(element, value);
      default:
        return Form.Element.Serializers.textarea(element, value);
    }
  },

  inputSelector: function(element, value) {
    if (Object.isUndefined(value)) return element.checked ? element.value : null;
    else element.checked = !!value;
  },

  textarea: function(element, value) {
    if (Object.isUndefined(value)) return element.value;
    else element.value = value;
  },

  select: function(element, value) {
    if (Object.isUndefined(value))
      return this[element.type == 'select-one' ?
        'selectOne' : 'selectMany'](element);
    else {
      var opt, currentValue, single = !Object.isArray(value);
      for (var i = 0, length = element.length; i < length; i++) {
        opt = element.options[i];
        currentValue = this.optionValue(opt);
        if (single) {
          if (currentValue == value) {
            opt.selected = true;
            return;
          }
        }
        else opt.selected = value.include(currentValue);
      }
    }
  },

  selectOne: function(element) {
    var index = element.selectedIndex;
    return index >= 0 ? this.optionValue(element.options[index]) : null;
  },

  selectMany: function(element) {
    var values, length = element.length;
    if (!length) return null;

    for (var i = 0, values = []; i < length; i++) {
      var opt = element.options[i];
      if (opt.selected) values.push(this.optionValue(opt));
    }
    return values;
  },

  optionValue: function(opt) {
    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
  }
};

/*--------------------------------------------------------------------------*/


Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
  initialize: function($super, element, frequency, callback) {
    $super(callback, frequency);
    this.element   = $(element);
    this.lastValue = this.getValue();
  },

  execute: function() {
    var value = this.getValue();
    if (Object.isString(this.lastValue) && Object.isString(value) ?
        this.lastValue != value : String(this.lastValue) != String(value)) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  }
});

Form.Element.Observer = Class.create(Abstract.TimedObserver, {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create(Abstract.TimedObserver, {
  getValue: function() {
    return Form.serialize(this.element);
  }
});

/*--------------------------------------------------------------------------*/

Abstract.EventObserver = Class.create({
  initialize: function(element, callback) {
    this.element  = $(element);
    this.callback = callback;

    this.lastValue = this.getValue();
    if (this.element.tagName.toLowerCase() == 'form')
      this.registerFormCallbacks();
    else
      this.registerCallback(this.element);
  },

  onElementEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  },

  registerFormCallbacks: function() {
    Form.getElements(this.element).each(this.registerCallback, this);
  },

  registerCallback: function(element) {
    if (element.type) {
      switch (element.type.toLowerCase()) {
        case 'checkbox':
        case 'radio':
          Event.observe(element, 'click', this.onElementEvent.bind(this));
          break;
        default:
          Event.observe(element, 'change', this.onElementEvent.bind(this));
          break;
      }
    }
  }
});

Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.EventObserver = Class.create(Abstract.EventObserver, {
  getValue: function() {
    return Form.serialize(this.element);
  }
});
(function() {

  var Event = {
    KEY_BACKSPACE: 8,
    KEY_TAB:       9,
    KEY_RETURN:   13,
    KEY_ESC:      27,
    KEY_LEFT:     37,
    KEY_UP:       38,
    KEY_RIGHT:    39,
    KEY_DOWN:     40,
    KEY_DELETE:   46,
    KEY_HOME:     36,
    KEY_END:      35,
    KEY_PAGEUP:   33,
    KEY_PAGEDOWN: 34,
    KEY_INSERT:   45,

    cache: {}
  };

  var docEl = document.documentElement;
  var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
    && 'onmouseleave' in docEl;

  var _isButton;
  if (Prototype.Browser.IE) {
    var buttonMap = { 0: 1, 1: 4, 2: 2 };
    _isButton = function(event, code) {
      return event.button === buttonMap[code];
    };
  } else if (Prototype.Browser.WebKit) {
    _isButton = function(event, code) {
      switch (code) {
        case 0: return event.which == 1 && !event.metaKey;
        case 1: return event.which == 1 && event.metaKey;
        default: return false;
      }
    };
  } else {
    _isButton = function(event, code) {
      return event.which ? (event.which === code + 1) : (event.button === code);
    };
  }

  function isLeftClick(event)   { return _isButton(event, 0) }

  function isMiddleClick(event) { return _isButton(event, 1) }

  function isRightClick(event)  { return _isButton(event, 2) }

  function element(event) {
    event = Event.extend(event);

    var node = event.target, type = event.type,
     currentTarget = event.currentTarget;

    if (currentTarget && currentTarget.tagName) {
      if (type === 'load' || type === 'error' ||
        (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
          && currentTarget.type === 'radio'))
            node = currentTarget;
    }

    if (node.nodeType == Node.TEXT_NODE)
      node = node.parentNode;

    return Element.extend(node);
  }

  function findElement(event, expression) {
    var element = Event.element(event);
    if (!expression) return element;
    var elements = [element].concat(element.ancestors());
    return Selector.findElement(elements, expression, 0);
  }

  function pointer(event) {
    return { x: pointerX(event), y: pointerY(event) };
  }

  function pointerX(event) {
    var docElement = document.documentElement,
     body = document.body || { scrollLeft: 0 };

    return event.pageX || (event.clientX +
      (docElement.scrollLeft || body.scrollLeft) -
      (docElement.clientLeft || 0));
  }

  function pointerY(event) {
    var docElement = document.documentElement,
     body = document.body || { scrollTop: 0 };

    return  event.pageY || (event.clientY +
       (docElement.scrollTop || body.scrollTop) -
       (docElement.clientTop || 0));
  }


  function stop(event) {
    Event.extend(event);
    event.preventDefault();
    event.stopPropagation();

    event.stopped = true;
  }

  Event.Methods = {
    isLeftClick: isLeftClick,
    isMiddleClick: isMiddleClick,
    isRightClick: isRightClick,

    element: element,
    findElement: findElement,

    pointer: pointer,
    pointerX: pointerX,
    pointerY: pointerY,

    stop: stop
  };


  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
    m[name] = Event.Methods[name].methodize();
    return m;
  });

  if (Prototype.Browser.IE) {
    function _relatedTarget(event) {
      var element;
      switch (event.type) {
        case 'mouseover': element = event.fromElement; break;
        case 'mouseout':  element = event.toElement;   break;
        default: return null;
      }
      return Element.extend(element);
    }

    Object.extend(methods, {
      stopPropagation: function() { this.cancelBubble = true },
      preventDefault:  function() { this.returnValue = false },
      inspect: function() { return '[object Event]' }
    });

    Event.extend = function(event, element) {
      if (!event) return false;
      if (event._extendedByPrototype) return event;

      event._extendedByPrototype = Prototype.emptyFunction;
      var pointer = Event.pointer(event);

      Object.extend(event, {
        target: event.srcElement || element,
        relatedTarget: _relatedTarget(event),
        pageX:  pointer.x,
        pageY:  pointer.y
      });

      return Object.extend(event, methods);
    };
  } else {
    Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
    Object.extend(Event.prototype, methods);
    Event.extend = Prototype.K;
  }

  function _createResponder(element, eventName, handler) {
    var registry = Element.retrieve(element, 'prototype_event_registry');

    if (Object.isUndefined(registry)) {
      CACHE.push(element);
      registry = Element.retrieve(element, 'prototype_event_registry', $H());
    }

    var respondersForEvent = registry.get(eventName);
    if (Object.isUndefined(respondersForEvent)) {
      respondersForEvent = [];
      registry.set(eventName, respondersForEvent);
    }

    if (respondersForEvent.pluck('handler').include(handler)) return false;

    var responder;
    if (eventName.include(":")) {
      responder = function(event) {
        if (Object.isUndefined(event.eventName))
          return false;

        if (event.eventName !== eventName)
          return false;

        Event.extend(event, element);
        handler.call(element, event);
      };
    } else {
      if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
       (eventName === "mouseenter" || eventName === "mouseleave")) {
        if (eventName === "mouseenter" || eventName === "mouseleave") {
          responder = function(event) {
            Event.extend(event, element);

            var parent = event.relatedTarget;
            while (parent && parent !== element) {
              try { parent = parent.parentNode; }
              catch(e) { parent = element; }
            }

            if (parent === element) return;

            handler.call(element, event);
          };
        }
      } else {
        responder = function(event) {
          Event.extend(event, element);
          handler.call(element, event);
        };
      }
    }

    responder.handler = handler;
    respondersForEvent.push(responder);
    return responder;
  }

  function _destroyCache() {
    for (var i = 0, length = CACHE.length; i < length; i++) {
      Event.stopObserving(CACHE[i]);
      CACHE[i] = null;
    }
  }

  var CACHE = [];

  if (Prototype.Browser.IE)
    window.attachEvent('onunload', _destroyCache);

  if (Prototype.Browser.WebKit)
    window.addEventListener('unload', Prototype.emptyFunction, false);


  var _getDOMEventName = Prototype.K;

  if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
    _getDOMEventName = function(eventName) {
      var translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
      return eventName in translations ? translations[eventName] : eventName;
    };
  }

  function observe(element, eventName, handler) {
    element = $(element);

    var responder = _createResponder(element, eventName, handler);

    if (!responder) return element;

    if (eventName.include(':')) {
      if (element.addEventListener)
        element.addEventListener("dataavailable", responder, false);
      else {
        element.attachEvent("ondataavailable", responder);
        element.attachEvent("onfilterchange", responder);
      }
    } else {
      var actualEventName = _getDOMEventName(eventName);

      if (element.addEventListener)
        element.addEventListener(actualEventName, responder, false);
      else
        element.attachEvent("on" + actualEventName, responder);
    }

    return element;
  }

  function stopObserving(element, eventName, handler) {
    element = $(element);

    var registry = Element.retrieve(element, 'prototype_event_registry');

    if (Object.isUndefined(registry)) return element;

    if (eventName && !handler) {
      var responders = registry.get(eventName);

      if (Object.isUndefined(responders)) return element;

      responders.each( function(r) {
        Element.stopObserving(element, eventName, r.handler);
      });
      return element;
    } else if (!eventName) {
      registry.each( function(pair) {
        var eventName = pair.key, responders = pair.value;

        responders.each( function(r) {
          Element.stopObserving(element, eventName, r.handler);
        });
      });
      return element;
    }

    var responders = registry.get(eventName);

    if (!responders) return;

    var responder = responders.find( function(r) { return r.handler === handler; });
    if (!responder) return element;

    var actualEventName = _getDOMEventName(eventName);

    if (eventName.include(':')) {
      if (element.removeEventListener)
        element.removeEventListener("dataavailable", responder, false);
      else {
        element.detachEvent("ondataavailable", responder);
        element.detachEvent("onfilterchange",  responder);
      }
    } else {
      if (element.removeEventListener)
        element.removeEventListener(actualEventName, responder, false);
      else
        element.detachEvent('on' + actualEventName, responder);
    }

    registry.set(eventName, responders.without(responder));

    return element;
  }

  function fire(element, eventName, memo, bubble) {
    element = $(element);

    if (Object.isUndefined(bubble))
      bubble = true;

    if (element == document && document.createEvent && !element.dispatchEvent)
      element = document.documentElement;

    var event;
    if (document.createEvent) {
      event = document.createEvent('HTMLEvents');
      event.initEvent('dataavailable', true, true);
    } else {
      event = document.createEventObject();
      event.eventType = bubble ? 'ondataavailable' : 'onfilterchange';
    }

    event.eventName = eventName;
    event.memo = memo || { };

    if (document.createEvent)
      element.dispatchEvent(event);
    else
      element.fireEvent(event.eventType, event);

    return Event.extend(event);
  }


  Object.extend(Event, Event.Methods);

  Object.extend(Event, {
    fire:          fire,
    observe:       observe,
    stopObserving: stopObserving
  });

  Element.addMethods({
    fire:          fire,

    observe:       observe,

    stopObserving: stopObserving
  });

  Object.extend(document, {
    fire:          fire.methodize(),

    observe:       observe.methodize(),

    stopObserving: stopObserving.methodize(),

    loaded:        false
  });

  if (window.Event) Object.extend(window.Event, Event);
  else window.Event = Event;
})();

(function() {
  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
     Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */

  var timer;

  function fireContentLoadedEvent() {
    if (document.loaded) return;
    if (timer) window.clearTimeout(timer);
    document.loaded = true;
    document.fire('dom:loaded');
  }

  function checkReadyState() {
    if (document.readyState === 'complete') {
      document.stopObserving('readystatechange', checkReadyState);
      fireContentLoadedEvent();
    }
  }

  function pollDoScroll() {
    try { document.documentElement.doScroll('left'); }
    catch(e) {
      timer = pollDoScroll.defer();
      return;
    }
    fireContentLoadedEvent();
  }

  if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
  } else {
    document.observe('readystatechange', checkReadyState);
    if (window == top)
      timer = pollDoScroll.defer();
  }

  Event.observe(window, 'load', fireContentLoadedEvent);
})();

Element.addMethods();

/*------------------------------- DEPRECATED -------------------------------*/

Hash.toQueryString = Object.toQueryString;

var Toggle = { display: Element.toggle };

Element.Methods.childOf = Element.Methods.descendantOf;

var Insertion = {
  Before: function(element, content) {
    return Element.insert(element, {before:content});
  },

  Top: function(element, content) {
    return Element.insert(element, {top:content});
  },

  Bottom: function(element, content) {
    return Element.insert(element, {bottom:content});
  },

  After: function(element, content) {
    return Element.insert(element, {after:content});
  }
};

var $continue = new Error('"throw $continue" is deprecated, use "return" instead');

var Position = {
  includeScrollOffsets: false,

  prepare: function() {
    this.deltaX =  window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0;
    this.deltaY =  window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0;
  },

  within: function(element, x, y) {
    if (this.includeScrollOffsets)
      return this.withinIncludingScrolloffsets(element, x, y);
    this.xcomp = x;
    this.ycomp = y;
    this.offset = Element.cumulativeOffset(element);

    return (y >= this.offset[1] &&
            y <  this.offset[1] + element.offsetHeight &&
            x >= this.offset[0] &&
            x <  this.offset[0] + element.offsetWidth);
  },

  withinIncludingScrolloffsets: function(element, x, y) {
    var offsetcache = Element.cumulativeScrollOffset(element);

    this.xcomp = x + offsetcache[0] - this.deltaX;
    this.ycomp = y + offsetcache[1] - this.deltaY;
    this.offset = Element.cumulativeOffset(element);

    return (this.ycomp >= this.offset[1] &&
            this.ycomp <  this.offset[1] + element.offsetHeight &&
            this.xcomp >= this.offset[0] &&
            this.xcomp <  this.offset[0] + element.offsetWidth);
  },

  overlap: function(mode, element) {
    if (!mode) return 0;
    if (mode == 'vertical')
      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
        element.offsetHeight;
    if (mode == 'horizontal')
      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
        element.offsetWidth;
  },


  cumulativeOffset: Element.Methods.cumulativeOffset,

  positionedOffset: Element.Methods.positionedOffset,

  absolutize: function(element) {
    Position.prepare();
    return Element.absolutize(element);
  },

  relativize: function(element) {
    Position.prepare();
    return Element.relativize(element);
  },

  realOffset: Element.Methods.cumulativeScrollOffset,

  offsetParent: Element.Methods.getOffsetParent,

  page: Element.Methods.viewportOffset,

  clone: function(source, target, options) {
    options = options || { };
    return Element.clonePosition(target, source, options);
  }
};

/*--------------------------------------------------------------------------*/

if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
  function iter(name) {
    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
  }

  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
  function(element, className) {
    className = className.toString().strip();
    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
  } : function(element, className) {
    className = className.toString().strip();
    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
    if (!classNames && !className) return elements;

    var nodes = $(element).getElementsByTagName('*');
    className = ' ' + className + ' ';

    for (var i = 0, child, cn; child = nodes[i]; i++) {
      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
          (classNames && classNames.all(function(name) {
            return !name.toString().blank() && cn.include(' ' + name + ' ');
          }))))
        elements.push(Element.extend(child));
    }
    return elements;
  };

  return function(className, parentElement) {
    return $(parentElement || document.body).getElementsByClassName(className);
  };
}(Element.Methods);

/*--------------------------------------------------------------------------*/

Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
  initialize: function(element) {
    this.element = $(element);
  },

  _each: function(iterator) {
    this.element.className.split(/\s+/).select(function(name) {
      return name.length > 0;
    })._each(iterator);
  },

  set: function(className) {
    this.element.className = className;
  },

  add: function(classNameToAdd) {
    if (this.include(classNameToAdd)) return;
    this.set($A(this).concat(classNameToAdd).join(' '));
  },

  remove: function(classNameToRemove) {
    if (!this.include(classNameToRemove)) return;
    this.set($A(this).without(classNameToRemove).join(' '));
  },

  toString: function() {
    return $A(this).join(' ');
  }
};

Object.extend(Element.ClassNames.prototype, Enumerable);

/*--------------------------------------------------------------------------*/

Object.extend(document, {
    isDocReady: false,
    isDocLoaded: false,
    ready: function(fn) { Event.observe(document, "doc:ready", fn); },
    load: function(fn) { Event.observe(document, "doc:loaded", fn); }
});
Event.observe(document, "dom:loaded", function() {
    Event.fire(document, "doc:ready");
    document.isDocReady = true;
    if (document.isDocLoaded)
        Event.fire(document, "doc:loaded");
});
Event.observe(window, "load", function() {
    document.isDocLoaded = true;
    if (!document.isDocReady) return;
    Event.fire(document, "doc:loaded");
});
Event.observe(document, "click", function() {
    hideFilter.apply(this, arguments);
});


/* Use the two following functions */
document.ready(function(){
    //ok to run some code
});
document.load(function(){
    //ok for DOM manipulation
    Event.observe(document.body, 'mouseup', function(e) {
    	irwButtonPressed = false;
    });
    // Add mouseevts for IE for color filter header
    if (Prototype.Browser.IE){
        if($('filterByColor') != null){
            Event.observe($('filterByColor'), "mouseover", function() {
                toggleFilterColorBg();
            });
            Event.observe($('filterByColor'), "mouseout", function() {
                toggleFilterColorBg();
            });
        }
    }
	// Check if the base target should be set to _self since this is needed by IHP2 in the Kiosk
	if (window.dialogArguments) {
        var mArgs = window.dialogArguments;
        if (mArgs.kiosk) { 
            var vBase = document.createElement('base');
            vBase.setAttribute('target', '_self'); 
            document.getElementsByTagName('head')[0].appendChild(vBase);
        }
	}
    // Check for global slideshow array
    if(typeof(js_fn_SLIDE_SHOW_IDS) != 'undefined') {
        slideshow = new Slideshow();
	};
    
    $$('#main input').each(function(input) {    
        if (input.visible() && (input.id == 'partNumber' || input.id == 'txtQuantity' || input.id == 'quantity')) {   
            input.observe('keydown', function(event) { 
                if(event.keyCode == Event.KEY_RETURN) { 
                    if(input.up('#formShoppingListLeftNav')) {
                        // shopping list
                        onAddItemToShoppingList();
					} else if(input.up('#ArticleAddForm')) {
                        // shopping cart
                        respondToAddToCart();      
                    }
                }
			});
		}
	});
});

function irwInit() {
	if (navigator.platform.toLowerCase().indexOf('mac') != -1) {
		var css = new Element('link', {'href':'/ms/css/macos.css', 'type':'text/css', 'rel':'stylesheet'});
		$$('head')[0].insert(css);
	}
}

var irwButtonPressed = false;

/**
* This function is used by the createButton functions to prevent duplicate IDs on a page
*/
var buttons = new Hash();
function generateButtonID(_id) {
	var newid = _id;
	var counter = 0;
	if (buttons.get(newid) != null) {
		counter = parseInt(buttons.get(newid)) + 1;
		newid = _id + "_" + counter;
	}
	buttons.set(_id, counter);
	return newid;
}	

var buttonTemplate = new Template("<div class=\"buttonContainer\">" + 
    "<a id=\"#{buttonId}\" class=\"#{buttonClass}\" href=\"#\" onclick=\"return false;\">" +
        "<div class=\"buttonLeft#{buttonLeftClass}\">&nbsp;</div>" +
        "<div class=\"buttonCaption#{buttonCaptionClass}\">" + 
            "<input type=\"button\" value=\"#{buttonCaption}\" />" + 
        "</div>" + 
        "<div class=\"buttonRight#{buttonRightClass}\">&nbsp;</div>" + 
    "</a>" + 
"</div>");

var scriptTemplate = new Template("<script type=\"text/javascript\">\n" + 
    "Event.observe($('#{buttonId}'), 'click', function(e) { if (!this.hasClassName('disabledButton')) {#{buttonFunction};}});" + 
    "var input = $('#{buttonId}').down('input');" + 
    "Event.observe(input, 'mousedown' , function(e) { if (!this.hasClassName('pressed')) this.addClassName('pressed'); if (!this.hasClassName('down')) this.addClassName('down'); if (this.hasClassName('downNoMove')) this.removeClassName('downNoMove'); irwButtonPressed = true;	});" +
    "Event.observe(input, 'mouseup' , function(e) { if (this.hasClassName('down')) this.removeClassName('down'); if (this.hasClassName('pressed')) this.removeClassName('pressed'); if (this.hasClassName('downNoMove')) this.removeClassName('downNoMove'); });" +
    "Event.observe(input, 'mouseout' , function(e) {	if (this.hasClassName('down')) this.removeClassName('down'); if (this.hasClassName('downNoMove')) this.removeClassName('downNoMove'); var a = this.up('a'); if (a.hasClassName('hover')) a.removeClassName('hover'); });" +
    "Event.observe(input, 'mouseover' , function(e) { var a = this.up('a'); if (!a.hasClassName('hover')) a.addClassName('hover'); if (this.hasClassName('pressed')) { if (irwButtonPressed) {	this.addClassName('down'); this.addClassName('downNoMove');	} else { this.removeClassName('pressed');	}	}	});" +
"</script>");

/**
* Creates new button with caption, class and listener function
* The listener function only executes if the button is enabled,
* that is the button does not contains the class 'disabledButton' 
*
* Each button gets a unique id, like irw_button_1, irw_button_2, etc.
* The function returns the generated ID
*/
function createButton(_caption, _id, _class, _func) {
	//check if there is only three parameters
	if (typeof(_func) == "undefined") {
		//assume that no id is specified
		_func = _class;
		_class = _id;
		_id = "irw_button";
	}
	var newid = generateButtonID(_id);
	var obj = new Object();
	obj.buttonId = newid;
	obj.buttonClass = _class;
	obj.buttonCaption = _caption;
	obj.buttonSize = _caption.length;
	obj.buttonLeftClass = "";
	obj.buttonCaptionClass = "";
	obj.buttonRightClass = "";	
	var reg = new RegExp("([a-zA-Z]+)Button","g");
	var m = null;
	var c = "";
	while (m = reg.exec(_class)) {
		if (m[1] != "disabled") {
			c += " " + m[1];
		}
	}
	if (c.length > 0) {
		var tmp = c.substring(1).split(' ');
		for (var i=0;i<tmp.length;i++) {
			obj.buttonLeftClass += " " + "buttonLeft" + tmp[i].substring(0,1).toUpperCase() + tmp[i].substring(1);
			obj.buttonCaptionClass += " " + "buttonCaption" + tmp[i].substring(0,1).toUpperCase() + tmp[i].substring(1);
			obj.buttonRightClass += " " + "buttonRight" + tmp[i].substring(0,1).toUpperCase() + tmp[i].substring(1);
		}
	}
	document.write(buttonTemplate.evaluate(obj));
	Event.observe($(newid), 'click', function(e) {
		if (!this.hasClassName('disabledButton')) {
			_func(e); 
		}
	});
	var input = $(newid).down('input');
	Event.observe(input, 'mousedown' , function(e) {
		if (!this.hasClassName('pressed')) this.addClassName('pressed');	
		if (!this.hasClassName('down')) this.addClassName('down');
		if (this.hasClassName('downNoMove')) this.removeClassName('downNoMove');
		irwButtonPressed = true;
	});
	Event.observe(input, 'mouseup' , function(e) {
		if (this.hasClassName('down')) this.removeClassName('down');
		if (this.hasClassName('pressed')) this.removeClassName('pressed');			
		if (this.hasClassName('downNoMove')) this.removeClassName('downNoMove');
	});
	Event.observe(input, 'mouseout' , function(e) {
		if (this.hasClassName('down')) this.removeClassName('down');
		if (this.hasClassName('downNoMove')) this.removeClassName('downNoMove');
		var a = this.up('a');
		if (a.hasClassName('hover')) a.removeClassName('hover');
	});
	Event.observe(input, 'mouseover' , function(e) {
		var a = this.up('a');
		if (!a.hasClassName('hover')) a.addClassName('hover');
		if (this.hasClassName('pressed')) {
			if (irwButtonPressed) {
				this.addClassName('down');
				this.addClassName('downNoMove');				
			} else {
				this.removeClassName('pressed');
			}
		}
	});
}

/**
* This function creates a string with the button and a script tag,
* which creates the observer. It is used by commerce for creating content
* dynamically, for example in the "Add to shopping cart" popup window.
* 
* It works in the same way as the previous function, except that the _func
* parameter is a string representation of a existing javascript function
*/
function createButtonLayout(_caption, _id, _class, _func) {
	//check if there is only three parameters
	if (typeof(_func) == "undefined") {
		//assume that no id is specified
		_func = _class;
		_class = _id;
		_id = "irw_button";
	}
	var newid = generateButtonID(_id);
	var newfunc = _func + (_func.indexOf('(') == -1 ? '(e)' : '');
	var obj = new Object();
	obj.buttonId = newid;
	obj.buttonClass = _class;
	obj.buttonCaption = _caption;
	obj.buttonSize = _caption.length;
	obj.buttonLeftClass = "";
	obj.buttonCaptionClass = "";
	obj.buttonRightClass = "";
	obj.buttonFunction = newfunc;	
	var reg = new RegExp("([a-zA-Z]+)Button","g");
	var m = null;
	var c = "";
	while (m = reg.exec(_class)) {
		if (m[1] != "disabled") {
			c += " " + m[1];
		}
	}
	if (c.length > 0) {
		var tmp = c.substring(1).split(' ');
		for (var i=0;i<tmp.length;i++) {
			obj.buttonLeftClass += " " + "buttonLeft" + tmp[i].substring(0,1).toUpperCase() + tmp[i].substring(1);
			obj.buttonCaptionClass += " " + "buttonCaption" + tmp[i].substring(0,1).toUpperCase() + tmp[i].substring(1);
			obj.buttonRightClass += " " + "buttonRight" + tmp[i].substring(0,1).toUpperCase() + tmp[i].substring(1);
		}
	}
	
	return buttonTemplate.evaluate(obj) + scriptTemplate.evaluate(obj);
}

/**
* This function is used to hide all filter dropdowns (e.g. div layer)
*/
function hideFilter() {
	var iterations = 0;
	var isFilter = function(ele) {
		if (iterations++ >= 5) {
			return false;
		}
		
		if (ele.className) {
			if ((ele.className.indexOf("filterDropdowns") >= 0) || (ele.className.indexOf("filterDropdown") >= 0) || (ele.className.indexOf("filter") >= 0))  {
				return true;
			}
		}
		
		if (ele.tagName) {
			if (ele.tagName.toLowerCase() != "body") {
				return isFilter(ele.parentNode);
			}
		}
		
		return false;
	};
	if (isFilter(arguments[0].target)) return;

	$$('.filterDropdowns .filterDropdown').each(function(dd){
        dd.hide();
    });
    $$('#filterContainer .filter').each(function(btn){
        btn.removeClassName('filterActive');
    });
}

/**
* This function is used for show/hide of a filter dropdown (e.g. div layer)
* It is used on department/category pages to filter products in the product listing
* @param btn        The element clicked to show/hide dropdown
* @param filter		The dropdown layer to show/hide onclick
*/
function toggleFilter(btn,filter){
    var offL = -5;
    var offT = $('filterContainer').getHeight()-6;
    
    filter.clonePosition(btn,{setHeight:false, setWidth:false, offsetLeft:offL, offsetTop:offT});
    // Min width of dropdown should be same as button
    var btnW = btn.getWidth();
    var filterW = filter.getWidth();
    if(filterW < btnW){filter.setStyle({width:(btnW)+'px'})};
    
    // Hide all first (but myself)
    $$('.filterDropdowns .filterDropdown').each(function(dd){
        if(filter.id != dd.id){dd.hide();}
    });
    $$('#filterContainer .filter').each(function(dd){
        if(btn.id != dd.id){dd.removeClassName('filterActive');}
    });
    
    // Toggle the filter
    filter.toggle();
    btn.toggleClassName('filterActive');
}

/**
* Toggles background image (png) for color filter btn
*/
function toggleFilterColorBg(){
    var el = $$('.filter .color')[0];
    el.toggleClassName('colorHover');
}

/**
* Checks if the buyOnline container fits on the filter row. If not, displays it on the pagination row instead
* It is used on department/category pages 
*/
function printBuyOnline() {
    var fc = $('filterContainer').getWidth();
    var fbo = $('filterBuyableOnline') != null ? $('filterBuyableOnline').getWidth() : 0;
    var fbt = 0, fbc = 0, sb = 0;
    
    if($('filterByType') != null){ fbt = $('filterByType').getWidth() };
    if($('filterByColor') != null){ fbc = $('filterByColor').getWidth() };
    if($('sortBy') != null){ sb = $('sortBy').getWidth() };

    var btnW = fbt + fbc + sb;
    var contentW = fbo + btnW +5;
    
    if(contentW >= fc){
        $('paginationBuyableOnline').show();
        $('filterBuyableOnline').hide();                
    }
}

/**
* Shows all the compareRow rows in the product listing on page load. 
* This is because they should not be visible if user has no JS.
*/
function displayOfNoJsContent(){
    var prodContainer = $('productsContainer');
    if(prodContainer == null) return;
    var objects = prodContainer.select('.compareRow');
    objects.each(function(item) {
        item.show();
    });
}


/*  NLP Releated JS  */

function loadNlpProducts(placeHolder, marketCode, products) {
  //  alert(products.length);     
    var langs = marketCode.split("_");
    
    var params = "?type=xml&dataset=normal,prices,allimages,parentCategories";
    var prodTemplate = new Template("<div class=\"product\"><a class=\"image\" href=\"#{url}\"><img src=\"#{image}\" border=\"0\" /><img class=\"newLowerPriceImage\" src=\"/ms/flash/rooms_ideas/mpa2/images/logos/newlowerprice/#{market}/nlp_01.png\" border=\"0\" /></a><div class=\"name\">#{name}</div><div class=\"description\">#{description}</div><div class=\"link\"><a href=\"#{url}\">#{link}</a></div></div>");
    var btnTemplate = new Template("<a class=\"leftBtn\"   href=\"javascript:nlpMoveLeft('#{id}',#{count});\"></a><a href=\"javascript:nlpMoveRight('#{id}',#{count});\" class=\"rightBtn\"></a>");
    
    var addNlpProducts = function(xml) {

	     
        var p = xml.getElementsByTagName('product');
        var html = btnTemplate.evaluate({'id':placeHolder, 'count':products.length}); 
        html += "<div class=\"nlpClipArea\"><div class=\"products\" style=\"width:" + (142*products.length) + "px;\">";
        for (var i = 0; i < p.length; i++) {
            var obj = {};
            var item = p[i].getElementsByTagName('item')[0];
            obj.url = item.getElementsByTagName('URL')[0].childNodes[0].nodeValue;    
            obj.name = item.getElementsByTagName('name')[0].childNodes[0].nodeValue;
            obj.image = item.getElementsByTagName('images')[0].getElementsByTagName('thumb')[0].childNodes[0].childNodes[0].nodeValue;
            var price = item.getElementsByTagName('prices')[0].getElementsByTagName('normal')[0].getElementsByTagName('priceNormal')[0].childNodes[0].nodeValue;
            obj.description = products[i].description.replace('{0}',price);
            obj.link = products[i].link;
            obj.market = marketCode;
            html += prodTemplate.evaluate(obj);
        }
        html += "</div></div>";
            
        $(placeHolder).update(html);
                
    }    

    var requestUrl = "/" + langs[1].toLowerCase() + "/" + langs[0].toLowerCase() + "/catalog/products/";
    products.each(function(product) {
        requestUrl += product.id + ',';        
    });    
    requestUrl = requestUrl.substr(0,requestUrl.length-1) + params;
    
   // alert(requestUrl);
    
    new Ajax.Request(requestUrl, {
    	method: 'get',
    	contentType: 'application/xml',
    	onSuccess: function(response) {
    		addNlpProducts(response.responseXML);		
    	}
    });
            
}

function nlpMoveLeft(placeHolder, count) {
    var pDiv = $(placeHolder).select('.products')[0];
    var m = pDiv.style.width.match("([0-9]+)");
    var w = m != null && m.length > 0 ? m[0] : 0;
    var pw = w/count;
    m = pDiv.style.left.match("([0-9]+)");
    var cl = m != null && m.length > 0 ? m[0] : 0;
    var c = cl/pw;
    c = (c+count-1) % count;
    new Effect.Move(pDiv, { x: -c*pw, y: 0, mode: 'absolute', duration:0.0 });
}


function nlpMoveRight(placeHolder, count) {
    var pDiv = $(placeHolder).select('.products')[0];
    var m = pDiv.style.width.match("([0-9]+)");
    var w = m != null && m.length > 0 ? m[0] : 0;
    var pw = w/count;
    m = pDiv.style.left.match("([0-9]+)");
    var cl = m != null && m.length > 0 ? m[0] : 0;
    var c = cl/pw;
    c = (c+1) % count;
    new Effect.Move(pDiv, { x: -c*pw, y: 0, mode: 'absolute', duration:0.0 });    
}



/*  NLP Releated JS ENDS  */


/** 
    Global IOWS functions wrapped in the Iows namespace.
    Functions used to parse the IOWS xml returned and display it in HTML format.
*/

var Iows = {
    /** Base parameters for the call **/
    method: "get",
    type: "xml",
    contentType: 'application/xml',
    dataset: "normal,prices,allimages,parentCategories,attributes",

    /** Returns the value from a specific node
    * @param node       : The element representing the node
    * @param tagName    : The element representing the tagName
    * @return           : The node value if present, otherwise an empty string */
    getNodeVal: function(node,tagName){
        try{
            var val = node.getElementsByTagName(tagName)[0].firstChild.nodeValue;
        }catch(e){
            var val = "";
        }
        return val;
    },

    /** 
    * Extracts the measures from the measure node and uses a template to return the html snippet
    * @param node           : The element representing the measure node
    * @param dimTemplate    : The template to evaluate a dimension
    * @param template       : The template to evaluate and return the measures
    * @param moreText       : A string representing the "more" text
    * @param moreLink       : A string representing the link for the "more" text
    * @return               : The evaluated html snippet from the template */
    getMeasures: function(node,dimTemplate,template,moreText,moreLink){
        var measure = "";
        
        if(node != "null null" && node != "null"){
            var array = node.replace("</v></m></rm> <rm><m><d>", "</v></m><m><d>").replace("<rm><m><d>","").replace("</v></m></rm>","").split("</v></m><m><d>");
            var len = array.length;
            for (var i=0;i<len;i++){
                measure += dimTemplate.evaluate({dimension: array[i].replace("</d><v>",":&nbsp;")});
                if(i==2){break;}
            }
            measure = '<div class=\"dimensions\">' + measure + '</div>';
            
            /*if (len > 3) {
                measure = measure + template.evaluate({text: moreText, link: moreLink});
            }*/
        }
        return measure;
    },

    /** 
    * Checks if the product has any parent in series, systems or collections and returns the proper one
    * @param template   : The template to use to evaluate and return the html 
    * @param node       : The element representing the Item node
    * @return           : The evaluated html snippet from the template */
    getSSC: function(node,template){
        var categoryNames = new Array("collections","systems","series");
        var categories = node.getElementsByTagName("categories")[0];
        
        if(typeof(categories) != 'undefined' && categories != null){
            for(var i = 0; i < 3;i++){
                var tmp = categories.getElementsByTagName(categoryNames[i]);
                var category = tmp[0].getElementsByTagName("category");
                if(category != null && category.length > 0){
                    var ssc = {"name":this.getNodeVal(category[0],'name'),
                                "link":this.getNodeVal(category[0],'URL')};
                                
                    return template.evaluate(ssc);
                }
            }
        }else{
            return "";
        }
    },

    /**
    * Parses the price information an returns an object with the price information.
    * @param node   : The element representing the node
    * @return       : An object with the following properties set: price, pricePkg family, familyPkg */
    getPrices: function(node){
        var obj = new Object();
        var prices = node.getElementsByTagName("prices")[0];
        var normal = this.getPricePart(prices,"normal");
        obj.price = normal.price;
        obj.pricePkg = normal.pricePkg;
        var family = this.getPricePart(prices,"family-normal");
        obj.family = family.price;
        obj.familyPkg = family.pricePkg;
        var dual = this.getPricePart(prices,"second");
        obj.priceDual = dual.price;
        obj.priceDualPkg = dual.pricePkg;
        
        try{
            obj.prfCharge = prices.getElementsByTagName("normal")[0].getElementsByTagName("priceNormal")[0].getAttribute("prfChargeFormatted");
            obj.noPrfCharge = prices.getElementsByTagName("normal")[0].getElementsByTagName("priceNormal")[0].getAttribute("priceWithNoPrfChargeFormatted");
        }
        catch (err){}

        return obj;
    }, 

    /**
    * Retrieves the set price of a price node. 
    * The method returns "priceChanged" if set, otherwise "priceNormal" is returned.
    * @param node       : The element representing the "prices" node
    * @param tagName    : The name of the prices-node to retrieve the price from
    * @return           : An object with the following properties set: price, pricePkg */
    getPricePart: function(node,tagName){
        var obj = new Object();
        var normal = node.getElementsByTagName(tagName)[0];
        var unitPrice = node.getAttribute("unitPricePrimary");
        var suffix = "";
        var perUnit = "";
        
        // If unitprice attribute exists, add suffix to get price from PerUnit node
        if(unitPrice != null && unitPrice == "true"){
            suffix = "PerUnit";
            unitPrice = true;
        }
        
        // Test if price changed exists, else get normal price
        var price = this.getNodeVal(normal,"priceChanged"+suffix);
        if(price.blank()){
            obj.price = this.getNodeVal(normal,"priceNormal"+suffix);
            if(unitPrice){
                obj.pricePkg = this.getNodeVal(normal,"priceNormal");
                obj.price = obj.price + this.getUnitSuffix(normal,"priceNormal"+suffix);
            }
        }else{
            obj.price = price;
            if(unitPrice){
                obj.pricePkg = this.getNodeVal(normal,"priceChanged");
                obj.price = obj.price + this.getUnitSuffix(normal,"priceChanged"+suffix);
            }
        }
        
        return obj;
    },
    
    /**
    * The method returns a unit suffix from the <priceXxxxxPerUnit> node if it exists, otherwise an empty string.
    * @param node       : The element representing the price node
    * @param tagName    : The name of the price-node to retrieve the price from
    * @return           : The unit suffix  */
    getUnitSuffix: function(node,tagName){
        var suffix = "";
        try{
            var priceNode = node.getElementsByTagName(tagName)[0];
            unit = priceNode.getAttribute("unit");
            if(unit != null){
                suffix = " / " + unit;
            };
        }catch(err){};
        
        return suffix;
    }
}




// script.aculo.us effects.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008

// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
//  Justin Palmer (http://encytemedia.com/)
//  Mark Pilgrim (http://diveintomark.org/)
//  Martin Bialasinki
// 
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/ 

// converts rgb() and #xxx to #xxxxxx format,  
// returns self (or first argument) if not convertable  
String.prototype.parseColor = function() {  
  var color = '#';
  if (this.slice(0,4) == 'rgb(') {  
    var cols = this.slice(4,this.length-1).split(',');  
    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);  
  } else {  
    if (this.slice(0,1) == '#') {  
      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();  
      if (this.length==7) color = this.toLowerCase();  
    }  
  }  
  return (color.length==7 ? color : (arguments[0] || this));  
};

/*--------------------------------------------------------------------------*/

Element.collectTextNodes = function(element) {  
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue : 
      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
  }).flatten().join('');
};

Element.collectTextNodesIgnoreClass = function(element, className) {  
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue : 
      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 
        Element.collectTextNodesIgnoreClass(node, className) : ''));
  }).flatten().join('');
};

Element.setContentZoom = function(element, percent) {
  element = $(element);  
  element.setStyle({fontSize: (percent/100) + 'em'});   
  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
  return element;
};

Element.getInlineOpacity = function(element){
  return $(element).style.opacity || '';
};

Element.forceRerendering = function(element) {
  try {
    element = $(element);
    var n = document.createTextNode(' ');
    element.appendChild(n);
    element.removeChild(n);
  } catch(e) { }
};

/*--------------------------------------------------------------------------*/

var Effect = {
  _elementDoesNotExistError: {
    name: 'ElementDoesNotExistError',
    message: 'The specified DOM element does not exist, but is required for this effect to operate'
  },
  Transitions: {
    linear: Prototype.K,
    sinoidal: function(pos) {
      return (-Math.cos(pos*Math.PI)/2) + 0.5;
    },
    reverse: function(pos) {
      return 1-pos;
    },
    flicker: function(pos) {
      var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
      return pos > 1 ? 1 : pos;
    },
    wobble: function(pos) {
      return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
    },
    pulse: function(pos, pulses) { 
      pulses = pulses || 5; 
      return (
        ((pos % (1/pulses)) * pulses).round() == 0 ? 
              ((pos * pulses * 2) - (pos * pulses * 2).floor()) : 
          1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
        );
    },
    spring: function(pos) { 
      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); 
    },
    none: function(pos) {
      return 0;
    },
    full: function(pos) {
      return 1;
    }
  },
  DefaultOptions: {
    duration:   1.0,   // seconds
    fps:        100,   // 100= assume 66fps max.
    sync:       false, // true for combining
    from:       0.0,
    to:         1.0,
    delay:      0.0,
    queue:      'parallel'
  },
  tagifyText: function(element) {
    var tagifyStyle = 'position:relative';
    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
    
    element = $(element);
    $A(element.childNodes).each( function(child) {
      if (child.nodeType==3) {
        child.nodeValue.toArray().each( function(character) {
          element.insertBefore(
            new Element('span', {style: tagifyStyle}).update(
              character == ' ' ? String.fromCharCode(160) : character), 
              child);
        });
        Element.remove(child);
      }
    });
  },
  multiple: function(element, effect) {
    var elements;
    if (((typeof element == 'object') || 
        Object.isFunction(element)) && 
       (element.length))
      elements = element;
    else
      elements = $(element).childNodes;
      
    var options = Object.extend({
      speed: 0.1,
      delay: 0.0
    }, arguments[2] || { });
    var masterDelay = options.delay;

    $A(elements).each( function(element, index) {
      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
    });
  },
  PAIRS: {
    'slide':  ['SlideDown','SlideUp'],
    'blind':  ['BlindDown','BlindUp'],
    'appear': ['Appear','Fade']
  },
  toggle: function(element, effect) {
    element = $(element);
    effect = (effect || 'appear').toLowerCase();
    var options = Object.extend({
      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
    }, arguments[2] || { });
    Effect[element.visible() ? 
      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
  }
};

Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;

/* ------------- core effects ------------- */

Effect.ScopedQueue = Class.create(Enumerable, {
  initialize: function() {
    this.effects  = [];
    this.interval = null;    
  },
  _each: function(iterator) {
    this.effects._each(iterator);
  },
  add: function(effect) {
    var timestamp = new Date().getTime();
    
    var position = Object.isString(effect.options.queue) ? 
      effect.options.queue : effect.options.queue.position;
    
    switch(position) {
      case 'front':
        // move unstarted effects after this effect  
        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
            e.startOn  += effect.finishOn;
            e.finishOn += effect.finishOn;
          });
        break;
      case 'with-last':
        timestamp = this.effects.pluck('startOn').max() || timestamp;
        break;
      case 'end':
        // start effect after last queued effect has finished
        timestamp = this.effects.pluck('finishOn').max() || timestamp;
        break;
    }
    
    effect.startOn  += timestamp;
    effect.finishOn += timestamp;

    if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
      this.effects.push(effect);
    
    if (!this.interval)
      this.interval = setInterval(this.loop.bind(this), 15);
  },
  remove: function(effect) {
    this.effects = this.effects.reject(function(e) { return e==effect });
    if (this.effects.length == 0) {
      clearInterval(this.interval);
      this.interval = null;
    }
  },
  loop: function() {
    var timePos = new Date().getTime();
    for(var i=0, len=this.effects.length;i<len;i++) 
      this.effects[i] && this.effects[i].loop(timePos);
  }
});

Effect.Queues = {
  instances: $H(),
  get: function(queueName) {
    if (!Object.isString(queueName)) return queueName;
    
    return this.instances.get(queueName) ||
      this.instances.set(queueName, new Effect.ScopedQueue());
  }
};
Effect.Queue = Effect.Queues.get('global');

Effect.Base = Class.create({
  position: null,
  start: function(options) {
    function codeForEvent(options,eventName){
      return (
        (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
        (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
      );
    }
    if (options && options.transition === false) options.transition = Effect.Transitions.linear;
    this.options      = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
    this.currentFrame = 0;
    this.state        = 'idle';
    this.startOn      = this.options.delay*1000;
    this.finishOn     = this.startOn+(this.options.duration*1000);
    this.fromToDelta  = this.options.to-this.options.from;
    this.totalTime    = this.finishOn-this.startOn;
    this.totalFrames  = this.options.fps*this.options.duration;
    
    eval('this.render = function(pos){ '+
      'if (this.state=="idle"){this.state="running";'+
      codeForEvent(this.options,'beforeSetup')+
      (this.setup ? 'this.setup();':'')+ 
      codeForEvent(this.options,'afterSetup')+
      '};if (this.state=="running"){'+
      'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
      'this.position=pos;'+
      codeForEvent(this.options,'beforeUpdate')+
      (this.update ? 'this.update(pos);':'')+
      codeForEvent(this.options,'afterUpdate')+
      '}}');
    
    this.event('beforeStart');
    if (!this.options.sync)
      Effect.Queues.get(Object.isString(this.options.queue) ? 
        'global' : this.options.queue.scope).add(this);
  },
  loop: function(timePos) {
    if (timePos >= this.startOn) {
      if (timePos >= this.finishOn) {
        this.render(1.0);
        this.cancel();
        this.event('beforeFinish');
        if (this.finish) this.finish(); 
        this.event('afterFinish');
        return;  
      }
      var pos   = (timePos - this.startOn) / this.totalTime,
          frame = (pos * this.totalFrames).round();
      if (frame > this.currentFrame) {
        this.render(pos);
        this.currentFrame = frame;
      }
    }
  },
  cancel: function() {
    if (!this.options.sync)
      Effect.Queues.get(Object.isString(this.options.queue) ? 
        'global' : this.options.queue.scope).remove(this);
    this.state = 'finished';
  },
  event: function(eventName) {
    if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
    if (this.options[eventName]) this.options[eventName](this);
  },
  inspect: function() {
    var data = $H();
    for(property in this)
      if (!Object.isFunction(this[property])) data.set(property, this[property]);
    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
  }
});

Effect.Parallel = Class.create(Effect.Base, {
  initialize: function(effects) {
    this.effects = effects || [];
    this.start(arguments[1]);
  },
  update: function(position) {
    this.effects.invoke('render', position);
  },
  finish: function(position) {
    this.effects.each( function(effect) {
      effect.render(1.0);
      effect.cancel();
      effect.event('beforeFinish');
      if (effect.finish) effect.finish(position);
      effect.event('afterFinish');
    });
  }
});

Effect.Tween = Class.create(Effect.Base, {
  initialize: function(object, from, to) {
    object = Object.isString(object) ? $(object) : object;
    var args = $A(arguments), method = args.last(), 
      options = args.length == 5 ? args[3] : null;
    this.method = Object.isFunction(method) ? method.bind(object) :
      Object.isFunction(object[method]) ? object[method].bind(object) : 
      function(value) { object[method] = value };
    this.start(Object.extend({ from: from, to: to }, options || { }));
  },
  update: function(position) {
    this.method(position);
  }
});

Effect.Event = Class.create(Effect.Base, {
  initialize: function() {
    this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
  },
  update: Prototype.emptyFunction
});

Effect.Opacity = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    // make this work on IE on elements without 'layout'
    if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
      this.element.setStyle({zoom: 1});
    var options = Object.extend({
      from: this.element.getOpacity() || 0.0,
      to:   1.0
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(position) {
    this.element.setOpacity(position);
  }
});

Effect.Move = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'relative'
    }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    this.element.makePositioned();
    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
    if (this.options.mode == 'absolute') {
      this.options.x = this.options.x - this.originalLeft;
      this.options.y = this.options.y - this.originalTop;
    }
  },
  update: function(position) {
    this.element.setStyle({
      left: (this.options.x  * position + this.originalLeft).round() + 'px',
      top:  (this.options.y  * position + this.originalTop).round()  + 'px'
    });
  }
});

// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
  return new Effect.Move(element, 
    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
};

Effect.Scale = Class.create(Effect.Base, {
  initialize: function(element, percent) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      scaleX: true,
      scaleY: true,
      scaleContent: true,
      scaleFromCenter: false,
      scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
      scaleFrom: 100.0,
      scaleTo:   percent
    }, arguments[2] || { });
    this.start(options);
  },
  setup: function() {
    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
    this.elementPositioning = this.element.getStyle('position');
    
    this.originalStyle = { };
    ['top','left','width','height','fontSize'].each( function(k) {
      this.originalStyle[k] = this.element.style[k];
    }.bind(this));
      
    this.originalTop  = this.element.offsetTop;
    this.originalLeft = this.element.offsetLeft;
    
    var fontSize = this.element.getStyle('font-size') || '100%';
    ['em','px','%','pt'].each( function(fontSizeType) {
      if (fontSize.indexOf(fontSizeType)>0) {
        this.fontSize     = parseFloat(fontSize);
        this.fontSizeType = fontSizeType;
      }
    }.bind(this));
    
    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
    
    this.dims = null;
    if (this.options.scaleMode=='box')
      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
    if (/^content/.test(this.options.scaleMode))
      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
    if (!this.dims)
      this.dims = [this.options.scaleMode.originalHeight,
                   this.options.scaleMode.originalWidth];
  },
  update: function(position) {
    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
    if (this.options.scaleContent && this.fontSize)
      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
  },
  finish: function(position) {
    if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
  },
  setDimensions: function(height, width) {
    var d = { };
    if (this.options.scaleX) d.width = width.round() + 'px';
    if (this.options.scaleY) d.height = height.round() + 'px';
    if (this.options.scaleFromCenter) {
      var topd  = (height - this.dims[0])/2;
      var leftd = (width  - this.dims[1])/2;
      if (this.elementPositioning == 'absolute') {
        if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
        if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
      } else {
        if (this.options.scaleY) d.top = -topd + 'px';
        if (this.options.scaleX) d.left = -leftd + 'px';
      }
    }
    this.element.setStyle(d);
  }
});

Effect.Highlight = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    // Prevent executing on elements not in the layout flow
    if (this.element.getStyle('display')=='none') { this.cancel(); return; }
    // Disable background image during the effect
    this.oldStyle = { };
    if (!this.options.keepBackgroundImage) {
      this.oldStyle.backgroundImage = this.element.getStyle('background-image');
      this.element.setStyle({backgroundImage: 'none'});
    }
    if (!this.options.endcolor)
      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
    if (!this.options.restorecolor)
      this.options.restorecolor = this.element.getStyle('background-color');
    // init color calculations
    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
  },
  update: function(position) {
    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
      return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
  },
  finish: function() {
    this.element.setStyle(Object.extend(this.oldStyle, {
      backgroundColor: this.options.restorecolor
    }));
  }
});

Effect.ScrollTo = function(element) {
  var options = arguments[1] || { },
    scrollOffsets = document.viewport.getScrollOffsets(),
    elementOffsets = $(element).cumulativeOffset(),
    max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();  

  if (options.offset) elementOffsets[1] += options.offset;

  return new Effect.Tween(null,
    scrollOffsets.top,
    elementOffsets[1] > max ? max : elementOffsets[1],
    options,
    function(p){ scrollTo(scrollOffsets.left, p.round()) }
  );
};

/* ------------- combination effects ------------- */

Effect.Fade = function(element) {
  element = $(element);
  var oldOpacity = element.getInlineOpacity();
  var options = Object.extend({
    from: element.getOpacity() || 1.0,
    to:   0.0,
    afterFinishInternal: function(effect) { 
      if (effect.options.to!=0) return;
      effect.element.hide().setStyle({opacity: oldOpacity}); 
    }
  }, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Appear = function(element) {
  element = $(element);
  var options = Object.extend({
  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
  to:   1.0,
  // force Safari to render floated elements properly
  afterFinishInternal: function(effect) {
    effect.element.forceRerendering();
  },
  beforeSetup: function(effect) {
    effect.element.setOpacity(effect.options.from).show(); 
  }}, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Puff = function(element) {
  element = $(element);
  var oldStyle = { 
    opacity: element.getInlineOpacity(), 
    position: element.getStyle('position'),
    top:  element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height
  };
  return new Effect.Parallel(
   [ new Effect.Scale(element, 200, 
      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
     Object.extend({ duration: 1.0, 
      beforeSetupInternal: function(effect) {
        Position.absolutize(effect.effects[0].element)
      },
      afterFinishInternal: function(effect) {
         effect.effects[0].element.hide().setStyle(oldStyle); }
     }, arguments[1] || { })
   );
};

Effect.BlindUp = function(element) {
  element = $(element);
  element.makeClipping();
  return new Effect.Scale(element, 0,
    Object.extend({ scaleContent: false, 
      scaleX: false, 
      restoreAfterFinish: true,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping();
      } 
    }, arguments[1] || { })
  );
};

Effect.BlindDown = function(element) {
  element = $(element);
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({ 
    scaleContent: false, 
    scaleX: false,
    scaleFrom: 0,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
    },  
    afterFinishInternal: function(effect) {
      effect.element.undoClipping();
    }
  }, arguments[1] || { }));
};

Effect.SwitchOff = function(element) {
  element = $(element);
  var oldOpacity = element.getInlineOpacity();
  return new Effect.Appear(element, Object.extend({
    duration: 0.4,
    from: 0,
    transition: Effect.Transitions.flicker,
    afterFinishInternal: function(effect) {
      new Effect.Scale(effect.element, 1, { 
        duration: 0.3, scaleFromCenter: true,
        scaleX: false, scaleContent: false, restoreAfterFinish: true,
        beforeSetup: function(effect) { 
          effect.element.makePositioned().makeClipping();
        },
        afterFinishInternal: function(effect) {
          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
        }
      })
    }
  }, arguments[1] || { }));
};

Effect.DropOut = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left'),
    opacity: element.getInlineOpacity() };
  return new Effect.Parallel(
    [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 
      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
    Object.extend(
      { duration: 0.5,
        beforeSetup: function(effect) {
          effect.effects[0].element.makePositioned(); 
        },
        afterFinishInternal: function(effect) {
          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
        } 
      }, arguments[1] || { }));
};

Effect.Shake = function(element) {
  element = $(element);
  var options = Object.extend({
    distance: 20,
    duration: 0.5
  }, arguments[1] || {});
  var distance = parseFloat(options.distance);
  var split = parseFloat(options.duration) / 10.0;
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left') };
    return new Effect.Move(element,
      { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
        effect.element.undoPositioned().setStyle(oldStyle);
  }}) }}) }}) }}) }}) }});
};

Effect.SlideDown = function(element) {
  element = $(element).cleanWhitespace();
  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
  var oldInnerBottom = element.down().getStyle('bottom');
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({ 
    scaleContent: false, 
    scaleX: false, 
    scaleFrom: window.opera ? 0 : 1,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makePositioned();
      effect.element.down().makePositioned();
      if (window.opera) effect.element.setStyle({top: ''});
      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
    },
    afterUpdateInternal: function(effect) {
      effect.element.down().setStyle({bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' }); 
    },
    afterFinishInternal: function(effect) {
      effect.element.undoClipping().undoPositioned();
      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
    }, arguments[1] || { })
  );
};

Effect.SlideUp = function(element) {
  element = $(element).cleanWhitespace();
  var oldInnerBottom = element.down().getStyle('bottom');
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, window.opera ? 0 : 1,
   Object.extend({ scaleContent: false, 
    scaleX: false, 
    scaleMode: 'box',
    scaleFrom: 100,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makePositioned();
      effect.element.down().makePositioned();
      if (window.opera) effect.element.setStyle({top: ''});
      effect.element.makeClipping().show();
    },  
    afterUpdateInternal: function(effect) {
      effect.element.down().setStyle({bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' });
    },
    afterFinishInternal: function(effect) {
      effect.element.hide().undoClipping().undoPositioned();
      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
    }
   }, arguments[1] || { })
  );
};

// Bug in opera makes the TD containing this element expand for a instance after finish 
Effect.Squish = function(element) {
  return new Effect.Scale(element, window.opera ? 1 : 0, { 
    restoreAfterFinish: true,
    beforeSetup: function(effect) {
      effect.element.makeClipping(); 
    },  
    afterFinishInternal: function(effect) {
      effect.element.hide().undoClipping(); 
    }
  });
};

Effect.Grow = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.full
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();    
  var initialMoveX, initialMoveY;
  var moveX, moveY;
  
  switch (options.direction) {
    case 'top-left':
      initialMoveX = initialMoveY = moveX = moveY = 0; 
      break;
    case 'top-right':
      initialMoveX = dims.width;
      initialMoveY = moveY = 0;
      moveX = -dims.width;
      break;
    case 'bottom-left':
      initialMoveX = moveX = 0;
      initialMoveY = dims.height;
      moveY = -dims.height;
      break;
    case 'bottom-right':
      initialMoveX = dims.width;
      initialMoveY = dims.height;
      moveX = -dims.width;
      moveY = -dims.height;
      break;
    case 'center':
      initialMoveX = dims.width / 2;
      initialMoveY = dims.height / 2;
      moveX = -dims.width / 2;
      moveY = -dims.height / 2;
      break;
  }
  
  return new Effect.Move(element, {
    x: initialMoveX,
    y: initialMoveY,
    duration: 0.01, 
    beforeSetup: function(effect) {
      effect.element.hide().makeClipping().makePositioned();
    },
    afterFinishInternal: function(effect) {
      new Effect.Parallel(
        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
          new Effect.Scale(effect.element, 100, {
            scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 
            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
        ], Object.extend({
             beforeSetup: function(effect) {
               effect.effects[0].element.setStyle({height: '0px'}).show(); 
             },
             afterFinishInternal: function(effect) {
               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 
             }
           }, options)
      )
    }
  });
};

Effect.Shrink = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.none
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();
  var moveX, moveY;
  
  switch (options.direction) {
    case 'top-left':
      moveX = moveY = 0;
      break;
    case 'top-right':
      moveX = dims.width;
      moveY = 0;
      break;
    case 'bottom-left':
      moveX = 0;
      moveY = dims.height;
      break;
    case 'bottom-right':
      moveX = dims.width;
      moveY = dims.height;
      break;
    case 'center':  
      moveX = dims.width / 2;
      moveY = dims.height / 2;
      break;
  }
  
  return new Effect.Parallel(
    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
    ], Object.extend({            
         beforeStartInternal: function(effect) {
           effect.effects[0].element.makePositioned().makeClipping(); 
         },
         afterFinishInternal: function(effect) {
           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
       }, options)
  );
};

Effect.Pulsate = function(element) {
  element = $(element);
  var options    = arguments[1] || { };
  var oldOpacity = element.getInlineOpacity();
  var transition = options.transition || Effect.Transitions.sinoidal;
  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
  reverser.bind(transition);
  return new Effect.Opacity(element, 
    Object.extend(Object.extend({  duration: 2.0, from: 0,
      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
    }, options), {transition: reverser}));
};

Effect.Fold = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height };
  element.makeClipping();
  return new Effect.Scale(element, 5, Object.extend({   
    scaleContent: false,
    scaleX: false,
    afterFinishInternal: function(effect) {
    new Effect.Scale(element, 1, { 
      scaleContent: false, 
      scaleY: false,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping().setStyle(oldStyle);
      } });
  }}, arguments[1] || { }));
};

Effect.Morph = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      style: { }
    }, arguments[1] || { });
    
    if (!Object.isString(options.style)) this.style = $H(options.style);
    else {
      if (options.style.include(':'))
        this.style = options.style.parseStyle();
      else {
        this.element.addClassName(options.style);
        this.style = $H(this.element.getStyles());
        this.element.removeClassName(options.style);
        var css = this.element.getStyles();
        this.style = this.style.reject(function(style) {
          return style.value == css[style.key];
        });
        options.afterFinishInternal = function(effect) {
          effect.element.addClassName(effect.options.style);
          effect.transforms.each(function(transform) {
            effect.element.style[transform.style] = '';
          });
        }
      }
    }
    this.start(options);
  },
  
  setup: function(){
    function parseColor(color){
      if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
      color = color.parseColor();
      return $R(0,2).map(function(i){
        return parseInt( color.slice(i*2+1,i*2+3), 16 ) 
      });
    }
    this.transforms = this.style.map(function(pair){
      var property = pair[0], value = pair[1], unit = null;

      if (value.parseColor('#zzzzzz') != '#zzzzzz') {
        value = value.parseColor();
        unit  = 'color';
      } else if (property == 'opacity') {
        value = parseFloat(value);
        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
          this.element.setStyle({zoom: 1});
      } else if (Element.CSS_LENGTH.test(value)) {
          var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
          value = parseFloat(components[1]);
          unit = (components.length == 3) ? components[2] : null;
      }

      var originalValue = this.element.getStyle(property);
      return { 
        style: property.camelize(), 
        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), 
        targetValue: unit=='color' ? parseColor(value) : value,
        unit: unit
      };
    }.bind(this)).reject(function(transform){
      return (
        (transform.originalValue == transform.targetValue) ||
        (
          transform.unit != 'color' &&
          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
        )
      )
    });
  },
  update: function(position) {
    var style = { }, transform, i = this.transforms.length;
    while(i--)
      style[(transform = this.transforms[i]).style] = 
        transform.unit=='color' ? '#'+
          (Math.round(transform.originalValue[0]+
            (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
          (Math.round(transform.originalValue[1]+
            (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
          (Math.round(transform.originalValue[2]+
            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
        (transform.originalValue +
          (transform.targetValue - transform.originalValue) * position).toFixed(3) + 
            (transform.unit === null ? '' : transform.unit);
    this.element.setStyle(style, true);
  }
});

Effect.Transform = Class.create({
  initialize: function(tracks){
    this.tracks  = [];
    this.options = arguments[1] || { };
    this.addTracks(tracks);
  },
  addTracks: function(tracks){
    tracks.each(function(track){
      track = $H(track);
      var data = track.values().first();
      this.tracks.push($H({
        ids:     track.keys().first(),
        effect:  Effect.Morph,
        options: { style: data }
      }));
    }.bind(this));
    return this;
  },
  play: function(){
    return new Effect.Parallel(
      this.tracks.map(function(track){
        var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
        var elements = [$(ids) || $$(ids)].flatten();
        return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
      }).flatten(),
      this.options
    );
  }
});

Element.CSS_PROPERTIES = $w(
  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 
  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
  'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
  'fontSize fontWeight height left letterSpacing lineHeight ' +
  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
  'right textIndent top width wordSpacing zIndex');
  
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;

String.__parseStyleElement = document.createElement('div');
String.prototype.parseStyle = function(){
  var style, styleRules = $H();
  if (Prototype.Browser.WebKit)
    style = new Element('div',{style:this}).style;
  else {
    String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
    style = String.__parseStyleElement.childNodes[0].style;
  }
  
  Element.CSS_PROPERTIES.each(function(property){
    if (style[property]) styleRules.set(property, style[property]); 
  });
  
  if (Prototype.Browser.IE && this.include('opacity'))
    styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);

  return styleRules;
};

if (document.defaultView && document.defaultView.getComputedStyle) {
  Element.getStyles = function(element) {
    var css = document.defaultView.getComputedStyle($(element), null);
    return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
      styles[property] = css[property];
      return styles;
    });
  };
} else {
  Element.getStyles = function(element) {
    element = $(element);
    var css = element.currentStyle, styles;
    styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
      results[property] = css[property];
      return results;
    });
    if (!styles.opacity) styles.opacity = element.getOpacity();
    return styles;
  };
};

Effect.Methods = {
  morph: function(element, style) {
    element = $(element);
    new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
    return element;
  },
  visualEffect: function(element, effect, options) {
    element = $(element)
    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
    new Effect[klass](element, options);
    return element;
  },
  highlight: function(element, options) {
    element = $(element);
    new Effect.Highlight(element, options);
    return element;
  }
};

$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
  'pulsate shake puff squish switchOff dropOut').each(
  function(effect) { 
    Effect.Methods[effect] = function(element, options){
      element = $(element);
      Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
      return element;
    }
  }
);

$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( 
  function(f) { Effect.Methods[f] = Element[f]; }
);

Element.addMethods(Effect.Methods);

/**************************************************************************** 
	The following functions are used to get, set and delete cookies
	Note: cookies are found (using getCookie) from subdomains (i.e. 
	*.domain.com) and subpaths (i.e. /path/to/calling/path/*).
	When deleting cookies, the path and domain must be the same as when set.
	
	Created by Klas Skogmar 2004-01-16
*****************************************************************************/

/**
	name - the name of the cookie. Only one cookie with the same name can exist.
	value - the value of the cookie
	path - the path (and subpaths) that the cookie should be valid for
	domain - the domain and subdomains that the cookie should be valid for
	expires - the time when the cookie will expire
*/
function setCookie(name, value, expires, path, domain, secure) {
	if(!expires) { expires = new Date(); expires.setDate(expires.getDate()+365); }
	document.cookie = name + "=" + escape(value) +
      "; expires=" + expires.toGMTString() +
      ((path) ? "; path=" + path : "") +
      ((domain) ? "; domain=" + domain : "") +
      ((secure) ? "; secure" : "");
}
function deleteCookie(name, path, domain) {
  if (getCookie(name)) {
    document.cookie = name + "=" + 
    ((path) ? "; path=" + path : "") +
    ((domain) ? "; domain=" + domain : "") +
    "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  }
}
function getCookie(name) {
	var cookie_start = document.cookie.indexOf(name + "=");
	if(cookie_start == -1) return null;
	var cookie_end = document.cookie.indexOf("; ", cookie_start);
	if(cookie_end == -1) cookie_end = document.cookie.length;
	return unescape(document.cookie.substring(cookie_start + name.length + 1, cookie_end));
}

function getCookiesEnabled(message) {
	var cookieEnabled = (navigator.cookieEnabled)?true:false

	if (typeof navigator.cookieEnabled == "undefined" && !cookieEnabled){ 
	document.cookie = "dummy"
	cookieEnabled = (document.cookie.indexOf("dummy")!= -1)?true:false
	}
	
	if (!cookieEnabled) { 
		alert(message)
		return false
	}
	return true
}

 function decode(utftext) {
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;

    while ( i < utftext.length ) {

        c = utftext.charCodeAt(i);

        if (c < 128) {
            string += String.fromCharCode(c);
            i++;
        }
        else if((c > 191) && (c < 224)) {
            c2 = utftext.charCodeAt(i+1);
            string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
            i += 2;
        }
        else {
            c2 = utftext.charCodeAt(i+1);
            c3 = utftext.charCodeAt(i+2);
            string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }
    }
    return string;
 }
  
  
function getDecodedCookie(cName){
	
	var cString = getCookie(cName);
	
	if ((cString==null)) {
      return null;
	}
	
	return decode(cString);
}  

/**
   This method is used to stores url of the page in a cookie ,
   if backToShopping META tag is present in a page. 
   This url would be used in the shopping cart page to when the user its backToShopping button
*/
function storeUrlForBackShopping(){
	var varBackToShopping;
	var cookieName="lastVisitedUrl";
	var metaTags = document.getElementsByTagName('META');
	for (var metaCount = 0; metaCount < metaTags.length; metaCount++) { 
		var item = metaTags[metaCount];   
		var itemName = item.getAttribute("NAME");
		if (itemName == null) {
			continue;
		}
		if (itemName== "backToShopping" ) {
			varBackToShopping= item.getAttribute("CONTENT");
			break;
		} 
	}
	if(varBackToShopping == "true"){
		var value=location.href;
		document.cookie=cookieName+"="+escape(value)+";path=/";
	}
}

function setSessionCookie(name, value, path, domain, secure) {
	document.cookie = name + "=" + escape(value) +
      ((path) ? "; path=" + path : "") +
      ((domain) ? "; domain=" + domain : "") +
      ((secure) ? "; secure" : "");
}
/**
   This method is used to set session cookie
*/
function setSessionCookie(name, value, path, domain, secure) {
        document.cookie = name + "=" + escape(value) +
      ((path) ? "; path=" + path : "") +
      ((domain) ? "; domain=" + domain : "") +
      ((secure) ? "; secure" : "");
}



/*
CVS Version : $Id: myaccount.js,v 1.13 2003/06/11 15:29:40 aankja Exp $

*/

function showlogoff(storeid,langid,logoffurl,linkname,confirmmsg){
if (storeid!="" && langid!="" && logoffurl!="" && linkname!="" && confirmmsg!="" && document.cookie.length > 0){
search="WCS_SESSION_ID";
offset = document.cookie.indexOf(search)

if (offset != -1) {
offset += search.length
end = document.cookie.indexOf(";", offset)
if (end == -1)
end = document.cookie.length
thevalue=unescape(document.cookie.substring(offset, end));
lastchar=thevalue.substring(thevalue.length-5,thevalue.length);
if (lastchar.indexOf(',,')==-1 && lastchar.indexOf('null')==-1 && thevalue.indexOf(storeid)!=-1 ){
document.writeln("<td>");
document.writeln("<div class=pipe>&nbsp;|&nbsp;</div>");
document.writeln("</td>");
document.writeln("<td>");
document.writeln("<script><a href=\"javascript:if(confirm('"+escape(confirmmsg)+"')){document.location='/webapp/wcs/stores/servlet/Logoff?langId="+langid+"&storeId="+storeid+"&URL="+logoffurl +"'};\" class=logout>"+linkname+"</a></" + "script>");
document.writeln("</td>");
}//write
} //offset
} //cookie
}

/**
	Enhanced version of the showlogoff function that doesn't ouput formatting
	@author KLSK
	@author BM26 (fixed bug between sites)
	@author KNBU (migrated to use WC5.6 cookie. Existing 5.4 is in a separate method OLD54haslogoffURL
	@author MTJO 2006-11-21  - (fixed problem with logout in firefox)
	@autho MAQT 2008-04-08 - Added check for cookie client_showlogoff_link
*/
function haslogoffURL(storeid){
	//document.write('<td>' + unescape(document.cookie) + '</td>');
	if (document.cookie == null) {
		// no cookie at all
		return false;
	}
	//change by maqt 080408
	//this should be the only check except for the first one. But we keep the famloggedin check becouse of the roll-out of 4.4.
	//there is also a internet explorer bug/feature that causes this cookie not to be set when logging in through the ecom flow. There's a redirect which kills the cookie.
	//therefore, we also have the old solution that check for the 12' position in one of the commerce cookies
	if (IRWreadCookie("client_showlogoff_link_" + storeid) && IRWreadCookie("client_showlogoff_link_" + storeid)=="true") {
		return true;
	}

/*

	//should be removed after fix of iebug with killed cookies in ecom redirects  /maqt
	// Split cookie
	var cookieArray = unescape(document.cookie).split(';');
	var wcauthstring = 'WC_USERSESSION_';
	var wcauthinfo = '';
	var wcstorestring = 'WC_ACTIVESTOREDATA';
	var wcstoreinfo = '';
	for (var i=0; i<cookieArray.length; i++) {
  	if (cookieArray[i].indexOf(wcauthstring) > -1) {
  		// Get authentication info
			wcauthinfo = cookieArray[i].substring(cookieArray[i].indexOf('=') + 1);
		}
		if (cookieArray[i].indexOf(wcstorestring) > -1) {
			// Get store info
			wcstoreinfo = cookieArray[i].substring(cookieArray[i].indexOf('=') + 1);
	  }
  }
	if (wcauthinfo == null || wcauthinfo == '') {
		return false;
	}

	var wcauthinfo_array = wcauthinfo.split(",");
	var wcstoreinfo_array = wcstoreinfo.split(",");

  var userId = wcauthinfo_array[0];

  var detailedInfo = wcauthinfo_array[12].substring(wcauthinfo_array[12].indexOf('[') + 1);
  var detailedInfo_array = detailedInfo.split("|");
  
var cookieStoreId = detailedInfo_array[0];


  // If 12th element is 'null' the user is not logged in
  if (wcauthinfo_array[11] == 'null') {
  	// Not logged in
  	return false;
  }

	// If the user changes store, kill the cookie
	
	if (storeid != cookieStoreId) {
 		var sDomain = document.domain;
 		
 		while (sDomain.indexOf('.') > -1) {
		  document.cookie = "WC_USERSESSION_" + userId + "=;domain=" + sDomain + ";path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		  document.cookie = "WC_AUTHENTICATION_" + userId + "=;domain=" + sDomain + ";path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		  sDomain = sDomain.substring(sDomain.indexOf('.') + 1);
		}
		//document.cookie = "WCS_ACTIVESTOREDATA=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		//document.cookie = "WCS_UNIQUE_ID=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		//document.cookie = "WCS_SSLCHECKCOOKIE=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		//document.cookie = "WCS_PARORG=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		//document.cookie = "WCS_CRNTCNTRCTS=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		//document.cookie = "WCS_ELGBCNTRCTS=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		//document.cookie = "WCS_SESSCNTRCTS=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		//document.cookie = "JSESSIONID=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		return false;
	}
*/
	// User is not logged in
	return false;

}

function setUserName() {
	var UserName=IRWreadCookie("displayname");
	if (UserName) {
		try {
			$('span_userName').update(UserName);
		} catch(e) {
		}
	}
}
function getCurrentURL(){
	var returnurl = document.location.pathname + document.location.search;
	// This is fixed in setupyouarehere.jsp..
	// var returnurl = document.location.pathname;
	return returnurl;
}

function logonLink() {
	var argForm;
	//netscape 6 && ie 5>
	if (document.getElementById){
	        argForm = document.getElementById("myAccount");
	}
	else if (document.all){ //Explorer 4
	        argForm = document.all['myAccount'];
	}
	else {
	        alert (js_fn_NOT_VALID_BROWSER);
	        return false;
	}
  argForm.submit();
}


function OLD54haslogoffURL(storeid){
	var wcssessionidcookie = getCookie("WCS_SESSION_ID");
	if (wcssessionidcookie == null) {
		//no cookie at all.
		return false;
	}

	//split variables in cookie.
	var wcssessionidcookie_array = wcssessionidcookie.split(",");

	//last String in array is the userid and if there is a user id, then user is logged in.

	var userId = wcssessionidcookie_array[wcssessionidcookie_array.length - 1];
	var loggedIn = userId != null && userId != "" && userId != "null";

	if (wcssessionidcookie_array[2] == storeid) {

		if (loggedIn) {
			//logged in customer, show logout.
			return true;
		}
		else {
			//not logged in but cookie for right country.
			return false;
		}
	}
	else {
		//User from wrong country, kill cookie.
		document.cookie = "WCS_SESSION_ID=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		document.cookie = "WCS_SSLCHECKCOOKIE=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		document.cookie = "WCS_AUTHENTICATION_ID=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		document.cookie = "WCS_PARORG=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		document.cookie = "WCS_CRNTCNTRCTS=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		document.cookie = "WCS_ELGBCNTRCTS=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		document.cookie = "WCS_SESSCNTRCTS=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		document.cookie = "JSESSIONID=;path=/;expires=Wednesday, 09-Nov-99 23:12:40 GMT";
		return false;
	}
}


//helper for reading cookie values
//added 080408 by MAQT
function IRWreadCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

/*
 * START Base64 encode/decode from http://www.webtoolkit.info/javascript-base64.html
 */

var Base64 = {

	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;

		input = Base64._utf8_encode(input);

		while (i < input.length) {

			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}

			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

		}

		return output;
	},

	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;

		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

		while (i < input.length) {

			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;

			output = output + String.fromCharCode(chr1);

			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}

		}

		output = Base64._utf8_decode(output);

		return output;

	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

}
/*
 * END Base64 encode/decode from http://www.webtoolkit.info/javascript-base64.html
 */

/**
*
*  URL encode / decode
*  http://www.webtoolkit.info/
*
**/

var Url = {

	// public method for url encoding
	encode : function (string)
	{
		string=escape(this._utf8_encode(string));
		string=string.replace(new RegExp('\\+','g'),'%2B');
		return string.replace(new RegExp('%20','g'),'+');
	},

	// public method for url decoding
	decode : function (string)
	{
		string = string.replace(new RegExp('\\+','g'),' ');
		return this._utf8_decode(unescape(string));
	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

}
/**
	Populates the logon/logoff part of the header based on user authentication state
	@author Magnus Hjersing (MHJE)
	@since CR5.1
*/	
function getUserInfo(storeID,requestType) {
    requestType = typeof(requestType) != 'undefined' ? requestType : 'async';
    if (document.cookie == null) {
            // no cookie at all -> user has never logged or doesn't support cookies
            return null;
    }

    var cookieStr = new String(document.cookie);
        
    if (!cookieStr.include("WC_")) {
        // No Commerce cookie present which means there is no session against server
            return null;
    }

    var userInfo = null;
    var displayname = null;

    if (IRWreadCookie("user_info_" + storeID)) {
        // There is a display name set
        displayname = new String(IRWreadCookie("user_info_" + storeID)).strip();
        if (displayname != null && displayname != 'notloggedin' && !displayname.blank()) {
            // The cookie is base64 and URL encoded
            decodedStr = Url.decode(Base64.decode(displayname));
            if(decodedStr != ""){
            // Ok there is a name set let's create a userinfo object to return to the header
            userInfo = new Object();
            var strArray = decodedStr.split(';');
            //for manupulating existing remembered cookie in production
             if (strArray.length < 5){
             var domain = window.location.href.replace(/^http[s]?:\/\/([^\/]+)\/.*$/, "$1"); 
             domain = domain.replace(/^.*(\.[^\.]+\.[^\.]+)$/, "$1");
             path ="/";
             deleteCookie("user_info_" + storeID, path ,domain);
             getUserInfoFromServer(storeID);
            }
            if (strArray.length > 0) {
                userInfo.firstName = unescape(strArray[0]);
            }
            if (strArray.length > 1) {
                userInfo.lastName = unescape(strArray[1]);
            }
            if (strArray.length > 2) {
                userInfo.title = unescape(strArray[2]);
            }
                //for # 215 FW11
            if (strArray.length > 3) {
             userInfo.numberShopCartItems = unescape(strArray[3]);
            }
             if (strArray.length > 4) {
             userInfo.totalPrice = unescape(strArray[4]);
            }
            }
        }
    }
    if (userInfo != null) {
        // There is info for the user to return to the header
        return userInfo;
    }
    
    if (cookieStr.include("WC_") && displayname != 'notloggedin' && requestType == 'async') {
        // No	valid displayname cookie found but there is a session with the server	
        // If displayname is set to notloggedin it just means that we already asked 
        // the server in this session
        getUserInfoFromServer(storeID);
    }

    if (cookieStr.include("WC_AUTHENTICATION") && displayname == 'notloggedin' && requestType == 'async') {
        // The cookie says the user is not logged in but there is WC cookie saying differently
        getUserInfoFromServer(storeID);
    }

    return null;
}

/**
	Retrives the display name for a known user from the server through AJAX call and
	updates the displayname cookie. If the user is not known the cookie will be set to
	"notloggedin" to avoid fetching it on every request.
	@author Magnus Hjersing (MHJE)
	@since CR5.1
*/
function getUserInfoFromServer(storeID) {
    try {
        var requestURL = '/webapp/wcs/stores/servlet/GetUserInfo?storeId='+storeID+'&extendedInfo=true';
        userRequest = new Ajax.Request(requestURL,{ 
            method: 'get', 
            onFailure: function () {
                //do nothing
            },
            onException: function (instance,object) {
                //do nothing
            },
            onInteractive: function () {
                //do nothing
            },
            onSuccess: function(transport){
                //removed as part #215
                updateWelcomeText();
                updateNoOfCartItems(storeID);
            }
        });
    } catch (e) {
        //do nothing
    }
    return;
}

function showError(str) {
	alert('error:\n'+str);
}

/**
    for #215 part FW11
*/
function generateScLinkListener(storeId) {
    var noOfItemsSpan = $('noOfCartItems');
    if(typeof noOfItemsSpan == 'undefined'  || noOfItemsSpan == null){
        return false;
    };

    var scTipDelay;
    var scTipTimeout = 20; // Fix to get correct positioning on first mouseover
    var scTooltip = IkeaPopup();
    var scLinkId = 'link_header_shopping_cart';		
    Event.observe($(scLinkId), 'mouseover', function(event){ 
        clearTimeout(scTipDelay);
        
        // Change timeout to correct value when div created
        scTipDelay = setTimeout( 
            function() {
                var quantity;
                var totalPrice;
                var userInfo = getUserInfo(storeId,'normal');
                if(userInfo != null) {
                    quantity = userInfo.numberShopCartItems.escapeHTML();
                    totalPrice = userInfo.totalPrice.escapeHTML();
                }
                if(quantity != 'undefined' && quantity > 0){
                    scTooltip.createGenericPopupNew(null,null,'cartPopup','cartPopup',event.target,1,26);
                    scTooltip.setGenericContent(generateLayoutForShoppingCartPopup(quantity,totalPrice));
                }
            },
            scTipTimeout
        );
    });
    
    Event.observe($(scLinkId), 'mouseout', function(event){
        clearTimeout(scTipDelay);
        scTooltip.hide();
    }); 
}
	
function generateLayoutForShoppingCartPopup(quantity,totalPrice) {
    var retString = " " +
    "<div class=\"cartPopupContainer\">" +  
        quantity + " " + js_fn_POPUP_CART_PRODUCTS +
        "<div class=\"cartPadding\">" + js_fn_POPUP_CART_TOTAL_PRICE + ": " +
        "<span class=\"totalPrice\">" + totalPrice + "</span>" +
        "</div>" +
    "</div>"
    return retString;
}
	
/** 
    for #215 FW11 to update the number of items in the crat header link
*/
function updateNoOfCartItems(storeId) {
    var noOfItemsSpan = $('noOfCartItems');
    if(typeof noOfItemsSpan != 'undefined'  && noOfItemsSpan != null){
        var userInfo = getUserInfo(storeId,'normal');
        if(userInfo != 'undefined' && userInfo!= null && userInfo.numberShopCartItems != 'undefined' && userInfo.numberShopCartItems != null)  {
            var noOfItems = userInfo.numberShopCartItems.escapeHTML();    
            if(noOfItems != 'undefined' && noOfItems != null && noOfItems != '0' && !noOfItems.blank()) {
                noOfItemsSpan.update("&nbsp;(" + noOfItems + ")");
            } else {
                noOfItemsSpan.update("");
            }
        } else {
            noOfItemsSpan.update("");
        };
    };
}
/*************************************
Generic JavaScript functions for opening popup windows
Created by Lars Henrik Rotnes
Last modified: 2002-10-01
*************************************/

/*
CVS Version : $Id: jsPop.js,v 1.6 2003/02/26 17:37:41 lhr Exp $

*/


/**
*Function to open a pop up window
*
* calls openPopUpWindow and discards the returned value. This is so the function openPopup can
* be used in the href attribute as href="javascript:openPopUp(...)".
* Note that this use is deprecated, but widespread all over the application. See
* the popupLink function below for a better alternative...!
* 
* argUrl   string 	= the location of the file to open in the popup window
* argWidth string 	= the width of the window
* argHeight string = the height of the window
* argTitle string 	= the title of the window
* argScroll int  	= specify if we need scrollbars, 1 = yes, 0 = no 
*/
var is = new Object()
is.ie = (document.all) ? 1:0
is.ns4 = (document.layers) ? 1:0
is.w3c = (document.getElementById && !is.ie) ? 1:0
is.win = (navigator.userAgent.toLowerCase().indexOf("win") > 0) ? 1:0
is.mac = (navigator.userAgent.toLowerCase().indexOf("mac") > 0) ? 1:0

function openPopUp(argUrl, argWidth, argHeight, argTitle, argScroll ) {
    openPopUpWindow(argUrl, argWidth, argHeight, argTitle, argScroll );
}

//function for for stat generation with exception handling
function IRWdcsMultiTrack() {
    try {
        if (window.gDomain===undefined) {
            WTdom_Load=false;
        } else {
            WTdom_Load=true;
        }
        if (window.WTmain_Load === true && window.WTdom_Load === true) {
            dcsMultiTrack.apply(this,arguments);
        }
    } catch (e) {}	
}

//Function added to launch the Artificial Assistant (en_BG, en_US, de_DE)
if(self.name ==''|| self.name==undefined){
self.name='IKEA';
}

//That's the target wished name of the IKEA window to make possible that the
//Assistant opens the links in the proper window. If the window actually has
//another name, please, tell us and we will change the target in the
//Assistant's links!!!!

function popUpAnna(URL,popW,popH) {

var w = 480, h = 340;

if (document.all || document.layers) {

   w = self.screen.availWidth;
   h = self.screen.availHeight;
}

var topPos = (h-popH)-(4*h/100), leftPos = (w-popW)-(1*w/100);

day = new Date();
id = day.getTime();

   eval("page" + id + " =window.open(URL,'popup','resizable=no, toolbar=no, location=no, status=no, scrollbars=no, menubar=no, titlebar=no, width=' + popW + ',height=' + popH + ',left=' + leftPos + ',top=' + topPos + ',screenX=' + leftPos + ',screenY=' + topPos);");
}

//**********************************************

/**
*Function to open a pop up window
*
*argUrl   string 	= the location of the file to open in the popup window
*argWidth string 	= the width of the window
*argHeight string = the height of the window
*argTitle string 	= the internal name for the window. This should be a one-word alphabetic name and is used only internally.
*                     IE does not accept regular NLS texts, so use a symbolic name for this parameter!
*argScroll int  	= specify if we need scrollbars, 1 = yes, 0 = no 
*/
var is = new Object()
is.ie = (document.all) ? 1:0
is.ns4 = (document.layers) ? 1:0
is.w3c = (document.getElementById && !is.ie) ? 1:0
is.win = (navigator.userAgent.toLowerCase().indexOf("win") > 0) ? 1:0
is.mac = (navigator.userAgent.toLowerCase().indexOf("mac") > 0) ? 1:0

function openPopUpWindow(argUrl, argWidth, argHeight, argTitle, argScroll ) {
  //for win ie, add extra width to accomodate scrollbar on pop07
 // if(is.ie && !is.mac  && argScroll=="1" && ( argTitle == "pop07" || argTitle == "pop08") ){
  //  argWidth = parseInt(argWidth) + 26;
  //}
    
    if(argScroll=="1" && !is.mac){
        argWidth = parseInt(argWidth) + 26;
    }
    
    if(argScroll=="1" && is.mac){
        argWidth = parseInt(argWidth) + 10;
    }
    
        
    var x = (screen.availWidth - argWidth ) / 2;
    var y = (screen.availHeight - argHeight ) / 2;
  
    var sFeatures = "width=" + argWidth + "," + 
                  "height=" + argHeight + "," + 
                                    "toolbar=no," + 
                  "status=no," + 
                                    "scrollbars=" + argScroll + "," + 
                                    "resizable=yes," + 
                  
                  "left=" + x + ", top="+ y;
    
    var windowOpened = false;
    
    if (window.open) {
        //alert('"'+argTitle+'"');
        newWindow = window.open(argUrl, argTitle, sFeatures, false);
    
        windowOpened = newWindow?true:false;
    
        if (windowOpened && newWindow.focus) {
    
            newWindow.focus();
        }
        
    }
    
    // return false if a window was opened. This was the function can
    // be used in the onclick action handler of an HTML link
    return !windowOpened;
}



/**
* Function to open the target of a link in a new window. Usage example:
* 	<a href="http://..." target="_blank" onclick="return popupLink(this,'Window Title')">Window Title</a>
* This will use Javascript to open a new window. If the window cannot be opened
* (if Javascript is disabled, or the user has a popup blocker installed), the
* link is opened using the standard feature of the web browser. Aka "graceful degradation"...
*
* Parameters:
* 	link	The DOM object reference of the A element that is used to open the link with
*	name	The internal name for the window. This should be a one-word alphabetic name and is used only internally.
*           IE does not accept regular NLS texts, so use a symbolic name for this parameter!
*/
function popupLink(link,name) {

    return openPopUpWindow(link.href, 500, 600, name, 'yes');
}

var baseAddUrl = "/webapp/wcs/stores/servlet/IrwWSInterestItemAdd?";     // The first part of the WS call to add a product to the shopping list
var baseGetAllListsUrl = "/webapp/wcs/stores/servlet/IrwWSGetAllInterestLists?";    // The WS call to get all saved lists. 
var baseCreateListUrl = "/webapp/wcs/stores/servlet/IrwWSCreateInterestList?";      // The WS call to create a new list. 
var baseDeleteListUrl = "/webapp/wcs/stores/servlet/IrwDeleteShoppingList?";        // The WS call to delete an existing list. 
var baseRenameListUrl = "/webapp/wcs/stores/servlet/IrwWSRenameInterestList?";      // The WS call to rename an existing list. 
var baseDisplayUrl = "/webapp/wcs/stores/servlet/InterestItemDisplay?";             // The default display url for a shopping list
var baseAddToCartUrl = "/webapp/wcs/stores/servlet/IrwWSOrderItemAdd";              // The default display url for a shopping list
var baseMoveOrderItemToShoppingList = "/webapp/wcs/stores/servlet/IrwWSOrderItemMoveToShoppingList?";              // The default display url for a shopping list
var addUrlSuffix = "&quantity=1";                                                   // Product quantity defaults to 1

var addToShopListPopup = IkeaPopup();

/**
 * Entry point method for Shopping list popups.
 * NOTE! some params (starting with js_fn_*) are global js params added to the calling jsp-page and coming from ShoppingListText_xx_XX.properties 
 * 
 * @param action    		A string to determine what is to be done and what layout to create in the popup
 * @param targetElement		A DOM object that fires the popup, e.g. the button clicked. Needed to position the popup.
 * @param storeId   		The store id
 * @param langId    		The language id
 * @return					Nothing
 */
function activateShopListPopup(action,targetElement,storeId,langId) {

    var newLayout = "";
    switch (action)
    {
    case "save":
        addToShopListPopup.createGenericPopup(260,"","slPopup","slPopup",targetElement,25,35);
        newLayout = generateLayoutForShopListPopup(js_fn_POPUP_LOGIN_HEADER,null,js_fn_POPUP_LOGIN_TEXT,null,js_fn_POPUP_CANCEL_BTN,"");
        addToShopListPopup.setGenericContent(newLayout);
        break;
    case "create":
        addToShopListPopup.createGenericPopup(260,"","slPopup","slPopup",targetElement,20,-120);
        if(isLoggedIn(storeId)){
            var noOfLists = $('shoppingList').select('.leftNavigation .navItem').size();
            if(noOfLists == js_fn_MAX_NO_OF_LISTS){
                newLayout = generateLayoutForShopListPopup(js_fn_POPUP_CREATE_HEADER,null,js_fn_POPUP_ERROR_MAX_NO_OF_LISTS,null,js_fn_POPUP_CANCEL_BTN,"error");
                addToShopListPopup.setGenericContent(newLayout);
            }else{
                newLayout = generateLayoutForShopListPopup(js_fn_POPUP_CREATE_HEADER,null,null,js_fn_POPUP_CREATE_BTN,js_fn_POPUP_CANCEL_BTN,"callCreateShoppingList('"+storeId+"','"+langId+"')");
                addToShopListPopup.setGenericContent(newLayout);
                enableListName();
            }
        }else{
            newLayout = generateLayoutForShopListPopup(js_fn_POPUP_LOGIN_HEADER,null,js_fn_POPUP_LOGIN_TEXT,null,js_fn_POPUP_CANCEL_BTN,"");
            addToShopListPopup.setGenericContent(newLayout);
        }
        break;
    case "rename":
        var curListObj = {name: js_fn_CURRENT_LISTNAME};
        addToShopListPopup.createGenericPopup(260,"","slPopup","slPopup",targetElement,-220,30);
        newLayout = generateLayoutForShopListPopup(js_fn_POPUP_RENAME_HEADER,curListObj,js_fn_POPUP_LOGIN_TEXT,js_fn_POPUP_RENAME_BTN,js_fn_POPUP_CANCEL_BTN,"callRenameShoppingList('"+storeId+"','"+langId+"','"+js_fn_CURRENT_LISTID+"')");
        addToShopListPopup.setGenericContent(newLayout);
        enableListName();
        break;
    case "delete":
        var curListObj = {name: js_fn_CURRENT_LISTNAME};
        addToShopListPopup.createGenericPopup(260,"","slPopup","slPopup",targetElement,-220,30);
        newLayout = generateLayoutForShopListPopup(js_fn_POPUP_DELETE_HEADER,curListObj,js_fn_POPUP_DELETE_TEXT,js_fn_POPUP_DELETE_BTN,js_fn_POPUP_CANCEL_BTN,"callDeleteShoppingList('"+storeId+"','"+langId+"','"+js_fn_CURRENT_LISTID+"')");
        addToShopListPopup.setGenericContent(newLayout);
        break;
    case "print":
        addToShopListPopup.createGenericPopup(260,"","slPopup","slPopup",targetElement,25,35);
        newLayout = generatePrintLayoutForShopListPopup(storeId,langId,js_fn_POPUP_PRINT_HEADER,js_fn_POPUP_PRINT_BTN,js_fn_POPUP_CANCEL_BTN,"irwStatShoppingList('printShoppingList'); getObject('formPrintShoppingList').submit();closePopup()",js_fn_LOCAL_STORES);
        addToShopListPopup.setGenericContent(newLayout);
        preSelectLocalStorePrint(irwstats_locale);  //Get locale from global stats variable
        preSelectPrintSorting($('formPrintShoppingList'));
        toggleSelStore($('formPrintShoppingList'),$('localStoreNumPrint'));
        break;
    case "add":
        try {
            irwStatShoppingList("POPpopupOpened");
        } catch(e) {}
        
	//Fix for IE6
	if(Browser.Version() == 6){
		disable();	
	}
	
        var prodId = targetElement.attributes.id.value;
	var quant = 1;
        prodId = prodId.replace("popupShoppingList","");
        prodId = prodId.replace("slideshowSaveToList","");
	var addCartContainer = $('addCartContainer');		
		 if(addCartContainer != undefined){
			if(addCartContainer.quantity != undefined){
				quant=addCartContainer.quantity.value;
				quant = quant.strip();
				if(checkNum(quant, 0, 1, 0, 0, 99) == false)
					quant=1;
					
					addUrlSuffix = "&quantity="+quant;
			}
			
		}

        addToShopListPopup.createGenericPopup(260,"","slPopup","slPopup",targetElement,-40,-145);
        if(isLoggedIn(storeId)){
            getSavedLists(storeId,langId,prodId); // Get all lists
        }else{
            var listObj = {name:"", defaultName: js_fn_DEFAULT_LISTNAME};
            newLayout = generateLayoutForShopListPopup(js_fn_POPUP_SELECT_HEADER,listObj,js_fn_POPUP_LOGIN_TEXT,js_fn_POPUP_SAVE_BTN,js_fn_POPUP_CANCEL_BTN,"respondToSaveToShopList('"+storeId+"','"+langId+"','"+prodId+"')");
            addToShopListPopup.setGenericContent(newLayout);
		
        }
		dynamicPositioning(targetElement,'slPopup', 10,0);
        break;
    case "email":
        addToShopListPopup.createGenericPopup(402,"","slPopup","slPopup",targetElement,25,35);
        newLayout = generateEmailLayoutForShopListPopup("/webapp/wcs/stores/servlet/IrwEmailShoppingList?storeId="+storeId+"&langId="+langId+"&listId="+js_fn_CURRENT_LISTID);
        addToShopListPopup.setGenericContent(newLayout);
        break;
    
    case "addToCart":   // Add to shopping cart (NOT shopping list)
        var prodId = targetElement.attributes.id.value;
		var quant = 1;
	var addCartContainer = $('addCartContainer');
	//Fix for IE6
	if(Browser.Version() == 6){
		disable();	
	}
		
	
	if(addCartContainer != undefined){
		if(addCartContainer.quantity != undefined){
			quant = addCartContainer.quantity.value;
			quant = quant.strip();
			if(checkNum(quant, 0, 1, 0, 0, 99) == false)
				quant=1;
		}
	}
        prodId = prodId.replace("popupAddToCart","");
        prodId = prodId.replace("slideshowAddToCart","");
		//Get hidden input field value if product is GPR
		var partNumberInForm = $("thePartnumberInForm");
		
		// Cookie is missing for certain criteria. Below section will regenerate cookie, if it doesn't exist
        var cookieExist = getCookie('JSESSIONID');
        if(null==cookieExist ){
        isLoggedIn(storeId);
        }
		
		if (partNumberInForm != undefined) {
			prodId = partNumberInForm.value;
		}
		try {
			// Changed by FW11 - part2 - IrwWSOrderItemAdd has been changed to accept partNumber
			irwStatShoppingList("buyOnline", prodId);
		} catch(e) {}

        addToShopListPopup.createGenericPopup(200,"","slPopup","slPopup",targetElement,0,-100);
        addItemToCart(prodId, name,storeId,quant,targetElement);
break;
    case "move":
        
        try {
            irwStatShoppingList("POPpopupOpened");
        } catch(e) {}
	        
        var rowId = targetElement.attributes.id.value;
        rowId = rowId.replace("popupShoppingList","");

		addToShopListPopup.createGenericPopup(260,"","slPopup","slPopup",targetElement,-40,-160);
		if(isLoggedIn(storeId)){
		    getSavedListsToMove(storeId,langId,rowId); // Get all lists
		}else{
		
		    var listObj = {name:"", defaultName: js_fn_DEFAULT_LISTNAME};
	    	newLayout = generateLayoutForShopListPopup(js_fn_POPUP_SELECT_HEADER,listObj,js_fn_POPUP_LOGIN_TEXT,js_fn_POPUP_SAVE_BTN,js_fn_POPUP_CANCEL_BTN,"respondOrderItemToShopList('"+storeId+"','"+langId+"','"+rowId+"')");
	    	addToShopListPopup.setGenericContent(newLayout);
        }
        break;
      // Start CR-IKEA00634068   
     case "selectStore":// Selects the local store
	       addToShopListPopup.createGenericPopup( 149, "", "thumpPopup", "slPopup", targetElement, -45, 17);
	     newLayout = generateSelectStoreLayout();
	     addToShopListPopup.setGenericContent(newLayout);
	     break;
	     
	   case "tipToSelectStore":// Selects the local store
	       addToShopListPopup.createGenericPopup( 149, "", "thumpPopup", "slPopup", targetElement, 126, -27);     
	     newLayout = generateTipToSelectStoreLayout();
	     addToShopListPopup.setGenericContent(newLayout);
	     break;
     // End CR-IKEA00634068 
    default:
        alert('something went wrong...');
    }
}


/**
 * Function generateLayoutForShopListPopup is a general function that generates a string with complete 
 * HTML layout to be inserted into an IkeaPopup.
 * @param header    		The header text
 * @param listObj     		The current list object if present with attributes id and name. Should be set to null if not used.
 * @param body      		The body text
 * @param btn         		The text for the "submit" button of the popup that fires the event
 * @param link      		The text for the cancel link to just close the popup
 * @param action      		The name of the event to add to the "btn" when clicked (Ex: respondToDelete)
 * @return					The HTML string to be inserted in the popup
*/
function generateLayoutForShopListPopup(header,listObj,body,btn,link,action){
    var retString = ""+
    "<div class=\"content\">"+
    createHeaderLayout(header,listObj,action)+
    "<form name=\"formShoppingListPopup\" method=\"\" action=\"\" id=\"formShoppingListPopup\" onsubmit=\""+action+";return false;\">"+
    createBodyLayout(body,listObj,action)+
    createFooterLayout(btn,link,action)+
    "</form>"+
    "</div>";
    
    return retString;
} 

/**
 * Function generatePrintLayoutForShopListPopup is a specific function that generates a string with complete 
 * HTML layout with printout information to be inserted into an IkeaPopup.
 * NOTE! some params (starting with js_fn_*) are global js params added to the calling jsp-page and coming from ShoppingListText_xx_XX.properties 
 * @param storeId    		The current store id
 * @param langId       		The current language id
 * @param header    		The header text
 * @param btn         		The text for the "submit" button of the popup that fires the event
 * @param link      		The text for the cancel link to just close the popup
 * @param action      		The name of the event to add to the "btn" when clicked (Ex: respondToDelete)
 * @param stores      		An object with the local stores. Contains attributes: value, name
 * @return					The HTML string to be inserted in the popup
*/
function generatePrintLayoutForShopListPopup(storeId,langId,header,btn,link,action,stores){
    var storesCount = stores.length;
    var optionString = "";
    for(var i=0;i<storesCount;i++) {
        optionString += "<option id=\"localStore_"+stores[i].value+"\" value=\""+stores[i].value+"\">"+stores[i].name+"</option>";
    }

    var retString = ""+
    "<div class=\"content\">"+
    createHeaderLayout(header)+
    "<form name=\"formPrintShoppingList\" method=\"get\" action=\"/webapp/wcs/stores/servlet/IrwPrintShoppingList\" id=\"formPrintShoppingList\" target=\"_new\">"+
    "<input type=\"hidden\" name=\"slId\" value="+js_fn_CURRENT_LISTID+">"+
    "<input type=\"hidden\" name=\"storeId\" value=\""+storeId+"\"/>"+
    "<input type=\"hidden\" name=\"langId\" value=\""+langId+"\"/>"+
    "<div class=\"headlineSelect text\">"+js_fn_POPUP_SELECT_STORE+"</div>"+
    "<select name=\"localStoreNum\" id=\"localStoreNumPrint\" onchange=\"toggleSelStore($('formPrintShoppingList'),this)\">"+
    "<option value=\"0\">"+js_fn_POPUP_SELECT_NONE+"</option>"+
    optionString+
    "</select>"+
    "<div class=\"headlineSort text\">"+js_fn_POPUP_PRINT_SORT_BY+"</div>"+
    "<div class=\"listRow\"><input type=\"radio\" id=\"time\" name=\"chkSort\" value=\"time\"/><label for=\"time\">"+js_fn_POPUP_PRINT_TIME_ADDED+"</label></div>"+
    "<div class=\"listRow\"><input type=\"radio\" id=\"weight\" name=\"chkSort\" value=\"weight\"/><label for=\"weight\">"+js_fn_POPUP_PRINT_WEIGHT+"</label></div>"+
    "<div class=\"listRow\"><input type=\"radio\" id=\"location\" name=\"chkSort\" value=\"location\"/><label for=\"location\">"+js_fn_POPUP_PRINT_LOCATION+"</label></div>"+
    "<div class=\"chkBoxRow\"><input type=\"checkbox\" id=\"chkPrintOffers\" name=\"chkPrintOffers\"/><label for=\"chkPrintOffers\">"+js_fn_POPUP_PRINT_STORE_OFFERS+"</label></div>"+
    createFooterLayout(btn,link,action)+
    "</form>"+
    "</div>";
    
    return retString;
}


/**
 * generateSavedListsLayoutForShopListPopup generates inner html layout for the user to select which list to save the product in
 * To be inserted into an IkeaPopup.
 */
function generateSavedListsLayoutForShopListPopup(savedLists,active,header,btn,link,action)
{
	var listString = "";
    var style = "";
    var checked = "";
    var listCount = savedLists.length;
    if(listCount>4){style = "scroll";}
    for(var i=0;i<listCount;i++) {
        if(active == null && i==0){checked = ' checked="checked"';} // if no active list returned from ws set first one
        if(savedLists[i].id==active){checked = ' checked="checked"';}
        listString += "<div class=\"listRow\"><input type=\"radio\" id=\"chkList"+i+"\" name=\"chkList\" value=\""+savedLists[i].id+"\" onclick=\"disableListName()\""+checked+"><label for=\"chkList"+i+"\">"+savedLists[i].name+"</label></div>";
        checked = "";
    }
    
    var retString = ""+
    "<div class=\"content\">"+
    createHeaderLayout(header,null,action)+
    "<form name=\"formShoppingListPopup\" method=\"post\" action=\"\" id=\"formShoppingListPopup\" onsubmit=\""+action+";return false;\">"+
    "<div id=\"listContainer\" class=\""+style+"\">"+listString+"</div>"+
    "<div class=\"listRow\"><input type=\"radio\" id=\"chkListName\" name=\"chkList\" value=\"0\" onclick=\"enableListName()\"/>&nbsp;<input type=\"text\" id=\"listName\" name=\"listName\" value=\""+js_fn_DEFAULT_LISTNAME+"\" disabled=\"true\"/></div>"+
    createFooterLayout(btn,link,action)+
    "</form>"+
    "</div>";
    return retString;
}

/**
 * Function populates an IkeaPopup with an iframe and resizes it based on the loaded document.
*/
function generateEmailLayoutForShopListPopup(page)
{
    var loader = addToShopListPopup.generateLoadingLayout();
    var retString = ""+
    "<div id=\"emailIframeLoader\" style=\"display:;\">" + loader + "</div>"+
    "<div id=\"emailIframeContainer\" style=\"visibility:hidden;\">"+
    "<a href=\"#\" onclick=\"closePopup();return false;\" id=\"emailCloseBtn\" rel=\"nofollow\"></a>"+
    "<iframe src=\""+page+"\" id=\"emailIframe\" height=\"0\" width=\"0\" scrolling=\"no\" frameborder=\"0\" onload=\"resizeMe($('emailIframe')); \"></iframe>"+
    "</div>"
    
    return retString;
}
 // Start CR-IKEA00634068 
/**
 * Function populates an IkeaPopup with local sores dropdown
*/
function generateSelectStoreLayout() {	
var stores =js_fn_LOCAL_STORES;
var storesCount = stores.length;
    var optionString = "";
    for(var i=0;i<storesCount;i++) {
        optionString += "<option id=\"localStore_"+stores[i].value+"\" value=\""+stores[i].value+"\">"+stores[i].name+"</option>";
    };
var okButton = createButtonLayout(OK,"jsButton_shopListPopup","button","stockDisplayforLocalStore()") + "&nbsp;";

  var retString = ""+
   "<div id=\"selectContainer\">"+
  "<div id=\"selectPopupHeadline\">" + IN_STOCK +"</div>"+
  "<div id=\"selectPopupSelect\">"+
  "<select class =\"storeselectpopup\" id=\"selectLocalStore\" name=\"selectLocalStore\" >"+ 
  "<option value=\"-1\" selected>"+ SELECT_STORE +"</option>"+  optionString+
  "</select>" +"</div>"+
  "<div>"+
  "<div style=\"float: left;\">"+okButton +"</div>"+
  "<div class=\"spaceLeft\" style=\"text-align: right;\">"+
  "<a onclick=\"closePopup();return false;\"href=\"#\" class=\"linkText\">"+CLOSE+
  "</a></div>"+"</div>"+"</div>"  
    return retString;

}

/**
 * Function displays a pop up to encourage to select store.
*/

function generateTipToSelectStoreLayout(){
var retString = ""+
	 "<div id=\"popupContainer\">"+
	 "<div id=\"arrImg\">"+ "</div>"+
	  "<div id=\"tipheadline\">"+TIP+"</div>"+
	   "<div id=\"tipbody\">"+SELECT_TEXT+
	   "</div>"+
	   "<span class=\"spaceLeft\">"+
     "<a onclick=\"closeTipPopup();return false;\"href=\"#\" class=\"linkText\">"+CLOSE+
     "</a></span></div>"+"</div>"
	    
	    return retString;
}
 // End CR-IKEA00634068 

/**
 * Helper functions to generate layout in popup */
function createHeaderLayout(header, listObj, action) {
    var list = "";
    
    if((listObj != null) && (typeof listObj != 'undefined') && (listObj != "")){
        // If prod added from PIP, display no name in header (action set in onAddToShoppingListComplete()) 
        if(action != "addFromPip"){
            list = "&nbsp;" + listObj.name;
        }
    }
    var retString = ""+
    "<div class=\"headline\" id=\"slPopupH1\">"+header+list+"</div>";
    
    return retString;
}

function createBodyLayout(body, listObj, action) {
    var retString = "<p>"+body+"</p>";
    
    if(action.indexOf("callCreate") != -1){
        retString = "<input type=\"text\" id=\"listName\" name=\"listName\" value=\"\"/>";
    }else if(action.indexOf("callRename") != -1){
        retString = "<input type=\"text\" id=\"listName\" name=\"listName\" value=\""+listObj.name+"\"/>";
    }else if(action.indexOf("respondToSaveToShopList") != -1){
        retString = "<div id=\"listContainer\">"+
        "<div class=\"listRow\"><input type=\"radio\" id=\"chkList1\" name=\"chkList\" value=\".\" checked=\"checked\"><label for=\"chkList1\">"+listObj.defaultName+"</label></div>"+
        "</div>"+
        "<p>"+body+"</p>";
    }
	else if(action.indexOf("respondOrderItemToShopList") != -1){
            retString = "<div id=\"listContainer\">"+
            "<div class=\"listRow\"><input type=\"radio\" id=\"chkList1\" name=\"chkList\" value=\".\" checked=\"checked\"><label for=\"chkList1\">"+listObj.defaultName+"</label></div>"+
            "</div>"+
            "<p>"+body+"</p>";
    }
	else if(action.indexOf("error") != -1){
    retString = "<p style=\"color:#FF5050\">"+body+"</p>";
    }
    
    return retString;
}

function createFooterLayout(btn, link, action) {
    var btnLayout = "";
    // If btn added create the button
    if(btn != null){  
     btnLayout = createButtonLayout(""+btn+"","jsButton_shopListPopup","button",""+action+"") ;
    }
 var retString = btnLayout + "<div class=\"shoppingListLink \"><a onclick=\"closePopup();addProductEvts();return false;\" href=\"#\" rel=\"nofollow\">"+link+"</a></div>";
 return retString;
}

/** Helper functions to generate layout in popup */

/**
 * Function adds an item to the Shopping Cart
 */
function addItemToCart(prodId,name,storeId,quant, targetElement) {
    loadingPopup();
	// Changed by FW11 - part2 - IrwWSOrderItemAdd has been changed to accept partNumber
    new Ajax.Request(baseAddToCartUrl, {
        method:'post',
        parameters: {partNumber: prodId, quantity: quant, type: 'json'}, 
        onSuccess: function(transport){
            var json = transport.responseText.evalJSON();
            var code = json.code;
            
            if (code == 0) {
				updateNoOfCartItems(storeId);
                var body = js_fn_POPUP_DONE_TEXT + " <a href=\""+js_fn_POPUP_VIEWCART_URL+"\" class=\"link\" rel=\"nofollow\">" + js_fn_SHOPPING_CART + "</a>";
                var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_DONE_HEADER,null,body,null,js_fn_POPUP_CLOSE_BTN,"");
            } else {
                var body = js_fn_ARTICLE + " " + js_fn_COULDNOTBEADDEDTOSC;
                var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_ERROR_HEADER,null,body,null,js_fn_POPUP_CANCEL_BTN,"");
            }
            addToShopListPopup.setGenericContent(newLayout);
			dynamicPositioning(targetElement, 'slPopup', 10,0);
			
        }
    }); 
} 
/* New function has added to chnage the position of the popup */
function setDynamicPosition(_ownerObj,popupId){
	var dimensions = $(popupId).getDimensions();
	var arr = $(_ownerObj).positionedOffset(); 
	var popHeight = dimensions.height;
	$(popupId).style.top = arr[1] - popHeight + 'px';
}

function getSavedLists(storeId,langId,prodId) {
    // Show the user that we are waiting for data
    loadingPopup();
	var completeURL = baseGetAllListsUrl + "storeId=" + storeId + "&langId=" + langId;
	
    // Call the completed IOWS URL
	new Ajax.Request(completeURL, {
		method: 'get',
		contentType: 'application/xml',
		onSuccess: function(response) {
		    onSavedListsRecieved(response.responseXML,storeId,langId,prodId);
		}
	});		
}


function onSavedListsRecieved(doc,storeId,langId,prodId) {
    // Parse the returned data
    try{
        var activeList = doc.getElementsByTagName("activeList")[0].firstChild.nodeValue;
        if(activeList == ""){activeList = null};
    }catch(e){
        var activeList = null;
    }
    var items = doc.getElementsByTagName("shoppingList");
    var noOfLists = items.length;
    var shoppingLists = new Array();
    
    if(noOfLists > 0) {
        for(var i=0;i<noOfLists;i++) {
            var listItem = parseXmlItemToListInfo(items[i]);
            shoppingLists[i] = listItem; 
        }
    }else{
        var defaultList = {id:'.',name:js_fn_DEFAULT_LISTNAME};
        shoppingLists[0] = defaultList; 
        activeList = null;
    }

    var newLayout = generateSavedListsLayoutForShopListPopup(shoppingLists,activeList,js_fn_POPUP_SELECT_HEADER,js_fn_POPUP_SAVE_BTN,js_fn_POPUP_CANCEL_BTN,"respondToSaveToShopList('"+storeId+"','"+langId+"','"+prodId+"')");
    addToShopListPopup.setGenericContent(newLayout);
}


/*
 * respondToSaveToShopList saves the product to the selected list
 */
function respondToSaveToShopList(storeId,langId,prodId)
{
    // Find selected list item
    var chkBtns = $('formShoppingListPopup').getInputs('radio');
    var listId = chkBtns.find(function(radio) { return radio.checked; }).value;
    
    if(listId == 0){    // If item added to a new list
        listName = $F('listName');
        // Add default name if not entered
        if(listName.strip()==""){
            listName = js_fn_DEFAULT_LISTNAME;  // listName should come from commerce and properties key
        }
    }else{  // Get the listname from the label
        var chkActive = chkBtns.find(function(radio) { return radio.checked; }).id;
        listName = $(chkActive).next().innerHTML;
    }

    //Get hidden input field value if product is GPR
    var partNumberInForm = $("thePartnumberInForm");
    if (""+partNumberInForm != "null") {
        prodId = partNumberInForm.value;
    } 
    
    var listObj = {id:listId, name:listName};
    callAddItemToShoppingList(prodId,storeId,langId,listObj);
}


/**
 * Makes an asynchronous call to the webservice for adding a product to the shopping list.
 * The data call is made asynchronously, when the result is returned
 * the method onAddToShoppingListComplete is called. 

 * @param productNumber		The product number that data is required for. (Example "40103685" = Goliat). 
 * @param storeId		    The store id
 * @param langId		    The language id
 * @param listObj			A list object with needed attributes to save. Contains attributes: id, name
 * @return					Always false, in order to stop link execution
 */
function callAddItemToShoppingList(productNumber,storeId,langId,listObj) {
    // Show the user that we are waiting for data
    loadingPopup();
    
    if(listObj.id==0){  //Product added to a new list
        var completeURL = baseCreateListUrl + "partNumber=" + productNumber + "&langId=" + langId + "&storeId=" + storeId + "&slName=" + encodeURI(listObj.name);
    } else {    //Product added to existing list
        var completeURL = baseAddUrl + "partNumber=" + productNumber + "&langId=" + langId + "&storeId=" + storeId + "&listId=" + listObj.id + addUrlSuffix;
    }

	new Ajax.Request(completeURL, {
		method: 'get',
		contentType: 'application/xml',
		onSuccess: function(response) {
            /**
            * Start
            * added arg productNumber for IKEA00694793
            **/
            onAddToShoppingListComplete(response.responseXML,langId,storeId,listObj,productNumber);
            /**
            * End IKEA00694793
            **/
		}
	});
    
	return false;
}


/**
 * Handles the data returned from the callAddItemToShoppingList asynchronous call.
 * The data is parsed to an operation code that should normally be 0.
 * Depending on success, the user is either shown a message that things went well, or an error message.
 * @param doc				The returned WS XML data
 * @return					Nothing
 */
function onAddToShoppingListComplete(doc,langId,storeId,listObj,productNumber) {
	var responseTag = doc.getElementsByTagName("actionResponse")[0];
	var codeTag = responseTag.getElementsByTagName("code")[0];
	var operationCode = parseInt(codeTag.firstChild.nodeValue);
	var operationSuccess = (operationCode == 0);
    
	if(operationSuccess) {
		try	{
            /**
            * Start IKEA00694793
            **/
            irwStatShoppingList("addFromPIPorSC",productNumber);
            /**
            * End IKEA00694793
            **/
		} catch (e) {
		}
        //Product was added to a new list so get the listObj from returned xml
        if(listObj.id==0){  
            var list = doc.getElementsByTagName("shoppingList")[0];
            listObj = parseXmlItemToListInfo(list);
        }
        var strBody = "<p>" + js_fn_POPUP_DONE_TEXT + " <a href=\""+baseDisplayUrl+"storeId="+storeId+"&langId="+langId+"&listId="+listObj.id+"\" class=\"link\" rel=\"nofollow\">"+listObj.name+"</a></p>";
		if(! isLoggedIn(storeId)){
			strBody += "<p>" + js_fn_POPUP_LOGIN_TEXT + "</p>";
		}
        var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_DONE_HEADER,listObj,strBody,null,js_fn_POPUP_CLOSE_BTN,"addFromPip");
        addToShopListPopup.setGenericContent(newLayout);
	} else {
        if(listObj.id==0 && operationCode == 6){ // If try to add to new list and max no of lists reached
            var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_ERROR_HEADER,null,js_fn_POPUP_ERROR_MAX_NO_OF_LISTS,null,js_fn_POPUP_CLOSE_BTN,"error");
        }else if(operationCode == 9){// Maximum number of shopping list item reached(maximum quantity for a product is 99).
            var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_ERROR_HEADER,null,js_fn_ERROR_SHOPPING_LIST_MAX_ITEM_QUANTITY_LIMIT_EXCEEDED,null,js_fn_POPUP_CLOSE_BTN,"error");
        }else if(operationCode == 10){// Maximum number of products in the list has been exceeded(maximum products in a list is 101).
            var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_ERROR_HEADER,null,js_fn_ERROR_SHOPPING_LIST_MAX_LIMIT_EXCEEDED,null,js_fn_POPUP_CLOSE_BTN,"error");
        }else{
            var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_ERROR_HEADER,null,js_fn_POPUP_ERROR_TEXT,null,js_fn_POPUP_CLOSE_BTN,"");
        }
        addToShopListPopup.setGenericContent(newLayout);
	}
}


function callCreateShoppingList(storeId,langId){
    // Get list name from the form
    var listName = $F('listName');

    if (validateListName(listName)){
        $('errMsg').hide();
    
        // Show the user that we are waiting for data
        loadingPopup();
        var completeURL = baseCreateListUrl + "langId=" + langId + "&storeId=" + storeId + "&slName=" + encodeURI(listName);

        new Ajax.Request(completeURL, {
            method: 'get',
            contentType: 'application/xml',
            onSuccess: function(response) {
                onCreateShoppingListComplete(response.responseXML,storeId,langId);
            }
        });
    }else{
        $('errMsg').show();
        $('errMsg.error').update(js_fn_ERROR_CREATE_LIST);
    };
    
	return false;
}


function onCreateShoppingListComplete(doc,storeId,langId) {
	var codeTag = doc.getElementsByTagName("code")[0];
	var operationCode = parseInt(codeTag.firstChild.nodeValue);
	var operationSuccess = (parseInt(codeTag.firstChild.nodeValue) == 0);
    
	if(operationSuccess) {
		try	{
			irwStatShoppingList("createNewList");
		} catch (e) {
		}
        // Redirect to display page with current list...
		location.href = baseDisplayUrl+ "langId=" + langId + "&storeId=" + storeId;
	} else {
        closePopup();
        $('errMsg').show();
        $('errMsg.error').update('Error: ' + operationCode);
	}
}

function callDeleteShoppingList(storeId,langId,listId){
    loadingPopup();
    location.href = baseDeleteListUrl + "langId=" + langId + "&storeId=" + storeId + "&slId=" + listId;
}

function onDeleteShoppingListComplete(doc,storeId,langId) {
	var codeTag = doc.getElementsByTagName("code")[0];
	var operationCode = parseInt(codeTag.firstChild.nodeValue);
	var operationSuccess = (parseInt(codeTag.firstChild.nodeValue) == 0);
    
	if(operationSuccess) {
        // Redirect to display page with current list...
		location.href = baseDisplayUrl+ "langId=" + langId + "&storeId=" + storeId;
	} else {
        closePopup();
        $('errMsg').show();
        $('errMsg.error').update('Error: ' + operationCode);
	}
}

function callRenameShoppingList(storeId,langId,listId){
    // Get list name from the form
    var listName = $F('listName');

    if (validateListName(listName)){
        $('errMsg').hide();
    
        // Show the user that we are waiting for data
        loadingPopup();
        var completeURL = baseRenameListUrl + "langId=" + langId + "&storeId=" + storeId + "&slId=" + listId + "&slName=" + encodeURI(listName);

        new Ajax.Request(completeURL, {
            method: 'get',
            contentType: 'application/xml',
            onSuccess: function(response) {
                onRenameShoppingListComplete(response.responseXML,listId,listName);
            }
        });
    }else{
        $('errMsg').show();
        $('errMsg.error').update(js_fn_ERROR_RENAME_LIST);
    };
    
	return false;
}

function onRenameShoppingListComplete(doc,listId,listName) {
	var codeTag = doc.getElementsByTagName("code")[0];
	var operationCode = parseInt(codeTag.firstChild.nodeValue);
	var operationSuccess = (parseInt(codeTag.firstChild.nodeValue) == 0);
    
	if(operationSuccess) {
        closePopup();
        // Update menu item in left nav
        var menuItem = "listId" + listId;
        $(menuItem).update(listName);
        $('errMsg').show();
        $('errMsg.error').update();
        $('errMsg.confirm').update(js_fn_LIST_RENAMED);
		js_fn_CURRENT_LISTNAME = listName; //Added for PR # IKEA00674147

	} else {
        closePopup();
        $('errMsg').show();
        $('errMsg.error').update('Error: ' + operationCode);
	}
}


function isLoggedIn(storeId){
    var status;
    var completeURL = "/webapp/wcs/stores/servlet/GetUserInfo?storeId=" + storeId;

	new Ajax.Request(completeURL, {
		method: 'post',
		contentType: 'application/xml',
        asynchronous: false,    // Needed to return status when response done!
		onSuccess: function(response) {
            var responseXML = response.responseXML;
            var loggedIn = responseXML.getElementsByTagName('loggedIn')[0].firstChild.data;
            if (loggedIn == 'Y' || loggedIn == 'P') {
                status = true;
            }else{
                status = false;
            }
		}
	});
    return status;
}


function parseXmlItemToListInfo(item) {
    var listId = item.getAttribute("id");
    var listName = item.getAttribute("name");
    var returnObject = {id:listId, name:listName};
    return returnObject;
}

/**
 * Closes the popup
 * @return	false to stop link exection
 */
function closePopup() {
    //Fix for IE6
	if(Browser.Version() == 6){
		enable();	
	}
    addToShopListPopup.hide();
    return false;
}
/**
 * Closes the Tip popup
 * @return false to stop link exection
 */
function closeTipPopup() {
    addToShopListPopup.hide();
    document.cookie = 'hasSeen=true;path=/;';
    return false;
}


/**
 * Makes the popup show the layout that informs the user that a remote call is loading.
 * Requires that a method called generateLoadingLayout that returns valid HTML layout is defined.
 * @return					false to stop link exection
 */
function loadingPopup() {
	addToShopListPopup.loadingPopup();
	return false;
}

function showSaving() {
    addToShopListPopup.loadingSaving();
	return false;
  }
/**
 * Functions for enable/disable the input "listName" where the user enters a name for a new list to create.
 * The input should only be enabled when the selectbox in front is selected. And when enabled the text in it should be selected.
 */
function enableListName() {
    $('listName').disabled = false;
    $('listName').select();
}

function disableListName() {
    $('listName').disabled = true;
}

/**
 * Function for enable/disable the "Sort by" radiobuttons and "Include local store offes" checkbox in the print popup.
 * Triggered onchange of select option and also on popup load.
 */
function toggleSelStore(formObj,selObj){
    var selVal = $F(selObj);
    var chkBtns = formObj.getInputs('radio');
    var chkBox = formObj.getInputs('checkbox');
    if(selVal=="0"){
        chkBtns.each(function(obj){
            obj.disabled = true;
        })
        chkBox.each(function(obj){
            obj.disabled = true;
        })
    }else{
        chkBtns.each(function(obj){
            obj.disabled = false;
        })
        chkBox.each(function(obj){
            obj.disabled = false;
        })
    }
}

/**
 * Helper function for generateEmailLayoutForShopListPopup() to resize the iframe after load since it does not support dynamic height
*/
function resizeMe(obj){
    var h = 0;
    
    var h = Try.these(             
        function() {return obj.contentDocument.body.getHeight();},       //FF & Safari
        function() {return obj.contentWindow.document.body.getHeight();},   //IE
        function() {return 710;}
    );
    
    obj.height = h;
    $('emailIframeLoader').hide(); 
    $('emailIframeContainer').style.visibility = 'visible';
}

/**
 * Input validation on shopping list name
*/
function validateListName(name) {
    // Add default name if not entered
    if(name.strip()==""){
        name = js_fn_DEFAULT_LISTNAME;  // Get name from global js variable
    }
    if (name == null || name.length <= 0 || name.length > 254) {
        return false;
    }    
    var vBlackList = ["/",";","<","=",">","?","[","]","{","}","%"]; 
    for (var i = 0; i < vBlackList.length; i++) {
        if (name.indexOf(vBlackList[i]) > -1) {
            return false;
        }
    };
    return true;
}

function getSavedListsToMove(storeId,langId,rowId) {
    // Show the user that we are waiting for data
    
    loadingPopup();
	var completeURL = baseGetAllListsUrl + "storeId=" + storeId + "&langId=" + langId;
	
    // Call the completed IOWS URL
	new Ajax.Request(completeURL, {
		method: 'get',
		contentType: 'application/xml',
		onSuccess: function(response) {
		    onSavedListsRecievedToMove(response.responseXML,storeId,langId,rowId);
		}
	});		
}


function onSavedListsRecievedToMove(doc,storeId,langId,rowId) {
    // Parse the returned data
    try{
        var activeList = doc.getElementsByTagName("activeList")[0].firstChild.nodeValue;
        if(activeList == ""){activeList = null};
    }catch(e){
        var activeList = null;
    }
    var items = doc.getElementsByTagName("shoppingList");
    var noOfLists = items.length;
    var shoppingLists = new Array();
    
    if(noOfLists > 0) {
        for(var i=0;i<noOfLists;i++) {
            var listItem = parseXmlItemToListInfo(items[i]);
            shoppingLists[i] = listItem; 
        }
    }else{
        var defaultList = {id:'.',name:js_fn_DEFAULT_LISTNAME};
        shoppingLists[0] = defaultList; 
        activeList = null;
    }

    var newLayout = generateSavedListsLayoutForShopListPopup(shoppingLists,activeList,js_fn_POPUP_SELECT_HEADER,js_fn_POPUP_SAVE_BTN,js_fn_POPUP_CANCEL_BTN,"respondOrderItemToShopList('"+storeId+"','"+langId+"','"+rowId+"')");
    addToShopListPopup.setGenericContent(newLayout);
}




/*
 * respondToOrderItemToShopList saves the product to the selected list
 */
function respondOrderItemToShopList(storeId,langId,rowId)
{

 // Find selected list item
    
    var quantity = '1';
    
    
    var chkBtns = $('formShoppingListPopup').getInputs('radio');
    var listId = chkBtns.find(function(radio) { return radio.checked; }).value;
    
    if(listId == 0){    // If item added to a new list
     
        listName = $F('listName');
        // Add default name if not entered
        if(listName.strip()==""){
            listName = js_fn_DEFAULT_LISTNAME;  // listName should come from commerce and properties key
        }
    }else{  // Get the listname from the label
    
        var chkActive = chkBtns.find(function(radio) { return radio.checked; }).id;
        listName = $(chkActive).next().innerHTML;
    
    }

    //Get hidden input field value if product is GPR
    var partNumberInForm = $("thePartnumberInForm");
    if (""+partNumberInForm != "null") {
        prodId = partNumberInForm.value;
    } 
    
    
    
    var listObj = {id:listId, name:listName};
    
    addOrderItemToShoppingList(rowId,storeId,langId,listObj);
}


/**
 * Makes an asynchronous call to the webservice for adding a product to the shopping list.
 * The data call is made asynchronously, when the result is returned
 * the method onAddToShoppingListComplete is called. 

 * @param productNumber		The product number that data is required for. (Example "40103685" = Goliat). 
 * @param storeId		    The store id
 * @param langId		    The language id
 * @param listObj			A list object with needed attributes to save. Contains attributes: id, name
 * @return					Always false, in order to stop link execution
 */
function addOrderItemToShoppingList(rowId,storeId,langId,listObj) {
    // Show the user that we are waiting for data

    showSaving();
  
	// As per IKEA00689033 we are using the item quantity stored in the order as input to IrwWSOrderItemMoveToShoppingListCmd instead of qty input by user.
	var completeURL = baseMoveOrderItemToShoppingList + "partNumber=" + $F('prodId_'+rowId) + "&quantity=" +$F('order_qty_'+rowId) +"&returnShoppingCart=true&recalcPrelDelivery=true" +"&listId="+listObj.id+"&slName=" + encodeURI(listObj.name);
	 
	new Ajax.Request(completeURL, 
    	{
		method: 'post',
		 type: 'json',
		
		onSuccess: function(transport) {
		onMoveToShoppingListComplete(transport.responseText.evalJSON(),langId,storeId,listObj,rowId);
	
		},
		onFailure: function(){ 
		    var response = transport.responseText || "no response text"; 
		    var errMsgDiv = getObject('errMsg');
		    errMsgDiv.style.display='block';
		    errMsgDiv.style.visibility='visible';
		   $('errMsg').value="Something went wrong...";
		   $('errMsg').visible();
            }
	});
	
	
    
	return false;
}



/**
 * Handles the data returned from the callAddItemToShoppingList asynchronous call.
 * The data is parsed to an operation code that should normally be 0.
 * Depending on success, the user is either shown a message that things went well, or an error message.
 * @param doc				The returned WS XML data
 * @return					Nothing
 */
function onMoveToShoppingListComplete(doc,langId,storeId,listObj,rowId) {
		
	var operationCode = parseInt(doc[0][0].code);
	
    	var operationSuccess = (operationCode == 0);
    	
    	if(operationSuccess) {
    
		updateNoOfCartItems(storeId);
	
		changeShoppingCartView(rowId,doc);
	
		try	{
			irwStatShoppingList("addFromPIPorSC");
		} catch (e) {
		}
		
	
        //Product was added to a new list so get the listObj from returned json
        if(listObj.id==0){  
           listObj.name = doc[0][0].listName;
           listObj.id = doc[0][0].listId;
            
        }
        var strBody = "<p>" + js_fn_POPUP_DONE_TEXT + " <a href=\""+baseDisplayUrl+"storeId="+storeId+"&langId="+langId+"&listId="+listObj.id+"\" class=\"link\" rel=\"nofollow\">"+listObj.name+"</a></p>";
		if(! isLoggedIn(storeId)){
			strBody += "<p>" + js_fn_POPUP_LOGIN_TEXT + "</p>";
		}
        var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_DONE_HEADER,listObj,strBody,null,js_fn_POPUP_CLOSE_BTN,"addFromPip");
        addToShopListPopup.setGenericContent(newLayout);
	} else {
	
        if(listObj.id==0 && operationCode == 6){ // If try to add to new list and max no of lists reached
            var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_ERROR_HEADER,null,js_fn_POPUP_ERROR_MAX_NO_OF_LISTS,null,js_fn_POPUP_CLOSE_BTN,"error");
        }else if(operationCode == 9){// Maximum number of shopping list item reached(maximum quantity for a product is 99).
            var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_ERROR_HEADER,null,js_fn_ERROR_SHOPPING_LIST_MAX_ITEM_QUANTITY_LIMIT_EXCEEDED,null,js_fn_POPUP_CLOSE_BTN,"error");
        }else{
            var newLayout = generateLayoutForShopListPopup(js_fn_POPUP_ERROR_HEADER,null,js_fn_POPUP_ERROR_TEXT,null,js_fn_POPUP_CLOSE_BTN,"");
        }
        addToShopListPopup.setGenericContent(newLayout);
	}
}



function changeShoppingCartView(rowId,json)
{

     var totalRow = $F('totalRow') ;
     
     if (json[1][0].isEmpty == 'true') {
	
	 showEmptyShoppingCart(rowId);

     }
     else{
                subTotalPriceDiv = getObject('txtSubTotal');            
                totalPriceDiv = getObject('txtTotal');
                             
	     if(totalRow == rowId)
		{
			 $('tr_'+rowId).hide();                 
			 

		}
				
		if(rowId < totalRow)
		{
		

			var finalRowId = parseInt(rowId)+1;
			document.getElementById('tr_'+rowId).style.visibility = "hidden";
			$('tr_'+rowId).hide();
		

			var className =  $('tr_'+rowId).className ;

				for (var i = finalRowId; i <=totalRow  ; i++) {
				  if(document.getElementById('tr_'+rowId).style.visibility != '')
				  {

				  $('tr_'+i).className = className;
					if(className=='whiteRow')
					{
						className = "grayRow";
					}
					else
					{
						className = "whiteRow";
					}
				  }

			}

		}
		
	
		subTotalPriceDiv.innerHTML = json[1][0].subTotal;
		totalPriceDiv.innerHTML = json[1][0].totalPrice;
	
		
		if(json[1][0].preShippingCost.length>0 && json[1][0].isEmpty == 'false' )
		{	
		        cartPreTotalValueDiv = getObject('cartPreTotalValue');            
		        preDeliveryDateDiv = getObject('preDeliveryDate');
		        preDeliveryMethodDiv = getObject('preDeliveryMethod');
		        deliveryCalcResultDiv = getObject('deliveryCalcResult');
        
			
			cartPreTotalValueDiv.innerHTML = json[1][0].preShippingCost;
			preDeliveryDateDiv.innerHTML = json[1][0].preDelTimesSlotStart;
			preDeliveryMethodDiv.innerHTML = json[1][0].preDelMethod;
			deliveryCalcResultDiv.innerHTML = json[1][0].preShippingCost;
			

		}
		
      }



}

function showEmptyShoppingCart(rowId)
{

    $('emptyCartMsg').show(); 
    $('tr_'+rowId).hide();
    $('tr_foot').hide();
   document.getElementById("beginCheckout").style.visibility = "hidden";
	

}

 // Start CR-IKEA00634068 
/**
 * For dynamic positioning
*/
function dynamicPositioning(_ownerObj,popupId,topPos,leftPos){
	var pos = _ownerObj.cumulativeOffset();	
	var ownerDimension = $(_ownerObj).getDimensions();	
	var dimensions = $(popupId).getDimensions();	
	var popLeft = ownerDimension.width + leftPos;
	$(popupId).style.top = pos.top - dimensions.height + 'px';
}
 // End CR-IKEA00634068 
 
  var Browser = {
   Version: function() {
     var version = 999;
     if (navigator.appVersion.indexOf("MSIE") != -1)       
       version = parseFloat(navigator.appVersion.split("MSIE")[1]);
     return version;
   }
}

function disable(){
	if($('subdiv') != null) {
		var contentDiv = document.getElementById('subdiv');
		var containedDivElements = contentDiv.getElementsByTagName("select");
		
		for(var i=0;i<containedDivElements.length;i++){
			containedDivElements[i].style.visibility = "hidden";
		}
	}	
}

function enable(){
	if($('subdiv') != null) {
		var contentDiv = document.getElementById('subdiv');
		var containedDivElements = contentDiv.getElementsByTagName("select");

		for(var i=0;i<containedDivElements.length;i++){
			containedDivElements[i].style.visibility = "visible";
		}
	}
}

/*** 
*************************************
JavaScript functions for: nav02
Created by Lars Henrik Rotnes
Last modified: 2002-10-07
*************************************
**/

/*
CVS Version : $Id: nav02.js,v 1.13 2003/06/03 13:09:54 bohuslav Exp $

*/

//browsercheck jonk 20030428
var w3c = (document.getElementById)? true:false; //ie 5 and up + mozilla + netscape 6 and up
var ie = (document.all)? true:false;
var ns = (document.layers)? true:false;

if(document.images) {
	var arrow_over = new Image();
	arrow_over.src = "/ms/img/navigation/goBtn_over.gif";
	var arrow = new Image();
	arrow.src = "/ms/img/navigation/goBtn.gif";
}

/**
*initialize the document, display default values in the option box
*the text and values that the option box is poulated with is collected
*from two arrays, aText and aValue which is defined in a separate file, navOptions.js
**/
function init(initVal){
	var selectID = "select1";  //the id of the select field that should be populated
	var catID = "catid";
	//check if the browser can run this script
	if (!optionTestIt(selectID) ){
		alert(js_fn_NOT_VALID_BROWSER); 
		return false;
	} 
	
	//netscape 6 && ie 5>
	if (document.getElementById){
		tmp = document.getElementById(selectID);
		tmp2 = document.getElementById(catID);
	}else if (document.all){ //Explorer 4
	  tmp = document.all[selectID];
	  tmp2 = document.all[catID];
	}else{ 
		alert(js_fn_NOT_VALID_BROWSER); 
		return false; 	
	}
	tmp2.value = pifCatalogId;
	tmp.options[0] = new Option(initVal,'#');
 	for(var i = 0; i < aText.length; i++ ){
 		tmp.options[i+1] = new Option(aText[i],aValue[i]);
 	}
 	tmp.selectedIndex = 0;
}

/**
*initialize the document, display default values in the option box
*the text and values that the option box is poulated with is collected
*from two arrays, aText and aValue which is defined in a separate file, navOptions.js
**/
function initNews(initVal, newVal){
	var selectID = "select1";  //the id of the select field that should be populated
	var catID = "catid";
	//check if the browser can run this script
	if (!optionTestIt(selectID) ){
		alert(js_fn_NOT_VALID_BROWSER); 
		return false;
	} 
	
	//netscape 6 && ie 5>
	if (document.getElementById){
		tmp = document.getElementById(selectID);
		tmp2 = document.getElementById(catID);
	}else if (document.all){ //Explorer 4
	  tmp = document.all[selectID];
	  tmp2 = document.all[catID];
	}else{ 
		alert(js_fn_NOT_VALID_BROWSER); 
		return false; 	
	}
	tmp2.value = pifCatalogId;
	tmp.options[0] = new Option(initVal,'#');
	tmp.options[1] = new Option(newVal,'NEW');
 	for(var i = 0; i < aText.length; i++ ){
 		tmp.options[i+2] = new Option(aText[i],aValue[i]);
 	}
 	tmp.selectedIndex = 0;
}
/**
*Open a new page
*
*argFieldId string  = id of the field that triggered the function
**/
function openNewPage(argFieldId){
	//netscape 6 && ie 5>
	if (document.getElementById){
		tmp = document.getElementById(argFieldId);
	}else if (document.all){ //Explorer 4
	  tmp = document.all[argFieldId];
	}else{ 
		alert(js_fn_NOT_VALID_BROWSER); 
		return false; 	
	}
	
	//if the first element in the dropdown is selected do nothing
	if( tmp.selectedIndex < 1 )
		return false;
	
	document.location.href = aValue[tmp.selectedIndex];
}


/**
*function to find out if the browser supports dynamic content handling with 
*option boxes.
*
*argFieldId string  = the id of the select field, used to test if the browser
*											handle dynamic populating of this field
**/
function optionTestIt(argFieldId)
{
	optionTest = true;

	//netscape 6 && ie 5>
	if (document.getElementById){
		tmp = document.getElementById(argFieldId);
	}else if (document.all){ //Explorer 4
	  tmp = document.all[argFieldId];
	}else{ 
 		optionTest = false;
 	}
 	
	lgth = tmp.options.length - 1;
	tmp.options[lgth] = null;
	if (tmp.options[lgth]) 
			optionTest = false;
	
	return optionTest;
}

/** Invoked when the mouse moves over of given image **/
function out(imgName) {
	if(document.images)
	eval('document.' + imgName + '.src = ' + imgName.substr(0, imgName.length-1) + '.src')
}

/** Invoked when the mouse moves over fo given image. **/
function over(imgName) {
	if(document.images)
	eval('document.' + imgName + '.src = ' + imgName.substr(0, imgName.length-1) + '_over.src')
}

function go(){
if (document.selecter.prod.options[document.selecter.prod.selectedIndex].value != "none") {
location = document.selecter.prod.options[document.selecter.prod.selectedIndex].value
		}
	}

//function for submitting dropdowns - jonk 20030402
//with button
/*
function browseIt(formName,selectName,formAction) {
	var w3c = (document.getElementById)? true:false;
	if (formAction == null){
		formAction = "/webapp/wcs/stores/servlet/CategoryDisplay";
	}
	if (w3c) {
		if (document.getElementById(selectName).value == "#") {
			document.getElementById(formName).action = "#";
		} else {
			document.getElementById(formName).action = formAction;
			document.getElementById(formName).submit();
		}
	} else {
		if (document.all[selectName].value == "#") {
			document.all[formName].action = "#";
		} else {
			document.all[formName].action = formAction;
			document.all[formName].submit();
		}
	}
}
*/
//function for submitting dropdowns - jonk 20030429
//without button
//added lines for cross-market store reference - bohuslav 20030603
function browseIt(formId,selectId) {
	if (w3c) {
		if (document.getElementById(selectId).value != "#") { //if the user uses the "back"-button the last selected value is still selected, this makes sure that the "browse here.." (#) doesn't get submitted.
			//document.getElementById(formId).action = document.getElementById(selectId).value; //set the form-action to the value of the selected option
			if (document.getElementById(selectId).value.indexOf(";;") != -1) {
				// parse harcoded link to store in another market
				var hc_link = document.getElementById(selectId).value;
				var keyVals = hc_link.split(";;");
				document.getElementById(formId).storeId.value = keyVals[0];
				document.getElementById(formId).langId.value = keyVals[1];
				document.getElementById(selectId).options[document.getElementById(selectId).options.length] = new Option ("Cross Link", keyVals[2], true, true);
			}
			else if (document.getElementById(selectId).value.indexOf("NEW") != -1) {
				document.getElementById(formId).action = '/webapp/wcs/stores/servlet/IkeamsNews';
			}	
			document.getElementById(formId).submit(); //submit the form
		}
	} else {
		if (document.all[selectId].value != "#") { //if the user uses the "back"-button the last selected value is still selected, this makes sure that the "browse here.." (#) doesn't get submitted.
			//document.all[formId].action = document.all[selectId].value; //set the form-action to the value of the selected option
			document.all[formId].submit(); //submit the form
		}
	}
}

//self-submitting select jonk 2005-10-07
function selectBrowse(frameName,formName,selectName) {
	var temp = "document." + formName + "." + selectName + ".options[document." + formName + "." + selectName + ".options.selectedIndex].value";
	if (eval (temp) != "do_nothing") {
		if (frameName=="") {
			location.href = eval (temp);
		} else if (frameName=="new") {
			window.open(eval (temp))
		} else {
			temp = frameName + ".location.href = " + temp;
			eval (temp);
		}
	}
}

//RangeIV change language
function changeLangId(langId) {
	var x = location.href.indexOf('langId');
	var y = location.href.indexOf('&', x);
	var newHref = location.href.substring(0, x);
	newHref = newHref.concat('langId=', langId);
	if (x < y ) {
		newHref = newHref.concat(location.href.substring(y));
	}
	location.href = newHref;
}

//RangeIV select store (ad version)
function selectStore(storeId, langId, storeNumber) {
	location.href = '/webapp/wcs/stores/servlet/IkeaNearYouView?storeId=' + storeId + '&langId=' + langId + '&StoreNumber=' + storeNumber;
}

//RangeIV select store (family version)
function selectStoreF(locale, storeNumber) {
    setCookie('selected_store_' + locale, storeNumber, null, '/' );

    if (arguments[2]) {
       location.href = location.href + '&localStore=' + arguments[2];
    } else {
        location.reload(true);
    }
}
var w3c = false;
var ie = false;
var timerID = null; 
var timerOn = false; 

if (document.getElementById) {
	var w3c = true;
}
if (document.all) {
	var ie = true;
}

//show a hidden layer
function displayLayer(strName,displayType){
    try {
		resetTimer();
		document.getElementById(strName).style.display = displayType;
	} catch (e) {}
}

//hide a shown layer
function noneLayer(strName){
	try {
		document.getElementById(strName).style.display = 'none';
	} catch(e) {}
}

function resetTimer() {
    if (timerOn) {  
        clearTimeout(timerID);  
        timerID = null;  
        timerOn = false;  
    } 
}

function showDropMenu(strName,displayType) {
    displayLayer(strName,displayType);
}

function hideDropMenu(strName) {
    if (timerOn == false) {  
        timerID = setTimeout('noneLayer("'+strName+'")',1000);
        timerOn = true;  
    } 
}

//swap image
function swapImage(imgName,imgSrc) {
	document.getElementById(imgName).src=imgSrc;
	//document.images[imgName].src=imgSrc;
}

//change the value of the search form
function logInFormValue(which,theValue) {
	if (document.getElementById(which).value == theValue) {
		document.getElementById(which).value='';
	} else if (document.getElementById(which).value == '') {
		document.getElementById(which).value=theValue;
	}
}

//change the state of the arrows in the menu
function rollArrow(chosen, objectID) {
	if(chosen == "active") {
		document.getElementById(objectID).className="arrowActive";
	}
	else {
		document.getElementById(objectID).className="arrow";
	}
}

//set style to an element
function setStyle(objId, style, styleValue) {
	document.getElementById(objId).style[style] = styleValue;
}

//change the class of an element
function changeClass(objectID, toClass) {
	document.getElementById(objectID).className=toClass;
}

//submit form
function submitIt(theFormName,parameter1,value1) { 
	document.getElementById(parameter1).value = value1; 
	temp = "document." + theFormName + ".submit()" 
	eval (temp); 
} 

// Functions for the search form in the header
function search(frmName){
    frm = document.getElementById(frmName);
    if(frm.onsubmit()){
        frm.submit();
    }
}

function checkSearch(searchForm){
    while(searchForm.query.value.charAt(searchForm.query.value.length-1)==' ') searchForm.query.value=searchForm.query.value.substring(0,searchForm.query.value.length-1);
    if (searchForm.query.value != "") {
        return true;
    } else {
        return false;
    }
}

// 070205 Functions created for Range IV by Jake
// A function to find all specified objects on a page and then show/hide them by definining the 'visibility' parameter to 'show' or 'hide'
// Function needed for IE 6 and below to hide select objects when dropdown layers are to be displayed (otherwise the select obj is showing through the layer)

// Object detection of IE7
var ie7 = (document.documentElement && typeof document.documentElement.style.maxHeight!="undefined")? true:false;

function tagVisibility(tag, visibility) {
	try {
	    if(ie && !ie7){ // Only fire if IE and not (e.g. less than)  IE7
	        var numOfForms = document.forms.length;
	        
	        for(var f=0; f<numOfForms; f++){
	            theForm = document.forms[f];

	            for(var i=0; i<theForm.length; i++){
	                var theElement = theForm.elements[i];
	                if(theElement.tagName == tag){
	                    if(visibility == 'hide'){
	                        hideElement(theElement);
	                    }else if(visibility == 'show'){
	                        showElement(theElement);
	                    }
	                }
	                
	                
	            }
	        }
	    }
	} catch (e) {}
}

function showElement(obj){
	obj.style.visibility = "visible";
}

function hideElement(obj){
	obj.style.visibility = "hidden";
}

/*  
 * DRUO 090312 - Search3
 */
 
 /*
 Removed IKEA00648492
 
function searchFieldValueUpdate(theFieldName)
{
	var this_url_path = window.location.pathname;
	var this_path_array = this_url_path.split("/");
	if(this_path_array[this_path_array.length-2] == "search")
	{
		if(document.getElementById(theFieldName).value == null || document.getElementById(theFieldName).value == '')
		{
			if (IRWreadCookie("RECENT_SEARCH_0"))
			{
				recentSearch = new String(IRWreadCookie("RECENT_SEARCH_0")).strip();
				if (recentSearch != null)
				{
					decodedStr = Url.decode(recentSearch);
				}
				document.getElementById(theFieldName).value=decodedStr;
			}
			else
			{
				document.getElementById(theFieldName).value='';
			}
		}
	}
}
*/

function postData(form,layout) {
	try {
	switch (layout) {
		case ( "optinnewsletter"):
			subscribeNewsletter(form);
		break
		default:
			alert('no handler found');
			//return true if no handler is found - then the form will be submited as normal
			return  true;
		break
	}
	//if a handler is found, return false - then the form wont be submited
	return false;
	} catch (e) {
		dev_e=e;
		return false;
		//return true if something goes wrong - then the form will be submited as normal
		return  true;
	}
}
function showError(string) {
	alert(string);
	//$('newsletterFormErrorContainer').show();
}
function subscribeNewsletter(form) {
	if (!form.action.endsWith('xml')) {
		form.action=form.action+'&returnType=xml';
		errorHeadline = $('newsletterFormErrorContainer').innerHTML;
		//set up loader
		$('progressbar').hide();
		$('progressbar').update("<img src=\"/ms/img/form/ajaxloader.gif\">");
	} else {
		$(form).getElements().each(function(item) {
			if(item.name=='zipCode' || item.name=='storeNumber' || item.name=='email1') {
				item.setStyle({
					backgroundColor: '#FFF'
				});
			}
		});
		$('newsletterFormErrorContainer').hide();
	}
	//hide all form fields and show a loader
	$(form).immediateDescendants().each(function(item) {
		item.setStyle({
			visibility: 'hidden'
		});
	});
	//disable the form until we have an answer
	$('progressbar').show();
	$('progressbar').setStyle({
			visibility: 'visible',
			margin: '-8px'
	});	
	$(form).request({ 
		method: 'get', 
		onFailure: function () {
			//failed fetching product information page... not correct status code
			showError('newsletter subscription service unavailable');
		},
		onException: function (instance,object) {
			//failed fetching product information page... misc error
			showError('misc error while loading');
			dev_instance=instance;
			dev_object=object;
		},
		onInteractive: function () {
			//show progress here
		},
		onSuccess: function(transport){ 
			$('progressbar').hide();	
			var requestXML = transport.responseXML;
				var validation  = requestXML.getElementsByTagName('validation')[0];
				var validationStatus = validation.attributes[1].nodeValue;
				if (validationStatus != 'true') {
					//handle errors
					var errorFields = validation.getElementsByTagName('field');
					var errorList='<ul>';
					for (i=0;i<errorFields.length;i++) {
						var item = errorFields[i];
						var itemName=item.getElementsByTagName('name')[0].firstChild.data;
						var itemMessage=item.getElementsByTagName('message')[0].firstChild.data;
						errorList=errorList+'<li>- '+itemMessage+'</li>';
						$(form).getElements().each(function(item) {
							if (item.name == itemName) {
								item.setStyle({
									backgroundColor: '#FF9797'
								});
							}
						});
					}
					errorList=errorList+'</ul>';
					//the answer returned erros, enable the form again
					$(form).immediateDescendants().each(function(item) {
						item.setStyle({
							visibility: 'visible'
						});
					});					
					$('newsletterFormErrorContainer').update(errorHeadline+errorList);
					$('newsletterFormErrorContainer').show();
					$('newsletterFormErrorContainer').siblings()[1].hide();
				} else {
					//post ok
					$('newsletterFormContainer').hide();
					$('newsletterFormConfirmationContainer').show();
					$('newsletterFormErrorContainer').hide();
				}
			return;
		}
	});
}
function subscribeNewsletter_error() {

}
function retest() {
	$('newsletterFormConfirmationContainer').hide();
	$('newsletterFormContainer').show();
	$('newsletterFormErrorContainer').hide();
	$('progressbar').update('');
	return false;
}

var cookieName = "irw_compare";
var cookieValueSeparator = "**";
var cbCount = 0;
var cbDisabled = true;
var cbArray = new Array();
var cbRecArray = new Array();
var buttonArray = new Array();

/* This function is needed in order for firefox to force a reload of the page when presseing backbutton */
window.onunload = function() {
cbCount=0; 
updateComparison();
};

/**
* Adds a product to the compare cookie
*/
function addProductToCompare(productNumber){
	var currentValue = getCookie(cookieName);
	var newVal = null;
	if(currentValue == null || currentValue == ""){
		newVal = productNumber;
	} else if (currentValue.indexOf(productNumber) == -1) {
		newVal = currentValue + cookieValueSeparator + productNumber;
	} else {
		return;
	}

	cbCount = cbCount + 1;
	document.cookie=cookieName+"="+escape(newVal)+";path=/";
}

/**
*Removes a product form the comparison
*cookie
*/
function removeProductToCompare(productNumber){
	var values = getCookie(cookieName);
	if(values == null || values == "" || values.indexOf(productNumber) == -1){
		return;
	}
	var newVal = values.replace(cookieValueSeparator + productNumber,'');
	//If the product is the first in the list
	newVal = newVal.replace(productNumber + cookieValueSeparator,'');
	//if the product is the only product	
	newVal = newVal.replace(productNumber,'');

	cbCount = cbCount - 1;
	document.cookie=cookieName+"="+escape(newVal)+";path=/";
}

function setComparisonCheckboxStatus(){
		
	try {
		if (navigator.appName.toLowerCase().indexOf("microsoft") != -1) {
			setTimeout("initCompareCheckboxStatus()", 0);
		} else {
			initCompareCheckboxStatus();
		}
	} catch (error) {
		initCompareCheckboxStatus();
	}
	
}

function initCompareCheckboxStatus() {
	//Unset all checkboxes in the products container and set an observer on each of them
	var prodContainer = $('productsContainer');
	if(prodContainer == null) return;
	var objects = prodContainer.select('div.cartContainer');
	objects.each(function(item) {
		//Get the checkbox
		var cb = item.down('input');
		cbArray.push(cb);
		//Show the compare checkbox and text
		cb.up(0).style.display = 'block';
		//Uncheck the checkbox
		cb.checked = false;
		cb.disabled = true;
		//Add click observer to the checkbox
		Event.observe(cb,'click',function(e) {
			updateCheckbox(e.target,false);
		});		
	});
	
	//check for product recommendation container
	var recCont = $('main').down('.rightContent').down('.prodRecsContainer');
	if (recCont != null) {
		//product recommendation container exists
		var i=0;
		var obj = null;
		while ((obj = recCont.down('input', i)) != null) {
			cbRecArray.push(obj);
			obj.up(0).style.display = 'block';
			obj.checked = false;
			obj.disabled = true;	
			Event.observe(obj, 'click', function(e) {
				updateCheckbox(e.target,true);
			});
			i = i + 1;
		}
	}	
		
	//Go through the coockie array and check the right checkboxes
	var values = getCookie(cookieName);
	if(values != null && values != ""){
		var products = values.split(cookieValueSeparator);
		var len = products.length;
		for(var i = 0; i < len;i++) {
			var cb = $('compare_'+products[i]);
			if (cb != null) {
				cb.checked = true;
				cb.disabled = false;
                // Also check the checkboxes used for display
                var cbDisplay = $('display_compare_'+products[i]);
				cbDisplay.checked = true;
				cbDisplay.disabled = false;
                cbDisplay.up(0).style.display = 'block';
			}
			var cbRec = $('prodrec_compare_'+products[i]);
			if (cbRec != null) {
				cbRec.checked = true;
				cbRec.disabled = false;
			}
			cbCount = cbCount + 1;
		}
	}
	//Store the 'Show comparison' buttons in an array
    try{
        buttonArray.push($('main').down('.rightContent').down('.paginationContainer',0).down('.buttons').down('a'));
        buttonArray.push($('main').down('.rightContent').down('.paginationContainer',1).down('.buttons').down('a'));
	}catch (e) {    //For search page
        buttonArray.push($('main').down('.rightContent').down('.paginationContainer',0).down('.paginationRight').down('a'));
        buttonArray.push($('main').down('.rightContent').down('.paginationContainer',1).down('.paginationRight').down('a'));
    }
	//If any cookies were found, try to enable the compare button
	updateComparison();
}

function updateCheckbox(cb,isProdRec) {
	var productNumber = cb.id.substring(cb.id.lastIndexOf('_')+1);
	if (cb.checked) {
		addProductToCompare(productNumber);
	} else {
		removeProductToCompare(productNumber);
	}
	var item = null;
	if (isProdRec) {
		item = $('compare_' + productNumber);
	}	else {
		item = $('prodrec_compare_' + productNumber);
	}
	if (item != null) {
		item.checked = cb.checked;
	}
	updateComparison();
}

function updateComparison() {
	try {
		buttonArray.each(function(item) {
			//Get the link in the pagination container.
			var b = (cbCount >= 2);
			//if the b (show) = false and the link is enabled, disable it.
			if (!b && !item.hasClassName('disabledButton')) {
				item.addClassName('disabledButton');
			} 
			//if the b (show) = true and the link is disbaled, enable it.
			else if (b && item.hasClassName('disabledButton')) {
				item.removeClassName('disabledButton');
			}
		});
		//allow maximum of 4 checkboxes
		if (cbCount >= 4 && !cbDisabled) {
			cbArray.each(function(item) {
				if (!item.checked) {
					item.disabled = true;
				}
				cbDisabled = true;
			});			
			cbRecArray.each(function(item) {
				if (!item.checked) {
					item.disabled = true;
				}
				cbDisabled = true;
			});			
		} else if (cbCount < 4 && cbDisabled) {
			cbArray.each(function(item) {
				item.disabled = false;
			});			
			cbRecArray.each(function(item) {
				item.disabled = false;
			});			
			cbDisabled = false;
		}		
	} catch (err) {}
}

/**
 * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
 *
 * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */
if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10];},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15];},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=new Array();var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="<embed type=\"application/x-shockwave-flash\" src=\""+this.getAttribute("swf")+"\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\"";_19+=" id=\""+this.getAttribute("id")+"\" name=\""+this.getAttribute("id")+"\" ";var _1a=this.getParams();for(var key in _1a){_19+=[key]+"=\""+_1a[key]+"\" ";}var _1c=this.getVariablePairs().join("&");if(_1c.length>0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="<object id=\""+this.getAttribute("id")+"\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\">";_19+="<param name=\"movie\" value=\""+this.getAttribute("swf")+"\" />";var _1d=this.getParams();for(var key in _1d){_19+="<param name=\""+key+"\" value=\""+_1d[key]+"\" />";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="<param name=\"flashvars\" value=\""+_1f+"\" />";}_19+="</object>";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.major<fv.major){return false;}if(this.major>fv.major){return true;}if(this.minor<fv.minor){return false;}if(this.minor>fv.minor){return true;}if(this.rev<fv.rev){return false;}return true;};deconcept.util={getRequestParameter:function(_2b){var q=document.location.search||document.location.hash;if(_2b==null){return q;}if(q){var _2d=q.substring(1).split("&");for(var i=0;i<_2d.length;i++){if(_2d[i].substring(0,_2d[i].indexOf("="))==_2b){return _2d[i].substring((_2d[i].indexOf("=")+1));}}}return "";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var _2f=document.getElementsByTagName("OBJECT");for(var i=_2f.length-1;i>=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;
/**
 *
 * Extra functions designed to work together with SWFObject v1.4.4 and Webtrends
 *
 */
  
 //This function checks for extra flash variables in url.
 function writeFlash(swfObject) {
	try {
		FlashVarArray=getFlashVars(swfObject.getAttribute('id'));
		for (var i=0;i<FlashVarArray.length;i++) {
			thisFlashVar=FlashVarArray[i].split("=");
			swfObject.addVariable(thisFlashVar[0], thisFlashVar[1]);
		}
	} catch (e) {
	}
	try {
        var installedVersion = deconcept.SWFObjectUtil.getPlayerVersion();  // Get installed version
        var swfObjectVersion = swfObject.getAttribute('version');   // Get version from flash obj
 
	// ----------------------------------------------------
	// 080624 PAMN - Temporary workaround
	// ----------------------------------------------------
	// See: http://www.adobe.com/support/documentation/en/flashplayer/9/releasenotes.html
	// MPA2 roomsettings requires fullscreen with wmode which 
	// requires a Flashplayer of version 9.0.115 and above when 
	// using wmode. We need to force a check on the revision as well as the
	// major version.

	if( swfObjectVersion.major == 1000 )
	{
		if(installedVersion.major < 9 || (installedVersion.major == 9 && installedVersion.minor == 0 && installedVersion.rev < 115))//Greater than version 9
		{
			//Keep failing
		}
		else
		{
			swfObjectVersion.major = installedVersion.major;
		}
	}
	// End workaround

        var flashBar = $('flashBar');   // The div containing the flash error msg
        //alert('installed= ' + installedVersion.major + ' obj= ' + swfObjectVersion.major);
        if(installedVersion.major >= swfObjectVersion.major){
    		swfObject.write("flashcontent");
        }else{
            flashBar.show();    // Show the flashbar
            $('flashcontent').hide();   // Hide (collapse) the flash area
        }
        //then rename the flash container to be able to take care of the next one (if more than one exists on the page)  (IE bug)
        var flashElement = $('flashcontent');
        flashElement.id='flashcontent_used';
	
				//Check if this is the first element in the rightContent div
				//or the element after the <a name="mainContent"></a> element in the main block
        var prev = flashElement.previous();
        var flashParent = null;
        if (prev == null) {
        	//element is the first
        	flashParent = flashElement.up(0);
        } else {
        	//check if element prevoius is the <a name="mainContent"> element
        	if (prev.tagName.toLowerCase() == 'a' && prev.readAttribute('name') == 'mainContent') {
        		flashParent = prev.up(0);
        	}
        }
        if (flashParent != null && (flashParent.hasClassName('rightContent') || flashParent.id == 'main')) {
        	flashElement.addClassName('firstFlashContent');
        }
        	        
        
    } catch (e) {
        // Fallback to old solution since new one does not work...due to missing code/files...
        try {
            swfObject.write("flashcontent");
    		//rename the container  (iebug)
    		document.getElementById('flashcontent').id='flashcontent_used';
        } catch (err) {
        }
	}
 }
 
 //Function that returns an array with Flash variables
 // The flash_id is used to identify the flash_vars. We need to add a '_' to the id since that is used in the querystring.
 // The id + '_' is then removed before pushed to the flashVar-array.
function getFlashVars(flash_id ) {
	flash_id = flash_id + '_';
	currentFlashVar = 'flash_' + flash_id ;

	thisArray=new Array();
	try {
		href=document.location.href;
		startPath='none';
		urlArray=new Array();
		urlArray=href.split('?');
		if (urlArray.length==2) {
			querystringArray=new Array();
			querystringArray=urlArray[1].split('&');
			for (var i=0;i<querystringArray.length;i++) {
				thisQueryVar=querystringArray[i].split("=");
				
				// If the id contains a space ' ' we have to replace '%20' from the url to ' '
				cleanedQuerystring = querystringArray[i].replace("%20"," ");
				//document.write(cleanedQuerystring);
				if (cleanedQuerystring.substring(0,(6 + flash_id.length))==currentFlashVar) {
					thisArray.push(cleanedQuerystring.substring(0,6) + cleanedQuerystring.substring((6 + flash_id.length),cleanedQuerystring.length));
				}
			}
		}
	} catch (e) {
	}
	return thisArray;
}

function swf_isDefined(variable) {
	return eval('(typeof('+variable+') != "undefined");');
}

//function for for stat generation with exception handling
function IRWdcsMultiTrack() {
	try {
		var trackRia = [];
		
		trackRia.push("IRWStats.version");
		trackRia.push("1.0");
	
		for (var IRWdcsCount = 0; IRWdcsCount < arguments.length; IRWdcsCount++) {
			if (arguments[IRWdcsCount].indexOf('DCS.dcsuri') == 0) {
				trackRia.push("IRWStats.riaRequestName");
				trackRia.push(arguments[IRWdcsCount+1].replace(/\'/g, ""));
				IRWdcsCount++;
			} else if (arguments[IRWdcsCount].indexOf('WT.ti') == 0) {
				trackRia.push("IRWStats.pageName");
				trackRia.push(arguments[IRWdcsCount+1].replace(/\'/g, ""));
				IRWdcsCount++;
			} else if (arguments[IRWdcsCount].indexOf('WT.cg_n') == 0) {
				trackRia.push("IRWStats.category");
				trackRia.push(arguments[IRWdcsCount+1].replace(/\'/g, ""));
				IRWdcsCount++;
			} else if (arguments[IRWdcsCount].indexOf('WT.cg_s') == 0) {
				trackRia.push("IRWStats.subCategory");
				trackRia.push(arguments[IRWdcsCount+1].replace(/\'/g, ""));
				IRWdcsCount++;
			}
		}
		
		var riaArgs = "";
		for (var args = 0; args < trackRia.length; args++) {
			riaArgs += "'"+trackRia[args]+"',";
		}
		riaArgs = riaArgs.substr(0, (riaArgs.length-1));
		eval("irwStatTrackRia("+riaArgs+");");
	} catch (e) {}	
}

//Function to handle flash calls from older versions
function IRWflashTrack() {
	try {
		var trackRia = [];
		
		trackRia.push("IRWStats.version");
		trackRia.push("1.0");
	
		for (var IRWdcsCount = 0; IRWdcsCount < arguments.length; IRWdcsCount++) {
			if (arguments[IRWdcsCount].indexOf('DCS.dcsuri') == 0) {
				var dcsData = arguments[IRWdcsCount+1].replace(/\'/g, "");

				var dcsArray = dcsData.split("/");

				trackRia.push("IRWStats.riaAsset");
				trackRia.push(dcsArray[0]);

				trackRia.push("IRWStats.riaAssetType");
				trackRia.push("other");

				trackRia.push("IRWStats.riaAction");
				trackRia.push(dcsArray[2]);

				trackRia.push("IRWStats.riaActionType");
				trackRia.push("unknown");

				IRWdcsCount++;

				break;
			}
		}
		
		var riaArgs = "";
		for (var args = 0; args < trackRia.length; args++) {
			riaArgs += "'"+trackRia[args]+"',";
		}
		riaArgs = riaArgs.substr(0, (riaArgs.length-1));
		eval("irwStatTrackRia("+riaArgs+");");
	} catch (e) {}	
}
/*
Author:     JBNN
Date:       08-02-15
Use:        These functions and variables are used for the new sliding dropdown menu for All Departments in top menu.
                They are dependant on prototype.js and scriptacoulus.js which should be initialized before this file.
                
Update:     09-01-21
                - Code improvements
                - New function(s) added for simplified left hand navigation
*/

var menuStatus = 'up';  // Parameter to determine whether menu is up or down and is changed when it is completely up/down
var menuPos = 'goUp';           // Parameter to force menu to stay in position on mouseout/mouseover
var toggleId;
var selectedPath = new Array(); 
var activeLinkClass = 'active'; 

/**
*Checks the current link and if it is a guides-link
*/
function checkIfGuidesLink(){
	checkCheckedLink(self.document.location);
}

/*
* If the link is a navigations link from leftNavLinks ad
* it will be selected and the current selection will be
* deselected from the product navigation
*/
function checkCheckedLink(link){
	var hash = link.hash;//self.document.location.hash;
	if(hash == null || '' == hash){
		return;
	}
	var ids = hash.split('-');
	if(ids.length < 2){
		return;
	}
	//Select and expand guides link
	var linkId = 'lnk1.leftnav-'+ids[1]+'-'+ids[2];
	setActiveLink(linkId,true);
	var item = $('lnkSubItemsNavEspot1'+ids[1]);
	toggleBtn(item,$('navToggleNavEspot1'+ids[1]));
	item.show();
	/*Checks if there is a current selected link in the product presentation
	* and de activates it*/
	var len = selectedPath.length;
	for(var i = 0; i < len;i++){
		var obj = selectedPath[i];
		if(!Object.isUndefined(obj.item) && obj.item != null){
			hideMenu($(obj.item),$(obj.btn));
		}else if(!Object.isUndefined(obj.active) && obj.active != null){
			setActiveLink(obj.active,false);		
		}
	}
}

/**
* 
* Activates or de-activates a link in the left navigation
* @param linkId The id of the link that should be (de|)activated 
* @param activate Set to true to activate link, false to deactivate
*/
function setActiveLink(linkId,activate){
	var selectLink = $(linkId);
	var spans = selectLink.getElementsBySelector("span");
	if(spans.length > 0){
		var span = spans[0];
		if(activate){
			span.addClassName(activeLinkClass);
		}else{
			span.removeClassName(activeLinkClass);
		}
			
	}	
}

/**
*
*Adds a container to the selected path
*/
function addContainerToSelectedPath(item,btn){
	selectedPath.push({"item":item,"btn":btn});
}

/**
*KHTJ
* Adds an active link to the selected path
*/
function addLinkToSelectedPath(linkId){
	selectedPath.push({"active":linkId});
}

/**
 * Function(s) for new simplified left hand navigation. Used on category/department pages
 */

function toggleMenuItem(item,btnToggle){
    new Effect.toggle(item, 'slide', {
        delay: 0.3,
        duration:0.6,
        afterFinish: toggleBtn(item, btnToggle)
    });
}

function toggleBtn(menu,btn) {
    if(menu.visible()){
        btn.update("+");
        btn.removeClassName('navToggleOpen');
        btn.next(0).removeClassName('open');
    }else{
        btn.update("&#x2212;");
        btn.addClassName('navToggleOpen');
        btn.next(0).addClassName('open');
    }
}

function hideMenu(item,btn){
    btn.update("+");
    btn.removeClassName('navToggleOpen');
    btn.next(0).removeClassName('open');
    item.hide();
}

/**
* Functions for All departments dropdown
*/

function callbackDownEnd(obj){
    menuStatus = 'down';
}

function callbackUpEnd(obj){
    menuStatus = 'up';
}

function menuSlideDown(){
    if(($('moreRoomsMenu').getStyle('display') == 'none') && (menuStatus == 'up')){
        // change status to prevent new call until the slide is done
        //trace('sliding down');
        new Effect.SlideDown('moreRoomsMenu', {
            queue: {position: 'end', scope: 'slideDown', limit: 1}, 
            duration: 0.4,
            afterFinish: callbackDownEnd
        });
    }
}

function menuSlideUp(){
    if(($('moreRoomsMenu').getStyle('display') == 'block') && (menuStatus == 'down')){
        // change status to prevent new call until the slide is done
        //trace('sliding up');
        new Effect.SlideUp('moreRoomsMenu', {
            queue: {position: 'end', scope: 'slideUp', limit: 1}, 
            duration: 0.4,
            afterFinish: callbackUpEnd
        });
    }
}

function menuSlideStart(){
    if(menuPos == 'goUp'){
        // If still 0 then no mouseover on menu, so close it
        menuSlideUp();
    }else{
        menuSlideDown();
    }
    return menuPos;
}

function menuToggle(direction){
    clearTimeout(toggleId);
    if(direction == 'down'){
        menuPos = 'goDown';
    }else{
        menuPos = 'goUp';
    }
    toggleId = setTimeout('menuSlideStart()',250);
}

/* Add observers to necessary tags (for drop down menu) */
Event.observe(window, 'load', function() {
	if ($('moreRoomsMenu')) {
	    // Add event listener to the div "moreRoomsMenu". This is used to check if user goes from menu button and then over the menu...or just leaves the menu button.
	    $('moreRoomsMenu').observe('mouseover', function(event){
	        element = Event.element(event);
	        myAncestors = element.ancestors();

	        // Traverses the parents of current tag
	        myAncestors.each(function(tag){
	            if(tag.id == 'moreRoomsMenu'){
	                menuPos = 'stayDown';
	            }
	        });
	    });

	    // Add event listener to the div "moreRoomsMenu". This is used to check if user goes from menu button and then over the menu...or just leaves the menu button.
	    $('moreRoomsMenu').observe('mouseout', function(e){
	        var element = Event.element(e);
	        var inside = false;

	        // Get the element we mouse out to
	        var goToElement = (e.relatedTarget) ? e.relatedTarget : e.toElement;
	        myAncestors = goToElement.ancestors();
	 
	        // Traverses the parents of the related target (the element that the mouse goes to) and try to find the "moreRoomsMenu"
	        myAncestors.each(function(tag){
	            if(tag.id == 'moreRoomsMenu'){
	                inside = true;
	            }
	        });
	        
	        // If inside is false, then we have left the menu...so slide it up
	        if(inside == false){
	            menuSlideUp();
	        }
	    });
	}
    
	if ($('moreRooms')) {
	    // Add events to all menu buttons preceeding the moreRooms button, to slide the menu up on mouseover
	    var myBtns = $('moreRooms').previousSiblings();
	    myBtns.each(function(tag){
	        tag.observe('mouseover', function(event){
	            menuSlideUp();
	        });
	    });
	}

    //this should be used as a temporary solution until the left navigation as been implemented in comerce 
    setupSearchMenu();
});

function setupSearchMenu() {
	var searchgroups = $$('.search-groups');
	if (searchgroups.length > 0) {
		try {
			$('minPrice').writeAttribute('style','');
			$('maxPrice').writeAttribute('style','');			
		} catch (err) { }
		var gindex = 1;
		searchgroups[gindex].select('div.header').each(function(obj) {
			if (gindex == 1) gindex = 2;
			var s = obj.readAttribute('onclick');
			var i = s.substring(s.indexOf('(')+2,s.indexOf(')')-1);
			var div = new Element('div', {'class':'contentWrapper'});
			var contentDiv = $('content-' + i);
			contentDiv.childElements().each(function(child) {
				div.insert(child);
			});
			contentDiv.insert(div);
			if (contentDiv.hasClassName('not-displayed')) {
				contentDiv.className = '';
				contentDiv.hide();
			} else {
				obj.addClassName('headerActive');
			}
			obj.writeAttribute('onclick', '');
			if (div.childElements().length == 0) {
				obj.addClassName('headerInactive');
			} else {
				Event.observe(obj, 'click', function(e) {
					this.toggleClassName('headerActive');
					toggleMenuItemSearch(this.next(0));
				});
				Event.observe(obj, 'mouseover', function(e) {
					if (!this.hasClassName('headerHover')) this.addClassName('headerHover');
				});
				Event.observe(obj, 'mouseout', function(e) {
					if (this.hasClassName('headerHover')) this.removeClassName('headerHover');
				});
			}
		});
		/*  IKEA00648492  removed
		var rel = searchgroups[gindex].down('h2');
		rel.addClassName('headerActive');
		rel.writeAttribute('onclick', '');
		Event.observe(rel, 'click', function(e) {
			this.toggleClassName('headerActive');
			toggleMenuItemSearch(this.next(0));
		});
		var div = new Element('div', {'class':'contentWrapper'});
		var contentDiv = $('content-5');
		contentDiv.childElements().each(function(child) {
			div.insert(child);
		});
		contentDiv.insert(div);
		
		*/
	}
}
	
function toggleMenuItemSearch(item) {
    new Effect.toggle(item, 'slide', {
        delay: 0.3,
        duration:0.6
    });
}

function openPrfPopup(id) {
	var offsetLeft = -15;
	var offsetTop = 17;

	var x = document.getElementById(
		id);
	var v = document.getElementById(
		"prfinfo");
	
	if(!v || !x){
		return;
	}
	v.style.display = "block";
	
	var xpos = getPosX(x);
	var ypos = getPosY(x);
	
	v.style.position = "absolute";
	v.style.top = (ypos - v.offsetHeight + offsetTop) + "px";
	v.style.left = (xpos + offsetLeft) + "px";
}

function closePrfPopup() {
	var v = document.getElementById(
		"prfinfo");
	v.style.display = "none";
}

function getPosX(obj) {
	var curleft = 0;
	if(obj.offsetParent) {
		while(1) {
			curleft += obj.offsetLeft;
			if(!obj.offsetParent)
				break;
			obj = obj.offsetParent;
		}
	} else if(obj.x) {
		curleft += obj.x;
	}
	return curleft;
}

function getPosY(obj) {
	var curtop = 0;
	if(obj.offsetParent) {
		while(1) {
			curtop += obj.offsetTop;
			if(!obj.offsetParent)
				break;
			obj = obj.offsetParent;
		}
	} else if(obj.y) {
		curtop += obj.y;
	}
	return curtop;
}

/**
* Slideshow
*
* This library is used to create a lightbox Slideshow in a web application. This library
* requires the Prototype 1.6 library and Script.aculo.us core, effects, and dragdrop
* libraries.
*	
*	Event.observe(window, 'load', function () {
*		slideshow = new Slideshow();
*	});
*     
*/
var californiaTemplate;
var Slideshow = Class.create({
	open : function (prodId) {
		this._centerWindow(this.container);
		this._fade('open', this.container);
        if(typeof(prodId) != 'undefined'){  // If clicked on a product in listing
            this.showProduct(prodId);
        }else{  // Clicked on slideshow button
            this.showProduct(this.firstProduct);
        }
		
		// Send data to web analytics
		irwStatPageFunctionality("product display>slideshow", "slideshow");
	},
	
	close : function () {
		this._fade('close', this.container);
	},
	
	_fade : function fadeBg(userAction,whichDiv){
		if(userAction=='close'){
			new Effect.Opacity('slideshowBg',
                {duration:.5,
				from:0.5,
				to:0,
				afterFinish:this._makeInvisible,
				afterUpdate:this._hideLayer(whichDiv)});
		}else{
			new Effect.Opacity('slideshowBg',
				{duration:.5,
				from:0,
				to:0.5,
				beforeUpdate:this._makeVisible,
				afterFinish:this._showLayer(whichDiv)});
		}
	},
	
	_makeVisible : function makeVisible(){
		$("slideshowBg").style.visibility="visible";
	},

	_makeInvisible : function makeInvisible(){
		$("slideshowBg").style.visibility="hidden";
	},

	_showLayer : function showLayer(userAction){
        new Effect.Appear($(userAction),
                   {duration:.7,
                    from:0,
                    to:1});
    },
	
	_hideLayer : function hideLayer(userAction){
        new Effect.Fade($(userAction),
                   {duration:.7,
                    from:1,
                    to:0});
	},

    _loader : function loader() {
        var loader = this.loaderTemplate.evaluate({loadingText:'Loading...'});
        return loader;
    },
	
	_centerWindow : function centerWindow(element) {
		if($(element) != null) {
            if(typeof window.innerHeight != 'undefined') {
                $(element).style.top = Math.round(document.viewport.getScrollOffsets().top + ((document.viewport.getHeight() - $(element).getHeight()))/2)+'px';
                $(element).style.left = Math.round(document.viewport.getScrollOffsets().left + ((document.viewport.getWidth() - $(element).getWidth()))/2)+'px';
            } else {  // IE
                $(element).style.top = Math.round(document.viewport.getScrollOffsets().top + ((document.viewport.getHeight() - $(element).getHeight()))/2)+'px';
                $(element).style.left = Math.round(document.viewport.getScrollOffsets().left + ((document.viewport.getWidth() - $(element).getWidth()))/2)+'px';
            }
        }
	},

    _handleError : function handleError(request,errObj) {
        // alert("Error: "+errObj.number
            // +"\nType: "+errObj.name
            // +"\nDescription: "+errObj.description
            // +"\nSource Object Id: "+errObj.srcElement.instanceId
        // );
    },

	_getProductInfo : function getProductInfo(prodId,show){
        var locale = $('lnkIKEALogoHeader').readAttribute('href');
        var url = locale + "catalog/products/" + prodId;

    	new Ajax.Request(url, {
            method: Iows.method,
            contentType: Iows.contentType,
            parameters:{type: Iows.type, dataset: Iows.dataset},
            onSuccess: function(response) {
                var xmlDoc = response.responseXML;
                this._addProduct(xmlDoc,show);
            }.bind(this),
            onFailure: this._handleError,
			onException: this._handleError
        });
	},

    _addProduct : function addProduct(doc,show) {
        var product = doc.getElementsByTagName('product')[0];
        
        // If error returned
        if(typeof(product) == 'undefined' || product == null){
            var error = doc.getElementsByTagName('error')[0];
            var partNo = error.getAttribute('referencedId');
            var code = error.getAttribute('code');
            var msg = Iows.getNodeVal(error,'message');
            
            var prodObj = new Object();
            prodObj.partNo = partNo;
            prodObj.prodName = 'Not available!';
            prodObj.keyMoreInfo = 'Sorry, product not available at the moment. ' + msg + '.';
            prodObj.imgL = 'http://www.ikea.com/ms/sv_SE/img/error/error279x279.jpg';
        }else{
            var item = product.getElementsByTagName('item')[0];
			var partNo = Iows.getNodeVal(item,'partNumber');
			var prodName = Iows.getNodeVal(item,'name'); 
			var pipLink = Iows.getNodeVal(item,'URL');
			var isNew = Iows.getNodeVal(item,'new');
			var buyable = Iows.getNodeVal(item,'buyable');
			var prodDesc = Iows.getNodeVal(item,'facts');
			var measure = Iows.getNodeVal(item,'measure');
			var bti = Iows.getNodeVal(item,'bti');
			var images = item.getElementsByTagName('images')[0];
			var large = images.getElementsByTagName('large')[0];
			var imgL = Iows.getNodeVal(large,'image');
			var small = images.getElementsByTagName('small')[0];
			var imgS = Iows.getNodeVal(small,'image');
			// get the descriptive attributes
			var descriptiveAttributes = getDescriptiveAttributes(item);
			// get the warning attribute from the descriptive attributes array
			var warningDescAttr = getDescAttributeByType(descAttrWarning,descriptiveAttributes);
            var isCalTitle20 = false;
            if(doc.getElementsByTagName("californiaTitle20").length>0){
				isCalTitle20 = true;
			}             
            // Object for the template
            var prodObj = new Object();
            prodObj.storeId = this.storeId; 
            prodObj.langId = this.langId;
            prodObj.imgL = imgL;
            prodObj.imgS = imgS;
            prodObj.prodName = prodName;
            prodObj.partNo = partNo;
            prodObj.pipLink = pipLink;
            prodObj.prodDesc = prodDesc;
            prodObj.keyBuyOnline = this.keys.get('fw11_buy_online');
            prodObj.keySaveToList = this.keys.get('fw11_save_to_shopping_list');
            prodObj.keyMoreInfo = this.keys.get('fw11_slideShow_more_info');
            
            var prices = Iows.getPrices(item);
            prodObj.normalPrice = prices.price;
            prodObj.dualPrice = prices.priceDual;
            if(prices.pricePkg != null){
                prodObj.pkgPrice = this.keys.get('fw11_price_per_package') + ' ' + prices.pricePkg;
            }
            // Family prices
            if(!prices.family.blank()){
                prodObj.keyFamily = this.keys.get('r4_ikea_family');
                prodObj.familyPrice = prices.family;
                if(prices.pricePkg != null){
                    prodObj.familyPkgPrice = this.keys.get('fw11_price_per_package') + ' ' + prices.familyPkg;
                }
                prodObj.displayFamilyPrice = this.familyPriceTemplate.evaluate(prodObj);
            }
            // Weee prices
            if(prices.prfCharge != null && prices.noPrfCharge != null){
                prodObj.prfCharge = prices.prfCharge
                prodObj.noPrfCharge = prices.noPrfCharge;
                prodObj.weee_prf = this.keys.get('weee_prf');
                prodObj.weee_less_prf = this.keys.get('weee_less_prf');
                if(bti == "true"){
                    prodObj.btiClass = "bti";
                }
                prodObj.displayPrfPrice = this.weeePrfTemplate.evaluate(prodObj);
            }
			if(warningDescAttr != null){
				prodObj.warningInfo = this.warningTemplate.evaluate(warningDescAttr);
			}
			if(isCalTitle20){
				prodObj.calTitle20 = this.californiaTemplate.evaluate(isCalTitle20);;
			}
            // New image
            if(isNew == "true"){
                prodObj.newImgAlt = this.keys.get('r4_all_products_new');
                prodObj.newImgSrc = "/ms/" + irwstats_locale + "/img/icons/new_large.gif";
                prodObj.newImg = this.newImgTemplate.evaluate(prodObj);
            }
            // Buy online button
            if(buyable == "true"){
                prodObj.buyOnline = this.buyOnlineTemplate.evaluate(prodObj);
            }
            // Measures
            var moreKey = this.keys.get('r4_more_options');
            prodObj.measure = Iows.getMeasures(measure,this.dimensionTemplate,this.moreInfoTemplate,moreKey,pipLink);
            // Series, Systems or Collection
            prodObj.ssc = Iows.getSSC(product,this.sscTemplate);
            // BTI wrappers
            if(bti == "true"){
                prodObj.btiIncludeBefore = this.btiIncludeBeforeTemplate.evaluate(prodObj);
                prodObj.btiIncludeAfter = this.btiIncludeAfterTemplate.evaluate(prodObj);
            }
        }
        // Update cache object for thumbs
        this._cacheThumb(prodObj);
        
        // Add the product to the product container
        var newProduct = this.slideshowProdTemplate.evaluate(prodObj);
        $('slideshowElements').insert(newProduct);
        
        if(show){
            this.showProduct(partNo,show);
        }
    },
    
    /** Main function to show a product in the slideshow
        First checks if the product is already stored in the product container. If so, show it and also change the active thumb.
        If not, requests it through _getProductInfo() that inserts it to the product container, and then does a callback here to show it.
        It also fires _addProducts() which adds the next set of products, mainly for the navigations thumbs...
    **/
    showProduct : function showProduct(prodId,show) {
        // Start product loader
        $('slideshowProduct').update(this._loader());
        // Find product in cache obj
        var product = this.thumbs.get(prodId);
        
        // If product not in cache, ajax it, else just show it
        if(typeof(product) == 'undefined'){
            this._getProductInfo(prodId,true);
        }else{
            var product = $('slideshowElements').down('#element'+prodId);
            product = product.clone(true);
            // Change the id to handle mouse events
            var moreInfo = product.down('#moreInfo'+prodId);
            moreInfo.writeAttribute('id', 'moreInfo');
            $('slideshowProduct').setOpacity(0);
            $('slideshowProduct').update(product);
            new Effect.Opacity('slideshowProduct',
                {duration:.4,
                from:0,
                to:1});
            
            // Wait for all ajax calls to be done before setting active thumb
            new PeriodicalExecuter(function(pe) {
                if(Ajax.activeRequestCount <= 0) {
                    pe.stop()
                    // Update thumbs container
                    this._updateThumbs(prodId);
                    // Update navigation buttons
                    this._updateNavigation(prodId);
                    // $('slideshowThumbLoader').hide();
                    // $('slideshowThumbs').show();
                }
            }.bind(this),.5);
        }
        
        if(!show){
            // Add products for navigation
            this._addProducts(this.products,prodId);
        }
    },
    
    /** Add a set of products to the product container (if not there)  **/
    _addProducts : function addProducts(products,curProduct) {
        var noToAdd = this.noOfThumbs;   // Constant of number of products to add
        var prodArray = products;
        var curPos = prodArray.indexOf(curProduct.toString());
        
        var startPos = curPos-1;
        if(startPos < 0){startPos = 0};
        var toPos = (startPos + noToAdd);
        if(toPos > prodArray.size()){toPos = prodArray.size()};
        
        for(i=startPos;i<toPos;i++){
            var prodId = prodArray[i];
            
            // Find product in cache obj
            var product = this.thumbs.get(prodId);
            // If product not in cache, ajax it
            if(typeof(product) == 'undefined' && prodId != curProduct){
                this._getProductInfo(prodId);
            }
        }
    },

    /** Creates a thumb object and adds it to the thumbs cache object (a Hashmap)  **/
    _cacheThumb : function cacheThumb(obj) {
        var thumbObj = new Object();
        thumbObj.partNo = obj.partNo;
        thumbObj.imgS = obj.imgS;
        thumbObj.prodName = obj.prodName;
        thumbObj.prodDesc = obj.prodDesc;
        thumbObj.price = obj.normalPrice;
        
        // Add obj to the thumbs cache object
        this.thumbs.set(obj.partNo, thumbObj);
    },

    /** Updates the slideshowThumbs container with the thumbs to show and sets the current product to active **/
    _updateThumbs : function updateThumbs(prodId) {
        var thumbsToShow = this.noOfThumbs;
        var products = this.products;
        var thumbs = this.thumbs;
        
        var curPos = products.indexOf(prodId);
        var startPos = curPos -1;
        var endPos = startPos + thumbsToShow;
        if(endPos > this.length){endPos = this.length};
        $('slideshowThumbs').update();  // Empty thumbs container
        for (var i = startPos; i < endPos; ++i) {
            if(i == -1){
                var emptyThumb = this.slideshowEmptyThumbTemplate.evaluate();
                $('slideshowThumbs').insert(emptyThumb);
            }else{
                var prod = products[i];
                var thumbObj = this.thumbs.get(prod);
                var newThumb = this.slideshowThumbTemplate.evaluate(thumbObj);
                $('slideshowThumbs').insert(newThumb);
                var thumb = $('slideshowThumbs').down('#thumb'+prodId);
                // Set the active thumb
                if(thumbObj.partNo == prodId){
                    thumb.addClassName('thumbContainerActive');
                }
            }
        }
    },

    _updateNavigation : function updateNavigation(activeId) {
        var prodArray = this.products;
        var activePos = prodArray.indexOf(activeId.toString());
        var prevPos = activePos-1
        var nextPos = activePos+1
        var btnPrev = $('slideshowBtnPrev');
        var btnNext = $('slideshowBtnNext');
		var btnPrevText = this.keys.get('fw11_slideShow_previous');
		var btnNextText = this.keys.get('fw11_slideShow_next');
        
        // Previous
        var previousThumb = prodArray[prevPos];
        if(typeof(previousThumb) != 'undefined'){
            btnPrev.removeClassName('inactive');
            btnPrev.stopObserving();
            btnPrev.observe('click', function(e){
                this.showProduct(previousThumb.toString());
            }.bind(this));
            // Add custom event to be able to fire on key press (arrow left)
            btnPrev.observe('ss:click', function(e){
                this.showProduct(previousThumb.toString());
            }.bind(this));
            btnPrev.title = btnPrevText.replace('{0}',prevPos+1).replace('{1}',this.length);
        }else{
            btnPrev.addClassName('inactive');
            btnPrev.stopObserving();
        }
        
        // Next
        var nextThumb = prodArray[nextPos];
        if(nextThumb != null){
            btnNext.removeClassName('inactive');
            btnNext.stopObserving();
            btnNext.observe('click', function(e){
                this.showProduct(nextThumb.toString());
            }.bind(this));
            // Add custom event to be able to fire on key press (arrow right)
            btnNext.observe('ss:click', function(e){
                this.showProduct(nextThumb.toString());
            }.bind(this));
			btnNext.title = btnNextText.replace('{0}',nextPos+1).replace('{1}',this.length);
        }else{
            btnNext.addClassName('inactive');
            btnNext.stopObserving();
        }
        $('moreInfo').show();
    },
    
	initialize : function() {
        // Set parameters
        this.products = js_fn_SLIDE_SHOW_IDS;
        this.length = this.products.length;
        this.container = 'slideshowContainer';
        this.noOfThumbs = 10;
        this.thumbs = new Hash();
        try{
            this.firstProduct = $('productsTable').down('td a').readAttribute('href').split('/').last();    // Find first id in product listing
        }catch(err){};
        var storeId = $('myAccount')['storeId'];
        this.storeId = $F(storeId);
        var langId = $('myAccount')['langId'];
        this.langId = $F(langId);
        
        // Translation keys from global js vars
        this.keys = new Hash();
        this.keys.set('r4_more_options', js_fn_MORE_OPTIONS);
        this.keys.set('r4_more_products', js_fn_MORE_PRODUCTS);
        this.keys.set('r4_ikea_family', js_fn_IKEA_FAMILY);
        this.keys.set('r4_all_products_new', js_fn_ALL_PRODUCTS_NEW);
        this.keys.set('fw11_buy_online', js_fn_BUY_ONLINE);
        this.keys.set('fw11_save_to_shopping_list', js_fn_SAVE_TO_SHOPPING_LIST);
        this.keys.set('weee_prf', js_fn_WEE_PRF);
        this.keys.set('weee_less_prf', js_fn_WEE_LESSPRF);
        this.keys.set('fw11_slideShow_more_info', js_fn_SLIDE_SHOW_MORE_INFO);
        this.keys.set('fw11_price_per_package', js_fn_PRICE_PER_PACKAGE);
        this.keys.set('fw11_slideShow_close', js_fn_SLIDE_SHOW_CLOSE);
		this.keys.set('fw11_slideShow_next', js_fn_SLIDE_SHOW_NEXT);
		this.keys.set('fw11_slideShow_previous', js_fn_SLIDE_SHOW_PREV);
		this.keys.set('californiaTitle20LegalText', js_fn_CAL_LEGAL_TEXT);
		this.keys.set('californiaTitle20UrlText', js_fn_CAL_URL_TEXT);
		this.keys.set('californiaTitle20UrlRef', js_fn_CAL_URL_REF);
		this.keys.set('californiaMoreInformation', js_fn_CAL_MORE_INFO);
		
        // Add the shell for the slideshow
        var slideshowContainer = '<div id=\"slideshowContainer\" style=\"display:none;\">' +
            '<div id=\"slideshowBorder\">' +
                '<div id=\"slideshowContent\">' +
                    '<div id=\"slideshowProduct\"></div>' +
                    '<div id=\"slideshowNavigation\" onmouseover=\"$(\'moreInfo\').show()\" onmouseout=\"$(\'moreInfo\').hide()\">' +
                        '<a id=\"slideshowBtnPrev\" class=\"slideshowBtn inactive\" onclick=\"return false;\" href=\"#\" title=\"Previous\">&nbsp;</a>' +
                        '<div id=\"slideshowThumbs\"></div>' +
                        '<div id=\"slideshowThumbLoader\" class="thumbLoader" style=\"display:none\"><img src=\"/ms/img/loading.gif\" width=\"27\" height=\"27\"/></div>' +
                        '<a id=\"slideshowBtnNext\" class=\"slideshowBtn\" onclick=\"return false;\" href=\"#\" title=\"Next\">&nbsp;</a>' +
                    '</div>' +
                    '<a id=\"slideshowCloseBtn\" onclick=\"slideshow.close();return false;\" href=\"#\" title=\"'+this.keys.get('fw11_slideShow_close')+'\"></a>' +
                '</div>' +
            '</div>' +
        '</div>';
        document.body.insert(slideshowContainer);

        // Main product template
        this.slideshowProdTemplate = new Template('<div id="element#{partNo}" onmouseover=\"$(\'moreInfo\').show()\" onmouseout=\"$(\'moreInfo\').hide()\"><a href=\"#{pipLink}\">' +
            '<img src=\"#{imgL}\" border=\"0\" alt=\"#{prodName} #{prodDesc} #{normalPrice}\" class=\"prodImg\" title=\"#{keyMoreInfo}\"/></a>' +
            '<div id=\"prodInfo#{partNo}\" class=\"prodInfo\">' +
                '#{newImg}' + 
                '#{btiIncludeBefore}' +
                '<div class=\"prodName\">#{prodName}</div>' +
                '<div class=\"prodDesc\">#{prodDesc}</div>' +
                '<div class=\"priceContainer\">' +
                    '<div class=\"prodPriceMain\"><span class=\"priceField1\">#{normalPrice}</span></div>'+
                    '<div class=\"prodPriceDual\"><span class=\"priceField1\">#{dualPrice}</span></div>' +
                    '<div><span class=\"priceField1\">#{pkgPrice}</span></div>' +
                    '#{displayPrfPrice}' +
                    '#{displayFamilyPrice}' +
                '</div>'+
                '#{btiIncludeAfter}' +
                '<div id=\"moreInfo#{partNo}\" style=\"display:none\">'+
					'#{warningInfo}' +
					'#{calTitle20}'+
                    '#{measure}' + 
                    '<div class="buttonsContainer">' +
                        '#{buyOnline}' + 
                        '<a href=\"#\" id=\"slideshowSaveToList#{partNo}\" onclick=\"activateShopListPopup(\'add\',$(\'slideshowSaveToList#{partNo}\'),#{storeId},#{langId});return false;\" class=\"listLink\">#{keySaveToList}</a>' +
                    '</div>' +
                    '#{ssc}' + 
                '</div>'+
            '</div>'+
        '</div>');
        
        this.slideshowThumbTemplate = new Template('<div id=\"thumb#{partNo}\" class=\"thumbContainer\" onclick=\"slideshow.showProduct(\'#{partNo}\')\" style=\"display:; background-image:url(#{imgS})\">' +
            '<a class=\"overlay\" title=\"#{prodName} #{prodDesc} #{price}\">&nbsp;</a></div>');
        this.slideshowEmptyThumbTemplate = new Template('<div id=\"thumbEmpty\" class=\"thumbContainer\"></div>');

        this.newImgTemplate = new Template('<div><img border=\"0\" class=\"newImgLarge\" alt=\"#{newImgAlt}\" src=\"#{newImgSrc}"/></div>');
        this.familyPriceTemplate = new Template("<div><span class=\"prodFamily\">#{keyFamily}</span><span class=\"prodPriceFamily\">#{familyPrice}</span></div>");
        this.btiIncludeBeforeTemplate = new Template("<div class=\"productBtiBack\"><div class=\"productBtiFront\">");
        this.btiIncludeAfterTemplate = new Template("</div></div>");
        this.weeePrfTemplate = new Template("<div id=\"prf#{partNo}\" class=\"prfcontainer#{btiClass}\">"
                +"<div class=\"lessprice\">#{weee_less_prf} #{noPrfCharge}</div><div class=\"prflist\"><a href=\"javascript:openPrfPopup('prf#{partNo}')\">#{weee_prf}</a><span>&nbsp;#{prfCharge}</span></div>"
                +"</div>");
        this.sscTemplate = new Template('<a href=\"#{link}\" class=\"moreLink\">'+this.keys.get('r4_more_products')+'</a>');
        this.dimensionTemplate = new Template('<div class=\"prodDimension\">#{dimension}</div>');
        this.moreInfoTemplate = new Template('<a href=\"#{link}\" title=\"#{text}\"><span class=\"moreOptions\">#{text}</span></a>');
        this.buyOnlineTemplate = new Template('<div class=\"buttonContainer\"><a onclick=\"activateShopListPopup(\'addToCart\',$(\'slideshowAddToCart#{partNo}\'),#{storeId},#{langId});return false;\" href=\"#\" class=\"button\" id=\"slideshowAddToCart#{partNo}\"><div class=\"buttonLeft\">&nbsp;</div><div class=\"buttonCaption\">#{keyBuyOnline}</div><div class=\"buttonRight\">&nbsp;</div></a></div>')
        this.loaderTemplate = new Template('<div class="loader">#{loadingText}<br/><br/><img src=\"/ms/img/loading.gif\" width=\"27\" height=\"27\"/></div>');
		this.warningTemplate = new Template('<div id="warningsection"><img class="warningImg" src="#{attrImage1}" alt="#{attrValue}" border="0" />#{attrValue}</div>');
		this.californiaTemplate = new Template("<div class='lightSource'>"+this.keys.get("californiaTitle20LegalText")+"&nbsp;"+this.keys.get("californiaTitle20UrlText")+"&nbsp;</div>"
			+"<div id='lightSourceMoreInfo'><a href='"+this.keys.get("californiaTitle20UrlRef")+"'>"+this.keys.get('californiaMoreInformation')+"</a></div>");
		// Create the containers
        if($('slideshowBg') == null) {
			var obj = this;
            var overlay = new Element('div', {'id': 'slideshowBg'});
            var h = document.body.getHeight();
            overlay.setStyle({height: (h)+'px'});
            overlay.observe('click',function(e) {
                obj.close();
            });
            document.body.insert(overlay);
		}
        if($('slideshowElements') == null) {
            var slideshowElements = new Element('div', {'id': 'slideshowElements'});
            document.body.insert(slideshowElements);
        }
        
        // Add key events
        document.observe('keyup', function(event){ 
            if(event.keyCode == Event.KEY_ESC){ 
                this.close();
            }
            if(event.keyCode == Event.KEY_LEFT){ 
                $('slideshowBtnPrev').fire('ss:click');
            }
            if(event.keyCode == Event.KEY_RIGHT){ 
                $('slideshowBtnNext').fire('ss:click');
            }
        }.bind(this));
        
        // Add event to center on resize
        Event.observe(document.onresize ? document : window, "resize", function() {
            this._centerWindow(this.container);
        }.bind(this));   

        //new Draggable(this.container);
		this._hideLayer(this.container);
	}
});
var cookieName = "irw_compare";
var backupCookieName = "irw_compare_backup";
var cookieValueSeparator = "**";
var prods;
var totalRequest = 0;
var loadedRequest = 0;
var productsURL;
var compareTable;
var productPaddingTemplate;
var familyPriceTemplate;
var weeePrfTemplate;
var weeePrfBtiTemplate;
var cartContainerTemplate;
var cartContainerNonBuyableTemplate;
var sscInclude;	
var cartInclude;
var toggleTemplate;
var fw_10_comparison_see_more;
var fw_10_comparison_see_less;
var fw_10_comparison_size;
var btiIncludeBeforeTemplate;
var btiIncludeAfterTemplate;
var moreOptionsTemplate;
var newImgTemplate;
var warningImgTemplate;
var warningTemplate;
var calTitle20Template;
var sizeId = 0;
var descAttrWarning = "WARNING";

var btiDisplay = false;
var overflowRows = {"gtk":"","presentation":"","keyFeatures":""};
var showHideCells = {"gtk":"","presentation":"","keyFeatures":""};

var sizeDataArray = new Array();
var sizeTemplate;
var sizeDataTemplate;
var sizeDataDimensionTemplate;
var widthClass;

//Good to know
var GTK_START = "<gtks><gtk><t>";
var GTK_SPLIT = "</t></gtk><gtk><t>";
var GTK_END = "</t></gtk></gtks>";
//KEY FEATURES (CUSTOMER BENEFITS)
var KF_START = "<cbs><cb><t>";
var KF_SPLIT = "</t></cb><cb><t>";
var KF_END = "</t></cb></cbs>";
//Product information
var PI_START = "<cbs><cb><t>";
var PI_SPLIT = "</t></cb><cb><t>";
var PI_END = "</t></cb></cbs>";

/**
* Request the product information
* async from the pip-page. Retrieves one product
* at so the url:s are AKAMAI cachable
* @param url The Url to retrieve
*/
function addContent(productNumber,compareIndex){
	var prodUrl = productsURL+productNumber;
	new Ajax.Request(prodUrl, {
        method: Iows.method,
        contentType: Iows.contentType,
        parameters:{type: Iows.type, dataset: Iows.dataset},
		onSuccess: function(response) {
			addProduct(response.responseXML,compareIndex);		
		}
	});
}

/**
* Called when an answer is recieved from the request.
* Uses the retrieved DOM Document to collect info
* regarding the product.
* @param  doc A Dom Document returned from the PIP-Page
*/
function addProduct(doc,compareIndex){
	try {
		/* Modified for FW11 feature 101 */
		var item = doc.getElementsByTagName("item")[0];
		if(getElementValue("measure", item)!=null){
		var size=getSize(item);}
		else{
		var size="";
		}
		var gtk = getGoodToKnow(doc);
		var keyFeatures = getKeyFeatures(doc);
		var prodDesc = getProductDescription(doc);	
		var presentation = getProductPresentation(doc,compareIndex);
		var docObj = {"presentation":presentation, 
									"gtk":gtk, 
									"prodDesc":prodDesc,
									"keyFeatures":keyFeatures,
									"size":size
									};
									
		if (docObj.presentation.bti != null && docObj.presentation.bti == "true") {
			btiDisplay = true;
		}
		prods[compareIndex] = docObj;
	} catch(err) {
		//An error occured when reading the product
	}
	loadedRequest++;
	//If all are loaded, render the table
	if(loadedRequest == totalRequest){
		$('loading').remove();
		widthClass = "width" + prods.length + "column";
		addCompareableRows();
		addProductEvts();
	} 
}

function generateSize(value){
	if (value == null || value == "null null" || value == "null"){
        return "";}
	else{
		//split the string into an array
		var splitSize=value.split("</m></rm> <rm><m>")
		var array = splitSize[0].replace("<rm><m>","").split("</m><m>");
		var sizeDataObj = new Object();
		sizeDataObj.dimension = '';
		for (var i=0;i<array.length && i<3;i++){
			var data = array[i].replace("<d>","").replace("</v>","").split("</d><v>");
			var sizeDataDimensionObj = new Object();
			var separator = i == array.length-1 || i == 2 ? '' : ',';
			sizeDataDimensionObj.text = data[0] + ': ' + data[1] + separator
			sizeDataObj.dimension = sizeDataObj.dimension + sizeDataDimensionTemplate.evaluate(sizeDataDimensionObj);
		}
		var array=sizeDataObj.dimension.split(",");
		sizeDataObj.dimension="";
		for(var i=0;i<array.length;i++){
			sizeDataObj.dimension=sizeDataObj.dimension+array[i];
		}
		var moreInfo = '';
		if (array.length > 3){
			moreInfo = 'More info available';
			try{
				moreInfo = $F("fw10_comparison_size_more_info");		
			} 
			catch (err) {}
			sizeDataObj.moreInfo = "<div class=\"moreInfo\"><span>" + moreInfo + "</span></div>"
		}
		//sizeDataArray.push(sizeDataTemplate.evaluate(sizeDataObj));
		var sizeObj = new Object();
		sizeObj.id = sizeId;
		var text = 'Size';
		try{
			text = $F("fw10_comparison_size");
		} 
		catch (err) {}
		sizeObj.text = text;
		sizeObj.dimension=sizeDataTemplate.evaluate(sizeDataObj);	
		sizeId++;
		return sizeTemplate.evaluate(sizeObj);
	}
}

function checkMoreOptions(item, product) {
	return product.indexOf(item) == -1;
}

/**
* Reads the good to know part of the product
* @param doc The document object representing the product
* @return The good to know strings as an array or an empty array
*/
function getGoodToKnow(doc){
	var gtk = doc.getElementsByTagName("goodToKnow");
	return getAttributeXMLAsList(gtk,GTK_START,GTK_SPLIT,GTK_END);	
}

/**
* Reads the key features part of the product
* @param doc The document object representing the product
* @return The key features strings as an array or an empty array
*/
function getKeyFeatures(doc){
	var kf = doc.getElementsByTagName("custBenefit");
	return getAttributeXMLAsList(kf,KF_START,KF_SPLIT,KF_END);
}

function getSize(item){
	 var size = getElementValue("measure", item);
	 var ret = new Array();
	 if(size =="null null" || size== "null"){
		return ret;
	}
	else{
		 var array = size.replace("</v></m></rm> <rm><m><d>", "</v></m><m><d>").replace("<rm><m><d>","").replace("</v></m></rm>","").split("</v></m><m><d>");
		 var len =array.length;
		 var sizeHtml="";
		 for (var i=0;i<len;i++){
			 sizeHtmlTemp = "<span class=\"prodDimension\">" + array[i].replace("</d><v>",":") + "</span>"
			 sizeHtml = sizeHtml + sizeHtmlTemp;
		 }
		 ret.push(sizeHtml);
		 //ret.push(sizeHtml.strip());
		 return ret;
	 }
 }
	
/**
* Reads the product description part of the product
* @param doc The document object representing the product
* @return The product description as an array or an empty array
*/
function getProductDescription(doc){
	var prodDesc = getElementValue("custMaterials",doc);
	var ret = new Array();
	if(prodDesc == null){
		return ret;
	}
	var prodDescObjs = new Array();
	var cms = prodDesc.split("<cm>");
	var len = cms.length;
	for(var i = 0; i < len;i++){
		var str = cms[i];
		if(str.indexOf("<m>") != -1) {
			prodDescObjs.push(getProdDescObj(str));
		}
	}
	var hashTable = {};
	len = prodDescObjs.length;
	for(var i = 0;i < len;i++){
		var ptDesc = prodDescObjs[i];
		var ptArr = hashTable[ptDesc.pt];
		if(ptArr == undefined){
			ptArr = new Array();
		}
		ptArr.push({"t":ptDesc.t,"m":ptDesc.m});
		hashTable[ptDesc.pt] = ptArr;
	}	
	for (var key in hashTable){
		if (hashTable.hasOwnProperty(key)){
			var breaker = "<br/>";
			if(key == "" || key == "&nbsp;"){
				breaker = "";
			}
			var html = key + breaker;
			var arr = hashTable[key];
			len = arr.length;
			for(var i = 0; i < len;i++){
				var t_m = arr[i];
				html = html + t_m.t+" "+t_m.m+"<br/>";
			}
			ret.push(html.strip());
		}
	}
	return ret;
}

/**
*Create a product description
*/
function getProdDescObj(cmstr){
	var prodDesc = new Object();
	prodDesc.pt = getValueFromXmlString(cmstr,"pt");
	prodDesc.t = getValueFromXmlString(cmstr,"t");
	prodDesc.m = getValueFromXmlString(cmstr,"m");
	return prodDesc;
}

function  getValueFromXmlString(tagData,tagName){
	var startIx = tagData.indexOf("<"+tagName+">");
	if(startIx == -1){
		return "";
	}
	var endIx = tagData.indexOf("</"+tagName+">",startIx);
	if(endIx == -1){
	  return "";
	}
	return tagData.substring(startIx+tagName.length+2,endIx);    
}

/**
* Creates an object representation of the data needed
* for the comparison
* @param doc The document representing the product
* @return An object with the following properties:
*		pipLink, thumb, name, desc, price, familyPrice
*		unitPrice, sscInclude, availableOnline
*/
function getProductPresentation(doc,compareIndex){
	var product = doc.getElementsByTagName("product")[0];
	var item = doc.getElementsByTagName("item")[0];
	var prices = getPrices(item);
	var descriptiveAttributes = getDescriptiveAttributes(item);
	var warningDescAttr = getDescAttributeByType(descAttrWarning,descriptiveAttributes);
	var isCalTitle20 = false;
	if(doc.getElementsByTagName("californiaTitle20").length>0){
		isCalTitle20 = true;
	}
	return {
		"pipLink": getElementValue("URL",item),
		"pipBigImg": getElementPathValue("normal/image",item),
		"thumb":getElementPathValue("thumb/image",item),
		"name":getElementValue("name",item),
		"desc":getElementValue("facts",item),
		"price":prices.price, 
		"familyPrice":prices.familyPrice,
		"unitPrice":prices.unitPrice,
		"sscInclude":getSSCInclude(doc),
		"availableOnline":getElementValue("buyable",item),
		"bti":getElementValue("bti",item),
		"newItem":getElementValue("new",item),
		"familyPriceInclude":"",		
		"btiIncludeBefore":"",
		"btiIncludeAfter":"",
		"size":generateSize(getElementValue("measure", item)),
		"weeePrfInclude":"",
		"prfCharge":prices.prfCharge,
		"priceWithNoPrfCharge":prices.priceWithNoPrfCharge,	
		"buyable":getElementValue("buyable",item),
		"hasMoreOptions":checkMoreOptions(getElementValue("partNumber", item), getElementValue("partNumber", product)),
		"partNumber":getElementValue("partNumber", item),
		"compareIndex":compareIndex,
		"warningAttribute":warningDescAttr,
		"calTitle20":isCalTitle20
		};
}

/**
* returns an array of descriptive attributes
*  
* @param  item A Dom Document returned from the PIP-Page
*/
function getDescriptiveAttributes(item){
	var attrArray;
	var descAtrributes = item.getElementsByTagName("descriptiveAttributes")[0];
	if(descAtrributes != null){
		var attribute = descAtrributes.getElementsByTagName("descriptiveAttribute");
		if(attribute.length > 0){
			attrArray = new Array();
			for(var i=0; i < attribute.length; i++){
				var attr = new Object();
				attr.attrType = attribute[i].getAttribute("type");
				attr.attrValue = getElementValue("value",attribute[i]);
				attr.attrImage1 = getElementValue("image1",attribute[i]);
				attrArray[i] = attr;
			}
		}
	}

	return attrArray;
}

/**
* returns an attribute object based on the attribute
* type passed
*  
* @param  attrType The attribute type used to get the attribute object
* @param  descAttrs Array of descriptive attributes
*/
function getDescAttributeByType(attrType, descAttrs){
	var attr;
	if(descAttrs != null && descAttrs.length > 0){
		for(var i=0; i < descAttrs.length; i++){
			if(descAttrs[i].attrType == attrType){
				attr = descAttrs[i];
			}
		}
	}
	return attr;
}

/**
* Parses the price information an returns an object
* the prices information.
* @param item An element representing the Item node
* @retuns An object with the following properties set:
*		price, familyPrice, unitPrice
*/
function getPrices(item){
	var ret = new Object();
	var prices = item.getElementsByTagName("prices")[0];
	ret.price = getPricePart("normal",prices);
	ret.familyPrice =	getPricePart("family-normal",prices);
	ret.unitPrice = null;
	try{
		if(showWeeeRelatedData){
			ret.prfCharge = prices.getElementsByTagName("normal")[0].getElementsByTagName("priceNormal")[0].getAttribute("prfChargeFormatted");
			ret.priceWithNoPrfCharge = prices.getElementsByTagName("normal")[0].getElementsByTagName("priceNormal")[0].getAttribute("priceWithNoPrfChargeFormatted");
		}
	} catch (err){}
	
	return ret;
}

/**
* Retrieves the set price of a price node. 
* The method return "priceChanged" if set otherwise 
*  "priceNormal" is returned.
* @param item The element representing the "prices" node
* @param itemTagName The name of the prices-node descendant
*					to retrieve the price from
*/
function getPricePart(itemTagName,item){
	var unitPrice = item.getAttribute("unitPricePrimary");
	var suffix = "";
	if(unitPrice != null && unitPrice == "true"){
		suffix = "PerUnit";
	}	
	var normal = item.getElementsByTagName(itemTagName)[0];
	var price = getElementValue("priceChanged"+suffix,normal);
	if(price == null){
		price = getElementValue("priceNormal"+suffix,normal);
	}
	return price;
}

/**
*Retrieves value from the element with the child node
* with the specified name
*/
function getElementValue(tagName,element){
	var item = element.getElementsByTagName(tagName);
	if(item != null && item.length > 0 && item[0].firstChild != null){
		return item[0].firstChild.data;
	}
	else{
		return null;
	}

}

/**
* Retrieves value from element with the specified path
*/
function getElementPathValue(tagNamePath,element){
	var paths = tagNamePath.split('/');
	var len = paths.length;
	var elem = new Array();
	elem.push(element);
	for(var i = 0; i < len;i++){
		if(elem != null && elem.length > 0){
			elem = elem[0].getElementsByTagName(paths[i]);
		}	
	}
	if(elem != null && elem.length > 0){
		return elem[0].firstChild.data;
	}
	else{
		return null;
	}
}

/**
* Checks if the product has any parent in series, systems or collections
* and if so it will return the formated fragment for linking to the ssc.
*/
var categoryNames = new Array("series","systems","collections");
function getSSCInclude(doc){
	var categories = doc.getElementsByTagName("categories")[0];
	for(var i = 0; i < 3;i++){
		var tmp = categories.getElementsByTagName(categoryNames[i]);
		var category = tmp[0].getElementsByTagName("category");
		//sscName, sscLink, r4_more_products
		if(category != null && category.length > 0){
				var ssc = {
									"name":getElementValue("name",category[0]),
									"link":getElementValue("URL",category[0])									
								};
				return sscInclude.evaluate(ssc);
		}
	}
	return "";

}

/**
*Splits the values in elemArray[0].firstChild into strings
*and returns them as an array. If the firstchild does not exist
*an empty list is returned
*/
function getAttributeXMLAsList(elemArray,startTags,splitTags,endTags) {
	var list = new Array();
	if(elemArray != null && elemArray.length > 0 && elemArray[0].firstChild != null){
		var xml = elemArray[0].firstChild.data;
		if (xml != null && !("" == xml)) {
			xml = xml.replace(startTags, "");
			xml = xml.replace(endTags, "");
			var items = xml.split(splitTags);
			var len = items.length;
			for (var i = 0; i < len; i++) {
				list.push(items[i]);
				}
   	}
   }
   return list;
}



/**
* Renders the compare table
*/
function addCompareableRows(){
    addPriceImageRow();
    var keyFeaturesIsLast = ((getMaxLength("keyFeatures") > 0) && ((getMaxLength("gtk")==0) && (getMaxLength("prodDesc")>0)));
    var gtkIsLast = getMaxLength("gtk")>0 && getMaxLength("prodDesc")==0;
    addCompareSectionRows("size",$F("fw10_comparison_size"),false,true);
    addCompareSectionRows("keyFeatures",$F("PD_txt_keyfeatures"),true,keyFeaturesIsLast);
    addCompareSectionRows("gtk",$F("PD_txt_goodToKnow"),true, gtkIsLast);
    addCompareSectionRows("prodDesc",$F("PD_txt_productDescription"),false, true);
}

/**
* Adds the row with the product image and price information.
* The image and price is rendered in a "ready-to-present" way from 
* the pip page.
*/
function addPriceImageRow(){
	var len = prods.length;
	var last = len -1;
	var row = new Element("tr");
	for(var i = 0; i < len;i++){
		var td;
		if(i == last){
			td = new Element("td",{ 'class': 'noBorder ' + 'lastTd ' + widthClass });
		}
		else{
			td = new Element("td",{ 'class': widthClass });
		}
		var prodInfo = prods[i].presentation;
		if(prodInfo.familyPrice != null){
			prodInfo.familyPriceInclude = familyPriceTemplate.evaluate(prodInfo);
		}
		var locale = "en_SE";
		try {
			locale = $F('locale');
		} catch (err) {}
		prodInfo.newImgAlt = "New";
		try {
			prodInfo.newImgAlt = $F('r4_all_products_new');
		} catch (err) {}	
		prodInfo.newImgSrc = "/ms/" + irwstats_locale + "/img/icons/new_small.gif";
		if (prodInfo.newItem != null && prodInfo.newItem == "true") {
			prodInfo.newImg = newImgTemplate.evaluate(prodInfo);
		}
		if (prodInfo.bti != null && prodInfo.bti == "true") {
			prodInfo.btiIncludeBefore = btiIncludeBeforeTemplate.evaluate(prodInfo);
			prodInfo.btiIncludeAfter = btiIncludeAfterTemplate.evaluate(prodInfo);			
		}
		if(prodInfo.prfCharge != null && prodInfo.priceWithNoPrfCharge != null){
			prodInfo.weee_less_prf = "Less PRF";
			prodInfo.weee_prf = "PRF";
			try{
				prodInfo.weee_less_prf = $F("weee_less_prf");
				prodInfo.weee_prf = $F("weee_prf");
			}
			catch (err) { }
			if(prodInfo.bti == "true"){
				prodInfo.weeePrfInclude = weeePrfBtiTemplate.evaluate(prodInfo);
			}
			else{
				prodInfo.weeePrfInclude = weeePrfTemplate.evaluate(prodInfo);
			}
		}		
		var hasEcommerce = "true";
		try{
				hasEcommerce = $F('hasEcommerce');
		}
		catch (err) {}
		if (hasEcommerce == "true") {
			if (prodInfo.buyable != null && prodInfo.buyable == "true") {
				prodInfo.cartText = $F('r4_cart_available');
				prodInfo.cartImage = 'cart.gif';
			} 
			else {
				prodInfo.cartText = $F('r4_cart_unavailable');
				prodInfo.cartImage = 'cart_not_available.gif';
			}
			prodInfo.cartInclude = cartInclude.evaluate(prodInfo);
		}
		if (prodInfo.hasMoreOptions) {
			prodInfo.moreOptions = moreOptionsTemplate.evaluate(prodInfo);
		}
		
		var longClass = btiDisplay ? " productContainerLong" : "";
		if(prodInfo.warningAttribute != null){
			prodInfo.warningImage = warningImgTemplate.evaluate(prodInfo.warningAttribute);
		}
		
		if(prodInfo.calTitle20 != null && prodInfo.calTitle20){
			prodInfo.calTitle20Msg = calTitle20Template.evaluate(prodInfo.calTitle20);
		}
		
		var toInsert;
	    if (prodInfo.buyable != null && prodInfo.buyable == "true") {		
			toInsert = "<div class=\"productContainer" + longClass + "\">"
				+productPaddingTemplate.evaluate(prodInfo)
				+cartContainerTemplate.evaluate(prodInfo)
				+"</div>";
		} 
		else {
			toInsert = "<div class=\"productContainer" + longClass + "\">"
				+productPaddingTemplate.evaluate(prodInfo)
				+cartContainerNonBuyableTemplate.evaluate(prodInfo)
				+"</div>";
		}
		
		td.innerHTML = toInsert;
		row.insert(td);						
	}
	compareTable.insert(row);	  
}


/**
*	Insert rows for a section in the compare table.
* Ads the heading as the first row and then the data 
* to compare.
* Since the each comparable item should be aligned on the same
* row the method will add as many rows as the product with the most data,
* for elements which does not have as much data as this element empty cells
* will be added. 
* @param Section The name of the section to add
*/
function addCompareSectionRows(section,heading,bullets,lastSection){
    var startBullet = "<span class=\"prodDescr\">";
    var endBullet = "</span>";
    if(bullets){
        startBullet = "<ul><li>";
        endBullet = "</li></ul>";
    }
    if(section == "size"){
        startBullet = "";
        endBullet = "";
    }
    var maxLength = getMaxLength(section);
    var prodsLength = prods.length;
    var overFlow = new Array();
    var hideRows = false;
	//only show border if there are items
	if (maxLength > 0) {
	    var borderRow = new Element("tr");
	    for(var j = 0; j < prodsLength;j++){
	        var cell;
	        cell = new Element("td",{'class': 'noBorder'});
	        var cellContent = new Element("div", {'class':'productBottom'});
	        cell.insert(cellContent);
	        borderRow.insert(cell);
	    }
	    compareTable.insert(borderRow);
	}
    for(var i = 0; i < maxLength;i++){
        var row = new Element("tr");
        if(i >= 5){
            overFlow.push(row);
        }
        //First row contains heading
        var h2 = "";
        if(i == 0){
            h2 = "<h2> "+heading+"</h2>";
        }
        var last = prodsLength -1;
        for(var j = 0; j < prodsLength;j++){
            var prod = prods[j];
            var cell;
            if(last == j) {
                cell = new Element("td",{ 'class': 'features noBorder'});
            }
			else{
                cell = new Element("td",{ 'class': 'features'});
            }
            var arr = prod[section];

            if(arr.length > i){
 								var div = new Element("div", { 'class': widthClass });
 								div.innerHTML = h2 + startBullet+arr[i]+endBullet;
                cell.insert(div);
            }
			else {
                cell.innerHTML = "&nbsp;";
            }

            row.insert(cell);
        }
        if(hideRows){
            row.hide();
        }
        compareTable.insert(row);
        /*If more than 5 rows an we are on the fifth
                * signal to hide the rest of the rows */
        if(i == 4 && maxLength > 5){
            hideRows = true;
        }
    }
    //Add row with hide/show all
    if(maxLength > 5){
        var toggleCells = new Array();
        var showAllRow = new Element("tr");
        for(var j = 0; j < prodsLength;j++){
            var cell;
            if(last == j) {
                cell = new Element("td",{ 'class': 'features noBorder'});
            }
			else{
                cell = new Element("td",{ 'class': 'features'});
            }
            var currLength  = prods[j][section].length;
            if(currLength > 5){
                cell.innerHTML = toggleTemplate.evaluate({"section":section,"linkText":fw_10_comparison_see_more});
                toggleCells.push(cell);
            } 
			else {
                cell.innerHTML = "&nbsp;";
            }
            showAllRow.insert(cell);
        }
        showHideCells[section] = toggleCells;
        compareTable.insert(showAllRow);
    }
    overflowRows[section] = overFlow;
}

function toggleSection(section){
	var arr = overflowRows[section];
	var len = arr.length;
	var toggleLink;
	/*If the item is visible it will toggle
	* to be hidden thus, show more should be  
	* the link text*/
	if(arr[0].visible()){
		toggleLink = toggleTemplate.evaluate({"section":section,"linkText":fw_10_comparison_see_more});
	}
	else{
		toggleLink = toggleTemplate.evaluate({"section":section,"linkText":fw_10_comparison_see_less});
	}
	for(var i = 0; i < len;i++){
		arr[i].toggle();
	}
	var linkSection = showHideCells[section];
	len = linkSection.length;
	for(var i = 0; i < len;i++){
		linkSection[i].innerHTML = toggleLink;
	}
}

/**
* Itterates the products to find the maximum value
* of the specifid tag.
* @param section The name of the section to find max value from
*/
function getMaxLength(section){
	var max = 0;
	var len = prods.length;
	for(var i = 0; i < len;i++){
		var prod = prods[i];
		var length = prod[section].length;
		if(length > max){
				max = length;
			}
	}
	return max;
}

/**
* Retrieves the products to compare from the cookie and creates
* request to retrieve the product data.
*/
function retrieveCompareProducts(storeId,langId){
	initComparePage(storeId,langId);
	var values = getCookie(cookieName);
	document.cookie=cookieName+"=;path=/";
	if (values == null || values == ""){
		// try to read the backup cookie
		values = getCookie(backupCookieName);
		if (values == null) {
			return;
		}
	} 
	else {
		//the cookie existed, copy the content to backup cookie
		document.cookie=backupCookieName+"="+values+";path=/";
	}
	var urls = values.split(cookieValueSeparator);
	var len = urls.length;
	//Max 4 to compare
	if(len > 4){
		len = 4;
	}
	var toSend = new Array();
	for(var i = 0; i < len;i++){
		var content = urls[i];
		if(content != null && content != ""){
			toSend.push(content);
		}
	}
	
    //Send statisics to omniture
	try {
        var stats = toSend.clone(); // Clone the original to keep it as is
		irwStatCompareProducts(stats);
	} 
	catch(e) {}
	totalRequest = toSend.length;
    prods = new Array(totalRequest);
    js_fn_SLIDE_SHOW_IDS.clear();
	for(var i = 0; i < totalRequest;i++){
		addContent(toSend[i],i);
        // Add id:s to slideshow array
        js_fn_SLIDE_SHOW_IDS.push(toSend[i]);
	}
}

function setCompareBaseUrl(baseProductUrl){
	productsURL = baseProductUrl;
}
	
function initComparePage(storeId,langId){
	var loading = new Element('div', {'id' : 'loading', 'class' : 'loading' });
	$('compare').insert(loading);
	loading.update('<img src="/ms/img/loading.gif" />');
	compareTable = $("compareTable");	
	fw_10_comparison_see_more = $F("fw10_comparison_see_more");
	fw_10_comparison_see_less = $F("fw10_comparison_see_less");
	//pipLink, name, desc, thumb, price, familyPriceInclude
	productPaddingTemplate = new Template(
	"#{newImg}"
	+"<div class=\"popupListener\" id=\"comparePopup#{compareIndex}\"><div class=\"productPadding\">"
		+"<a href=\"#{pipLink}\">"
				+"<img id=\"compareImage#{compareIndex}\" border=\"0\" class=\"prodImg\" alt=\"#{name} #{desc}\" "
					+"src=\"#{thumb}\" />"
				+"#{btiIncludeBefore}"
				+"<span class=\"prodNameCompare\" >#{name}</span> "
				+"<span class=\"prodDescCompare\" >#{desc}</span> "
				+"<span class=\"prodPriceCompare\">#{price}</span>" //Price del behöver vara separat
				+"#{familyPriceInclude}"
				+"#{btiIncludeAfter}"
		+"</a>"
		+"#{weeePrfInclude}"
	+"</div></div>  ");
	//bti templates
	btiIncludeBeforeTemplate = new Template("<div class=\"productBtiBack\"><div class=\"productBtiFront\">");
	btiIncludeAfterTemplate = new Template("</div></div>");
	//new template
	newImgTemplate = new Template("<img class=\"newImgSmall\" src=\"#{newImgSrc}\" alt=\"#{newImgAlt}\" border=\"0\" />");
	//ikeaFamily, familyPrice
	familyPriceTemplate = new Template("<div class=\"prodFamily\">"+$F("r4_ikea_family")+"</div> "
			+"<div class=\"prodPriceFamily\">#{familyPrice}<br/></div> ");
	//WEEE prf and price without prf
	weeePrfTemplate = new Template("<div id=\"prf#{partNumber}\" class=\"prfcontainer\">"
			+"<div class=\"lessprice\">#{weee_less_prf} #{priceWithNoPrfCharge}</div>"
			+"<div class=\"prflist\"><a href=\"javascript:openPrfPopup('prf#{partNumber}')\">#{weee_prf}</a><span>&nbsp;#{prfCharge}</span></div>"
			+"</div>");
	weeePrfBtiTemplate = new Template("<div id=\"prf#{partNumber}\" class=\"prfcontainer bti\">"
			+"<div class=\"lessprice\">#{weee_less_prf} #{priceWithNoPrfCharge}</div>"
			+"<div class=\"prflist\"><a href=\"javascript:openPrfPopup('prf#{partNumber}')\">#{weee_prf}</a><span>&nbsp;#{prfCharge}</span></div>"
			+"</div>");
	cartContainerTemplate = new Template("<div id=\"cartContainer#{partNumber}\"   class=\"cartContainer moreInfo\">"
		+"#{warningImage}"
		+"#{calTitle20Msg}"
		+"#{size}"
		+"#{moreOptions}"
	    +" <div class=\"buttonsCompareContainer\">"
		+" <div class=\"buttonsContainer\">"
		+"<div class=\"buttonContainer\"><a onclick=\"activateShopListPopup('addToCart',$('popupAddToCart#{partNumber}'),"+storeId+","+langId+");return false;\" href=\"#\" class=\"button\" id=\"popupAddToCart#{partNumber}\"><div class=\"buttonLeft\">&nbsp;</div><div class=\"buttonCaption\">"+$F("fw10_comparison_add_to_cart")+"</div><div class=\"buttonRight\">&nbsp;</div></a></div>"				    
		+"<a href=\"#\" id=\"popupShoppingList#{partNumber}\" onclick=\"activateShopListPopup('add',$('popupShoppingList#{partNumber}'),"+storeId+","+langId+");return false;\" class=\"listLink\">"+$F("fw10_comparison_add_to_shoppingList")+"</a>"			    
		+"</div>"
		+"</div>"
		+ "#{sscInclude}"
		+"</div>");
	cartContainerNonBuyableTemplate = new Template("<div id=\"cartContainer#{partNumber}\"   class=\"cartContainer moreInfo\">"
	    		+"#{warningImage}"
	    		+"#{calTitle20Msg}"
				+"#{size}"
				+"#{moreOptions}"
	    +" <div class=\"buttonsCompareContainer\">"
		+" <div class=\"buttonsContainer\">"
		+"<a href=\"#\" id=\"popupShoppingList#{partNumber}\" onclick=\"activateShopListPopup('add',$('popupShoppingList#{partNumber}'),"+storeId+","+langId+");return false;\" class=\"listLink\">"+$F("fw10_comparison_add_to_shoppingList")+"</a>"			    
		+ "<div class=\"compare\"><input type=\"hidden\" id=\"compare_#{partNumber}\" value=\"\"/></div>"
		+"</div>"
		+"</div>"
		+ "#{sscInclude}"
		+"</div>");
	sscInclude = new Template("<span class=\"linkContainer\">"
		+"<a class=\"moreLink\" href=\"#{link}\">"+$F("r4_more_products")+"</a>"
		+"</span>  ");	
	cartInclude = new Template("<a href=\"#{pipLink}\" >"  
				+"<img border=\"0\" alt=\"#{cartText}\" class=\"cart\" "
				+"	src=\"/ms/img/product_list/#{cartImage}\" />"
		+"</a> ");
    //section, linkText	
	toggleTemplate = new Template("<a href=\"#\" onclick=\"toggleSection('#{section}');return false;\">#{linkText}</a>");
	//size 
	sizeTemplate = new Template("<div id=\"compare_size_#{id}\">#{dimension}</div>");
	sizeDataDimensionTemplate = new Template("<span class=\"prodDimension\">#{text}</span>");
	sizeDataTemplate = new Template("#{dimension}#{moreInfo}");
	moreOptionsTemplate = new Template("<a title=\""+$F("r4_more_options_for")+"\" "
			+"	href=\"#{pipLink}\">"
			+"	<span class=\"moreOptions\">"+$F("r4_more_options")+"</span>"
		+"</a>");
	warningImgTemplate = new Template('<img class="warningImg" src="#{attrImage1}" alt="#{attrValue}" border="0" />');
	calTitle20Template = new Template("<div class='lightSourceMiniPIP'>"+$F("californiaTitle20LegalText")+"&nbsp;"+$F("californiaTitle20UrlText")+"&nbsp;"
		+"<div><a href='"+$F("californiaTitle20UrlRef")+"'>"+$F('californiaMoreInformation')+"</a></div></div>");
}

/* SiteCatalyst code version: H.17.
Copyright 1997-2008 Omniture, Inc. More info available at
http://www.omniture.com */
/************************ ADDITIONAL FEATURES ************************
     Plugins
*/

var s;

/* IKEA Functions */
var irw_fh = function(h) {
	try {
		var r = /^javascript\:[\ ]*window\.open\(\'([^\']+)\'.*$/;
		
		if (r.test(h)) {
			return h.replace(r, "$1");
		} else {
			return h;
		}
	} catch(e) {
		return h;
	}
};
/* END - IKEA Functions */


function s_doPlugins(s) {
	
s.events=s.getCartOpen("s_scOpen");

if(!s.campaign){
	s.campaign=s.getQueryParam('cid')
	s.campaign=s.getValOnce(s.campaign,'ecamp',0)
}

s.eVar14 = s.crossVisitParticipation(s.campaign,'s_cpm','90','5','>','purchase');

if(!s.eVar2){
	s.eVar2=s.getQueryParam('icid')
	s.eVar2=s.getValOnce(s.eVar2,'icamp',0)
}
if (s.eVar2) {
	s.eVar3="internal campaign"
	s.eVar3=s.getValOnce(s.eVar3,'omtrpfm',0)  
}

if(!s.prop6){
	s.prop6=s.getQueryParam('query','',decodeURIComponent(location.search))
	s.prop6=s.getValOnce(s.prop6,'sete',0)
}
	
if(s.prop6) {
		s.prop6=s.prop6.toLowerCase()
}

// dynamic picking of TZone
var d = new Date()
var gmtHours = -d.getTimezoneOffset()/60;
omtrtimezone='0';
if (gmtHours>0) 
{
omtrtimezone='+' +gmtHours;
}
else
{
omtrtimezone='-' +gmtHours;
}

// dynamic picking of TZone ends

/* TimeParting GMT */
s.prop14=s.eVar19=s.getTimeParting('h',omtrtimezone,new Date().getFullYear()); // Set hour 
s.prop15=s.eVar20=s.getTimeParting('d',omtrtimezone,new Date().getFullYear()); // Set day
s.prop16=s.eVar21=s.getTimeParting('w',omtrtimezone,new Date().getFullYear()); // Set Weekend / Weekday


/*Copy Settings*/

if(s.prop6){ 
        s.eVar1=s.prop6
		s.prop7=1;
		s.prop42=1;
	s.events=s.apl(s.events,'event1',',',1)    
} 

if(s.prop8){ 
        s.eVar7=s.prop8
	s.eVar7=s.getValOnce(s.eVar7,'s_evar7',0) 
} 



if(s.prop37){ 
        s.eVar15=s.prop37
	s.eVar15=s.getValOnce(s.eVar15,'s_evar15',0)  
} 


if(s.prop10){
        s.eVar10=s.prop10
	s.eVar10=s.getValOnce(s.eVar10,'s_evar10',0)  
} 


if(s.prop11){ 
        s.eVar11=s.prop11
	s.eVar11=s.getValOnce(s.eVar11,'s_evar11',0)   
} 


if(s.prop13){ 
        s.eVar13=s.prop13
	s.events=s.apl(s.events,'event7',',',1)
	s.eVar13=s.getValOnce(s.eVar13,'s_evar13',0)  
} 


if(s.eVar17){ 
	s.events=s.apl(s.events,'event11',',',1)
	s.eVar17=s.getValOnce(s.eVar17,'s_evar17',0)  
} 


if(s.prop17){ 
        s.eVar22=s.prop17
	s.eVar22=s.getValOnce(s.eVar22,'s_evar22',0)  
} 

//Populate Downloads in variables as well
var url=s.downloadLinkHandler('exe,zip,wav,mp3,mov,mpg,avi,wmv,pdf,doc,docx,xls,xlsx,ppt,pptx');
if(url){
	s.linkTrackVars="eVar9,prop9,events";
	s.prop9=url;
	s.eVar9=url;	
	s.linkTrackEvents="event5";
	s.events=s.apl(s.events,'event5',',',1)
}

if(!s.prop28)
{s.prop28="anonymous"};


if(s.prop28){ 
s.eVar24=s.prop28
	s.eVar24=s.getValOnce(s.eVar24,'s_evar24',0)  
}

// set on first page of visit with new max versions
s.detectRIA('s_ria','prop33','','','','');

/*getDaysSinceLastVisit v1.1 */
s.prop35=s.getDaysSinceLastVisit('s_lv');

/*getNewRepeat 1.0*/
s.prop34=s.getNewRepeat();

	
//Set the pageName in prop20 based on the name of the HTML if it's not set in the Flash file
if(!s.prop19){
		s.prop20=s.pageName
	}


if(!s.prop2)
{s.prop2="n/a"};

}

function set_s_var(){

/* NB! The s_account variable will get set in the header that is loading this file.

var s_account="ikeasedev"
*/
s=s_gi(s_account)

/************************** CONFIG SECTION **************************/
/* Country and Language as set by the adapter. */


s.prop8 = s_country;
s.prop17 = s_language;
s.prop41  = s_urls;  //  Added 


/* You may add or alter any code config here. */
s.cookieDomainPeriods="2"
/* Conversion Config */
s.currencyCode="EUR"
/* Link Tracking Config */
s.trackDownloadLinks=true
s.trackExternalLinks=true
s.trackInlineStats=true
s.linkDownloadFileTypes="exe,zip,wav,mp3,mov,mpg,avi,wmv,pdf,doc,docx,xls,xlsx,ppt,pptx"
s.linkInternalFilters="javascript:,ikea.com,ikeadt.com,193.108.42.79"
s.linkLeaveQueryString=false
s.linkTrackVars="None"
s.linkTrackEvents="None"
/* Plugin Config */
s.usePlugins=true

s.doPlugins=s_doPlugins
/************************** PLUGINS SECTION *************************/
/* You may insert any plugins you wish to use here.                 */
/*
 * Plugin: getQueryParam 2.1 - return query string parameter(s)
 */
s.getQueryParam=new Function("p","d","u",""
+"var s=this,v='',i,t;d=d?d:'';u=u?u:(s.pageURL?s.pageURL:s.wd.locati"
+"on);if(u=='f')u=s.gtfs().location;while(p){i=p.indexOf(',');i=i<0?p"
+".length:i;t=s.p_gpv(p.substring(0,i),u+'');if(t)v+=v?d+t:t;p=p.subs"
+"tring(i==p.length?i:i+1)}return v");
s.p_gpv=new Function("k","u",""
+"var s=this,v='',i=u.indexOf('?'),q;if(k&&i>-1){q=u.substring(i+1);v"
+"=s.pt(q,'&','p_gvf',k)}return v");
s.p_gvf=new Function("t","k",""
+"if(t){var s=this,i=t.indexOf('='),p=i<0?t:t.substring(0,i),v=i<0?'T"
+"rue':t.substring(i+1);if(p.toLowerCase()==k.toLowerCase())return s."
+"epa(v)}return ''");
/*
 * Plugin: getValOnce 0.2 - get a value once per session or number of days
 */
s.getValOnce=new Function("v","c","e",""
+"var s=this,k=s.c_r(c),a=new Date;e=e?e:0;if(v){a.setTime(a.getTime("
+")+e*86400000);s.c_w(c,v,e?a:0);}return v==k?'':v");
/*
 * Utility Function: split v1.5 - split a string (JS 1.0 compatible)
 */
s.split=new Function("l","d",""
+"var i,x=0,a=new Array;while(l){i=l.indexOf(d);i=i>-1?i:l.length;a[x"
+"++]=l.substring(0,i);l=l.substring(i+d.length);}return a");
/*
 * Plugin: downloadLinkHandler 0.5 - identify and report download links
 */
s.downloadLinkHandler=new Function("p",""
+"var s=this,h=s.p_gh(),n='linkDownloadFileTypes',i,t;h=irw_fh(h);if("
+"!h||(s.linkType&&(h||s.linkName)))return '';i=h.indexOf('?');t=s[n]"
+";s[n]=p?p:t;if(s.lt(h)=='d')s.linkType='d';else h='';s[n]=t;return "
+"h;");
/*
 * Time Parting Plugin - the code has been modified to get the users time
 */
s.getTimeParting=new Function("t","z","y",""
+"dc=new Date('1/1/2000');f=15;ne=8;if(dc.getDay()!=6||"
+"dc.getMonth()!=0){return'Data Not Available'}else{;z=parseInt(z);"
+"if(y=='2009'){f=8;ne=1};gmar=new Date('3/1/'+y);dsts=f-gmar.getDay("
+");gnov=new Date('11/1/'+y);dste=ne-gnov.getDay();spr=new Date('3/'"
+"+dsts+'/'+y);fl=new Date('11/'+dste+'/'+y);cd=new Date();"
+";utc=cd.getTime()"
+";tz=new Date(utc + (3600000*z));thisy=tz.getFullYear("
+");var days=['Sunday','Monday','Tuesday','Wednesday','Thursday','Fr"
+"iday','Saturday'];if(thisy!=y){return'Data Not Available'}else{;thi"
+"sh=tz.getHours();thismin=tz.getMinutes();thisd=tz.getDay();var dow="
+"days[thisd];var ap='AM';var dt='Weekday';var mint='00';if(thismin>3"
+"0){mint='30'}if(thish>=12){ap='PM';thish=thish-12};if (thish==0){th"
+"ish=12};if(thisd==6||thisd==0){dt='Weekend'};var timestring=thish+'"
+":'+mint+ap;var daystring=dow;var endstring=dt;if(t=='h'){return tim"
+"estring}if(t=='d'){return daystring};if(t=='w'){return en"
+"dstring}}};"
);

/*
 * Utility Function: p_gh
 */
s.p_gh=new Function(""
+"var s=this;if(!s.eo&&!s.lnk)return '';var o=s.eo?s.eo:s.lnk,y=s.ot("
+"o),n=s.oid(o),x=o.s_oidt;if(s.eo&&o==s.eo){while(o&&!n&&y!='BODY'){"
+"o=o.parentElement?o.parentElement:o.parentNode;if(!o)return '';y=s."
+"ot(o);n=s.oid(o);x=o.s_oidt}}return o.href?o.href:'';");
/*
 * Plugin Utility: apl v1.1
 */
s.apl=new Function("l","v","d","u",""
+"var s=this,m=0;if(!l)l='';if(u){var i,n,a=s.split(l,d);for(i=0;i<a."
+"length;i++){n=a[i];m=m||(u==1?(n==v):(n.toLowerCase()==v.toLowerCas"
+"e()));}}if(!m)l=l?l+d+v:v;return l");
/*
 * Utility Function: split v1.5 (JS 1.0 compatible)
 */
s.split=new Function("l","d",""
+"var i,x=0,a=new Array;while(l){i=l.indexOf(d);i=i>-1?i:l.length;a[x"
+"++]=l.substring(0,i);l=l.substring(i+d.length);}return a");

/* crossVisitParticipation*/                                                                              
                                                                                                        
s.crossVisitParticipation = new Function("v","cn","ex","ct","dl","ev",""                          
+"var s=this;var ay=s.split(ev,',');for(var u=0;u<ay.length;u++){if(s"                     
+".events&&s.events.indexOf(ay[u])!=-1){s.c_w(cn,'');return '';}}if(!"                     
+"v||v=='')return '';var arry=new Array();var a=new Array();var c=s.c"                     
+"_r(cn);var g=0;var h=new Array();if(c&&c!='') arry=eval(c);var e=ne"                     
+"w Date();e.setFullYear(e.getFullYear()+5);if(arry.length>0&&arry[ar"                     
+"ry.length-1][0]==v)arry[arry.length-1]=[v, new Date().getTime()];el"                     
+"se arry[arry.length]=[v, new Date().getTime()];var data=s.join(arry"                     
+",{delim:',',front:'[',back:']',wrap:'\\''});var start=arry.length-c"                     
+"t < 0?0:arry.length-ct;s.c_w(cn,data,e);for(var x=start;x<arry.leng"                     
+"th;x++){var diff=Math.round(new Date()-new Date(parseInt(arry[x][1]"                     
+")))/86400000;if(diff<ex){h[g]=arry[x][0];a[g++]=arry[x];}}var r=s.j"                     
+"oin(h,{delim:dl});return r;");
/*
 * s.join: 1.0 - s.join(v,p)
 */

s.join = new Function("v","p",""
+"var s = this;var f,b,d,w;if(p){f=p.front?p.front:'';b=p.back?p.back"
+":'';d=p.delim?p.delim:'';w=p.wrap?p.wrap:'';}var str='';for(var x=0"
+";x<v.length;x++){if(typeof(v[x])=='object' )str+=s.join( v[x],p);el"
+"se str+=w+v[x]+w;if(x<v.length-1)str+=d;}return f+str+b;");
/*
 * Plugin: getCartOpen v 1.1 - returns events string with scOpen added
 * the first time scAdd occurs during a visit.
 */
s.getCartOpen=new Function("c",""
+"var s=this,t=new Date,e=s.events?s.events:'',i=0;t.setTime(t.getTim"
+"e()+1800000);if(s.c_r(c)||e.indexOf('scOpen')>-1){if(!s.c_w(c,1,t))"
+"{s.c_w(c,1,0)}}else{if(e.indexOf('scAdd')>-1){if(s.c_w(c,1,t)){i=1}"
+"else if(s.c_w(c,1,0)){i=1}}}if(i){e=e+',scOpen'}return e");

/*
 * Plugin: getAndPersistValue 0.3 - get a value on every page
 */
s.getAndPersistValue=new Function("v","c","e",""
	+"var s=this,a=new Date;"
	+"e=e?e:0;"
	+"a.setTime(a.getTime()+e*86400000);"
	+"if(v)s.c_w(c,v,e?a:0);"
	+"return s.c_r(c);"
);
/*
 * Plugin: getNewRepeat 1.0 - Return whether user is new or repeat
 */
s.getNewRepeat=new Function(""
+"var s=this,e=new Date(),cval,ct=e.getTime(),y=e.getYear();e.setTime"
+"(ct+30*24*60*60*1000);cval=s.c_r('s_nr');if(cval.length==0){s.c_w("
+"'s_nr',ct,e);return 'New';}if(cval.length!=0&&ct-cval<30*60*1000){s"
+".c_w('s_nr',ct,e);return 'New';}if(cval<1123916400001){e.setTime(cv"
+"al+30*24*60*60*1000);s.c_w('s_nr',ct,e);return 'Repeat';}else retur"
+"n 'Repeat';");
/*
 * Plugin: Days since last Visit 1.1.H - capture time from last visit
 */
s.getDaysSinceLastVisit=new Function("c",""
+"var s=this,e=new Date(),es=new Date(),cval,cval_s,cval_ss,ct=e.getT"
+"ime(),day=24*60*60*1000,f1,f2,f3,f4,f5;e.setTime(ct+3*365*day);es.s"
+"etTime(ct+30*60*1000);f0='Cookies Not Supported';f1='First Visit';f"
+"2='More than 30 days';f3='More than 7 days';f4='Less than 7 days';f"
+"5='Less than 1 day';cval=s.c_r(c);if(cval.length==0){s.c_w(c,ct,e);"
+"s.c_w(c+'_s',f1,es);}else{var d=ct-cval;if(d>30*60*1000){if(d>30*da"
+"y){s.c_w(c,ct,e);s.c_w(c+'_s',f2,es);}else if(d<30*day+1 && d>7*day"
+"){s.c_w(c,ct,e);s.c_w(c+'_s',f3,es);}else if(d<7*day+1 && d>day){s."
+"c_w(c,ct,e);s.c_w(c+'_s',f4,es);}else if(d<day+1){s.c_w(c,ct,e);s.c"
+"_w(c+'_s',f5,es);}}else{s.c_w(c,ct,e);cval_ss=s.c_r(c+'_s');s.c_w(c"
+"+'_s',cval_ss,es);}}cval_s=s.c_r(c+'_s');if(cval_s.length==0) retur"
+"n f0;else if(cval_s!=f1&&cval_s!=f2&&cval_s!=f3&&cval_s!=f4&&cval_s"
+"!=f5) return '';else return cval_s;");
/*
 * Plugin: detectRIA v0.1 - detect and set Flash, Silverlight versions
 */
s.detectRIA=new Function("cn", "fp", "sp", "mfv", "msv", "sf", ""
+"cn=cn?cn:'s_ria';msv=msv?msv:2;mfv=mfv?mfv:10;var s=this,sv='',fv=-"
+"1,dwi=0,fr='',sr='',w,mt=s.n.mimeTypes,uk=s.c_r(cn),k=s.c_w('s_cc',"
+"'true',0)?'Y':'N';fk=uk.substring(0,uk.indexOf('|'));sk=uk.substrin"
+"g(uk.indexOf('|')+1,uk.length);if(k=='Y'&&s.p_fo('detectRIA')){if(u"
+"k&&!sf){if(fp){s[fp]=fk;}if(sp){s[sp]=sk;}return false;}if(!fk&&fp)"
+"{if(s.pl&&s.pl.length){if(s.pl['Shockwave Flash 2.0'])fv=2;x=s.pl['"
+"Shockwave Flash'];if(x){fv=0;z=x.description;if(z)fv=z.substring(16"
+",z.indexOf('.'));}}else if(navigator.plugins&&navigator.plugins.len"
+"gth){x=navigator.plugins['Shockwave Flash'];if(x){fv=0;z=x.descript"
+"ion;if(z)fv=z.substring(16,z.indexOf('.'));}}else if(mt&&mt.length)"
+"{x=mt['application/x-shockwave-flash'];if(x&&x.enabledPlugin)fv=0;}"
+"if(fv<=0)dwi=1;w=s.u.indexOf('Win')!=-1?1:0;if(dwi&&s.isie&&w&&exec"
+"Script){result=false;for(var i=mfv;i>=3&&result!=true;i--){execScri"
+"pt('on error resume next: result = IsObject(CreateObject(\"Shockwav"
+"eFlash.ShockwaveFlash.'+i+'\"))','VBScript');fv=i;}}fr=fv==-1?'flas"
+"h not detected':fv==0?'flash enabled (no version)':'flash '+fv;}if("
+"!sk&&sp&&s.apv>=4.1){var tc='try{x=new ActiveXObject(\"AgControl.A'"
+"+'gControl\");for(var i=msv;i>0;i--){for(var j=9;j>=0;j--){if(x.is'"
+"+'VersionSupported(i+\".\"+j)){sv=i+\".\"+j;break;}}if(sv){break;}'"
+"+'}}catch(e){try{x=navigator.plugins[\"Silverlight Plug-In\"];sv=x'"
+"+'.description.substring(0,x.description.indexOf(\".\")+2);}catch('"
+"+'e){}}';eval(tc);sr=sv==''?'silverlight not detected':'silverlight"
+" '+sv;}if((fr&&fp)||(sr&&sp)){s.c_w(cn,fr+'|'+sr,0);if(fr)s[fp]=fr;"
+"if(sr)s[sp]=sr;}}");
 
s.p_fo=new Function("n",""
+"var s=this;if(!s.__fo){s.__fo=new Object;}if(!s.__fo[n]){s.__fo[n]="
+"new Object;return 1;}else {return 0;}");


/*
 * Function - read combined cookies v 0.3
 */
if(!s.__ccucr){s.c_rr=s.c_r;s.__ccucr = true;
s.c_r=new Function("k",""
+"var s=this,d=new Date,v=s.c_rr(k),c=s.c_rr('s_pers'),i,m,e;if(v)ret"
+"urn v;k=s.ape(k);i=c.indexOf(' '+k+'=');c=i<0?s.c_rr('s_sess'):c;i="
+"c.indexOf(' '+k+'=');m=i<0?i:c.indexOf('|',i);e=i<0?i:c.indexOf(';'"
+",i);m=m>0?m:e;v=i<0?'':s.epa(c.substring(i+2+k.length,m<0?c.length:"
+"m));if(m>0&&m!=e)if(parseInt(c.substring(m+1,e<0?c.length:e))<d.get"
+"Time()){d.setTime(d.getTime()-60000);s.c_w(s.epa(k),'',d);v='';}ret"
+"urn v;");}
/*
 * Function - write combined cookies v 0.3
 */
if(!s.__ccucw){s.c_wr=s.c_w;s.__ccucw = true;
s.c_w=new Function("k","v","e",""
+"this.new2 = true;"
+"var s=this,d=new Date,ht=0,pn='s_pers',sn='s_sess',pc=0,sc=0,pv,sv,"
+"c,i,t;d.setTime(d.getTime()-60000);if(s.c_rr(k)) s.c_wr(k,'',d);k=s"
+".ape(k);pv=s.c_rr(pn);i=pv.indexOf(' '+k+'=');if(i>-1){pv=pv.substr"
+"ing(0,i)+pv.substring(pv.indexOf(';',i)+1);pc=1;}sv=s.c_rr(sn);i=sv"
+".indexOf(' '+k+'=');if(i>-1){sv=sv.substring(0,i)+sv.substring(sv.i"
+"ndexOf(';',i)+1);sc=1;}d=new Date;if(e){if(e.getTime()>d.getTime())"
+"{pv+=' '+k+'='+s.ape(v)+'|'+e.getTime()+';';pc=1;}}else{sv+=' '+k+'"
+"='+s.ape(v)+';';sc=1;}if(sc) s.c_wr(sn,sv,0);if(pc){t=pv;while(t&&t"
+".indexOf(';')!=-1){var t1=parseInt(t.substring(t.indexOf('|')+1,t.i"
+"ndexOf(';')));t=t.substring(t.indexOf(';')+1);ht=ht<t1?t1:ht;}d.set"
+"Time(ht);s.c_wr(pn,pv,d);}return v==s.c_r(s.epa(k));");}




/* Configure Modules and Plugins */

s.loadModule("Media")
s.Media.autoTrack=false
s.Media.trackVars="None"
s.Media.trackEvents="None"

/* WARNING: Changing any of the below variables will cause drastic
changes to how your visitor data is collected.  Changes should only be
made when instructed to do so by your account manager.*/

if ((typeof(s_trackingServer) != "undefined") && (s_trackingServer == false)) {
	s.dc=122;
} else {
	s.visitorNamespace="ikea";
	s.trackingServer="metrics.ikea.com";
	s.trackingServerSecure="smetrics.ikea.com";

	s.dc=122;
	s.vmk="4A686ACF";
}



/****************************** MODULES *****************************/
/* Module: Media */
s.m_Media_c="(`OWhilePlaying~='s_media_'+m._in+'_~unc^D(~;`E~m.ae(mn,l,\"'+p+'\",~){var m=this~o;w.percent=((w.off^e+1)/w`X)*100;w.percent=w.percent>1~o.'+f~=new ~o.Get~:Math.floor(w.percent);w.timeP"
+"layed=i.t~}`x p');p=tcf(o)~Time~x,x!=2?p:-1,o)}~if(~m.monitor)m.monitor(m.s,w)}~m.s.d.getElementsByTagName~ersionInfo~'^N_c_il['+m._in+'],~'o','var e,p=~else~i.to~=Math.floor(~}catch(e){p=~m.track~"
+"s.wd.addEventListener~.name~m.s.rep(~layState~||^8~Object~m.s.wd[f1]~^A+=i.t+d+i.s+d+~.length~parseInt(~Player '+~s.wd.attachEvent~'a','b',c~Media~pe='m~;o[f1]~m.s.isie~.current~);i.~p<p2||p-p2>5)~"
+".event=~m.close~i.lo~vo.linkTrack~=v+',n,~.open~){w.off^e=~;n=m.cn(n);~){this.e(n,~v=e='None';~Quick~MovieName()~);o[f~out(\"'+v+';~return~1000~i.lx~m.ol~o.controls~m.s.ape(i.~load',m.as~)}};m.~scr"
+"ipt';x.~,t;try{t=~Version()~n==~'--**--',~pev3~o.id~i.ts~tion~){mn=~1;o[f7]=~();~(x==~){p='~&&m.l~l[n])~:'')+i.e~':'E')+o~var m=s~!p){tcf~xc=m.s.~Title()~()/~7+'~+1)/i.l~;i.e=''~3,p,o);~m.l[n]=~Dat"
+"e~5000~;if~i.lt~';c2='~tm.get~Events~set~Change~)};m~',f~(x!=~4+'=n;~~^N.m_i('`c');m.cn=f`2n`5;`x `Rm.s.rep(`Rn,\"\\n\",''),\"\\r\",''),^9''^g`o=f`2n,l,p,b`5,i`8`U,tm`8^X,a='',x`ql=`Yl)`3!l)l=1`3n&"
+"&p){`E!m.l)m.l`8`U`3m.^K`k(n)`3b&&b.id)a=b.id;for (x in m.l)`Em.l[x]^J[x].a==a)`k(m.l[x].n`hn=n;i.l=l;i.p=m.cn(p`ha=a;i.t=0;^C=0;i.s`M^c`C^R`y`hlx=0;^a=i.s;`l=0^U;`L=-1;^Wi}};`k=f`2n`r0,-1^g.play=f"
+"`2n,o`5,i;i=m.e(n,1,o`hm`8F`2`Ii`3m.l){i=m.l[\"'+`Ri.n,'\"','\\\\\"')+'\"]`3i){`E`z==1)m.e(i.n,3,-1`hmt=^e`Cout(i.m,^Y)}}'`hm(^g.stop=f`2n,o`r2,o)};`O=f`2n`5^Z `0) {m.e(n,4,-1^4e=f`2n,x,o`5,i,tm`8^"
+"X,ts`M^c`C^R`y),ti=`OSeconds,tp=`OMilestones,z`8Array,j,d=^9t=1,b,v=`OVars,e=`O^d,`dedia',^A,w`8`U,vo`8`U`qi=n^J&&m.l[n]?m.l[n]:0`3i){w`Q=n;w`X=i.l;w.playerName=i.p`3`L<0)w`j\"OPEN\";`K w`j^H1?\"PL"
+"AY\":^H2?\"STOP\":^H3?\"MONITOR\":\"CLOSE\")));w`o`C`8^X^Gw`o`C.^e`C(i.s*`y)`3x>2||^i`z&&^i2||`z==1))) {b=\"`c.\"+name;^A = ^2n)+d+i.l+d+^2p)+d`3x){`Eo<0&&^a>0){o=(ts-^a)+`l;o=o<i.l?o:i.l-1}o`Mo)`3"
+"x>=2&&`l<o){i.t+=o-`l;^C+=o-`l;}`Ex<=2){i.e+=^H1?'S^M;`z=x;}`K `E`z!=1)m.e(n,1,o`hlt=ts;`l=o;`W`0&&`L>=0?'L'+`L^L+^i2?`0?'L^M:'')^Z`0){b=0;`d_o'`3x!=4`p`600?100`A`3`F`E`L<0)`d_s';`K `Ex==4)`d_i';`K"
+"{t=0;`sti=ti?`Yti):0;z=tp?m.s.sp(tp,','):0`3ti&&^C>=ti)t=1;`K `Ez){`Eo<`L)`L=o;`K{for(j=0;j<z`X;j++){ti=z[j]?`Yz[j]):0`3ti&&((`L^T<ti/100)&&((o^T>=ti/100)){t=1;j=z`X}}}}}}}`K{m.e(n,2,-1)^Z`0`pi.l`6"
+"00?100`A`3`F^W0`3i.e){`W`0&&`L>=0?'L'+`L^L^Z`0){`s`d_o'}`K{t=0;m.s.fbr(b)}}`K t=0;b=0}`Et){`mVars=v;`m^d=e;vo.pe=pe;vo.^A=^A;m.s.t(vo,b)^Z`0){^C=0;`L=o^U}}}}`x i};m.ae=f`2n,l,p,x,o,b){`En&&p`5`3!m."
+"l||!m.^Km`o(n,l,p,b);m.e(n,x,o^4a=f`2o,t`5,i=^B?^B:o`Q,n=o`Q,p=0,v,c,c1,c2,^Ph,x,e,f1,f2`1oc^h3`1t^h4`1s^h5`1l^h6`1m^h7`1c',tcf,w`3!i){`E!m.c)m.c=0;i`1'+m.c;m.c++}`E!^B)^B=i`3!o`Q)o`Q=n=i`3!^0)^0`8"
+"`U`3^0[i])`x;^0[i]=o`3!xc)^Pb;tcf`8F`2`J0;try{`Eo.v`H&&o`g`c&&^1)p=1`N0`B`3^O`8F`2`J0^6`9`t`C^7`3t)p=2`N0`B`3^O`8F`2`J0^6`9V`H()`3t)p=3`N0`B}}v=\"^N_c_il[\"+m._in+\"],o=^0['\"+i+\"']\"`3p==1^IWindo"
+"ws `c `Zo.v`H;c1`np,l,x=-1,cm,c,mn`3o){cm=o`g`c;c=^1`3cm&&c^Ecm`Q?cm`Q:c.URL;l=cm.dura^D;p=c`gPosi^D;n=o.p`S`3n){`E^88)x=0`3^83)x=1`3^81`T2`T4`T5`T6)x=2;}^b`Ex>=0)`4`D}';c=c1+c2`3`f&&xc){x=m.s.d.cr"
+"eateElement('script');x.language='j^5type='text/java^5htmlFor=i;x`j'P`S^f(NewState)';x.defer=true;x.text=c;xc.appendChild(x`v6]`8F`2c1+'`E^83){x=3;'+c2+'}^e`Cout(`76+',^Y)'`v6]()}}`Ep==2^I`t`C `Z(`"
+"9Is`t`CRegistered()?'Pro ':'')+`9`t`C^7;f1=f2;c`nx,t,l,p,p2,mn`3o^E`9`u?`9`u:`9URL^Gn=`9Rate^Gt=`9`CScale^Gl=`9Dura^D^Rt;p=`9`C^Rt;p2=`75+'`3n!=`74+'||`i{x=2`3n!=0)x=1;`K `Ep>=l)x=0`3`i`42,p2,o);`4"
+"`D`En>0&&`7^S>=10){`4^V`7^S=0}`7^S++;`7^j`75+'=p;^e`C`w`72+'(0,0)\",500)}'`e`8F`2`b`v4]=-^F0`e(0,0)}`Ep==3^IReal`Z`9V`H^Gf1=n+'_OnP`S^f';c1`nx=-1,l,p,mn`3o^E`9^Q?`9^Q:`9Source^Gn=`9P`S^Gl=`9Length^"
+"R`y;p=`9Posi^D^R`y`3n!=`74+'){`E^83)x=1`3^80`T2`T4`T5)x=2`3^80&&(p>=l||p==0))x=0`3x>=0)`4`D`E^83&&(`7^S>=10||!`73+')){`4^V`7^S=0}`7^S++;`7^j^b`E`72+')`72+'(o,n)}'`3`V)o[f2]=`V;`V`8F`2`b1+c2)`e`8F`2"
+"`b1+'^e`C`w`71+'(0,0)\",`73+'?500:^Y);'+c2`v4]=-1`3`f)o[f3]=^F0`e(0,0^4as`8F`2'e',`Il,n`3m.autoTrack&&`G){l=`G(`f?\"OBJECT\":\"EMBED\")`3l)for(n=0;n<l`X;n++)m.a(^K;}')`3`a)`a('on^3);`K `E`P)`P('^3,"
+"false)";
s.m_i("Media");
/* Module: Survey */
s.m_Survey_c="s_sv_globals~=function(~var m=this,~_root\",(e?e+\".\":\"\")+d+\".2o7.net/survey/~.length~};m._~g.triggerRequested~execute~return~suites~g.commonRevision~rl=location.protocol+\"//\"+c.~"
+"=window~;if(~.match(/~g.pending~=navigator.~g.pageImpressions~g.manualTriggers~g.incomingLists~&&i.constructor~){this._boot();~.toLowerCase()~gather~m._blocked())~=1;m._script(~.module._load~setTim"
+"eout(\"~.url+\"/~r.requested~g.commonUrl~.replace(/\\~){var ~);m.~<b[1]:n==\"~param(c,\"~;for(~m.onLoad~else if(~Name~||{},~||\"\",~]={l:m._~_booted~typeof ~:s.page~\",\"~=\"s_sv_~=[];~~var m=s.m_i"
+"(\"Survey\"`Xlaunch`1i,e,c,o,f`L`2g`C.`0`el,j`Dg.unloaded||`O`8 0;i=i`K&&i.constructor==Array?i:[i];l=`I`aj=0;j<i`4;++j)l[l`4`g`9,i:i[j],e:e||0,c:c||0,o:o||0,f:f||0`5`7();`8 1;`5t`1`L`2s=m.s,g`C.`0"
+"`el`D`O`8;l=`H;l[l`4`g`9,n`j`d`fu`jURL`fr:s.referrer`fc:s.campaign||\"\"`5`7();`5rr`1`Wg`C.`0`ef=g.onScQueueEmpty||0`Df)f();`5blocked`1){`2g`C.`0||{};`8 !m.`h||g.stop||!`F&&!`6;`5`7`1){if(`0.`7)`R`"
+"0.`7();\",0);`5boot`1){`2s=m.s,w`C,g,c,d=s.dc,e=s.visitor`dspace,n`Gapp`d`M,a`GuserAgent,v`GappVersion,h,i,j,k,l,b`Dw.`0)`8`D!((b=v`EAppleWebKit\\/([0-9]+)/))?521`Ynetscape\"?a`Egecko\\//i):(b=a`Eo"
+"pera[ \\/]?([0-9]+).[0-9]+/i))?7`Ymicrosoft internet explorer\"&&!v`Emacintosh/i)&&(b=v`Emsie ([0-9]+).([0-9]+)/i))&&(5<b[1]||b[1]==5&&4<b[2])))`8;g=w.`0={};g.module=m;`F=0;`J`m`H`m`I`me=\"survey\""
+";c=g.config={`5`Zdynamic`3dynamic\"`X_`Z`N`3`N\");g.u`Bdynamic_root;g.`NU`B`N_root;g.dataCenter=d;g.onListLoaded=new Function(\"r`kb`kd`ki`kl`k`0`Qed(r,b,d,i,l);\"`X_`9=(m.`9||s.un)`M.split(`k);l=m"
+"._`9;b={}`aj=0;j<l`4;++j){i=l[j]`Di&&!b[i]){h=i`4`ak=0;k<i`4;++k)h=(h&0x03ffffff)<<5^ h>>26^ i.charCodeAt(k);b[i]={url:g`S`9/\"+(h%251+100)+\"/\"+encodeURIComponent(i`V|/,\"||\")`V//,\"|-\"))};++`F"
+";}}g.`9=b;`R`0`Q();\",0`X`h=1;`5param`1c,n,v`Wp`l\",w`C,u=\"undefined\"`D`ic[n]==u)c[n]=`iw[p+n]==u?v:w[p+n];`5load`1){`2g=`0,q=g.`9,r,i,n`lsid\",b=m.s.c_r(n)`D!b){b=parseInt((new Date()).getTime()"
+"*Math.random()`Xs.c_w(n,b);}for(i in q){r=q[i]`D!`T){`T`Pr`Slist.js?\"+b);}}`5loaded`1r,b,d,i,l){`2g=`0,n=`J;--`F`D!`A){g.bulkRevision=b;`A=r;`U=g`Scommon/\"+b;}`c`A!=r)`8`D!l`4)`8;n[n`4]={r:i,l:l}"
+"`Dg.`7)g.`7();`c!`6){`6`P`U+\"/trigger.js\");}`5script`1u`Wd=document,e=d.createElement(\"script\");e.type=\"text/javascript\";e.src=u;d.getElementsByTag`d(\"head\")[0].appendChild(e);}`D`b)`b(s,m)";
s.m_i("Survey");

/************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
var s_code='',s_objectID;function s_gi(un,pg,ss){var c="=fun`o(~){`Ps=^O~.substring(~#1 ~.indexOf(~;@z~`e@z~=new Fun`o(~.length~.toLowerCase()~`Ps#7c_il['+s^Zn+'],~=new Object~};s.~`YMigrationServer~"
+".toUpperCase~){@z~','~s.wd~);s.~')q='~=new Array~ookieDomainPeriods~.location~^LingServer~dynamicAccount~var ~link~s.m_~s.apv~BufferedRequests~=='~Element~)@zx^a!Object#VObject.prototype#VObject.pr"
+"ototype[x])~etTime~visitor~$u@a(~referrer~s.pt(~s.maxDelay~}c#D(e){~else ~.lastIndexOf(~^xc_i~.protocol~=new Date~^xobjectID=s.ppu=$E=$Ev1=$Ev2=$Ev3=~#e+~=''~}@z~@ji=~ction~javaEnabled~onclick~Name"
+"~ternalFilters~javascript~s.dl~@6s.b.addBehavior(\"# default# ~=parseFloat(~typeof(v)==\"~window~cookie~while(~s.vl_g~Type~;i#T{~tfs~s.un~;v=^sv,255)}~&&s.~o^xoid~browser~.parent~document~colorDept"
+"h~String~.host~s.rep(~s.eo~'+tm@R~s.sq~parseInt(~t=s.ot(o)~track~nload~j='1.~this~#OURL~}else{~s.vl_l~lugins~'){q='~dynamicVariablePrefix~');~Sampling~s.rc[un]~Event~._i~&&(~loadModule~resolution~s"
+".c_r(~s.c_w(~s.eh~s.isie~\"m_\"+n~;@jx in ~Secure~Height~tcf~isopera~ismac~escape(~'s_~.href~screen.~s.fl(~s#7gi(~Version~harCode~variableProvider~.s_~)s_sv(v,n[k],i)}~){s.~)?'Y':'N'~u=m[t+1](~i)cl"
+"earTimeout(~e&&l$YSESSION'~name~home#O~;try{~,$k)~s.ssl~s.oun~s.rl[u~Width~o.type~s.vl_t~Lifetime~s.gg('objectID~sEnabled~')>=~'+n+'~.mrq(@uun+'\"~ExternalLinks~charSet~lnk~onerror~currencyCode~.sr"
+"c~disable~.get~MigrationKey~(''+~&&!~f',~r=s[f](~u=m[t](~Opera~Math.~s.ape~s.fsg~s.ns6~conne~InlineStats~&&l$YNONE'~Track~'0123456789~true~for(~+\"_c\"]~s.epa(~t.m_nl~s.va_t~m._d~=s.sp(~n=s.oid(o)~"
+",'sqs',q);~LeaveQuery~n){~\"'+~){n=~){t=~'_'+~\",''),~if(~vo)~s.sampled~=s.oh(o);~+(y<1900?~n]=~&&o~:'';h=h?h~;'+(n?'o.~sess~campaign~lif~'http~s.co(~ffset~s.pe~'&pe~m._l~s.c_d~s.brl~s.nrs~s[mn]~,'"
+"vo~s.pl~=(apn~space~\"s_gs(\")~vo._t~b.attach~2o7.net'~Listener~Year(~d.create~=s.n.app~)}}}~!='~'=')~1);~'||t~)+'/~s()+'~){p=~():''~'+n;~a['!'+t]~){v=s.n.~channel~100~rs,~.target~o.value~s_si(t)~'"
+")dc='1~\".tl(\")~etscape~s_')t=t~omePage~='+~l&&~&&t~[b](e);~\"){n[k]~';s.va_~a+1,b):~return~mobile~height~events~random~code~=s_~=un~,pev~'MSIE ~'fun~floor(~atch~transa~s.num(~m._e~s.c_gd~,'lt~tm."
+"g~.inner~;s.gl(~,f1,f2~',s.bc~page~Group,~.fromC~sByTag~')<~++)~)){~||!~?'&~+';'~[t]=~[i]=~[n];~' '+~'+v]~>=5)~:'')~+1))~!a[t])~~s._c=^pc';`H=`y`5!`H`g@t`H`gl`K;`H`gn=0;}s^Zl=`H`gl;s^Zn=`H`gn;s^Zl["
+"s^Z$4s;`H`gn++;s.an#7an;s.cls`0x,c){`Pi,y`l`5!c)c=^O.an;`n0;i<x`8^3n=x`2i,i+1)`5c`4n)>=0)y+=n}`3y`Cfl`0x,l){`3x?@Tx)`20,l):x`Cco`0o`F!o)`3o;`Pn`B,x^io)@zx`4'select#S0&&x`4'filter#S0)n[x]=o[x];`3n`C"
+"num`0x){x`l+x;@j`Pp=0;p<x`8;p#T@z(@h')`4x`2p,p#f<0)`30;`31`Crep#7rep;s.sp#7sp;s.jn#7jn;@a`0x`1,h=@hABCDEF',i,c=s.@L,n,l,e,y`l;c=c?c`E$f`5x){x`l+x`5c`UAUTO'^a'').c^vAt){`n0;i<x`8^3c=x`2i,i+$an=x.c^v"
+"At(i)`5n>127){l=0;e`l;^0n||l<4){e=h`2n%16,n%16+1)+e;n=(n-n%16)/16;l++}y+='%u'+e}`6c`U+')y+='%2B';`ey+=^oc)}x=y^Qx=x?^F^o''+x),'+`G%2B'):x`5x&&c^7em==1&&x`4'%u#S0&&x`4'%U#S0){i=x`4'%^V^0i>=0){i++`5h"
+"`28)`4x`2i,i+1)`E())>=0)`3x`20,i)+'u00'+x`2i);i=x`4'%',i$X}`3x`Cepa`0x`1;`3x?un^o^F''+x,'+`G ')):x`Cpt`0x,d,f,a`1,t=x,z=0,y,r;^0t){y=t`4d);y=y<0?t`8:y;t=t`20,y);@Wt,a)`5r)`3r;z+=y+d`8;t=x`2z,x`8);t"
+"=z<x`8?t:''}`3''`Cisf`0t,a){`Pc=a`4':')`5c>=0)a=a`20,c)`5t`20,2)`U$s`22);`3(t!`l$w==a)`Cfsf`0t,a`1`5`ba,`G,'is@Vt))@b+=(@b!`l?`G`kt;`30`Cfs`0x,f`1;@b`l;`bx,`G,'fs@Vf);`3@b`Csi`0wd`1,c`l+s_gi,a=c`4"
+"\"{\"),b=c`f\"}\"),m;c#7fe(a>0&&b>0?c`2#00)`5wd&&wd.^B&&c){wd.s`Xout(#B`o s_sv(o,n,k){`Pv=o[k],i`5v`F`xstring\"||`xnumber\")n[k]=v;`eif (`xarray$y`K;`n0;i<v`8;i++^y`eif (`xobject$y`B;@ji in v^y}}fu"
+"n`o $o{`Pwd=`y,s,i,j,c,a,b;wd^xgi`7\"un\",\"pg\",\"ss\",@uc+'\");wd.^t@u@9+'\");s=wd.s;s.sa(@u^5+'\"`I^4=wd;`b^1,\",\",\"vo1\",t`I@M=^G=s.`Q`r=s.`Q^2=`H`j\\'\\'`5t.m_$v@m)`n0;i<@m`8^3n=@m[i]`5@tm=t"
+"#ac=t[^h]`5m&&c){c=\"\"+c`5c`4\"fun`o\")>=0){a=c`4\"{\");b=c`f\"}\");c=a>0&&b>0?c`2#00;s[^h@k=c`5#G)s.^b(n)`5s[n])@jj=0;j<$G`8;j#Ts_sv(m,s[n],$G[j]$X}}`Pe,o,t@6o=`y.opener`5o$5^xgi@wo^xgi(@u^5+'\")"
+"`5t)$o}`d}',1)}`Cc_d`l;#Hf`0t,a`1`5!#Ft))`31;`30`Cc_gd`0`1,d=`H`M^E@4,n=s.fpC`L,p`5!n)n=s.c`L`5d@U$H@vn?^Jn):2;n=n>2?n:2;p=d`f'.')`5p>=0){^0p>=0&&n>1$ed`f'.',p-$an--}$H=p>0&&`bd,'.`Gc_gd@V0)?d`2p):"
+"d}}`3$H`Cc_r`0k`1;k=@a(k);`Pc=#bs.d.`z,i=c`4#bk+$Z,e=i<0?i:c`4';',i),v=i<0?'':@lc`2i+2+k`8,e<0?c`8:e));`3v$Y[[B]]'?v:''`Cc_w`0k,v,e`1,d=#H(),l=s.`z@E,t;v`l+v;l=l?@Tl)`E$f`5@3@f@w(v!`l?^Jl?l:0):-60)"
+"`5t){e`i;e.s`X(e.g`X()+(t*$k0))}`mk@f^zd.`z=k+'`Zv!`l?v:'[[B]]')+'; path=/;'+(@3?' expires$ue.toGMT^D()#X`k(d?' domain$ud#X:'^V`3^dk)==v}`30`Ceh`0o,e,r,f`1,b=^p'+e+@xs^Zn,n=-1,l,i,x`5!^fl)^fl`K;l=^"
+"fl;`n0;i<l`8&&n<0;i++`Fl[i].o==o&&l[i].e==e)n=i`mn<0@vi;l[n]`B}x=l#ax.o=o;x.e=e;f=r?x.b:f`5r||f){x.b=r?0:o[e];x.o[e]=f`mx.b){x.o[b]=x.b;`3b}`30`Ccet`0f,a,t,o,b`1,r,^l`5`S>=5^a!s.^m||`S>=7#U^l`7's`G"
+"f`Ga`Gt`G`Pe,r@6@Wa)`dr=s[t](e)}`3r^Vr=^l(s,f,a,t)^Q@zs.^n^7u`4#A4@H0)r=s[b](a);else{^f(`H,'@N',0,o);@Wa`Ieh(`H,'@N',1)}}`3r`Cg^4et`0e`1;`3s.^4`Cg^4oe`7'e`G`Ac;^f(`y,\"@N\",1`Ie^4=1;c=s.t()`5c)s.d."
+"write(c`Ie^4=0;`3@i'`Ig^4fb`0a){`3`y`Cg^4f`0w`1,p=w^A,l=w`M;s.^4=w`5p&&p`M!=$vp`M^E==l^E^z^4=p;`3s.g^4f(s.^4)}`3s.^4`Cg^4`0`1`5!s.^4^z^4=`H`5!s.e^4)s.^4=s.cet('g^4@Vs.^4,'g^4et',s.g^4oe,'g^4fb')}`3"
+"s.^4`Cmrq`0u`1,l=@A],n,r;@A]=0`5l)@jn=0;n<l`8;n#T{r=l#as.mr(0,0,r.r,0,r.t,r.u)}`Cbr`0id,rs`1`5s.@Q`T#V^e^pbr',rs))$I=rs`Cflush`T`0){^O.fbr(0)`Cfbr`0id`1,br=^d^pbr')`5!br)br=$I`5br`F!s.@Q`T)^e^pbr`G"
+"'`Imr(0,0,br)}$I=0`Cmr`0$8,q,$lid,ta,u`1,dc=s.dc,t1=s.`N,t2=s.`N^j,tb=s.`NBase,p='.sc',ns=s.`Y`r$O,un=s.cls(u?u:(ns?ns:s.fun)),r`B,l,imn=^pi_'+(un),im,b,e`5!rs`Ft1`Ft2^7ssl)t1=t2^Q@z!tb)tb='$S`5dc)"
+"dc=@Tdc)`9;`edc='d1'`5tb`U$S`Fdc`Ud1$p12';`6dc`Ud2$p22';p`l}t1#8+'.'+dc+'.'+p+tb}rs=$B'+(@8?'s'`k'://'+t1+'/b/ss/'+^5+'/'+(s.#2?'5.1':'1'$cH.20.2/'+$8+'?AQB=1&ndh=1'+(q?q`k'&AQE=1'`5^g@Us.^n`F`S>5."
+"5)rs=^s$l4095);`ers=^s$l2047)`mid^zbr(id,rs);#1}`ms.d.images&&`S>=3^a!s.^m||`S>=7)^a@c<0||`S>=6.1)`F!s.rc)s.rc`B`5!^X){^X=1`5!s.rl)s.rl`B;@An]`K;s`Xout('@z`y`gl)`y`gl['+s^Zn+']@J)',750)^Ql=@An]`5l)"
+"{r.t=ta;r.u#8;r.r=rs;l[l`8]=r;`3''}imn+=@x^X;^X++}im=`H[imn]`5!im)im=`H[im$4new Image;im^xl=0;im.o^M`7'e`G^O^xl=1;`Pwd=`y,s`5wd`gl){s=wd`gl['+s^Zn+'];s@J`Inrs--`5!$J)`Rm(\"rr\")}')`5!$J^znrs=1;`Rm("
+"'rs')}`e$J++;im@P=rs`5rs`4$F=@H0^a!ta||ta`U_self$ba`U_top'||(`H.@4$wa==`H.@4)#Ub=e`i;^0!im^x$ve.g`X()-b.g`X()<500)e`i}`3''}`3'<im'+'g sr'+'c=@urs+'\" width=1 #3=1 border=0 alt=\"\">'`Cgg`0v`1`5!`H["
+"^p#c)`H[^p#c`l;`3`H[^p#c`Cglf`0t,a`Ft`20,2)`U$s`22);`Ps=^O,v=s.gg(t)`5v)s#Yv`Cgl`0v`1`5s.pg)`bv,`G,'gl@V0)`Chav`0`1,qs`l,fv=s.`Q@gVa$lfe=s.`Q@g^Ys,mn,i`5$E){mn=$E`20,1)`E()+$E`21)`5$K){fv=$K.^LVars"
+";fe=$K.^L^Ys}}fv=fv?fv+`G+^R+`G+^R2:'';`n0;i<@n`8^3`Pk=@n[i],v=s[k],b=k`20,4),x=k`24),n=^Jx),q=k`5v&&k$Y`Q`r'&&k$Y`Q^2'`F$E||s.@M||^G`Ffv^a`G+fv+`G)`4`G+k+`G)<0)v`l`5k`U#4'&&fe)v=s.fs(v,fe)`mv`Fk`U"
+"^U`JD';`6k`U`YID`Jvid';`6k`U^P^Tg'^6`6k`U`a^Tr'^6`6k`Uvmk'||k`U`Y@S`Jvmt';`6k`U`D^Tvmf'`5@8^7`D^j)v`l}`6k`U`D^j^Tvmf'`5!@8^7`D)v`l}`6k`U@L^Tce'`5v`E()`UAUTO')v='ISO8859-1';`6s.em==2)v='UTF-8'}`6k`U"
+"`Y`r$O`Jns';`6k`Uc`L`Jcdp';`6k`U`z@E`Jcl';`6k`U^w`Jvvp';`6k`U@O`Jcc';`6k`U$j`Jch';`6k`U#E`oID`Jxact';`6k`U$9`Jv0';`6k`U^c`Js';`6k`U^C`Jc';`6k`U`t^u`Jj';`6k`U`p`Jv';`6k`U`z@G`Jk';`6k`U^9@B`Jbw';`6k`"
+"U^9^k`Jbh';`6k`U@d`o^2`Jct';`6k`U@5`Jhp';`6k`Up^S`Jp';`6#Fx)`Fb`Uprop`Jc$g`6b`UeVar`Jv$g`6b`Ulist`Jl$g`6b`Uhier^Th'+n^6`mv)qs+='&'+q+'$u(k`20,3)$Ypev'?@a(v):v$X`3qs`Cltdf`0t,h@wt?t`9$6`9:'';`Pqi=h`"
+"4'?^Vh=qi>=0?h`20,qi):h`5t&&h`2h`8-(t`8#f`U.'+t)`31;`30`Cltef`0t,h@wt?t`9$6`9:''`5t&&h`4t)>=0)`31;`30`Clt`0h`1,lft=s.`QDow^MFile^2s,lef=s.`QEx`s,$A=s.`QIn`s;$A=$A?$A:`H`M^E@4;h=h`9`5s.^LDow^MLinks&"
+"&lft&&`blft,`G#Id@Vh))`3'd'`5s.^L@K&&h`20,1)$Y# '^alef||$A)^a!lef||`blef,`G#Ie@Vh))^a!$A#V`b$A,`G#Ie@Vh)))`3'e';`3''`Clc`7'e`G`Ab=^f(^O,\"`q\"`I@M=$C^O`It(`I@M=0`5b)`3^O$x`3@i'`Ibc`7'e`G`Af,^l`5s.d"
+"^7d.all^7d.all.cppXYctnr)#1;^G=e@P`V?e@P`V:e$m;^l`7\"s\",\"`Pe@6@z^G^a^G.tag`r||^G^A`V||^G^ANode))s.t()`d}\");^l(s`Ieo=0'`Ioh`0o`1,l=`H`M,h=o^q?o^q:'',i,j,k,p;i=h`4':^Vj=h`4'?^Vk=h`4'/')`5h^ai<0||("
+"j>=0&&i>j)||(k>=0&&i>k))$eo`h$5`h`8>1?o`h:(l`h?l`h:'^Vi=l.path@4`f'/^Vh=(p?p+'//'`k(o^E?o^E:(l^E?l^E#e)+(h`20,1)$Y/'?l.path@4`20,i<0?0:i$c'`kh}`3h`Cot`0o){`Pt=o.tag`r;t=t$w`E?t`E$f`5t`USHAPE')t`l`5"
+"t`Ft`UINPUT'&&@C&&@C`E)t=@C`E();`6!t$5^q)t='A';}`3t`Coid`0o`1,^K,p,c,n`l,x=0`5t@U^8$eo`h;c=o.`q`5o^q^at`UA$b`UAREA')^a!c#Vp||p`9`4'`t#S0))n$2`6c@v^Fs.rep(^Fs.rep@Tc,\"\\r@y\"\\n@y\"\\t@y' `G^Vx=2}`"
+"6$n^at`UINPUT$b`USUBMIT')@v$n;x=3}`6o@P$w`UIMAGE')n=o@P`5@t^8=^sn@7;^8t=x}}`3^8`Crqf`0t,un`1,e=t`4$Z,u=e>=0?`G+t`20,e)+`G:'';`3u&&u`4`G+un+`G)>=0?@lt`2e#f:''`Crq`0un`1,c#8`4`G),v=^d^psq'),q`l`5c<0)"
+"`3`bv,'&`Grq@Vun);`3`bun,`G,'rq',0)`Csqp`0t,a`1,e=t`4$Z,q=e<0?'':@lt`2e+1)`Isqq[q]`l`5e>=0)`bt`20,e),`G@r`30`Csqs`0un,q`1;^Iu[u$4q;`30`Csq`0q`1,k=^psq',v=^dk),x,c=0;^Iq`B;^Iu`B;^Iq[q]`l;`bv,'&`Gsqp"
+"',0`Ipt(^5,`G@rv`l^i^Iu`W)^Iq[^Iu[x]]+=(^Iq[^Iu[x]]?`G`kx^i^Iq`W^7sqq[x]^ax==q||c<2#Uv+=(v#W'`k^Iq[x]+'`Zx);c++}`3^ek,v,0)`Cwdl`7'e`G`Ar=@i,b=^f(`H,\"o^M\"),i,o,oc`5b)r=^O$x`n0;i<s.d.`Qs`8^3o=s.d.`"
+"Qs[i];oc=o.`q?\"\"+o.`q:\"\"`5(oc`4$P<0||oc`4\"^xoc(\")>=0)$5c`4$q<0)^f(o,\"`q\",0,s.lc);}`3r^V`Hs`0`1`5`S>3^a!^g#Vs.^n||`S#d`Fs.b^7$R^Y)s.$R^Y('`q#N);`6s.b^7b.add^Y$T)s.b.add^Y$T('click#N,false);`"
+"e^f(`H,'o^M',0,`Hl)}`Cvs`0x`1,v=s.`Y^W,g=s.`Y^W#Pk=^pvsn_'+^5+(g?@xg#e,n=^dk),e`i,y=e@R$U);e.set$Uy+10$31900:0))`5v){v*=$k`5!n`F!^ek,x,e))`30;n=x`mn%$k00>v)`30}`31`Cdyasmf`0t,m`Ft&&m&&m`4t)>=0)`31;"
+"`30`Cdyasf`0t,m`1,i=t?t`4$Z:-1,n,x`5i>=0&&m){`Pn=t`20,i),x=t`2i+1)`5`bx,`G,'dyasm@Vm))`3n}`30`Cuns`0`1,x=s.`OSele`o,l=s.`OList,m=s.`OM#D,n,i;^5=^5`9`5x&&l`F!m)m=`H`M^E`5!m.toLowerCase)m`l+m;l=l`9;m"
+"=m`9;n=`bl,';`Gdyas@Vm)`5n)^5=n}i=^5`4`G`Ifun=i<0?^5:^5`20,i)`Csa`0un`1;^5#8`5!@9)@9#8;`6(`G+@9+`G)`4`G+un+`G)<0)@9+=`G+un;^5s()`Cm_i`0n,a`1,m,f=n`20,1),r,l,i`5!`Rl)`Rl`B`5!`Rnl)`Rnl`K;m=`Rl[n]`5!a"
+"&&m&&#G@Um^Z)`Ra(n)`5!m){m`B,m._c=^pm';m^Zn=`H`gn;m^Zl=s^Zl;m^Zl[m^Z$4m;`H`gn++;m.s=s;m._n=n;$G`K('_c`G_in`G_il`G_i`G_e`G_d`G_dl`Gs`Gn`G_r`G_g`G_g1`G_t`G_t1`G_x`G_x1`G_rs`G_rr`G_l'`Im_l[$4m;`Rnl[`R"
+"nl`8]=n}`6m._r@Um._m){r=m._r;r._m=m;l=$G;`n0;i<l`8;i#T@zm[l[i]])r[l[i]]=m[l[i]];r^Zl[r^Z$4r;m=`Rl[$4r`mf==f`E())s[$4m;`3m`Cm_a`7'n`Gg`Ge`G@z!g)g=^h;`Ac=s[g@k,m,x,f=0`5!c)c=`H[\"s_\"+g@k`5c&&s_d)s[g"
+"]`7\"s\",s_ft(s_d(c)));x=s[g]`5!x)x=`H[\\'s_\\'+g]`5!x)x=`H[g];m=`Ri(n,1)`5x^a!m^Z||g!=^h#Um^Z=f=1`5(\"\"+x)`4\"fun`o\")>=0)x(s);`e`Rm(\"x\",n,x,e)}m=`Ri(n,1)`5@ol)@ol=@o=0;`ut();`3f'`Im_m`0t,n,d,e"
+"@w@xt;`Ps=^O,i,x,m,f=@xt,r=0,u`5`R$v`Rnl)`n0;i<`Rnl`8^3x=`Rnl[i]`5!n||x==@tm=`Ri(x);u=m[t]`5u`F@Tu)`4#B`o@H0`Fd&&e)@Xd,e);`6d)@Xd);`e@X)}`mu)r=1;u=m[t+1]`5u@Um[f]`F@Tu)`4#B`o@H0`Fd&&e)@1d,e);`6d)@1"
+"d);`e@1)}}m[f]=1`5u)r=1}}`3r`Cm_ll`0`1,g=`Rdl,i,o`5g)`n0;i<g`8^3o=g[i]`5o)s.^b(o.n,o.u,o.d,o.l,o.e,$ag#Z0}`C^b`0n,u,d,l,e,ln`1,m=0,i,g,o=0#M,c=s.h?s.h:s.b,b,^l`5@ti=n`4':')`5i>=0){g=n`2i+$an=n`20,i"
+")}`eg=^h;m=`Ri(n)`m(l||(n@U`Ra(n,g)))&&u^7d&&c^7$V`V`Fd){@o=1;@ol=1`mln`F@8)u=^Fu,$B:`Ghttps:^Vi=^ps:'+s^Zn+':@I:'+g;b='`Ao=s.d@R`VById(@ui+'\")`5s$5`F!o.$v`H.'+g+'){o.l=1`5o.@2o.i);o.i=0;`Ra(\"@I"
+"\",@ug+'@u(e?',@ue+'\"'`k')}';f2=b+'o.c++`5!`c)`c=250`5!o.l$5.c<(`c*2)/$k)o.i=s`Xout(o.f2@7}';f1`7'e',b+'}^V^l`7's`Gc`Gi`Gu`Gf1`Gf2`G`Pe,o=0@6o=s.$V`V(\"script\")`5o){@C=\"text/`t\"$7id=i;o.defer=@"
+"i;o.o^M=o.onreadystatechange=f1;o.f2=f2;o.l=0;'`k'o@P=u;c.appendChild(o)$7c=0;o.i=s`Xout(f2@7'`k'}`do=0}`3o^Vo=^l(s,c,i,u#M)^Qo`B;o.n=n+':'+g;o.u=u;o.d=d;o.l=l;o.e=e;g=`Rdl`5!g)g=`Rdl`K;i=0;^0i<g`8"
+"&&g[i])i++;g#Zo}}`6@tm=`Ri(n);#G=1}`3m`Cvo1`0t,a`Fa[t]||$h)^O#Ya[t]`Cvo2`0t,a`F#g{a#Y^O[t]`5#g$h=1}`Cdlt`7'`Ad`i,i,vo,f=0`5`ul)`n0;i<`ul`8^3vo=`ul[i]`5vo`F!`Rm(\"d\")||d.g`X()-$Q>=`c){`ul#Z0;s.t($0"
+"}`ef=1}`m`u@2`ui`Idli=0`5f`F!`ui)`ui=s`Xout(`ut,`c)}`e`ul=0'`Idl`0vo`1,d`i`5!$0vo`B;`b^1,`G$L2',$0;$Q=d.g`X()`5!`ul)`ul`K;`ul[`ul`8]=vo`5!`c)`c=250;`ut()`Ct`0vo,id`1,trk=1,tm`i,sed=Math&&@Z#5?@Z#C@"
+"Z#5()*$k00000000000):#J`X(),$8='s'+@Z#C#J`X()/10800000)%10+sed,y=tm@R$U),vt=tm@RDate($c^HMonth($c'$3y+1900:y)+' ^HHour$d:^HMinute$d:^HSecond$d ^HDay()+#b#J`XzoneO$D(),^l,^4=s.g^4(),ta`l,q`l,qs`l,#6"
+"`l,vb`B#L^1`Iuns(`Im_ll()`5!s.td){`Ptl=^4`M,a,o,i,x`l,c`l,v`l,p`l,bw`l,bh`l,^N0',k=^e^pcc`G@i',0@0,hp`l,ct`l,pn=0,ps`5^D&&^D.prototype){^N1'`5j.m#D){^N2'`5tm.setUTCDate){^N3'`5^g^7^n&&`S#d^N4'`5pn."
+"toPrecisio@t^N5';a`K`5a.forEach){^N6';i=0;o`B;^l`7'o`G`Pe,i=0@6i=new Iterator(o)`d}`3i^Vi=^l(o)`5i&&i.next)^N7'}}}}`m`S>=4)x=^rwidth+'x'+^r#3`5s.isns||s.^m`F`S>=3$i`p(@0`5`S>=4){c=^rpixelDepth;bw=`"
+"H#K@B;bh=`H#K^k}}$M=s.n.p^S}`6^g`F`S>=4$i`p(@0;c=^r^C`5`S#d{bw=s.d.^B`V.o$D@B;bh=s.d.^B`V.o$D^k`5!s.^n^7b){^l`7's`Gtl`G`Pe,hp=0`vh$t\");hp=s.b.isH$t(tl)?\"Y\":\"N\"`d}`3hp^Vhp=^l(s,tl);^l`7's`G`Pe,"
+"ct=0`vclientCaps\");ct=s.b.@d`o^2`d}`3ct^Vct=^l(s$X`er`l`m$M)^0pn<$M`8&&pn<30){ps=^s$M[pn].@4@7#X`5p`4ps)<0)p+=ps;pn++}s.^c=x;s.^C=c;s.`t^u=j;s.`p=v;s.`z@G=k;s.^9@B=bw;s.^9^k=bh;s.@d`o^2=ct;s.@5=hp"
+";s.p^S=p;s.td=1`m$0{`b^1,`G$L2',vb`Ipt(^1,`G$L1',$0`ms.useP^S)s.doP^S(s);`Pl=`H`M,r=^4.^B.`a`5!s.^P)s.^P=l^q?l^q:l`5!s.`a@Us._1_`a^z`a=r;s._1_`a=1`m(vo&&$Q)#V`Rm('d'#U`Rm('g')`5s.@M||^G){`Po=^G?^G:"
+"s.@M`5!o)`3'';`Pp=s.#O`r,w=1,^K,@q,x=^8t,h,l,i,oc`5^G$5==^G){^0o@Un$w$YBODY'){o=o^A`V?o^A`V:o^ANode`5!o)`3'';^K;@q;x=^8t}oc=o.`q?''+o.`q:''`5(oc`4$P>=0$5c`4\"^xoc(\")<0)||oc`4$q>=0)`3''}ta=n?o$m:1;"
+"h$2i=h`4'?^Vh=s.`Q@s^D||i<0?h:h`20,i);l=s.`Q`r;t=s.`Q^2?s.`Q^2`9:s.lt(h)`5t^ah||l))q+=$F=@M_'+(t`Ud$b`Ue'?@a(t):'o')+(h?$Fv1`Zh)`k(l?$Fv2`Zl):'^V`etrk=0`5s.^L@e`F!p$es.^P;w=0}^K;i=o.sourceIndex`5@F"
+"')@v@F^Vx=1;i=1`mp&&n$w)qs='&pid`Z^sp,255))+(w#Wpidt$uw`k'&oid`Z^sn@7)+(x#Woidt$ux`k'&ot`Zt)+(i#Woi$ui#e}`m!trk@Uqs)`3'';$1=s.vs(sed)`5trk`F$1)#6=s.mr($8,(vt#Wt`Zvt)`ks.hav()+q+(qs?qs:s.rq(^5)),0,i"
+"d,ta);qs`l;`Rm('t')`5s.p_r)s.p_r(`I`a`l}^I(qs);^Q`u($0;`m$0`b^1,`G$L1',vb`I@M=^G=s.`Q`r=s.`Q^2=`H`j''`5s.pg)`H^x@M=`H^xeo=`H^x`Q`r=`H^x`Q^2`l`5!id@Us.tc^ztc=1;s.flush`T()}`3#6`Ctl`0o,t,n,vo`1;s.@M="
+"$Co`I`Q^2=t;s.`Q`r=n;s.t($0}`5pg){`H^xco`0o){`P^t\"_\",1,$a`3$Co)`Cwd^xgs`0u@t`P^tun,1,$a`3s.t()`Cwd^xdc`0u@t`P^tun,$a`3s.t()}}@8=(`H`M`h`9`4$Bs@H0`Id=^B;s.b=s.d.body`5s.d@R`V#R`r^zh=s.d@R`V#R`r('H"
+"EAD')`5s.h)s.h=s.h[0]}s.n=navigator;s.u=s.n.userAgent;@c=s.u`4'N$r6/^V`Papn$W`r,v$W^u,ie=v`4#A'),o=s.u`4'@Y '),i`5v`4'@Y@H0||o>0)apn='@Y';^g$N`UMicrosoft Internet Explorer'`Iisns$N`UN$r'`I^m$N`U@Y'"
+"`I^n=(s.u`4'Mac@H0)`5o>0)`S`ws.u`2o+6));`6ie>0){`S=^Ji=v`2ie+5))`5`S>3)`S`wi)}`6@c>0)`S`ws.u`2@c+10));`e`S`wv`Iem=0`5^D#Q^v){i=^o^D#Q^v(256))`E(`Iem=(i`U%C4%80'?2:(i`U%U0$k'?1:0))}s.sa(un`Ivl_l='^U"
+",`YID,vmk,`Y@S,`D,`D^j,ppu,@L,`Y`r$O,c`L,`z@E,#O`r,^P,`a,@O$zl@p^R,`G`Ivl_t=^R+',^w,$j,server,#O^2,#E`oID,purchaseID,$9,state,zip,#4,products,`Q`r,`Q^2';@j`Pn=1;n<51;n#T@D+=',prop@I,eVar@I,hier@I,l"
+"ist$g^R2=',tnt,pe#91#92#93,^c,^C,`t^u,`p,`z@G,^9@B,^9^k,@d`o^2,@5,p^S';@D+=^R2;@n@p@D,`G`Ivl_g=@D+',`N,`N^j,`NBase,fpC`L,@Q`T,#2,`Y^W,`Y^W#P`OSele`o,`OList,`OM#D,^LDow^MLinks,^L@K,^L@e,`Q@s^D,`QDow"
+"^MFile^2s,`QEx`s,`QIn`s,`Q@gVa$l`Q@g^Ys,`Q`rs,@M,eo,_1_`a$zg@p^1,`G`Ipg=pg#L^1)`5!ss)`Hs()",
w=window,l=w.s_c_il,n=navigator,u=n.userAgent,v=n.appVersion,e=v.indexOf('MSIE '),m=u.indexOf('Netscape6/'),a,i,s;if(un){un=un.toLowerCase();if(l)for(i=0;i<l.length;i++){s=l[i];if(!s._c||s._c=='s_c'){if(s.oun==un)return s;else if(s.fs&&s.sa&&s.fs(s.oun,un)){s.sa(un);return s}}}}w.s_an='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
w.s_sp=new Function("x","d","var a=new Array,i=0,j;if(x){if(x.split)a=x.split(d);else if(!d)for(i=0;i<x.length;i++)a[a.length]=x.substring(i,i+1);else while(i>=0){j=x.indexOf(d,i);a[a.length]=x.subst"
+"ring(i,j<0?x.length:j);i=j;if(i>=0)i+=d.length}}return a");
w.s_jn=new Function("a","d","var x='',i,j=a.length;if(a&&j>0){x=a[0];if(j>1){if(a.join)x=a.join(d);else for(i=1;i<j;i++)x+=d+a[i]}}return x");
w.s_rep=new Function("x","o","n","return s_jn(s_sp(x,o),n)");
w.s_d=new Function("x","var t='`^@$#',l=s_an,l2=new Object,x2,d,b=0,k,i=x.lastIndexOf('~~'),j,v,w;if(i>0){d=x.substring(0,i);x=x.substring(i+2);l=s_sp(l,'');for(i=0;i<62;i++)l2[l[i]]=i;t=s_sp(t,'');d"
+"=s_sp(d,'~');i=0;while(i<5){v=0;if(x.indexOf(t[i])>=0) {x2=s_sp(x,t[i]);for(j=1;j<x2.length;j++){k=x2[j].substring(0,1);w=t[i]+k;if(k!=' '){v=1;w=d[b+l2[k]]}x2[j]=w+x2[j].substring(1)}}if(v)x=s_jn("
+"x2,'');else{w=t[i]+' ';if(x.indexOf(w)>=0)x=s_rep(x,w,t[i]);i++;b+=62}}}return x");
w.s_fe=new Function("c","return s_rep(s_rep(s_rep(c,'\\\\','\\\\\\\\'),'\"','\\\\\"'),\"\\n\",\"\\\\n\")");
w.s_fa=new Function("f","var s=f.indexOf('(')+1,e=f.indexOf(')'),a='',c;while(s>=0&&s<e){c=f.substring(s,s+1);if(c==',')a+='\",\"';else if((\"\\n\\r\\t \").indexOf(c)<0)a+=c;s++}return a?'\"'+a+'\"':"
+"a");
w.s_ft=new Function("c","c+='';var s,e,o,a,d,q,f,h,x;s=c.indexOf('=function(');while(s>=0){s++;d=1;q='';x=0;f=c.substring(s);a=s_fa(f);e=o=c.indexOf('{',s);e++;while(d>0){h=c.substring(e,e+1);if(q){i"
+"f(h==q&&!x)q='';if(h=='\\\\')x=x?0:1;else x=0}else{if(h=='\"'||h==\"'\")q=h;if(h=='{')d++;if(h=='}')d--}if(d>0)e++}c=c.substring(0,s)+'new Function('+(a?a+',':'')+'\"'+s_fe(c.substring(o+1,e))+'\")"
+"'+c.substring(e+1);s=c.indexOf('=function(')}return c;");
c=s_d(c);if(e>0){a=parseInt(i=v.substring(e+5));if(a>3)a=parseFloat(i)}else if(m>0)a=parseFloat(u.substring(m+10));else a=parseFloat(v);if(a>=5&&v.indexOf('Opera')<0&&u.indexOf('Opera')<0){w.s_c=new Function("un","pg","ss","var s=this;"+c);return new s_c(un,pg,ss)}else s=new Function("un","pg","ss","var s=new Object;"+s_ft(c)+";return s");return s(un,pg,ss)}

}




var irwStatLocalVars = new Array();
var irwStatsLoaded = true;
var irwStatsInitialized = false;

var irwLocalFlags = new Array();
var irwLocalTrackVars = new Array();
var irwLocalMetaTags = new Array();

// NB! Setting irwStatsDebug to true will make all errors in here throw alerts aswell!
var irwStatsDebug = false;

var urls = self.location.host+self.location.pathname;  //

// NB! In order to get case-insensitivity, all tMapArr keys need to be lower-case!
tMapArr = new Array();
tMapArr["pagename"] = { toVar:false, eval:"s.pageName = value; irwstatAddLocalFlag('pageName_SET')", changeCase:"lower" };
tMapArr["pagenamelocal"] = { toVar:false, eval:"s.prop1 = value; irwstatAddLocalFlag('pageNameLocal_SET')", changeCase:"lower" };
tMapArr["fallback_pagename"] = { toVar:true, varName:"s.pageName", changeCase:"lower" };
tMapArr["fallback_pagenamelocal"] = { toVar:true, varName:"s.prop1", changeCase:"lower" };
tMapArr["country"] = { toVar:true, varName:"s.prop8", changeCase:"lower" };
tMapArr["language"] = { toVar:true, varName:"s.prop17", changeCase:"lower" };
tMapArr["pagetype"] = { toVar:true, varName:"s.prop5", changeCase:"lower" };
tMapArr["event"] = { toVar:false, eval:"irwstatOmnitureAddEvent(value)" };

tMapArr["category"] = { toVar:false, eval:"s.prop2 = value; irwStatLocalVars[\"riaCategory\"] = value", changeCase:"lower" };  // omniture-name: department  
tMapArr["subcategory"] = { toVar:true, varName:"s.prop3", changeCase:"lower" };    // omniture-name: category
tMapArr["chapter"] = { toVar:true, varName:"s.prop4", changeCase:"lower" };        // omniture-name: Sub category
tMapArr["system"] = { toVar:true, varName:"s.prop21", changeCase:"lower" };        // omniture-name: Subsub Category
tMapArr["systemchapter"] = { toVar:true, varName:"s.prop22", changeCase:"lower" }; // omniture-name: Subsubsub Category
tMapArr["categorytabid"] = { toVar:false, eval:"irwStatLocalVars[\"categoryTabId\"] = 'tab'", changeCase:"lower" };

// 2.6.3 - Local names (not sent to omniture, used to build pagenamelocal)
tMapArr["categorylocal"] = { toVar:false, eval:"irwStatLocalVars[\"categoryLocal\"] = value", changeCase:"lower" };
tMapArr["subcategorylocal"] = { toVar:false, eval:"irwStatLocalVars[\"subcategoryLocal\"] = value", changeCase:"lower" };
tMapArr["chapterlocal"] = { toVar:false, eval:"irwStatLocalVars[\"chapterLocal\"] = value", changeCase:"lower" };
tMapArr["systemlocal"] = { toVar:false, eval:"irwStatLocalVars[\"systemLocal\"] = value", changeCase:"lower" };
tMapArr["systemchapterlocal"] = { toVar:false, eval:"irwStatLocalVars[\"systemChapterLocal\"] = value", changeCase:"lower" };
// End - 2.6.3 - Local names

//CR IKEA00658987 Search - WA for no-hits at all and no-hits on products
tMapArr["nofsearchresultsproduct"] = { toVar:true, varName:"s.prop7", changeCase:"lower" };
tMapArr["nofsearchresultstotal"] = { toVar:true, varName:"s.prop42", changeCase:"lower" };
// End of CR IKEA00658987 Search - WA for no-hits at all and no-hits on products

tMapArr["products"] = { toVar:false, eval:"irwstatOmnitureAddProduct(value); irwStatLocalVars[\"products\"] = value", changeCase:"lower" };
tMapArr["productfindingmethod"] = { toVar:true, varName:"s.eVar3", changeCase:"lower" };
tMapArr["scinuse"] = { toVar:false, eval:"irwstatOmnitureRemoveEvent('event27');irwstatOmnitureAddEvent('event6');irwstatOmnitureAddEvent('event25');irwstatOmnitureAddEvent('event26')" };
tMapArr["scinstock"] = { toVar:true, varName:"s.prop11", changeCase:"lower" };
tMapArr["scstoreno"] = { toVar:true, varName:"s.prop10", changeCase:"lower" };
tMapArr["scproduct"] = { toVar:false, eval:"s.prop12 = value; irwstatOmnitureAddProduct(value)", changeCase:"lower" };
tMapArr["sccontactmethod"] = {toVar:false, eval:"irwstatOmnitureAddEvent('event7'); s.prop13 = value;", changeCase:"lower" };
tMapArr["ecomorderid"] = { toVar:true, varName:"s.purchaseID", changeCase:"lower" };
tMapArr["ecompaymentmethod"] = { toVar:true, varName:"s.eVar5", changeCase:"lower" };
tMapArr["ecomshippingmethod"] = { toVar:true, varName:"s.eVar6", changeCase:"lower" };

// Start - New in ECNA
tMapArr["ecomstatus"] = { toVar:false, eval:"irwstatAddLocalFlag('eComStatus_SET'); irwStatLocalVars[\"eComStatus\"] = value", changeCase:"lower" };
// End - ECNA

tMapArr["newslettersignup"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatOmnitureAddEvent('event9')"}], changeCase:"lower" };
tMapArr["internalpagetype"] = { toVar:false, eval:"irwStatLocalVars[\"internalPageType\"] = value" };
tMapArr["cartopenedinsession"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('cartOpenedInSession_SET')"}] };
tMapArr["lastpagecart"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('lastPageCart_SET')"}] };
tMapArr["addtocart"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatOmnitureAddEvent('scAdd')"}], changeCase:"lower" };
tMapArr["scaddproducts"] = { toVar:false, eval:"irwstatAddLocalFlag('scAddProducts_SET'); irwStatLocalVars[\"scAddProducts\"] = value", changeCase:"lower" };
tMapArr["productalreadyincart"] = { toVar: false, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('productAlreadyInCart_SET');"}], changeCase:"lower" };
tMapArr["removefromcart"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatOmnitureAddEvent('scRemove')"}], changeCase:"lower" };
tMapArr["checkoutstart"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatOmnitureAddEvent('scCheckout')"}], changeCase:"lower" };
tMapArr["currencycode"] = { toVar:true, varName:"s.currencyCode", changeCase:"upper" };
tMapArr["familyloginsuccessful"] = { toVar: false };
tMapArr["familyusersignedup"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatOmnitureAddEvent('event8')"}], changeCase:"lower" };
tMapArr["shoppingcartview"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatOmnitureAddEvent('scView')" }], changeCase:"lower" };
tMapArr["downloadurl"] = { toVar:false, eval:"s.prop9 = value; s.eVar9 = value; irwstatOmnitureAddEvent('event5')", changeCase:"lower" };

// 2.5.3+2.7.4    + s.eVar29 on prodview
tMapArr["prodview"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatOmnitureAddEvent('prodView'); irwstatAddLocalFlag('prodView'); s.eVar29 = '+1'" }], changeCase:"lower" };
tMapArr["event3"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatOmnitureAddEvent('event3')" }], changeCase:"lower" };
tMapArr["purchase"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatOmnitureAddEvent('purchase')" }], changeCase:"lower" };
// End - 2.5.3

// 2.7.2
tMapArr["front"] = { toVar:true, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('front')" }], changeCase:"lower" };
// End - 2.7.2

// Phase2 Form addition
tMapArr["hasform"] = { toVar:false, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('form')" }], changeCase:"lower" };
// End - Phase2 Form addition

// newproduct fix
tMapArr["newproduct"] = { toVar:false, eval:"irwstatAddLocalFlag('newProduct')", changeCase:"lower" };

// merchandising category change
tMapArr["merchandisingcategory"] = { toVar:false, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('merchandisingcategory_SET')"}], changeCase:"lower" };

// IKEA00216626
tMapArr["friendlypagename"] = { toVar:false, eval:"irwStatLocalVars[\"friendlyPageName\"] = value" };
// End - IKEA00216626

// Phase2 Filter/Sort (Page functionality property)
tMapArr["filter"] = { toVar:false, eval:"s.prop24 = \"filter>\"+value", changeCase:"lower" };
tMapArr["sort"] = { toVar:false, eval:"s.prop24 = \"sort>\"+value", changeCase:"lower" };
// End - Phase2 Filter/Sort

// Phase2 Form errors
tMapArr["formerrorfields"] = { toVar:false, eval:"irwstatAddLocalFlag('formErrorFields_SET'); irwStatLocalVars[\"formErrorFields\"] = value", changeCase:"lower" };
tMapArr["formerrortexts"] = { toVar:false, eval:"irwstatAddLocalFlag('formErrorTexts_SET'); irwStatLocalVars[\"formErrorTexts\"] = value", changeCase:"lower" };
tMapArr["formerrorname"] = { toVar:false, eval:"irwstatAddLocalFlag('formErrorName_SET'); irwStatLocalVars[\"formErrorName\"] = value", changeCase:"lower" };
// End - Phase2 Form errors

// Phase2 Search visited
tMapArr["searchvisited"] = { toVar:false, eval:"s.eVar27 = '+1'", changeCase:"lower" };
// End - Phase2 Search visited

// Phase2 Page functionality
tMapArr["pagefunctionality"] = { toVar:true, varName:"s.prop24", changeCase:"lower" };
// End - Phase2 Page functionality

// Phase2 Family Discout
tMapArr["familydiscount"] = { toVar:false, conditional:[{option:"yes", eval:"irwstatOmnitureAddEvent('event14')"}], changeCase:"lower" };
// End - Phase2 Family Discout

// Phase2 Member Signup
tMapArr["memberloginstart"] = { toVar:false, eval:"irwstatAddLocalFlag('memberLoginStarted_SET');", changeCase:"lower" };
tMapArr["memberloggedin"] = { toVar:false, eval:"irwstatOmnitureAddEvent('event2'); s.prop28 = value; irwstatAddLocalFlag('memberType_SET'); irwstatAddLocalFlag('memberLoggedIn_SET')", changeCase:"lower" };
tMapArr["membertype"] = { toVar:false, eval:"s.prop28 = value; irwstatAddLocalFlag('memberType_SET')", changeCase:"lower" };
tMapArr["membersignupstart"] = { toVar:false, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('memberSignupStart_SET'); irwstatOmnitureAddEvent('event24')"}], changeCase:"lower" };
tMapArr["membersignupstarted"] = { toVar:false, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('memberSignupStarted_SET');"}], changeCase:"lower" };
tMapArr["checkoutguest"] = { toVar:false, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('checkoutGuest_SET');"}], changeCase:"lower" };
// End - Phase2 Member Signup

// Phase2 Shopping List
tMapArr["emailshoppinglist"] = { toVar:false, conditional:[{option:"yes", eval:"s.eVar30 = 'email'; irwstatOmnitureAddEvent('event20')"}], changeCase:"lower" };
// End - Phase2 Shopping List

//CR #IKEA00642649
tMapArr["usertypetransition"] = { toVar:false, eval:"irwstatOmnitureAddEvent('event15'); s.eVar32 = value", changeCase:"lower" };

// Phase2 Local store number
tMapArr["localstoreno"] = { toVar:false, eval:"s.prop32 = value; s.eVar17 = value", changeCase:"lower" };
tMapArr["newsletterstoreno"] = { toVar:false, eval:"s.prop32 = value", changeCase:"lower" };
// End - Phase2 Local store number

// ## FIX ##
tMapArr["trackdownload"] = { toVar:false, conditional:[{option:"no", eval:"irwstatAddLocalFlag('disableDownloadTrack_SET');"}], changeCase:"lower" };
// ## FIX ##

// ## FIX ##
tMapArr["riaapplicationstart"] = { toVar: false };
tMapArr["riaapplicationcomplete"] = { toVar: false };
// ## FIX ##

tMapArr["supportrequest"] = { toVar: false, eval:"s.eVar31 = value; irwstatOmnitureAddEvent('event16')", changeCase:"lower" };
tMapArr["addbypartnumbererror"] = { toVar: false, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('addByPartNumberError_SET');"}], changeCase:"lower" };

// Flash tracking
tMapArr["version"] = { toVar:false, eval:"irwStatLocalVars[\"version\"] = value", changeCase:"lower" };
tMapArr["riaassettype"] = { toVar:false, eval:"irwStatLocalVars[\"riaAssetType\"] = value", changeCase:"lower" }; 
tMapArr["riaasset"] = { toVar:false, eval:"irwStatLocalVars[\"riaAsset\"] = value", changeCase:"lower" }; 
tMapArr["riaaction"] = { toVar:false, eval:"irwStatLocalVars[\"riaAction\"] = value; irwstatAddLocalFlag('riaAction_SET');", changeCase:"lower" };
tMapArr["riaactiontype"] = { toVar:false, eval:"irwStatLocalVars[\"riaActionType\"] = value", changeCase:"lower" };
tMapArr["riaroomset"] = { toVar:false, eval:"irwStatLocalVars[\"riaRoomSet\"] = value", changeCase:"lower" };
tMapArr["riapageview"] = { toVar:false, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('riaPageView_SET');"}], changeCase:"lower" };
tMapArr["riarequestname"] = { toVar:false, eval:"irwStatLocalVars[\"riaRequestName\"] = value; irwstatAddLocalFlag('riaRequestName_SET');", changeCase:"lower" };
//tMapArr["riaproduct"] = { toVar:false, eval:"irwstatOmnitureAddProduct(value); irwstatOmnitureAddEvent('prodView'); irwstatAddLocalFlag('prodView'); s.eVar29 = '+1'", changeCase:"lower" };

//  Added for Billy planner and Besta Planner
tMapArr["riaproduct"] = { toVar:false, eval:"irwstatOmnitureAddProduct(value); irwstatOmnitureAddEvent('event12'); irwstatAddLocalFlag('event12'); s.eVar29 = '+1'", changeCase:"lower" };

//Area Tagging for CR IKEA00657647 Search  WA tagging of Search Engine Result Page (SERP)
tMapArr["pagearea"] = { toVar:true, varName:"s.prop29", changeCase:"lower" };
tMapArr["detailedpagearea"] = { toVar:true, varName:"s.prop30", changeCase:"lower" };

// Tag is set if stockcheck event is sent from previous page, used in pip page
tMapArr["stockcheckperformed"] = { toVar:false, conditional:[{option:"yes", eval:"irwstatAddLocalFlag('stockchkperformed_SET');"}], changeCase:"lower" };

function irwstatClearLocalData() {
	irwStatLocalVars = new Array();
	
	irwLocalFlags = new Array();
	irwLocalTrackVars = new Array();
	irwLocalMetaTags = new Array();
}

/**
 * @desc Add a flag for local processing
 * @param flagName (String) - Name of flag to set
 */
function irwstatAddLocalFlag(flagName) {
	var __funcName__ = "irwstatAddLocalFlag";

	try {
		irwLocalFlags.push(flagName);
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

/**
 * @desc Remove a flag for local processing
 * @param flagName (String) - Name of flag to remove
 */
function irwstatDeleteLocalFlag(flagName) {
	var __funcName__ = "irwstatDeleteLocalFlag";

	try {
		for (var flagCount = 0; flagCount < irwLocalFlags.length; flagCount++) {
			if (irwLocalFlags[flagCount] == flagName) {
				irwLocalFlags.splice(flagCount,1);
			}
		}
		
		
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

/**
 * @desc Check if a local flag has been set
 * @param flagName (String) - Name of flag to check status of
 * @return Bool - True/False if flag has been set
 */
function irwstatCheckLocalFlag(flagName) {
	var __funcName__ = "irwstatCheckLocalFlag";

	try {
		for (var flagCount = 0; flagCount < irwLocalFlags.length; flagCount++) {
			if (irwLocalFlags[flagCount] == flagName) {
				return true;
			}
		}
		
		return false;
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatAddTrackVar(varName) {
	var __funcName__ = "irwstatAddTrackVar";

	try {
		if (irwstatCheckLocalFlag("trackVarExclusive_SET")) {
			return;
		}
		
		if ((arguments.length > 1) && (arguments[1] == "exclusive")) {	
			irwstatAddLocalFlag("trackVarExclusive_SET");
			irwLocalTrackVars = new Array();
			s.linkTrackVars = "";
			s.linkTrackEvents = "";
		}
		
		varName = varName.replace(/^IRWStats\.(.*)$/, "$1").toLowerCase();
		irwLocalTrackVars.push(varName);
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatCheckTrackVar(varName) {
	var __funcName__ = "irwstatCheckTrackVar";

	try {
		for (var varCount = 0; varCount < irwLocalTrackVars.length; varCount++) {
			if (irwLocalTrackVars[varCount] == varName) {
				return true;
			}
		}
		
		return false;
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatAddMetaTag(tagName, tagValue) {
	var __funcName__ = "irwstatAddMetaTag";

	try {
		// NB! This function used to add META-elements to the DOM-tree.
		//     This has been changed because of an issue (IKEA00675942)
		//     with old data getting sent multiple times, a separation
		//     between local and global META-tags is achieved by storing
		//     the locally created META-tags in an array.
		if (tagName.substring(0, 9) == "IRWStats." ) {
			irwLocalMetaTags.push({name:tagName.substr(9, tagName.length).toLowerCase(), value:tagValue});
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatReadMetaTags() {
	var __funcName__ = "irwstatReadMetaTags";

	try {
        /**
        * Start IKEA00693517
        **/
		var metaTags = $$('meta');
        /**
        * End IKEA00693517
        **/
		var irwTags = new Array();

	  	for (var metaCount = 0; metaCount < metaTags.length; metaCount++) { 
	   		var item = metaTags[metaCount];
			
			if (item.getAttribute("HTTP-EQUIV")) {
				var equiv = item.getAttribute("HTTP-EQUIV");
			
				if (equiv.toUpperCase() != "CONTENT-TYPE") {
					continue;
				}
				
				if (item.getAttribute("CONTENT")) {
					var charset = item.getAttribute("CONTENT");
					if (charset.indexOf("charset=") < 0) {
						continue;
					}
					charset = charset.substr(charset.indexOf("charset=")+8);
					irwstatOmnitureAddCharset(charset);
				}
			}
			
	 		var itemName = item.getAttribute("NAME");
			if (itemName == null) {
				continue;
			}
	  		if (itemName.substring(0, 9) == "IRWStats." ) {
	  			var tag = { };
				tag.name = itemName.substr(9, itemName.length).toLowerCase();
				tag.value = item.getAttribute("CONTENT").replace(/\'/g, '').replace(/\"/g, '');
	  			irwTags.push(tag);
	  		}
	  	}
		
		for (var metaCount = 0; metaCount < irwLocalMetaTags.length; metaCount++) {
			var item = irwLocalMetaTags[metaCount];
			
			if (irwstatCheckTag(item.name, irwTags)) {
				for (var tagCount = 0; tagCount < irwTags.length; tagCount++) {
					if (irwTags[tagCount].name == item.name) {
						// Replace the variable in the array
						irwTags[tagCount].value = item.value;
						break;
					}
				}
			} else {
				// The local META-tag is new, add it to the tag-array.
				irwTags.push(item);
			}
		}
		
		// Add pagename and pagenamelocal if data is missing
		var tag = { };
		
		if ((irwTags.length < 1) || (! irwstatCheckTag("pagename", irwTags))) {
			tag.name = "fallback_pagename";
			tag.value = location.href.replace(/\'/g, '').replace(/\"/g, '');;
			irwTags.push(tag);
		}
		
		if ((irwTags.length < 2) || (! irwstatCheckTag("pagenamelocal", irwTags))) {
			tag = { };
			tag.name = "fallback_pagenamelocal";
			tag.value = document.title.replace(/\'/g, '').replace(/\"/g, '');;
			irwTags.push(tag);
		}
		
		return irwTags;
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatCheckTag(tagName, irwTags) {
	var __funcName__ = "irwstatCheckTag";

	try {
		for (var tagCount = 0; tagCount < irwTags.length; tagCount++) {
			if (irwTags[tagCount].name == tagName) {
				return true;
			}
		}
		
		return false;
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatDisableTag(tagName, irwTags) {
	var __funcName__ = "irwstatDisableTag";
	
	try {
		for (var tagCount = 0; tagCount < irwTags.length; tagCount++) {
			if (irwTags[tagCount].name == tagName) {
				irwTags[tagCount].value = null;
				break;
			}
		}
		
		return irwTags;
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatGetCookie(name) {
	var __funcName__ = "irwstatGetCookie";

	try {
		// Is there any cookies at all?
		if (document.cookie.length > 0) {
			// Look for the cookie named 'name'.
			start = document.cookie.indexOf(name + "=");
			if (start != -1) {
				// Found it. Now retrieve the value of the cookie
				// and return it unescaped.
				start = start + name.length+1; 
				end = document.cookie.indexOf(";", start);
				if (end == -1) end = document.cookie.length;
				return unescape(document.cookie.substring(start, end));
			} 
		}
		
		// Cookie not found, return empty string.
		return "";
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatSetCookie(name, value, expiredays) {
	var __funcName__ = "irwstatSetCookie";

	try {
		// Make a new date-object to get the expiration-date.
		var exdate = new Date();
		
		// Expiration-date = now+expiredays.
		exdate.setDate(exdate.getDate() + expiredays);
		
		var domain = window.location.href.replace(/^http[s]?:\/\/([^\/]+)\/.*$/, "$1"); 
		domain = domain.replace(/^.*(\.[^\.]+\.[^\.]+)$/, "$1");
		
		// Set the cookie. (And escape the value)
		document.cookie = name + "=" + escape(value)+
		((expiredays==null) ? "" : ";expires="+exdate.toGMTString())+"; path=/; domain="+domain;
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

// ## FIX ## - Cookie persistance should be same as Commerce Login...
function irwstatSetTrailingTag(tagName, tagValue) {
	var __funcName__ = "irwstatSetTrailingTag";
	
	try {
		var trailingTag = irwstatGetCookie("IRWStats.trailingTag");		
		irwstatSetCookie("IRWStats.trailingTag", trailingTag+tagName+","+tagValue+"|", 1);
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatReadTrailingTag() {
	var __funcName__ = "irwstatReadTrailingTag";
	
	try {
		var trailingTag = irwstatGetCookie("IRWStats.trailingTag");
		irwstatSetCookie("IRWStats.trailingTag", "", -1);
		
		while (trailingTag.length > 0) {
			var tagName = trailingTag.substr(0, trailingTag.indexOf(","));
			var tagValue = "";
			if (trailingTag.indexOf("|") > 0) {
				tagValue = trailingTag.substr(trailingTag.indexOf(",")+1, trailingTag.indexOf("|") - (trailingTag.indexOf(",")+1));
			} else {
				tagValue = trailingTag.substr(trailingTag.indexOf(",")+1);
			}
			
			if (trailingTag.indexOf("|") > 0) {
				trailingTag = trailingTag.substr(trailingTag.indexOf("|")+1);
			} else {
				trailingTag = "";
			}
			
			
			irwstatAddMetaTag(tagName, tagValue);
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatCheckCategories(irwTags) {
	var __funcName__ = "irwstatCheckCategories";
	
	try {
		var hasCategory = false;
		var hasSubCategory = false;
		var hasChapter = false;
		var hasSystem = false;
		var hasSystemChapter = false;
		
		if (irwstatCheckTag("category", irwTags)) hasCategory = true;
		if (irwstatCheckTag("subcategory", irwTags)) hasSubCategory = true;
		if (irwstatCheckTag("chapter", irwTags)) hasChapter = true;
		if (irwstatCheckTag("system", irwTags)) hasSystem = true;
		if (irwstatCheckTag("systemchapter", irwTags)) hasSystemChapter = true;
		
		if (! hasCategory) hasSubCategory = false;
		if (! hasSubCategory) hasChapter = false;
		if ((! hasSubCategory) && (! hasChapter)) hasSystem = false;
		if (! hasSystem) hasSystemChapter = false;
		
		// Invalidate tags that shouldn't be allowed
		if (! hasCategory) {
			irwTags = irwstatDisableTag("category", irwTags);
			irwTags = irwstatDisableTag("categorylocal", irwTags);
		} else {
			irwstatAddLocalFlag("hasCategory");
		}
		if (! hasSubCategory) {
			irwTags = irwstatDisableTag("subcategory", irwTags);
			irwTags = irwstatDisableTag("subcategorylocal", irwTags);
		} else {
			irwstatAddLocalFlag("hasSubCategory");
		}
		if (! hasChapter) {
			irwTags = irwstatDisableTag("chapter", irwTags);
			irwTags = irwstatDisableTag("chapterlocal", irwTags);
		} else {
			irwstatAddLocalFlag("hasChapter");
		}
		if (! hasSystem) {
			irwTags = irwstatDisableTag("system", irwTags);
			irwTags = irwstatDisableTag("systemlocal", irwTags);
		} else {
			irwstatAddLocalFlag("hasSystem");
		}
		if (! hasSystemChapter) {
			irwTags = irwstatDisableTag("systemchapter", irwTags);
			irwTags = irwstatDisableTag("systemchapterlocal", irwTags);
		} else {
			irwstatAddLocalFlag("hasSystemChapter");
		}
		
		return irwTags;
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatPostProcessVariable(varName) {
	var __funcName__ = "irwstatPostProcessVariable";

	try {
		var irwStatsCaller = "";
		if (typeof(irwstatPostProcessVariable.caller) == "function") {
			if (typeof(irwstatPostProcessVariable.caller.name) != "undefined") {
				irwStatsCaller = irwstatPostProcessVariable.caller.name;
			} else {
				irwStatsCaller = new String(irwstatPostProcessVariable.caller);
				irwStatsCaller = irwStatsCaller.split("\n")[0];
			}
		}
		
		if (irwstatCheckLocalFlag("trackVarExclusive_SET")) {
			if ((irwStatsCaller.indexOf("irwstatPrepareVendor") < 0) 
				&& (irwStatsCaller.indexOf("irwstatPostProcessEval") < 0)) {
				return;
			}
		}
		
		omnitureAddLinkTrack(varName);
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatPostProcessEval(evalString, value) {
	var __funcName__ = "irwstatPostProcessEval";

	try {
		var irwStatsCaller = "";
		if (typeof(irwstatPostProcessEval.irwStatsCaller) == "function") {
			if (typeof(irwstatPostProcessVariable.caller.name) != "undefined") {
				irwStatsCaller = irwstatPostProcessEval.caller.name;
			} else {
				irwStatsCaller = new String(irwstatPostProcessEval.caller);
				irwStatsCaller = irwStatsCaller.split("\n")[0];
			}
		}
	
		if (irwstatCheckLocalFlag("trackVarExclusive_SET")) {
			if (irwStatsCaller.indexOf("irwstatPrepareVendor") < 0) {
				return;
			}
		}
	
		var matches = []
		matches.push({regexp:/^.*(s\.[^\ \=]+)[\ ]?\=.*$/g, replace:"$1"});
		matches.push({regexp:/^.*irwstatOmnitureAddEvent[\ ]?\([\ ]?value[\ ]?\).*$/g, replace:false});
		matches.push({regexp:/^.*irwstatOmnitureAddEvent[\ ]?\(\'([^\']+)\'\).*$/g, replace:"$1"});
		matches.push({regexp:/^.*irwstatOmnitureAddProduct[\ ]?\([\ ]?value[\ ]?\).*$/g, replace:"s.products"});
		matches.push({regexp:/^.*irwstatOmnitureAddProduct[\ ]?\(\'([^\']+)\'\).*$/g, replace:"s.products"});
		
		for (var matchNo = 0; matchNo < matches.length; matchNo++) {
			if (matches[matchNo].regexp.test(evalString)) {
				if (matches[matchNo].replace !== false) {
					irwstatPostProcessVariable(evalString.replace(matches[matchNo].regexp, matches[matchNo].replace));
				} else {
					irwstatPostProcessVariable(value);
				}
			}
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatPrepareVendor(tags) {
	var __funcName__ = "irwstatPrepareVendor";

	try {
		// Check categories before processing
		tags = irwstatCheckCategories(tags);
	
		for (var metaCount = 0; metaCount < tags.length; metaCount++) {
			if (typeof(tMapArr[tags[metaCount].name]) != "object") {
				continue;
			}
		
			var tagMap = tMapArr[tags[metaCount].name];
			var value = tags[metaCount].value;
			
			// Allow other functions to invalidate a tag by setting null
			if (value == null) {
				continue;
			}
			
			if (typeof(tagMap.changeCase) != "undefined") {
				if (tagMap.changeCase.toLowerCase() == "lower") {
					value = value.toLowerCase();
				} else if (tagMap.changeCase.toLowerCase() == "upper") {
					value = value.toUpperCase();
				}
			}
			
			value = value.replace(/[\ ]*\|[\ ]*/g, '>');
				
			if ((tagMap.toVar) && (typeof(tagMap.conditional) == "undefined")) {
				if (typeof(tagMap.varName) != "undefined") {
					eval(tagMap.varName+"='"+value+"'");
					if (irwstatCheckTrackVar(tags[metaCount].name)) {
						irwstatPostProcessVariable(tagMap.varName);
					}
				}
			} else if (typeof(tagMap.conditional) != "undefined") {
				for (condCount = 0; condCount < tagMap.conditional.length; condCount++) {
					if (tags[metaCount].value.toLowerCase() == tagMap.conditional[condCount].option.toLowerCase()) {
						if (typeof(tagMap.conditional[condCount].varName) != "undefined") {
							eval(tagMap.conditional[condCount].varName+"='"+value+"'");
							if (irwstatCheckTrackVar(tags[metaCount].name)) {
								irwstatPostProcessVariable(tagMap.conditional[condCount].varName);
							}
						} else if (typeof(tagMap.conditional[condCount].eval) != "undefined") {
							eval(tagMap.conditional[condCount].eval);
							if (irwstatCheckTrackVar(tags[metaCount].name)) {
								irwstatPostProcessEval(tagMap.conditional[condCount].eval, value);
							}
						}
					}
				}
			} else if (typeof(tMapArr[tags[metaCount].name].eval) != "undefined") {
				eval(tMapArr[tags[metaCount].name].eval);
				if (irwstatCheckTrackVar(tags[metaCount].name)) {
					irwstatPostProcessEval(tMapArr[tags[metaCount].name].eval, value);
				}
			}
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

// Omniture specific global-variable
var s_account = "";

// Statistics global-variable (dev or live)
var irwstats_stattype = "";

// Global-variables that will be loaded by omniture
var s_language = "";
var s_country = "";
var s_trackingServer = true;

var s_urls = "";

function irwstatPrepareConfig() {
	var __funcName__ = "irwstatPrepareConfig";

	try {
		irwstatArgs = "";
		for (var irwstat_arg = 0; irwstat_arg < arguments.length; irwstat_arg++) {
			irwstatArgs += "'"+arguments[irwstat_arg]+"', ";
		}
		
		if (irwstatArgs.length > 0) {
			irwstatArgs = irwstatArgs.substr(0, (irwstatArgs.length-2));
		}
		eval("irwstatPrepareOmnitureConfig("+irwstatArgs+");");
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatPrepareOmnitureConfig() {
	var __funcName__ = "irwstatPrepareOmnitureConfig";

	if (arguments.length < 2) {
		var myLocation = document.location.href;
		var serverHost = "";
		if (myLocation.indexOf('http://') == 0) {
			var serverHost = myLocation.substr(myLocation.indexOf('http://')+7, myLocation.indexOf('/', myLocation.indexOf('http://')+7)-7);
		} else if (myLocation.indexOf('https://') == 0) {
			var serverHost = myLocation.substr(myLocation.indexOf('https://')+8, myLocation.indexOf('/', myLocation.indexOf('https://')+8)-8);
		}
		
		if ((serverHost == "www.ikea.com")
		   || (serverHost == "secure.ikea.com")
		   || (serverHost == "preview.ikea.com")) {
			irwstats_stattype = "live";
		} else if (serverHost.length > 0) {
			irwstats_stattype = "dev";
		}
		
		if (arguments.length == 1) {
			var locale = arguments[0];
		} else {
            /**
            * Start IKEA00693517
            **/
			var metaTags = $$('meta');
			
            /**
            * End IKEA00693517
            **/
		  	for (var metaCount = 0; metaCount < metaTags.length; metaCount++) { 
		   		var item = metaTags[metaCount];
				
				if (item.getAttribute("HTTP-EQUIV")) {
					continue;
				}
				
		 		var itemName = item.getAttribute("NAME");
				if (itemName.toLowerCase() == "language") {
					var locale = item.getAttribute("CONTENT");
					locale.replace(/-/, "_");
				}
		  	}
		}
	} else {
		var locale = arguments[0];
		irwstats_stattype = arguments[1];
	}

	try {
		s_language = locale.substr(0, locale.indexOf("_")).toLowerCase();
		s_country = locale.substr(locale.indexOf("_")+1).toLowerCase();
		
		
        /**
        * Start of IKEA00693413
        **/
        var urls1 = urls;
        var urls2 = '';
        var str1Length = urls1.length;
        if (urls1.charAt(str1Length-1) == '/') {
          urls2 = urls1.slice(0,-1);
          s_urls =urls2;
        }
        else{
            s_urls = urls;
        }
        /**
        * End of IKEA00693413
        **/
		if (irwstats_stattype == "dev") {
			s_account = "ikea"+s_country+irwstats_stattype;
			s_trackingServer = false;
			irwStatsInitialized = true;
			
			var checkBAT = function() {
				var loc = document.location.href;
				for (var i = 0; i < arguments.length; i++) {
					if (loc.indexOf(arguments[i]) >= 0) {
						return true;
					}
				}
				
				return false;
			};
			
			// CTE-F should be directed to BAT
			if (checkBAT("cfirw.ikeadt.com", "cfirw01.ikeadt.com", "cfirw02.ikeadt.com")) {
				s_account = "ikeasebat";
			}
		} else if (irwstats_stattype == "live") {
			s_account = "ikea"+s_country+"prod,ikeaallprod";
			s_trackingServer = true;
			irwStatsInitialized = true;
		}
        set_s_var();
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatOmnitureAddCharset(charset) {
	var __funcName__ = "irwstatOmnitureAddCharset";

	try {
		//s.charSet = charset.toUpperCase();
		s.charSet = "Auto";
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatOmnitureAddEvent(eventName) {
	var __funcName__ = "irwstatOmnitureAddEvent";
	
	try {
		if ((eventName == "event12") && (s.products.length == 0)) {	
			return;
		}
	
		if ((typeof(s.events) == "undefined") || (s.events.length == 0)) {
			s.events = eventName;
		} else {
			if (s.events.indexOf(eventName) < 0) {
				s.events += ","+eventName;
			}
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatOmnitureRemoveEvent(eventName) {
	var __funcName__ = "irwstatOmnitureRemoveEvent";

	try {
		if ((typeof(s.events) == "undefined") || (s.events.length == 0)) {
			return;
		} else {
			if (s.events.indexOf(eventName) >= 0) {
				if (s.events.indexOf(eventName+",") >= 0) {
					eventName += ",";
				}
				var temp = s.events.substr(0, s.events.indexOf(eventName));
				temp += s.events.substr(s.events.indexOf(eventName)+eventName.length);
				if (temp.substr(temp.length - 1, 1) == ",") {
					temp = temp.substr(0, temp.length - 1);
				}
				s.events = temp;
			}
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatTrackRia() {
	var __funcName__ = "irwStatTrackRia";
	
	try {
		s.products = "";
		s.events = "";
		var riaAction = "ria action";
	
		for (var irwTagCount = 0; irwTagCount < arguments.length; irwTagCount++) {
			if (arguments[irwTagCount].substr(0, 9) != "IRWStats.") {
				continue;
			}
			
			if (arguments[irwTagCount].toLowerCase() == "irwstats.riarequestname") {
				riaAction = arguments[irwTagCount+1];
			} else {
				irwstatAddTrackVar(arguments[irwTagCount]);
				irwstatAddMetaTag(arguments[irwTagCount], arguments[irwTagCount+1]);
			}
			irwTagCount++;
		}
		
		irwLocalFlags = new Array();
		irwStatLocalVars = new Array();
		irwstatAddLocalFlag("addAllPropsAndEvents");
		
		if (irwStatsInitialized == false) {
			irwstatPrepareConfig();
		}
		
		irwstatSendLink("o", riaAction);
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatPopupAnna() {
	var __funcName__ = "irwStatPopupAnna";
	
	try {
		omnitureRemoveVariable("prop", "eVar", "event", "pageName", "products");
		s.pageName = s.prop1 = s.prop2 = s.prop5 = s.eVar31 = "ask anna";
		irwstatOmnitureAddEvent("event16");
		
		// Clear flags and local vars
		irwLocalFlags = new Array();
		irwStatLocalVars = new Array();
		
		irwstatAddLocalFlag("pageName_SET");
		irwstatAddLocalFlag("pageNameLocal_SET");
		irwstatAddLocalFlag("categories_SET");
		
		omnitureExecute();
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatFormError(formName, formField, formErrorText) {
	var __funcName__ = "irwStatFormError";
	
	try {
		irwstatAddMetaTag("IRWStats.formErrorName", formName);
		irwstatAddMetaTag("IRWStats.formErrorFields", formField);
		irwstatAddMetaTag("IRWStats.formErrorTexts", formErrorText);
		
		s.linkTrackVars = "prop27";
		s.linkTrackEvents = "";
		
		irwstatSendLink("o", "form error");
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatCompareProducts(productArray) {
	var __funcName__ = "irwStatCompareProducts";
	try {
		s.eVar16 = "";
		if ((typeof(productArray) == "object") && (productArray.length > 0)) {
			var prodArray = productArray.slice();
			prodArray.sort();
			
			var productID;
			for (var prodCount = 0; prodCount < prodArray.length; prodCount++) {
				productID = prodArray[prodCount];
				if ((typeof(productID) != "undefined") && (productID.substr(0,1).toLowerCase() == "s")) {
					productID = productID.substr(1);
				}
				s.eVar16 += productID+">";
			}
		}
		s.eVar16 = s.eVar16.substr(0, s.eVar16.length-1);
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatPageFunctionality(pageFunctionality, actionName) {
	var __funcName__ = "irwStatPageFunctionality";
	
	try {
		irwstatAddMetaTag("IRWStats.pageFunctionality", pageFunctionality);
		irwstatAddLocalFlag("addAllPropsAndEvents");
		irwstatAddTrackVar("IRWStats.pageFunctionality", "exclusive");
		
		irwstatSendLink("o", actionName);
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatShoppingList() {
	var __funcName__ = "irwStatShoppingList";
	
	try {
		if (arguments.length < 1) {
			return;
		}
		
		var listAction = arguments[0].toLowerCase();
		var actionName = "shopping list";
		var restoreProducts = "";
		
		if (listAction == "buyonline") {
			if (arguments.length < 2) {
				throw new Error("buyonline expects productID as second parameter.");
			}
			irwstatOmnitureAddEvent("scAdd");
			restoreProducts = s.products;
			s.products = "";
			irwstatOmnitureAddProduct(arguments[1]);
			
			s.linkTrackVars = "events,products";
			s.linkTrackEvents = "scAdd";
			
			actionName += " buy online";
		} else if (listAction == "createnewlist") {
			s.prop24 = "shopping list created";
			
			s.linkTrackVars = "prop24";
			s.linkTrackEvents = "";
			
			actionName += " create";
		} else if (listAction == "addbypartnumber") {
			if (arguments.length < 2) {
				throw new Error("addbypartnumber expects productID as second parameter.");
			}
		
			irwstatOmnitureAddEvent("event17");
			irwstatOmnitureAddProduct(arguments[1]);
			restoreProducts = s.products;
			s.products = "";
			irwstatOmnitureAddProduct(arguments[1]);
			
			s.linkTrackVars = "events,products";
			s.linkTrackEvents = "event17";
			
			actionName += " add by part number";
		} else if (listAction == "addfrompiporsc") {
			irwstatOmnitureAddEvent("event17");
			s.prop24 = "shopping list add from pip or stockcheck";
			
            /**
            * Start IKEA00694793
            **/
            restoreProducts = s.products;
            s.products = "";
            irwstatOmnitureAddProduct(arguments[1]);
            /**
            * End IKEA00694793
            **/
			s.linkTrackVars = "prop24,events,products";
			s.linkTrackEvents = "event17";
			
			actionName += " add from pip or stockcheck";
		} else if (listAction == "poppopupopened") {
			s.prop24 = "shopping list popup opened";
			
			s.linkTrackVars = "prop24";
			s.linkTrackEvents = "";
			
			actionName += " popup opened";
		} else if (listAction == "emailshoppinglist") {
			s.eVar30 = "email";
			irwstatOmnitureAddEvent("event20");
			
			s.linkTrackVars = "eVar30,events,products";
			s.linkTrackEvents = "event20";
			
			actionName += " email";
		} else if (listAction == "removeproduct") {
			if (arguments.length < 2) {
				throw new Error("addbypartnumber expects productID as second parameter.");
			}
		
			s.eVar30 = "remove";
			irwstatOmnitureAddEvent("event18");
			irwstatOmnitureRemoveProduct(arguments[1]);
			restoreProducts = s.products;
			s.products = "";
			irwstatOmnitureAddProduct(arguments[1]);
			
			s.linkTrackVars = "eVar30,events,products";
			s.linkTrackEvents = "event18";
		
			actionName += " remove";
		 }
        /**
        * Start IKEA00694222 
        **/
        else if (listAction == "updateproduct") {
            if (arguments.length < 2) {
                throw new Error("addbypartnumber expects productID as second parameter.");
            }
        
            irwstatOmnitureAddEvent("event17");
            irwstatOmnitureAddProduct(arguments[1]);
            restoreProducts = s.products;
            s.products = "";
            irwstatOmnitureAddProduct(arguments[1]);
            
            s.linkTrackVars = "events,products";
            s.linkTrackEvents = "event17";
            
            actionName += " update";
        } 
        /**
        * End IKEA00694222 
        **/			
		 else if (listAction == "printshoppinglist") {
			s.eVar30 = "print";
			irwstatOmnitureAddEvent("event20");
			
			s.linkTrackVars = "eVar30,events,products";
			s.linkTrackEvents = "event20";
		
			actionName += " print";
		} else if (listAction == "saveshoppinglist") {
			s.eVar30 = "save";
			
			s.linkTrackVars = "eVar30,products";
			s.linkTrackEvents = "";
		
			actionName += " save";
		}
		
        /**
        * Start IKEA00694793 
        **/
        irwstatAddLocalFlag("shoppingList_prod");
        /**
        * End IKEA00694793
        **/
		omnitureExecuteLink("o", actionName);
		
		if (restoreProducts.length > 0) {
			s.products = restoreProducts;
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatProductChanged(productID) {
	var __funcName__ = "irwStatProductChanged";

	try {
		s.products = "";
		
		if (productID.substr(0,1) != ";") {
			s.products = ";";
		}
		
		
		s.prop6 = "";
		s.events = "prodView,event3";
		if(!irwstatCheckLocalFlag("prodView")) {
			irwstatAddLocalFlag('prodView');
		}
		        /**
        * Start IKEA00694536
        **/
        if (productID.substr(0,1) == "S") {
            productID = productID.substr(1,productID.length);
        }
        /**
        * End IKEA00694536
        **/        
        s.products += productID;
		
		omnitureExecute();
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}


function irwstatOmnitureAddProduct(productID) {
	var __funcName__ = "irwstatOmnitureAddProduct";

	try {
		if (productID.length < 2) {
			return;
		}

		if ((typeof(s.products) != "undefined") && (s.products.length > 0)) {
			if (s.products.indexOf(productID) >= 0) {
				return;
			}
		
			s.products += ",";
		} else {
			s.products = "";
		}
		
		if (productID.substr(0,1) != ";") {
			s.products += ";";
			if (productID.substr(0,1).toLowerCase() == "s") {
				productID = productID.substr(1);
			}
		} else if (productID.substr(1,1).toLowerCase() == "s") {
			productID = ";" + productID.substr(2);
		}
		s.products += productID;
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatOmnitureRemoveProduct(productID) {
	var __funcName__ = "irwstatOmnitureRemoveProduct";

	try {
		if (productID.length < 2) {
			return;
		}
		
		if ((typeof(s.products) == "undefined") || (s.products.length < 1)) {
			return;
		}
		
		if (productID.substr(0,1) == ";") {
			productID = productID.substr(1);
		}
		
		var productSearch;
		eval("productSearch = /^(.*)\,\;"+productID+"(.*)$/");
		
		if (!productSearch.test(s.products)) {
			eval("productSearch = /^\;" + productID + "[\,]?(.*)$/");
			if (!productSearch.test(s.products)) {
				return;
			}
			
			s.products = s.products.replace(productSearch, "$1");
		} else {
			s.products = s.products.replace(productSearch, "$1$2");
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatScAdd(prodArray) {
	var __funcName__ = "irwStatScAdd";

	try {	
		if (prodArray.constructor.toString().indexOf("Array") == -1) {
			prodArray = [ prodArray ];
		}
		
		var products = "";
		for (prodCount = 0; prodCount < prodArray.length; prodCount++) {
			products += ";"+prodArray[prodCount]+",";
		}
		products = products.substr(0, products.length-1);
		
		irwstatSetTrailingTag("IRWStats.addToCart", "yes");
		irwstatSetTrailingTag("IRWStats.scAddProducts", products);
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatScRemove(prodArray) {
	var __funcName__ = "irwStatScRemove";

	try {
		if (prodArray.constructor.toString().indexOf("Array") == -1) {
			prodArray = [ prodArray ];
		}
		
		var products = "";
		for (prodCount = 0; prodCount < prodArray.length; prodCount++) {
			products += ";"+prodArray[prodCount]+",";
		}
		products = products.substr(0, products.length-1);
		
		irwstatSetTrailingTag("IRWStats.removeFromCart", "yes");
		irwstatSetTrailingTag("IRWStats.products", products);
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatLocalStoreViewed(storeNo) {
	var __funcName__ = "irwStatLocalStoreViewed";

	try {
		s.events = "event11";
		s.eVar17 = storeNo.toLowerCase();
		
		s.linkTrackVars = 'events';
		s.linkTrackEvents = 'event11';
		
		omnitureExecuteLink("o", "local_store_viewed");
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwStatFamilyNewsletterSignup() {
	var __funcName__ = "irwStatFamilyNewsletterSignup";

	try {
		s.events = "event9";
		
		s.linkTrackVars = 'events';
		s.linkTrackEvents = 'event9';
		
		omnitureExecuteLink("o", "newsletter_signup");
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatSend() {
	var __funcName__ = "irwstatSend";

	try {
		irwstatReadTrailingTag();
	
		var irwTags = irwstatReadMetaTags();
		if ((irwTags == null) || (irwTags.length < 1)) {
			return;
		}
		irwstatPrepareVendor(irwTags);
		
		omnitureExecute();
		
		irwstatClearLocalData();
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatSendLink() {
	var __funcName__ = "irwstatSendLink";

	try {
		var irwTags = irwstatReadMetaTags();
		if ((irwTags == null) || (irwTags.length < 1)) {
			return;
		}
		irwstatPrepareVendor(irwTags);
		
		if (irwstatCheckLocalFlag("riaPageView_SET")) {
			omnitureExecute();
			return;
		}
		
		irwstatArgs = "";
		for (var irwstat_arg = 0; irwstat_arg < arguments.length; irwstat_arg++) {
			irwstatArgs += "'"+arguments[irwstat_arg]+"', ";
		}
		
		if (irwstatArgs.length > 0) {
			irwstatArgs = irwstatArgs.substr(0, (irwstatArgs.length-2));
		}
		eval("omnitureExecuteLink("+irwstatArgs+");");
		
		irwstatClearLocalData();
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function irwstatHandleError(err, func) {
	if (irwstats_stattype == "dev") {
		errMsg = func+": "+err+"\n";
		if (irwStatsDebug) {
			alert(errMsg);
		}
		throw new Error(errMsg);
	}
}

// ## FIX ## -- Needs documentation
function omnitureRemoveVariable() {
	var __funcName__ = "omnitureRemoveVariable";
	
	try {
		if (arguments.length < 1) {
			return;
		}
	
		var keys = [];
	    for (var property in s) {
			keys.push(property);
		}
		
		for (var arg = 0; arg < arguments.length; arg++) {	
			for (var prop = 0; prop < keys.length; prop++) {
				if (keys[prop].indexOf(arguments[arg]) == 0) {
					eval("s."+keys[prop]+" = '';");
				}
			}
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function omniturePushCategory(newCat) {
	var __funcName__ = "omniturePushCategory";

	try {
		// NB! If s.prop22 is set it will get pushed out. (Shouldn't be the case though).
		if (typeof(s.prop21) != "undefined") s.prop22 = s.prop21;
		if (typeof(s.prop4) != "undefined") s.prop21 = s.prop4;
		if (typeof(s.prop3) != "undefined") s.prop4 = s.prop3;
		if (typeof(s.prop2) != "undefined") s.prop3 = s.prop2;
		s.prop2 = newCat;
		
		if (typeof(irwStatLocalVars["systemLocal"]) != "undefined") irwStatLocalVars["systemChapterLocal"] = irwStatLocalVars["systemLocal"];
		if (typeof(irwStatLocalVars["chapterLocal"]) != "undefined") irwStatLocalVars["systemLocal"] = irwStatLocalVars["chapterLocal"];
		if (typeof(irwStatLocalVars["subcategoryLocal"]) != "undefined") irwStatLocalVars["chapterLocal"] = irwStatLocalVars["subcategoryLocal"];
		if (typeof(irwStatLocalVars["categoryLocal"]) != "undefined") irwStatLocalVars["subcategoryLocal"] = irwStatLocalVars["categoryLocal"];
		irwStatLocalVars["categoryLocal"] = newCat;
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function omnitureLastChanges() {
	var __funcName__ = "omnitureLastChanges";

	try {
		if (irwStatLocalVars["internalPageType"] != "static") {
			omnitureUpdatePageName();
		}
		omnitureUpdateCategories();
		omnitureUpdateCustomTags();
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function omnitureUpdateCategories() {
	var __funcName__ = "omnitureUpdateCategories";

	try {
		if (irwstatCheckLocalFlag("categories_SET")) {
			return;
		}
		
		if (typeof(s.prop3) != "undefined") {
			// First check that we have no > (delimiter) in the category properties
			if ((s.prop3.indexOf(">") > 0)
				|| ((typeof(s.prop4) != "undefined") && (s.prop4.indexOf(">") > 0))
				|| ((typeof(s.prop21) != "undefined") && (s.prop21.indexOf(">") > 0))
				|| ((typeof(s.prop22) != "undefined") && (s.prop22.indexOf(">") > 0))) {
				irwstatAddLocalFlag("categories_SET");
				return;
			}
		}
		
		if ((typeof(s.prop2) != "undefined") && (typeof(s.prop3) != "undefined")) s.prop3 = s.prop2+">"+s.prop3;
		if ((typeof(s.prop3) != "undefined") && (typeof(s.prop4) != "undefined")) s.prop4 = s.prop3+">"+s.prop4;
		if ((typeof(s.prop4) != "undefined") && (typeof(s.prop21) != "undefined")) {
			s.prop21 = s.prop4+">"+s.prop21;
		} else if ((typeof(s.prop3) != "undefined") && (typeof(s.prop21) != "undefined")) {
			s.prop21 = s.prop3+">"+s.prop21;
		}
		if ((typeof(s.prop21) != "undefined") && (typeof(s.prop22) != "undefined")) s.prop22 = s.prop21+">"+s.prop22;
		
		irwstatAddLocalFlag("categories_SET");
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function omnitureUpdatePageName() {
	var __funcName__ = "omnitureUpdatePageName";

	try {
		if (! irwstatCheckLocalFlag("pageName_SET")) {
			if (typeof(s.prop2) != "undefined") s.pageName = s.prop2;
			if ((typeof(s.prop3) != "undefined") && (s.prop3.length > 0)) s.pageName += ">"+s.prop3;
			if ((typeof(s.prop4) != "undefined") && (s.prop4.length > 0)) s.pageName += ">"+s.prop4;
			if ((typeof(s.prop21) != "undefined") && (s.prop21.length > 0)) s.pageName += ">"+s.prop21;
			if ((typeof(s.prop22) != "undefined") && (s.prop22.length > 0)) s.pageName += ">"+s.prop22;
			if ((typeof(irwStatLocalVars["categoryTabId"]) != "undefined") && (irwStatLocalVars["categoryTabId"].length > 0)) {
				s.pageName += ">"+irwStatLocalVars["categoryTabId"];
				// remove the front flag if tab information is present so that the front string does not appear
				irwstatDeleteLocalFlag("front");
				// value set when user clicks on the tab
				s.eVar40 = "tab selected";	
				// make sure that the value is et only once per user session	
				s.eVar40=s.getValOnce(s.eVar40,'s_evar40',0);
			}
			if ((typeof(irwStatLocalVars["friendlyPageName"]) != "undefined") && (irwStatLocalVars["friendlyPageName"].length > 0)) {
				s.prop1 += ">"+irwStatLocalVars["friendlyPageName"];
			}				
			
			irwstatAddLocalFlag("pageName_SET");
		}
		
		if (! irwstatCheckLocalFlag("pageNameLocal_SET")) {
			if ((irwStatLocalVars["categoryLocal"]) && (irwStatLocalVars["categoryLocal"].length > 0)) {
				s.prop1 = irwStatLocalVars["categoryLocal"];
			} else {
				return;
			}
			if ((typeof(irwStatLocalVars["subcategoryLocal"]) != "undefined") && (irwStatLocalVars["subcategoryLocal"].length > 0)) {
				s.prop1 += ">"+irwStatLocalVars["subcategoryLocal"];
			}
			if ((typeof(irwStatLocalVars["chapterLocal"]) != "undefined") && (irwStatLocalVars["chapterLocal"].length > 0)) {
				s.prop1 += ">"+irwStatLocalVars["chapterLocal"];
			}
			if ((typeof(irwStatLocalVars["systemLocal"]) != "undefined") && (irwStatLocalVars["systemLocal"].length > 0)) {
				s.prop1 += ">"+irwStatLocalVars["systemLocal"];
			}
			if ((typeof(irwStatLocalVars["systemChapterLocal"]) != "undefined") && (irwStatLocalVars["systemChapterLocal"].length > 0)) {
				s.prop1 += ">"+irwStatLocalVars["systemChapterLocal"];
			}		
			if ((typeof(irwStatLocalVars["categoryTabId"]) != "undefined") && (irwStatLocalVars["categoryTabId"].length > 0)) {
				s.prop1 += ">"+irwStatLocalVars["categoryTabId"];
			}
			irwstatAddLocalFlag("pageNameLocal_SET");
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function omnitureUpdateCustomTags() {
	var __funcName__ = "omnitureUpdateCustomTags";
	
	try {
		// Set s.prop25 (product flow) if we have prodView
		if (irwstatCheckLocalFlag("prodView")) {
			if (s.products.substr(0, 1) == ";") {
				s.prop25 = s.products.substr(1);
			} else {
				s.prop25 = s.products;
			}
		}
	
        /** 
        * Start IKEA00694793
        **/
        if(!irwstatCheckLocalFlag("shoppingList_prod") && typeof(s.events) == "undefined") s.products = "";
        /** 
        * End IKEA00694793
        **/
		if (irwstatCheckLocalFlag("merchandisingcategory_SET")) {
			s.eVar4 = s.pageName;
			irwstatPostProcessVariable("s.eVar4");
		}
		
		if ((irwstatCheckLocalFlag("front")) && (! irwstatCheckLocalFlag("front_SET"))) {
			irwstatAddLocalFlag("front_SET");
			s.pageName += ">front";
			s.prop1 += ">front";
		}
		if ((irwstatCheckLocalFlag("form")) && (! irwstatCheckLocalFlag("form_SET"))) {
			irwstatAddLocalFlag("form_SET");
			s.pageName += ">form";
			s.prop1 += ">form";
		}
        if ((irwstatCheckLocalFlag("prodView")) && (! irwstatCheckLocalFlag("prodView_SET"))) {
            irwstatAddLocalFlag("prodView_SET");
            s.pageName += ">prodview";
            s.prop1 += ">prodview";
        }
		if (irwstatCheckLocalFlag("riaAction_SET")) {
			if ((typeof(irwStatLocalVars["riaAsset"]) != "undefined") 
				&& (typeof(irwStatLocalVars["riaAssetType"]) != "undefined")
				&& (typeof(irwStatLocalVars["riaAction"]) != "undefined")
				&& (typeof(irwStatLocalVars["riaActionType"]) != "undefined")) {

				//IKEA00659368
				if (irwStatLocalVars["riaAssetType"] == "other") {
				irwStatLocalVars["riaAssetType"] = irwStatLocalVars["riaCategory"];
				}
				//ends IKEA00659368
								
				s.eVar23 = s.prop18 = irwStatLocalVars["riaAssetType"]+">"+irwStatLocalVars["riaAsset"];
				s.prop19 = irwStatLocalVars["riaAsset"]+">"+irwStatLocalVars["riaActionType"]+">"+irwStatLocalVars["riaAction"];
				s.prop20 = s.prop19;
				
				s.pageName += ">"+irwStatLocalVars["riaAsset"];
				s.prop1 += ">"+irwStatLocalVars["riaAsset"];
				
				irwstatPostProcessVariable("s.eVar12");
				irwstatPostProcessVariable("s.eVar23");
				irwstatPostProcessVariable("s.prop18");
				irwstatPostProcessVariable("s.prop19");
				irwstatPostProcessVariable("s.prop20");
			}
			if ((typeof(irwStatLocalVars["riaRoomSet"]) != "undefined") && (irwStatLocalVars["riaRoomSet"].length > 0)) {
				s.prop23 = irwStatLocalVars["riaRoomSet"];
				irwstatPostProcessVariable("s.prop23");
			}
		}
		
		// Check if we need to set event2 - for checkout pages
		if (irwstatCheckLocalFlag("memberLoginStarted_SET")) {
			if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"] == "ecom-step1")) {
				irwstatOmnitureAddEvent("event2");
				irwstatPostProcessVariable("event2");
			}
		}
		
		if (irwstatCheckLocalFlag("memberSignupStart_SET")) {
			if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"].substr(0, 4) == "ecom")) {
				if (irwstatCheckLocalFlag("checkoutGuest_SET")) {
					s.eVar18 = "guest ecom flow";
				} else {
					s.eVar18 = "ecom sign up";
				}
				irwstatPostProcessVariable("s.eVar18");
			} else {
				irwstatSetTrailingTag("IRWStats.memberSignupStarted", "yes");
			}
		}
		
		// Change in fammily_code --
		if (irwstatCheckLocalFlag("memberSignupStarted_SET")) {
		   if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"] == "user confirmation") && 
		      (typeof(s.prop5) != "undefined") && (s.prop5 == "family")) {
			 s.eVar18 = "family sign up";
			 irwstatOmnitureAddEvent("event8");
			 irwstatPostProcessVariable("s.eVar18");
			 irwstatPostProcessVariable("event8");
		   } else if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"] == "user confirmation")) {
			 s.eVar18 = "sign up";
			 irwstatOmnitureAddEvent("event8");
			 irwstatPostProcessVariable("s.eVar18");
			 irwstatPostProcessVariable("event8");
		   } else if ((typeof(s.prop5) != "undefined") && (s.prop5 == "shopping list")) {
			 s.eVar18 = "sign up";
			 irwstatOmnitureAddEvent("event8");
			 irwstatPostProcessVariable("s.eVar18");
			 irwstatPostProcessVariable("event8");
		   } else if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"] == "ecom-step2")) {
			 s.eVar18 = "ecom sign up";
			 irwstatOmnitureAddEvent("event8");
			 irwstatPostProcessVariable("s.eVar18");
			 irwstatPostProcessVariable("event8");
		   }
		}
		// Change in fammily_code -- ends
			
		// Check for Form-errors
		if ((irwstatCheckLocalFlag("formErrorFields_SET")) && (irwstatCheckLocalFlag("formErrorName_SET"))) {
			var errorField = irwStatLocalVars["formErrorFields"];
			if (errorField.indexOf(";") > 0) {
				errorField = errorField.substr(0, errorField.indexOf(";"));
			}
			
			var errorText = "unknown";
			if (irwstatCheckLocalFlag("formErrorTexts_SET")) {
				errorText = irwStatLocalVars["formErrorTexts"];
				if (errorText.indexOf(";") > 0) {
					errorText = errorText.substr(0, errorText.indexOf(";"));
				}
			}
			
			var errorForm = irwStatLocalVars["formErrorName"];
			
			s.prop27 = errorForm+">"+errorField+">"+errorText;
			irwstatPostProcessVariable("s.prop27");
		}
		
		// Set page functionality property if we're on Request Password Page
		if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"] == "request-password")) {
			s.prop24 = "request a new password";
			irwstatPostProcessVariable("s.prop24");
		}
		
		// If we're in the ecom-flow, unset s.prop3 and s.prop4 if it is set
		// Also, set family discount price if it is there
		if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"].substr(0, 4) == "ecom")) {
			s.prop3 = "";
			s.prop4 = "";
		} else if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"].substr(0, 13) == "paydistrorder")) {
			s.prop3 = "";
			s.prop4 = "";
		} else if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"].substr(0, 10) == "stockcheck")) {
			s.prop3 = "";
			s.prop4 = "";
		} else if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"] == "search")) {
			s.prop3 = "";
			s.prop4 = "";
		}
		
		// Shopping cart logic - start
		if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"] == "ecom-step0")) {
			// Only set scView if last page was not the shopping cart
			if (! irwstatCheckLocalFlag("lastPageCart_SET")) {
				irwstatOmnitureAddEvent("scView");
				irwstatPostProcessVariable("scView");
			}
			if (! irwstatCheckLocalFlag("cartOpenedInSession_SET")) {
				irwstatOmnitureAddEvent("scOpen");
				irwstatPostProcessVariable("scOpen");
				irwstatSetTrailingTag("IRWStats.cartOpenedInSession", "yes");
			}
			
			// Make sure the lastPageCart tag is set
			irwstatSetTrailingTag("IRWStats.lastPageCart", "yes");
		}
		
		if (irwstatCheckLocalFlag("cartOpenedInSession_SET")) {
			irwstatSetTrailingTag("IRWStats.cartOpenedInSession", "yes");
		}
		// End - shopping cart logic
		
		
		// If we have ecomstatus, set the formError-property accordingly (ECNA)
		if ((irwstatCheckLocalFlag("eComStatus_SET")) && (typeof(irwStatLocalVars["eComStatus"]) != "undefined")) {
			// Get the step number
			var stepName = "";
			if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"].substr(0, 4) == "ecom")) {
				stepName = irwStatLocalVars["internalPageType"].substr(5, 5);
			} else if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"].substr(0, 13) == "paydistrorder")) {
				stepName = irwStatLocalVars["internalPageType"].substr(14, 5);
			}
			
			s.prop27 = s.prop2+">"+stepName+">fraud check>";
		
			switch (irwStatLocalVars["eComStatus"]) {
				case "1":
					s.prop27 += "passed";
					break;
					
				case "-2":
					s.prop27 += "rejected";
					break;
					
				case "-3":
					s.prop27 += "review";
					break;
					
				case "-4":
					s.prop27 += "error";
					break;
					
				default:
					// null, 0 and "" is also possible - but we don't send any data for those.
					s.prop27 = "";
					delete(s.prop27);
					break;
			}
		}
		
		// Set s.eVar28 to +1 if we're on the stockcheck result page
		if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"] == "stockcheck-result")) {
			s.eVar28 = "+1";
			irwstatPostProcessVariable("s.eVar28");			
			// if stock check is performed from pip page
			if (irwstatCheckLocalFlag("stockchkperformed_SET")) {
				irwstatOmnitureRemoveEvent("event6");
				irwstatOmnitureRemoveEvent("event25");
				irwstatOmnitureRemoveEvent("event26");	
				irwstatOmnitureAddEvent("event27");			
			}
		}
		
		if ((typeof(irwStatLocalVars["internalPageType"]) != "undefined") && (irwStatLocalVars["internalPageType"].substr(0, 14) == "range-category")) {
			if ((irwstatCheckLocalFlag("hasSystemChapter")) || (irwstatCheckLocalFlag("hasSystem")) || (irwStatLocalVars["internalPageType"] == "range-category-series")) {
				s.prop5 = "series, collections and systems";
			} else if (irwstatCheckLocalFlag("hasChapter")) {
				s.prop5 = "subcategory";
			} else if (irwstatCheckLocalFlag("hasSubCategory")) {
				s.prop5 = "category";
			} else if (irwstatCheckLocalFlag("hasCategory")) {
				s.prop5 = "department";
			}
		
			if (s.prop2 != "series") {
				if ((irwstatCheckLocalFlag("hasCategory")) && (! irwstatCheckLocalFlag("hasSubCategory"))) {
					s.hier1 = "topnav";
					if (typeof(s.prop2) != "undefined") s.hier1 += ">"+s.prop2;
					irwstatPostProcessVariable("s.hier1");
				} else if ((irwstatCheckLocalFlag("hasSubCategory")) || (irwstatCheckLocalFlag("hasChapter"))) {
					s.hier1 = "leftnav";
					if (typeof(s.prop4) != "undefined") s.hier1 += ">"+s.prop4;
					else if (typeof(s.prop3) != "undefined") s.hier1 += ">"+s.prop3;
					irwstatPostProcessVariable("s.hier1");
				}
			}
		}
		
		if (irwstatCheckLocalFlag("memberType_SET")) {
			if ((typeof(s.prop24) != "undefined") && (s.prop24 == "logout")) {
				s.prop28 = "";
			} else {
				irwstatSetTrailingTag("IRWStats.memberType", s.prop28);
			}
		} else {
			s.prop28 = "";
		}
		
		if (irwstatCheckLocalFlag("addByPartNumberError_SET")) {
			irwstatOmnitureRemoveEvent("scAdd");
			s.prop24 = "";
		} else if (irwstatCheckLocalFlag("productAlreadyInCart_SET")) {
			irwstatOmnitureRemoveEvent("scAdd");
		} else if (irwstatCheckLocalFlag("scAddProducts_SET")) {
		   s.products = "";
		   irwstatOmnitureAddProduct(irwStatLocalVars["scAddProducts"]);   
		}
		
		/* LSP Modifications   IKEA00674841  */
		
		if (s.prop5 == "local store") {
			var omnitureSplashFlag = false;
			var omnitureLsp = "";
			var omnitureLspFlag = false;
			var omnitureProp3 = "";
			var appendStr = "";
			
			var mySplitResult = s_urls.split("/");
			var lspStoreName = mySplitResult[4] ? mySplitResult[4] : false;
			
			var trim = function(value) {
				return value.replace(/^s+/g, '').replace(/s+$/g, '');
			};
			
			if ((mySplitResult.length < 6) || (mySplitResult[5] == "storeInfo") || (trim(mySplitResult[5]).length == 0)) {
				appendStr = ">front";
			} else if (mySplitResult.length >= 6) {
				appendStr = ">" + mySplitResult[5];
			}
		
			if (document.referrer.length > 0) {
				var fileNameRegex = /\.(htm|html)$/i;
				if (fileNameRegex.test(document.referrer)) {
					var isSplashPage = document.referrer.split("/");
					var splashResRegex = /[a-z]+_[A-Z]+/;
					if (splashResRegex.test(isSplashPage[4])) {
						omnitureSplashFlag = true;
					}
				}
				
				omnitureLsp = "store information>";
				omnitureProp3 = omnitureLsp+"ikea "+lspStoreName;
				
				if (omnitureSplashFlag) {
					omnitureLsp = omnitureLsp+"ikea "+lspStoreName+">front";
				} else {
					omnitureLsp = omnitureLsp+"ikea "+lspStoreName+appendStr;
				}
				omnitureLspFlag = true;
			} else {
				// Directly from homepage or from inside any links in store pages
				omnitureLsp = "store information>";
								
				if (mySplitResult.length > 3) {
					var storeRegex = /^store$/i;
					if (storeRegex.test(mySplitResult[3])) {
						omnitureProp3 = omnitureLsp+"ikea "+lspStoreName;
						omnitureLsp = omnitureLsp+"ikea "+lspStoreName+appendStr;
						omnitureLspFlag = true;
					}
				}
			}
			
			if ((lspStoreName !== false) && (omnitureLspFlag)) {
				s.pageName = omnitureLsp;
				s.prop3 = omnitureProp3;
				s.prop4 = omnitureLsp.replace(/>front$/, ""); // Remove the string front from the prop4 variable
				s.prop20 = omnitureLsp;
			}
		}
		
		/* LSP Modifications  ENDS*/
     /**
       * Start IKEA00691897 
       **/ 
       if (typeof(s.prop24) != "undefined" && s.prop24.substr(0,7) == "filter>" && s.prop1 =="search>search result alternative 1" && s.prop2 =="search" && s.prop5 =="search" && s.prop29 =="search>search_result_alternative>narrow_down_result" && s.prop30=="search>search_result_alternative>narrow_down_result>product_categories")
       { 
           s.prop24="filter>category";
       }

       if (typeof(s.prop24) != "undefined" && s.prop24.substr(0,7) == "filter>" && s.prop2 =="search" && s.prop5 =="search" && s.prop30=="search>search_result_alternative>narrow_down_result>color")
       {
           s.prop24="filter>color";
       }

       if (typeof(s.prop24) != "undefined" && s.prop24.substr(0,7) == "filter>" && s.prop2 =="search" && s.prop5 =="search" && s.prop30=="search>search_result>narrow_down_result>product_categories")
       {
           s.prop24="filter>category";
       }

       if (typeof(s.prop24) != "undefined" && s.prop24.substr(0,7) == "filter>" && s.prop2 =="search" && s.prop5 =="search" && s.prop30=="search>search_result>narrow_down_result>color")
       {
           s.prop24="filter>color";
       }

       if (s.prop5=="category" && typeof(s.prop24) != "undefined" && s.prop24.substr(0,7) == "filter>")
       {
           s.prop24="filter>color";
       }
       
       if (typeof(s.prop24) == "undefined" && s.prop5 =="search" && (s.prop30=="search>search_result>search_result_bar>sort" || s.prop30=="search>search_result_alternative>search_result_bar>sort")){
            var url = window.location.href;
            var str = url.substr(url.lastIndexOf("=")+1);
            if(str == "name") {
                s.prop24="sort>name";
            } else if (str == "price")
            {
                s.prop24="sort>price";
            } else if (str == "newest")
            {
                s.prop24="sort>newest";
            } else
            {
                 s.prop24="sort>relevance";
            }
       }

       if(s.prop5=="subcategory" && typeof(s.prop24) != "undefined"){
           var prop24 =  s.prop24.substr(0,s.prop24.indexOf(">"));
           if(prop24 == "filter"){
               s.prop24="filter>color";
           }
       }

       if (typeof(s.prop1) != "undefined" && s.prop5=="subcategory" && typeof(s.prop24) == "undefined")
       { 
           s.prop24="filter>category";
       }
       /**
       * End IKEA00691897 
       **/

       /**
       * Start IKEA00693258 to set search>did you mean
       **/
       if (s.prop2 =="search" && s.prop5 =="search" && s.prop30=="search>search_result_alternative>search_result_bar>did_you_mean")
       { 
           s.prop24="search>did you mean";
       }
       /**
       * End IKEA00693258 to set search>did you mean
       **/
       /**
       * Start IKEA00694228
       **/
       if(s.events == "scAdd" && s.products.substr(0,2) == ";S"){
           s.products = ";"+s.products.substr(2,s.products.length);
       }
       /**
       * End IKEA00694228 
       **/

       /**
       * Start IKEA00694793
       **/
       if(typeof(s.events) != "undefined"){
	   	if (typeof(s.products) != "undefined") {
			if (s.products.substr(0, 2) == ";S" && (s.events.substr(s.events.lastIndexOf(",") + 1) == "event17" || s.events == "event17")) {
				s.products = ";" + s.products.substr(2, s.products.length);
			}
		}
       }
       /**
       * End IKEA00694793
       **/
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function omnitureAddLinkTrack(varName) {
	var __funcName__ = "omnitureExecute";

	try {
		if (! irwstatCheckLocalFlag("addAllPropsAndEvents")) {
			return;
		}
		
		varName = varName.replace(/s./g, "");
				
		if (((varName.substr(0, 5) == "event") && (varName.substr(0, 6) != "events")) || (varName.substr(0, 8) == "prodView")) {
			if (s.linkTrackEvents.indexOf(varName) >= 0) {
				return;
			}
			
			if (s.linkTrackEvents == "None") {
				s.linkTrackEvents = "";
			}
			
			if (s.linkTrackEvents.length >= 0) {
				s.linkTrackEvents += ",";
			}
			s.linkTrackEvents += varName;
			
			omnitureAddLinkTrack("s.events");
		} else {
			if (s.linkTrackVars.indexOf(varName) >= 0) {
				return;
			}
			
			if (s.linkTrackVars == "None") {
				s.linkTrackVars = "";
			}
		
			if (s.linkTrackVars.length > 0) {
				s.linkTrackVars += ",";
			}
			s.linkTrackVars += varName;
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function omnitureExecute() {
	var __funcName__ = "omnitureExecute";

	try {
		omnitureLastChanges();
		
		if (typeof(s.charSet) == "undefined") {
			s.charSet = "Auto";
		}
		
		// Bugfix (proxy problem)
		if (irwstats_stattype == "dev") {
			s.visitorNamespace = "irwdev";
		}
		
		if (! irwstatCheckLocalFlag("revertToLink_SET")) {
			var s_code = s.t();
			if (s_code) {
				document.write(s_code)
			}
		} else {
			var s_code = s.tl(this, "o", irwStatLocalVars["linkTrackName"]);
		
			if (s_code) {
				document.write(s_code)
			}
		}
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}

function omnitureExecuteLink() {
	var __funcName__ = "omnitureExecuteLink";

	try {
		omnitureLastChanges();
		
		if (typeof(s.charSet) == "undefined") {
			s.charSet = "Auto";
		}
		
		// Bugfix (proxy problem)
		if (irwstats_stattype == "dev") {
			s.visitorNamespace = "irwdev";
		}
		
		delete(s.pageName);
		var s_code = s.tl(this, arguments[0], arguments[1]);
		if (s_code) {
			document.write(s_code)
		}
		
		irwstatClearLocalData();
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}


function trim (myString)
{
return myString.replace(/^s+/g,'').replace(/s+$/g,'')
}

function irwStatDynamicListFiltered(listName, filterName) {
	var __funcName__ = "irwStatDynamicListFiltered";
	try {
		// For now don't send pagefunctionality since there is no global english text available
		// irwstatAddMetaTag("IRWStats.pagefunctionality", s.prop2 + ">" + listName.toLowerCase() + ">" + filterName.toLowerCase());
      var suffix = ">filter";
      if (s.pageName != null && !s.pageName.endsWith(suffix)) {
	      irwstatAddMetaTag("IRWStats.pageName", s.pageName + suffix);
	    }
      irwstatSend();
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}


// Added by Ramge Presentation
// Process stock check statistics in PIP page
function irwStatStockCheckFromPIP() {
	var __funcName__ = "irwStatStockCheckFromPIP";
	try {
		if (arguments.length < 2) {
			return;
		}
		
		var actionName = "stock check from pip";
		s.prop11 = arguments[0].toLowerCase();		
		s.prop10 = arguments[1];
		s.prop12 = s.products.substring(1);		
		irwstatOmnitureAddEvent("event6");
		irwstatOmnitureAddEvent("event25");
		s.linkTrackVars = "prop10,prop11,prop12,eVar10,eVar11,eVar12,products,events";
		
		if(irwstatCheckLocalFlag("stockChkPressed")) {
		    s.eVar28 = "+1";
			s.linkTrackVars = "prop10,prop11,prop12,eVar10,eVar11,eVar12,eVar28,products,events";				
			irwstatOmnitureAddEvent("event26");
			s.linkTrackEvents = "event6,event25,event26";
		} else {		    
			s.linkTrackEvents = "event6,event25";
		}
		//Used in next page to identify stock check has already done from pip	
		irwstatSetTrailingTag("IRWStats.stockCheckPerformed", "yes");
		
		omnitureExecuteLink("o", actionName);					
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}


// Send stock check notification statistics
function irwStatStockCheckNotification() {
	var __funcName__ = "irwStatStockCheckNotification";
	try {
		if (arguments.length < 1) {
			return;
		}
		
		var actionName = "stock check notification";
		s.prop13 = arguments[0].toLowerCase();		
		
		irwstatOmnitureAddEvent("event7");		
		s.linkTrackVars = "prop13,eVar13,events,products";	
		s.linkTrackEvents = "event7";
	
				
	omnitureExecuteLink("o", actionName);					
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}
}
// Added by Range Presentation
// Sends download event
function irwStatDownload(link) {
	var __funcName__ = "irwStatDownload";
	try {
		irwstatOmnitureAddEvent("event5");
		s.prop9 = link.href;
		s.eVar9 = link.href;
		s.linkTrackVars = "prop9,eVar9,events";				
		s.linkTrackEvents = "event5";
		omnitureExecuteLink("d", link.name);
	} catch(e) {
		irwstatHandleError(e, __funcName__);
	}	
}


//  Tooltip script which pops up a layer with content when an object is hovered and also follows the mouse
//  The script is using objects and methods in the prototype and scriptacolous library, so these need to be included before this script.
//  Creator: Jake (jbnn) && Sigge (sfid)
//  Date: 090107 - 090204
var tooltip;
var globalProdId;
var windowHeight;
/**
 * Add event observer to check all a-tags for the rel attribute, 
 * which holds the link to the Big img.
 */
Event.observe(window, 'load', function() {
    var tipId = 'bigImg';
    var tipDelay;
    var tipTimeout = 20;     // Fix  to get correct positioning on first mouseover
    var prodInfoDelay;
	var isOvered = false;
	
    tooltip = IkeaPopup();
	windowHeight = document.body.clientHeight;
    // Check if container exists first
    if($('productsContainer') != null) {
        if(!ie) {
            $('productsContainer').observe('mousemove',function(evt){tooltip.globalEvent = evt;});
        }
        $('productsContainer').observe('mouseover', function(event){
			if(!isOvered){
            $$('#productsContainer a[rel]').each(function(element) {
                var prodId = element.down('img').readAttribute('id');
                $(prodId).observe('mouseover', function(event){
                    globalProdId = prodId;
                    clearTimeout(tipDelay);
                    // Change timeout to correct value when div created
                    if($(tipId) != null){
                        tipTimeout = 400;
                    }
                    tipDelay = setTimeout(function(){tooltip.createToolTip(element.rel,'','',$(prodId),tipId)},tipTimeout);
                    // This is for IE6. If there are select dropdowns these need to be hidden, else they will render through this popup layer
                    tagVisibility('SELECT','hide');
                });
                $(prodId).observe('mouseout', function(event){
                    clearTimeout(tipDelay);
                    tooltip.hide();
                    tagVisibility('SELECT','show');
                });
            });
			isOvered = true;
            }		
        });
        addProductEvts();
    }
});
/**
* Object for common IKEA JS popup and tooltip handling
*/
function IkeaPopup(){
    var cssClass = 'tt';
    var top = 5;    // tooltip offset top
    var left = 1;   // tooltip offset left
    var tt,h;
    var ie = document.all ? true : false;
    var contentHolderId;
    var globalEvent;
    return{
     /**
     * Creates a JS popup layer to be populated with content
     * 
     * @param _width  The width in pixels for the popup
     * @param _height  The height in pixels for the popup
     * @param _id      The ID that will be given to the div that holds the content of the popup
     * @param _ownerObj   The prototype DOM element that the popup will align to
         * @param _offsetX    The x position of the popup related to the _ownerObj
         * @param _offsetY     The y position of the popup related to the _ownerObj
     * @return    Nothing
     */
         createGenericPopup:function(_width,_height,_id,_class,_ownerObj,_offsetX,_offsetY,setOuterLayout){
            var col1, col2, ttCont;         
			if(tt == null){
				contentHolderId = _id;
				if(setOuterLayout == null) {					
					tt = new Element('div', {'id': _id, 'class': _class + ' shadow-one' });
					conA = new Element('div', {'class': 'corner-a'});
					tt.insert(conA);
					conB = new Element('div', {'class': 'corner-b'});
					tt.insert(conB);
				
					shadow2 = new Element('div', {'class': 'shadow-two'});
					tt.insert(shadow2);
					shadow3 = new Element('div', {'class': 'shadow-three'});
					shadow2.insert(shadow3);
					shadow4 = new Element('div', {'class': 'shadow-four'});
					shadow3.insert(shadow4); 
				}else{
				    tt = new Element('div', {'id': _id, 'class': _class +' outerPopupContainer' });
					topShadow = new Element('div', {'class': 'divPopupTop'});
					tt.insert(topShadow);
				  	midShadow = new Element('div', {'class': 'divPopupMid'});
					tt.insert(midShadow);
					botShadow = new Element('div', {'class': 'divPopupBottom'});
					tt.insert(botShadow);
				}
				document.body.insert(tt);
            }
            tt.setOpacity(0);
            tt.show();
            tt.style.height = _height ? _height + 'px' : 'auto';            
            tt.style.width = _width ? _width + 'px' : 'auto';
            tt.style.border='none';
            if(setOuterLayout == null) {
				pos = _ownerObj.cumulativeOffset();			
				tt.style.top = pos.top + _offsetY + 'px';
				tt.style.left = pos.left + _offsetX + 'px';
			}else{
				var arr = $(_ownerObj).positionedOffset();
				var dimensions = $('thumpPopup').getDimensions(); 
				tt.style.top = arr[1] - dimensions.height + 'px';
				tt.style.left = arr[0] -55 + 'px';
			}
			
            if(!ie){
				new Effect.Opacity(tt,{
					from: 0.0,
					to: 1.0,
					duration: 0.4
				});
			}else{
				tt.setOpacity(1);
			}
        },
setDynamicHeight:function(_ownerObj,popupId){
	var dimensions = $(popupId).getDimensions();
	var arr = $(_ownerObj).positionedOffset(); 
	var popHeight = dimensions.height -10;
	$(popupId).style.top = arr[1] - popHeight + 'px';
},
createGenericPopupNew:function(_width,_height,_id,_class,_ownerObj,_offsetX,_offsetY){
            var col1, col2, ttCont;
            
			if(tt == null){
                contentHolderId = _id;
                tt = new Element('div', {'id': _id, 'class': _class + ' shadow-one' });
                conA = new Element('div', {'class': 'corner-a'});
                tt.insert(conA);
				conB = new Element('div', {'class': 'corner-b'});
                tt.insert(conB);
				
                shadow2 = new Element('div', {'class': 'shadow-two'});
                tt.insert(shadow2);
				shadow3 = new Element('div', {'class': 'shadow-three'});
                shadow2.insert(shadow3);
				shadow4 = new Element('div', {'class': 'shadow-four'});
                shadow3.insert(shadow4);                
                document.body.insert(tt);
            }
		_ownerObj.observe('mousemove', this.pos);
            tt.setOpacity(0);
            tt.show();
			 h = parseInt(tt.offsetHeight) + top;
            tt.style.height = _height ? _height + 'px' : 'auto';            
            tt.style.width = _width ? _width + 'px' : 'auto';
            tt.style.border='none';
            pos = _ownerObj.cumulativeOffset();
				
			
             if(!ie && Prototype.Browser.WebKit){
				new Effect.Opacity(tt,{
					from: 0.0,
					to: 1.0,
					duration: 0.4
				});
			}else{
				tt.setOpacity(1);
			}
        },
	 /**
     * Creates a JS tooltip that follows the mousepointer
     * 
     * @param width  The width in pixels for the tooltip
     * @param height  The height in pixels for the tooltip
     * @param objId  The prototype DOM element that the tooltip will align to
     * @param ttId  The ID that will be given to the div that holds the content of the tooltip
     * @return   Nothing
     */
        createToolTip:function(content,width,height,objId,ttId){
            var img, imgAttr, col1, col2, ttCont, prodInfoCont;
            if(tt == null){
                tt = new Element('div', {'id': ttId, 'class': cssClass});
                col1 = new Element('div', {'class': 'offset color1'});
                tt.insert(col1);
                col2 = new Element('div', {'class': 'offset color2'});
                col1.insert(col2);
                ttCont = new Element('div', {'class': 'offset ttContainer'});
                col2.insert(ttCont);
                img = new Element('img', {'id': 'bigViewImg' ,'class': 'bigView'});
                ttCont.insert(img);
                imgAttr = new Element('div', {'id': 'bigImgAttributes'});
                ttCont.insert(imgAttr);
                document.body.insert(tt);
            }
            objId.observe('mousemove', this.pos);
            tt.setOpacity(0);
            // Update content in tooltip
            $('bigViewImg').replace('<img src="' + content +'" id="bigViewImg" class="bigView" />');
            try {
                prodInfoCont = objId.up('.colProduct').down('.prodInfoContainer').adjacent('.prodInfo');
                $('bigImgAttributes').update();
                prodInfoCont.each(function(element){
                    $('bigImgAttributes').insert(element.cloneNode(true));
                });
            }
			catch(e){
                $('bigImgAttributes').setStyle({ margin: '0', padding: '0' });
            };
            tt.show();
            tt.style.width = width ? width + 'px' : 'auto';
            if(!width && ie){
                tt.style.width = tt.offsetWidth;
            }
            h = parseInt(tt.offsetHeight) + top;
            new Effect.Opacity(tt,{
                from: 0.0,
                to: 1.0,
                duration: 0.4
            });
            if(!ie) setTimeout("tooltip.refreshPos();",10);
        },
        /**
        * Aligns the popup to a given Prototype DOM element
        *
        * @param objId  The Prototype DOM element that the popup will align with
        * @return   Nothing
        */
        alignToObject:function(objId){
            var pos, left, top;
            // Get the position of the specified obj
            pos = objId.cumulativeOffset();
            left = pos.left;
            top = pos.top;
            // Set position
            layerHeight = tt.getHeight();
            top = top - layerHeight - 5;
            left = left - 32;
            // Move the layer 
            tt.style.top = top + 'px';
            tt.style.left = left + 'px';
            tt.show();
        },
        /**
        * Helper function to createToolTip
        *
        * @param e   Event object
        * @return   Nothing
        */
        pos:function(e){
            var u = ie ? window.event.clientY + document.documentElement.scrollTop : e.pageY;      // Get y-position of mouse
            var l = ie ? window.event.clientX + document.documentElement.scrollLeft : e.pageX;     // Get x-position of mouse
            var winW = document.viewport.getWidth();    // Get the window width
            var w = tt.getWidth();           // Get the width of the tip
			
				
			
            if((l + w) > winW){
                tt.style.left = (l - w) + 'px';
            }
			else{
                tt.style.left = (l + left) + 'px';
            }
		if($(this).tagName =="A")
			{
			 var prodIdTop = $(this).viewportOffset().top;
				if (navigator.platform.toLowerCase().indexOf('mac') != -1) 
				 {
						if(Prototype.Browser.Gecko)
						{
							tt.style.top = (u +12) + 'px';
							tt.style.left=(l-6) + 'px';
						} else if(Prototype.Browser.WebKit)
						{
							tt.style.top = (u +10) + 'px';
							tt.style.left=(l-7) + 'px';
						}
				 } 		
				else {
					if(Prototype.Browser.IE)
						{
						tt.style.top = (u +15) + 'px';
						tt.style.left=(l-8)+'px';
						}
					else {
						tt.style.top = (u +17) + 'px';
						tt.style.left=(l-5)+'px';
						}
					}
			 }
			else{
			var prodIdTop = $(globalProdId).viewportOffset().top;
            if((prodIdTop) < (h -50)){
                // Move layer below mouse
                tt.style.top = (u + 25) + 'px';
            }
			else{
                // Position layer above mouse
				
                tt.style.top = (u - h) + 'px';
            }
			}
           
            //$('trace').update('this: ' + this.id + '<br/> top:' + u + '<br/> left:' + l + '<br/> prodIdTop:' + prodIdTop);
        },
        refreshPos:function() {
            tooltip.pos(tooltip.globalEvent);
        },
        /**
        * Updates the content in the popup
        *
        * @param layoutString A string with a valid HTML snippet
        * @return    Nothing
        */
		setGenericContent:function(layoutString, targetClass) {
			
			if(targetClass == null){
				tt.down('.shadow-four').update(layoutString);
			}else{
				tt.down(targetClass).update(layoutString);
			}
		},
        /**
		* Returns a prototype object that holds the content of the popup
		* @return  A prototype object that holds the content of the popup
		*/
		getContent:function() {
		   return tt;
		},
		/**
		* Generates a layout with a spinning circle. Handy when loading ajax.
		*/
		generateLoadingLayout:function(){
		   var retString = "<div class=\"content\" style=\"text-align:center;\"><div class=\"headline\" style=\"text-align:left;\">Loading ...</div><img src=\"/ms/img/loading.gif\" /></div>";
		   return retString;
		},
		generateLoadingLayoutSaving:function(){
				   var retString = "<div class=\"content\" style=\"text-align:center;\"><div class=\"headline\" style=\"text-align:left;\">Saving ...</div><img src=\"/ms/img/loading.gif\" /></div>";
				   return retString;
		},
		/**
		* Makes the popup show the layout that informs the user that a remote call is loading.
		* Requires that a method called generateLoadingLayout that returns valid HTML layout is defined.
		* @return     false to stop link exection
		*/
		loadingPopup:function() {
		   this.setGenericContent(this.generateLoadingLayout());
		   var picDiv = tt.down('.ttContainer');
		   // picDiv.style.position = "relative";
		   // picDiv.style.left = ((parseInt(tt.getWidth()) / 2) - 16)+"px";
		   // picDiv.style.top = ((parseInt(tt.getHeight()) / 2) - 16)+"px";
		   return false;
		},
		loadingSaving:function() {
				   this.setGenericContent(this.generateLoadingLayoutSaving());
				   var picDiv = tt.down('.ttContainer');
				   // picDiv.style.position = "relative";
				   // picDiv.style.left = ((parseInt(tt.getWidth()) / 2) - 16)+"px";
				   // picDiv.style.top = ((parseInt(tt.getHeight()) / 2) - 16)+"px";
				   return false;
		},
		/**
		* Hides the popup
		*
		* @return   Nothing
		*/
        hide:function(){
            if(tt){
                tt.hide();
            }
        }
    };
};
/**
 * Creator: JBNN
 * Date: 091216
 * New functions for creating a popup div in the product listing on mouseover
 */
function showProdInfo(obj){
    var newObject = obj.down().cloneNode(true);
    var id = obj.down('.productPadding a').readAttribute('href').split('/').last();
    var offL = setProductOffset(obj).left;
    var offT = setProductOffset(obj).top;
	
    var slideshow = typeof(js_fn_SLIDE_SHOW_ENABLED) != "undefined" ? js_fn_SLIDE_SHOW_ENABLED : false;
    
    // Remove noscript tags
    var noscript = newObject.select('noscript');
    noscript.each(function(tag){tag.remove()});
    
    // Initiate the popup
    $('productPopup').clonePosition(obj,{setHeight:false, setWidth:false, offsetLeft:offL, offsetTop:offT});
    $('popupContent').update(newObject);
    if(Prototype.Browser.IE){
        $('productPopup').show();
		setTimeout(function(){checkHeight()},200);
    }
	else{
        $('productPopup').hide();
        $('productPopup').appear({duration:0.2});
		//checkHeight function called to enabled the autoscrolling of the popup
		setTimeout(function(){checkHeight()},200); 
    }
    if(slideshow){
        $('popupContent').insert('<a href="javascript:slideshow.open(\''+id+'\');" class="zoom" title="Slideshow">&nbsp;</a>');
    }
    $('productPopup').down('div.cartContainer').removeClassName('moreInfo');
    // Add events to Buy online button (if it exists) and Save to list link
    var buyOnlineBtn = $('productPopup').down('div.buttonContainer .button');
    if (typeof buyOnlineBtn != 'undefined') {
        $(buyOnlineBtn).observe('click', function(){
            removeProductEvts();
        });
    }
    var saveToListLnk = $('productPopup').down('div.buttonsContainer .listLink');
    $(saveToListLnk).observe('click', function(){
        removeProductEvts();
    });
    // Find compare container and show it
    var compareCont = $('productPopup').down('div.compare');
	if (typeof compareCont != 'undefined') {
    compareCont.style.display = 'block';
    // Find chk in container
    var cb = compareCont.down('input');
    // Force a (re)check (for IE of course)
    var objCb = obj.down('div.cartContainer .compare').down('input');
    if (objCb.checked){cb.checked = 'checked'};
    //Add click observer to the checkbox in popup that will copy values to the original objects in the product listing
    Event.observe(cb,'click',function(e) {
        var element = Event.element(e);
        var chkValue = element.checked;
        var objCb = obj.down('div.cartContainer .compare').down('input');
        var compareCont = $('display_'+objCb.id).up('div.compare');    //Get the div with the chk for display
        objCb.checked = chkValue;
        var cbDisplay = compareCont.down('input');
        cbDisplay.checked = chkValue;
        cbDisplay.stopObserving('click');
        cbDisplay.observe('click',function(e) {
            objCb.checked = this.checked;
            if(!objCb.checked){compareCont.hide()}
            updateCheckbox(objCb,false);   //Set cookie in compare.js
        });
        if(chkValue){
            compareCont.style.display = 'block';
        }
		else{
            compareCont.style.display = 'none';
        }
        updateCheckbox(objCb,false);   //Set cookie in compare.js
    }); 
    }
}

//Calculating the height of the current window, if the height of the popup is exceeding the maximum height of the window, 
//Automatic scrolling is enabled

function checkHeight(){
var newWindowHeight ;
 if($('productPopup').down != null){
  var body = document.body;
  var popUpDimensions = $('productPopup').getDimensions();
  var popUpPositions = $('productPopup').positionedOffset(); 
  newWindowHeight = popUpDimensions.height + popUpPositions.top; 
  if(newWindowHeight > windowHeight){
   window.scrollTo(100,newWindowHeight);
  }
 }
}

// Add event listeners to the productsContainer and each td
function addProductEvts(){
    if($('productPopup') != null) {
        // Add event listener to the div "productsContainer". If user goes out of the product listing area then hide the productPopup
		// for compare view the container will be 'compare'
		var container = 'productsContainer';
		if($('compare') != null){
			container = 'compare';
		}
        $(container).observe('mouseout', function(e){
            var element = Event.element(e);
            var inside = false;
            // Get the element we mouse out to
            var goToElement = (e.relatedTarget) ? e.relatedTarget : e.toElement;
            if(goToElement == null){return};
            myAncestors = goToElement.ancestors();
            // Traverses the parents of the related target (the element that the mouse goes to) and try to find the "productsContainer" or "compare"
            myAncestors.each(function(tag){
                if(tag.id == container){
                    inside = true;
                }
            });
            // If inside is false, then we have left the area...so hide the popup
            if(inside == false){
                $('productPopup').hide();
            }
        });
        // Add event listener to every td to display the productPopup
        $$('#productsTable td').each(function(td) { 
            if((!td.hasClassName('productDivider') && !td.hasClassName('compareContainer') && !td.hasClassName('noBorder') && !td.hasClassName('features'))
			 || (td.hasClassName('width2column') || td.hasClassName('width3column') || td.hasClassName('width4column'))){
                if (typeof td.down('div.popupListener') != 'undefined') {
					var popupId = td.down('div.popupListener').readAttribute('id');
					$(popupId).observe('mouseover', function(e){
						prodInfoDelay = setTimeout(function(){showProdInfo(td)},250);										
					});
					$(popupId).observe('mouseout', function(e){			     
						clearTimeout(prodInfoDelay);
					});         				
				} else {
					td.observe('mouseover', function(e){
						prodInfoDelay = setTimeout(function(){showProdInfo(td)},250);
					});
					td.observe('mouseout', function(e){
						clearTimeout(prodInfoDelay);
					});
				}
            }
        });
		
		// more listeners for compare view
		if($('compare') != null){
			$$('#productsTable td').each(function(td) { 
				 //if(td.hasClassName('width2column') || td.hasClassName('width3column') || td.hasClassName('width4column') ){
					td.observe('mouseover', function(e){	
						var element = Event.element(e);
						var inside = false;
						//alert('mouse out');
						// Get the element we mouse out to
						var goToElement = (e.relatedTarget) ? e.relatedTarget : e.toElement;
						if(goToElement == null){return};
						myAncestors = goToElement.ancestors();
						// Traverses the parents of the related target (the element that the mouse goes to) and try to find the "productPopup"
						myAncestors.each(function(tag){
							if(tag.id == 'productPopup'){
							//alert(tag.id);
								inside = true;
							}
						});
						// If inside is false, then we have left the area...so hide the popup
						if(inside == false){
							$('productPopup').hide();
						}				
				
					});         
				//}
			});
			$('productPopup').observe('mouseout',function(e) {
				var element = Event.element(e);
				var inside = false;
				//alert('mouse out');
				// Get the element we mouse out to
				var goToElement = (e.relatedTarget) ? e.relatedTarget : e.toElement;
				if(goToElement == null){return};
				myAncestors = goToElement.ancestors();
				// Traverses the parents of the related target (the element that the mouse goes to) and try to find the "productPopup"
				myAncestors.each(function(tag){
					if(tag.id == 'productPopup'){
					//alert(tag.id);
						inside = true;
					}
				});
				// If inside is false, then we have left the area...so hide the popup
				if(inside == false){
					$('productPopup').hide();
				}
			});	
		}		
    } 
}

// Remove all event listeners for the productPopup
function removeProductEvts(){    
	$$('#productsTable td').each(function(td) { 
		if((!td.hasClassName('productDivider') && !td.hasClassName('compareContainer') && !td.hasClassName('noBorder') && !td.hasClassName('features'))
		 || (td.hasClassName('width2column') || td.hasClassName('width3column') || td.hasClassName('width4column'))){
			if (typeof td.down('div.popupListener') != 'undefined') {
				var popupId = td.down('div.popupListener').readAttribute('id');		
				$(popupId).stopObserving('mouseover');
			} else {
				td.stopObserving('mouseover');
			}				
		}
	});
	if($('compare') == null) {
		$('productsContainer').stopObserving('mouseout');
	} else {		
		$('compare').stopObserving('mouseout');
		$('productPopup').stopObserving('mouseout');
		$$('#productsTable td').each(function(td) { 			
			td.stopObserving('mouseover'); 			
		});
	}
}

// Pixel fix to open all popups in correct offse
