/**
 * Main Seagull JavaScript library.
 *
 * @package seagull
 * @subpackage SGL
 */
var SGL = {
    isReady: false,
    ready: function(f) {
        // If the DOM is already ready
        if (SGL.isReady) {
            // Execute the function immediately
            if (typeof f == 'string') {
                eval(f);
            } else if (typeof f == 'function') {
                f.apply(document);
            }
        // Otherwise add the function to the wait list
        } else {
            SGL.onReadyDomEvents.push(f);
        }
    },
    onReadyDomEvents: [],
    onReadyDom: function() {
        // make sure that the DOM is not already loaded
        if (!SGL.isReady) {
            // Flag the DOM as ready
            SGL.isReady = true;

            if (SGL.onReadyDomEvents) {
                for (var i = 0, j = SGL.onReadyDomEvents.length; i < j; i++) {
                    if (typeof SGL.onReadyDomEvents[i] == 'string') {
                        eval(SGL.onReadyDomEvents[i]);
                    } else if (typeof SGL.onReadyDomEvents[i] == 'function') {
                        SGL.onReadyDomEvents[i].apply(document);
                    }
                }
                // Reset the list of functions
				SGL.onReadyDomEvents = null;
            }
        }
    }
};

/**
 *  Cross-browser onDomReady solution
 *  Dean Edwards/Matthias Miller/John Resig
 */
new function() {
    /* for Mozilla/Opera9 */
    if (document.addEventListener) {
        document.addEventListener("DOMContentLoaded", SGL.onReadyDom, false);
        return;
    }

    /* for Internet Explorer */
    /*@cc_on @*/
    /*@if (@_win32)
        document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
        var script = document.getElementById("__ie_onload");
        script.onreadystatechange = function() {
            if (this.readyState == "complete") {
                SGL.onReadyDom(); // call the onload handler
            }
        };
        return;
    /*@end @*/

    /* for Safari */
    if (/WebKit/i.test(navigator.userAgent)) { // sniff
        SGL.webkitTimer = setInterval(function() {
            if (/loaded|complete/.test(document.readyState)) {
                // Remove the timer
                clearInterval(SGL.webkitTimer);
                SGL.webkitTimer = null;
                // call the onload handler
                SGL.onReadyDom();
            }
        }, 10);
        return;
    }

    /* for other browsers */
    oldWindowOnload = window.onload || null;
    window.onload = function() {
        if (oldWindowOnload) {
            oldWindowOnload();
        }
        SGL.onReadyDom();
        return;
    }
}

// ----------
// --- BC ---
// ----------

/**
 * Used for async load of sourcefourge bloody button,
 */
function async_load()
{
    var node;
    try {
        // variable _asyncDom is set from JavaScript in the iframe
        // node = top._asyncDom.cloneNode(true); // kills Safari 1.2.4
        node = top._asyncDom;
        // try to remove the first script element, the one that
        // executed all document.writes().
        node.removeChild(node.getElementsByTagName('script')[0]);
    } catch (e) {}
    try {
        // insert DOM fragment at a DIV with id "async_demo" on current page
        document.getElementById('async_demo').appendChild(node);
    } catch (e) {
        try {
            // fallback for some non DOM compliant browsers
            document.getElementById('async_demo').innerHTML = node.innerHTML;
        } catch (e2) {};
    }
}

/**
 * Make Seagull SEF URL.
 *
 * @param object params
 *
 * @return string
 */
function makeUrl(params)
{
    var ret = SGL_JS_FRONT_CONTROLLER != ''
        ? SGL_JS_WEBROOT + '/' + SGL_JS_FRONT_CONTROLLER
        : SGL_JS_WEBROOT;
    var moduleName = params.module ? params.module : '';
    var managerName = params.manager ? params.manager : moduleName;

    switch (SGL_JS_URL_STRATEGY) {

    // make classic URL
    case 'SGL_UrlParser_ClassicStrategy':
        if (ret.charAt(ret.length - 1) != '?') {
            ret = ret + '?';
        }
        ret = ret + 'moduleName=' + escape(moduleName) + '&managerName=' + escape(managerName);
        for (x in params) {
            if (x == 'module' || x == 'manager') {
                continue;
            }
            // add param
            ret = '&' + ret + escape(x) + '=' + escape(params[x]);
        }
        break;

    // make default Seagull SEF URL
    default:
        ret = ret + '/' + escape(moduleName) + '/' + escape(managerName) + '/';
        for (x in params) {
            if (x == 'module' || x == 'manager') {
                continue;
            }
            ret = ret + escape(x) + '/' + escape(params[x]) + '/';
        }
        break;
    }
    return ret;
}

SGL.ready(function() {
    var msg = document.getElementById('broadcastMessage');
    if (msg) {
        msg.getElementsByTagName('a')[0].onclick = function() {
            msg.style.display = 'none';
        }
    }
});

String.prototype.trim = function(){ return this.replace(/^\s+|\s+$/g,'') };

/**
 * Main CSI JavaScript library.
 *
 * @package csi
 */
var CSI = {
    isReady: false,
    blockSwitch: function(hidden){
    	if(typeof hidden == 'undefined'){
    		if(document.getElementById('local').style.display == 'none'){
	    		//Mostrar
	    		CSI.mostrarBloque();
	    	} else {
	    		//Ocultar
	    		CSI.ocultarBloque();
	    	}	
    	} else {
    		if(hidden){
    			CSI.ocultarBloque();
    		} else {
    			CSI.mostrarBloque();
    		}
    	}
    },
    mostrarBloque: function(){
    	$('local').show();
    	$('main').setStyle({marginLeft: '200px'});
		$('blockSwitcher').setStyle({left: '195px',backgroundImage: 'url(' + SGL_JS_WEBROOT + '/themes/' + SGL_JS_THEME + '/images/bg/switcher_lf.gif)'});
    },
    ocultarBloque: function(){
    	$('local').hide();
    	$('main').setStyle({marginLeft: '0px'});
		$('blockSwitcher').setStyle({left: '1px',backgroundImage: 'url(' + SGL_JS_WEBROOT + '/themes/' + SGL_JS_THEME + '/images/bg/switcher_rg.gif)'});
    },
    handleCollapsibleElements: function(parentElement, triggerElement){
    	parentElement.select('.collapsible').each(
    		function(element){
    			if(element.hasClassName('collapsed')){
    				CSI.extendElement(element);
    			} else if (element.hasClassName('extended')){
    				CSI.collapseElement(element);
    			}
    		}
    	);
    	CSI.changeTriggerIcon(triggerElement);
    },
    changeTriggerIcon:function (element){
    	if(element.innerHTML == ' + info'){
    		element.innerHTML = '-';
    	} else {
    		element.innerHTML = ' + info';
    	}
    },
    extendElement: function(element){
    	element.removeClassName('collapsed');
		element.addClassName('extended');
    },
    collapseElement: function(element){
    	element.removeClassName('extended');
		element.addClassName('collapsed');
    },
    
    generateSimpleTip: function(elementToAttachToID, contentElementID, title, isElementText,vHook,vStem,showOn){
    	if(typeof $(elementToAttachToID).prototip != 'undefined' && $(elementToAttachToID).prototip != null && $(elementToAttachToID).prototip != 'undefined'){
    		$(elementToAttachToID).prototip.show();
    	} else {
    		var dummyElement;
    		if(!isElementText){
    			dummyElement = $(contentElementID);
    		} else {
    			dummyElement = contentElementID;
    		}
    					
    		if(!vHook){
    			vHook = { target: 'bottomMiddle', tip: 'topRight' };
    		}
    							
			if(!vStem){
				vStem = 'topRight';
			}
			
			if(!showOn){
				showOn = 'click';
				hideOn = { element: 'closeButton', event: 'click' };
			} else {
				hideOn = 'mouseout';
			}
			
    		new Tip(elementToAttachToID, 
				dummyElement, 
				{ 
					title : title,
					images: SGL_JS_WEBROOT + '/js/prototip/images/prototip/styles/default/',
					closeButton: true,
					showOn: showOn,
					hideOn: hideOn,
					stem: vStem,
				  	hook: vHook,
				  	offset: { x: 0, y: 5 },
				  	width: 'auto',
				  	hideOthers: true,
					hideAfter: 1
				}
			);
			$(elementToAttachToID).prototip.show();
    	}
    },
    
    translate: function (cadena){
		if(typeof CSI.Localisation != 'undefined') {
			if(CSI.Localisation[cadena]) {
				return CSI.Localisation[cadena];
			}
		}
		return '_' + cadena + '_';
	}
};


/**
 * Library to deal with AJAX requests.
 *
 * @package csi
 */
CSI.Ajax =
{
	genericErrorMessage: CSI.translate('There was a problem performing your request. Please, try again later'),
    onCompleteCallback: false,
    onLoadingCallback: false,
    onFailureCallback: false,
    sanitizeObject: function(data) {
    	var dummy = $H(data);
    	var res = new Hash();
    	dummy.each(function(item){
    		tmp = parseInt(item.key);
    		if(!isNaN(tmp)){
    			res.set(item.key,item.value);
    		}
    	});
    	return res;
    },
    buildNames: function(data){
    	data = CSI.Ajax.sanitizeObject(data);
        return $H($H($H(data).get($H(data).keys().first())).keys());   
    },
    executeCallbacks: function(){
        if(CSI.Ajax.onCompleteCallback != false && typeof CSI.Ajax.onCompleteCallback == 'function'){
            CSI.Ajax.onCompleteCallback.call(CSI.Ajax);
        }
    }
};

/**
 * Library to deal with C17 ajax requests.
 *
 * @package csi
 */
 
CSI.Ajax.Ayuda = {
    save: function (params){
        new Ajax.Request(
            makeUrl({module: 'default', action: 'saveAyuda'}),
            {
                parameters: params,
                method: 'post',
                asynchronous:true,
                evalScripts:false,
                onSuccess: function(req) {
                    var txt = req.responseText; 
                    $('helpContent').update(txt);
                    $('helpTxt').update(txt);
                    $('helpForm').hide();
                },
	            onFailure: function(){
	                $('helpForm').reset();
	                $('helpIndicator').hide();
	                alert(CSI.Ajax.genericErrorMessage);
	            },
	            onLoading: function(){
	                $('helpIndicator').show();
	            },
	            onComplete: function(){
	                $('helpIndicator').hide();
	            }
            }
        );
 	}
};

/*  Prototype JavaScript framework, version 1.6.0.2
 *  (c) 2005-2008 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/
 *
 *--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.6.0.2',

  Browser: {
    IE:     !!(window.attachEvent && !window.opera),
    Opera:  !!window.opera,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
  },

  BrowserFeatures: {
    XPath: !!document.evaluate,
    ElementExtensions: !!window.HTMLElement,
    SpecificElementExtensions:
      document.createElement('div').__proto__ &&
      document.createElement('div').__proto__ !==
        document.createElement('form').__proto__
  },

  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;


/* Based on Alex Arnell's inheritance implementation. */
var Class = {
  create: function() {
    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) {
      var subclass = function() { };
      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;
  }
};

Class.Methods = {
  addMethods: function(source) {
    var ancestor   = this.superclass && this.superclass.prototype;
    var properties = Object.keys(source);

    if (!Object.keys({ toString: true }).length)
      properties.push("toString", "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 = Object.extend((function(m) {
          return function() { return ancestor[m].apply(this, arguments) };
        })(property).wrap(method), {
          valueOf:  function() { return method },
          toString: function() { return method.toString() }
        });
      }
      this.prototype[property] = value;
    }

    return this;
  }
};

var Abstract = { };

Object.extend = function(destination, source) {
  for (var property in source)
    destination[property] = source[property];
  return destination;
};

Object.extend(Object, {
  inspect: function(object) {
    try {
      if (Object.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;
    }
  },

  toJSON: function(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 (Object.isElement(object)) return;

    var results = [];
    for (var property in object) {
      var value = Object.toJSON(object[property]);
      if (!Object.isUndefined(value))
        results.push(property.toJSON() + ': ' + value);
    }

    return '{' + results.join(', ') + '}';
  },

  toQueryString: function(object) {
    return $H(object).toQueryString();
  },

  toHTML: function(object) {
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
  },

  keys: function(object) {
    var keys = [];
    for (var property in object)
      keys.push(property);
    return keys;
  },

  values: function(object) {
    var values = [];
    for (var property in object)
      values.push(object[property]);
    return values;
  },

  clone: function(object) {
    return Object.extend({ }, object);
  },

  isElement: function(object) {
    return object && object.nodeType == 1;
  },

  isArray: function(object) {
    return object != null && typeof object == "object" &&
      'splice' in object && 'join' in object;
  },

  isHash: function(object) {
    return object instanceof Hash;
  },

  isFunction: function(object) {
    return typeof object == "function";
  },

  isString: function(object) {
    return typeof object == "string";
  },

  isNumber: function(object) {
    return typeof object == "number";
  },

  isUndefined: function(object) {
    return typeof object == "undefined";
  }
});

Object.extend(Function.prototype, {
  argumentNames: function() {
    var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
    return names.length == 1 && !names[0] ? [] : names;
  },

  bind: function() {
    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
    var __method = this, args = $A(arguments), object = args.shift();
    return function() {
      return __method.apply(object, args.concat($A(arguments)));
    }
  },

  bindAsEventListener: function() {
    var __method = this, args = $A(arguments), object = args.shift();
    return function(event) {
      return __method.apply(object, [event || window.event].concat(args));
    }
  },

  curry: function() {
    if (!arguments.length) return this;
    var __method = this, args = $A(arguments);
    return function() {
      return __method.apply(this, args.concat($A(arguments)));
    }
  },

  delay: function() {
    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
    return window.setTimeout(function() {
      return __method.apply(__method, args);
    }, timeout);
  },

  wrap: function(wrapper) {
    var __method = this;
    return function() {
      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
    }
  },

  methodize: function() {
    if (this._methodized) return this._methodized;
    var __method = this;
    return this._methodized = function() {
      return __method.apply(null, [this].concat($A(arguments)));
    };
  }
});

Function.prototype.defer = Function.prototype.delay.curry(0.01);

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"';
};

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;
  }
};

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();
      } finally {
        this.currentlyExecuting = false;
      }
    }
  }
});
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, {
  gsub: function(pattern, replacement) {
    var result = '', source = this, match;
    replacement = arguments.callee.prepareReplacement(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;
  },

  sub: function(pattern, replacement, count) {
    replacement = this.gsub.prepareReplacement(replacement);
    count = Object.isUndefined(count) ? 1 : count;

    return this.gsub(pattern, function(match) {
      if (--count < 0) return match[0];
      return replacement(match);
    });
  },

  scan: function(pattern, iterator) {
    this.gsub(pattern, iterator);
    return String(this);
  },

  truncate: function(length, truncation) {
    length = length || 30;
    truncation = Object.isUndefined(truncation) ? '...' : truncation;
    return this.length > length ?
      this.slice(0, length - truncation.length) + truncation : String(this);
  },

  strip: function() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
  },

  stripTags: function() {
    return this.replace(/<\/?[^>]+>/gi, '');
  },

  stripScripts: function() {
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
  },

  extractScripts: function() {
    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];
    });
  },

  evalScripts: function() {
    return this.extractScripts().map(function(script) { return eval(script) });
  },

  escapeHTML: function() {
    var self = arguments.callee;
    self.text.data = this;
    return self.div.innerHTML;
  },

  unescapeHTML: function() {
    var div = new Element('div');
    div.innerHTML = this.stripTags();
    return div.childNodes[0] ? (div.childNodes.length > 1 ?
      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
      div.childNodes[0].nodeValue) : '';
  },

  toQueryParams: function(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;
    });
  },

  toArray: function() {
    return this.split('');
  },

  succ: function() {
    return this.slice(0, this.length - 1) +
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  },

  times: function(count) {
    return count < 1 ? '' : new Array(count + 1).join(this);
  },

  camelize: function() {
    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;
  },

  capitalize: function() {
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  },

  underscore: function() {
    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
  },

  dasherize: function() {
    return this.gsub(/_/,'-');
  },

  inspect: function(useDoubleQuotes) {
    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
      var character = String.specialChar[match[0]];
      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
    });
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  },

  toJSON: function() {
    return this.inspect(true);
  },

  unfilterJSON: function(filter) {
    return this.sub(filter || Prototype.JSONFilter, '#{1}');
  },

  isJSON: function() {
    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);
  },

  evalJSON: function(sanitize) {
    var json = this.unfilterJSON();
    try {
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
    } catch (e) { }
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
  },

  include: function(pattern) {
    return this.indexOf(pattern) > -1;
  },

  startsWith: function(pattern) {
    return this.indexOf(pattern) === 0;
  },

  endsWith: function(pattern) {
    var d = this.length - pattern.length;
    return d >= 0 && this.lastIndexOf(pattern) === d;
  },

  empty: function() {
    return this == '';
  },

  blank: function() {
    return /^\s*$/.test(this);
  },

  interpolate: function(object, pattern) {
    return new Template(this, pattern).evaluate(object);
  }
});

if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
  escapeHTML: function() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  },
  unescapeHTML: function() {
    return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
  }
});

String.prototype.gsub.prepareReplacement = function(replacement) {
  if (Object.isFunction(replacement)) return replacement;
  var template = new Template(replacement);
  return function(match) { return template.evaluate(match) };
};

String.prototype.parseQuery = String.prototype.toQueryParams;

Object.extend(String.prototype.escapeHTML, {
  div:  document.createElement('div'),
  text: document.createTextNode('')
});

with (String.prototype.escapeHTML) div.appendChild(text);

var Template = Class.create({
  initialize: function(template, pattern) {
    this.template = template.toString();
    this.pattern = pattern || Template.Pattern;
  },

  evaluate: function(object) {
    if (Object.isFunction(object.toTemplateReplacements))
      object = object.toTemplateReplacements();

    return this.template.gsub(this.pattern, function(match) {
      if (object == null) return '';

      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].gsub('\\\\]', ']') : 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 = {
  each: function(iterator, context) {
    var index = 0;
    iterator = iterator.bind(context);
    try {
      this._each(function(value) {
        iterator(value, index++);
      });
    } catch (e) {
      if (e != $break) throw e;
    }
    return this;
  },

  eachSlice: function(number, iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var index = -number, slices = [], array = this.toArray();
    while ((index += number) < array.length)
      slices.push(array.slice(index, index+number));
    return slices.collect(iterator, context);
  },

  all: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result = true;
    this.each(function(value, index) {
      result = result && !!iterator(value, index);
      if (!result) throw $break;
    });
    return result;
  },

  any: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result = false;
    this.each(function(value, index) {
      if (result = !!iterator(value, index))
        throw $break;
    });
    return result;
  },

  collect: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var results = [];
    this.each(function(value, index) {
      results.push(iterator(value, index));
    });
    return results;
  },

  detect: function(iterator, context) {
    iterator = iterator.bind(context);
    var result;
    this.each(function(value, index) {
      if (iterator(value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  },

  findAll: function(iterator, context) {
    iterator = iterator.bind(context);
    var results = [];
    this.each(function(value, index) {
      if (iterator(value, index))
        results.push(value);
    });
    return results;
  },

  grep: function(filter, iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var results = [];

    if (Object.isString(filter))
      filter = new RegExp(filter);

    this.each(function(value, index) {
      if (filter.match(value))
        results.push(iterator(value, index));
    });
    return results;
  },

  include: function(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;
  },

  inGroupsOf: function(number, fillWith) {
    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
    return this.eachSlice(number, function(slice) {
      while(slice.length < number) slice.push(fillWith);
      return slice;
    });
  },

  inject: function(memo, iterator, context) {
    iterator = iterator.bind(context);
    this.each(function(value, index) {
      memo = iterator(memo, value, index);
    });
    return memo;
  },

  invoke: function(method) {
    var args = $A(arguments).slice(1);
    return this.map(function(value) {
      return value[method].apply(value, args);
    });
  },

  max: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator(value, index);
      if (result == null || value >= result)
        result = value;
    });
    return result;
  },

  min: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator(value, index);
      if (result == null || value < result)
        result = value;
    });
    return result;
  },

  partition: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var trues = [], falses = [];
    this.each(function(value, index) {
      (iterator(value, index) ?
        trues : falses).push(value);
    });
    return [trues, falses];
  },

  pluck: function(property) {
    var results = [];
    this.each(function(value) {
      results.push(value[property]);
    });
    return results;
  },

  reject: function(iterator, context) {
    iterator = iterator.bind(context);
    var results = [];
    this.each(function(value, index) {
      if (!iterator(value, index))
        results.push(value);
    });
    return results;
  },

  sortBy: function(iterator, context) {
    iterator = iterator.bind(context);
    return this.map(function(value, index) {
      return {value: value, criteria: iterator(value, index)};
    }).sort(function(left, right) {
      var a = left.criteria, b = right.criteria;
      return a < b ? -1 : a > b ? 1 : 0;
    }).pluck('value');
  },

  toArray: function() {
    return this.map();
  },

  zip: function() {
    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));
    });
  },

  size: function() {
    return this.toArray().length;
  },

  inspect: function() {
    return '#<Enumerable:' + this.toArray().inspect() + '>';
  }
};

Object.extend(Enumerable, {
  map:     Enumerable.collect,
  find:    Enumerable.detect,
  select:  Enumerable.findAll,
  filter:  Enumerable.findAll,
  member:  Enumerable.include,
  entries: Enumerable.toArray,
  every:   Enumerable.all,
  some:    Enumerable.any
});
function $A(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

if (Prototype.Browser.WebKit) {
  $A = function(iterable) {
    if (!iterable) return [];
    if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
        iterable.toArray) return iterable.toArray();
    var length = iterable.length || 0, results = new Array(length);
    while (length--) results[length] = iterable[length];
    return results;
  };
}

Array.from = $A;

Object.extend(Array.prototype, Enumerable);

if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
  _each: function(iterator) {
    for (var i = 0, length = this.length; i < length; i++)
      iterator(this[i]);
  },

  clear: function() {
    this.length = 0;
    return this;
  },

  first: function() {
    return this[0];
  },

  last: function() {
    return this[this.length - 1];
  },

  compact: function() {
    return this.select(function(value) {
      return value != null;
    });
  },

  flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(Object.isArray(value) ?
        value.flatten() : [value]);
    });
  },

  without: function() {
    var values = $A(arguments);
    return this.select(function(value) {
      return !values.include(value);
    });
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  reduce: function() {
    return this.length > 1 ? this : this[0];
  },

  uniq: function(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  },

  intersect: function(array) {
    return this.uniq().findAll(function(item) {
      return array.detect(function(value) { return item === value });
    });
  },

  clone: function() {
    return [].concat(this);
  },

  size: function() {
    return this.length;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  },

  toJSON: function() {
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (!Object.isUndefined(value)) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }
});

// use native browser JS 1.6 implementation if available
if (Object.isFunction(Array.prototype.forEach))
  Array.prototype._each = Array.prototype.forEach;

if (!Array.prototype.indexOf) Array.prototype.indexOf = function(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;
};

if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(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;
};

Array.prototype.toArray = Array.prototype.clone;

function $w(string) {
  if (!Object.isString(string)) return [];
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

if (Prototype.Browser.Opera){
  Array.prototype.concat = function() {
    var array = [];
    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
    for (var i = 0, length = arguments.length; i < length; i++) {
      if (Object.isArray(arguments[i])) {
        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
          array.push(arguments[i][j]);
      } else {
        array.push(arguments[i]);
      }
    }
    return array;
  };
}
Object.extend(Number.prototype, {
  toColorPart: function() {
    return this.toPaddedString(2, 16);
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  },

  toPaddedString: function(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
  },

  toJSON: function() {
    return isFinite(this) ? this.toString() : 'null';
  }
});

$w('abs round ceil floor').each(function(method){
  Number.prototype[method] = Math[method].methodize();
});
function $H(object) {
  return new Hash(object);
};

var Hash = Class.create(Enumerable, (function() {

  function toQueryPair(key, value) {
    if (Object.isUndefined(value)) return key;
    return key + '=' + encodeURIComponent(String.interpret(value));
  }

  return {
    initialize: function(object) {
      this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
    },

    _each: function(iterator) {
      for (var key in this._object) {
        var value = this._object[key], pair = [key, value];
        pair.key = key;
        pair.value = value;
        iterator(pair);
      }
    },

    set: function(key, value) {
      return this._object[key] = value;
    },

    get: function(key) {
      return this._object[key];
    },

    unset: function(key) {
      var value = this._object[key];
      delete this._object[key];
      return value;
    },

    toObject: function() {
      return Object.clone(this._object);
    },

    keys: function() {
      return this.pluck('key');
    },

    values: function() {
      return this.pluck('value');
    },

    index: function(value) {
      var match = this.detect(function(pair) {
        return pair.value === value;
      });
      return match && match.key;
    },

    merge: function(object) {
      return this.clone().update(object);
    },

    update: function(object) {
      return new Hash(object).inject(this, function(result, pair) {
        result.set(pair.key, pair.value);
        return result;
      });
    },

    toQueryString: function() {
      return this.map(function(pair) {
        var key = encodeURIComponent(pair.key), values = pair.value;

        if (values && typeof values == 'object') {
          if (Object.isArray(values))
            return values.map(toQueryPair.curry(key)).join('&');
        }
        return toQueryPair(key, values);
      }).join('&');
    },

    inspect: function() {
      return '#<Hash:{' + this.map(function(pair) {
        return pair.map(Object.inspect).join(': ');
      }).join(', ') + '}>';
    },

    toJSON: function() {
      return Object.toJSON(this.toObject());
    },

    clone: function() {
      return new Hash(this);
    }
  }
})());

Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
Hash.from = $H;
var ObjectRange = Class.create(Enumerable, {
  initialize: function(start, end, exclusive) {
    this.start = start;
    this.end = end;
    this.exclusive = exclusive;
  },

  _each: function(iterator) {
    var value = this.start;
    while (this.include(value)) {
      iterator(value);
      value = value.succ();
    }
  },

  include: function(value) {
    if (value < this.start)
      return false;
    if (this.exclusive)
      return value < this.end;
    return value <= this.end;
  }
});

var $R = function(start, end, exclusive) {
  return new ObjectRange(start, end, exclusive);
};

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)) {
      // simulate other verbs over post
      params['_method'] = this.method;
      this.method = 'post';
    }

    this.parameters = params;

    if (params = Object.toQueryString(params)) {
      // when GET, append parameters to URL
      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';
    }

    // user-defined headers
    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') {
      // avoid memory leak in MSIE: clean up
      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) {
  // DOM level 2 ECMAScript Language Binding
  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() {
  var element = this.Element;
  this.Element = function(tagName, attributes) {
    attributes = attributes || { };
    tagName = tagName.toLowerCase();
    var cache = Element.cache;
    if (Prototype.Browser.IE && 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(this.Element, element || { });
}).call(window);

Element.cache = { };

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).style.display = 'none';
    return element;
  },

  show: function(element) {
    $(element).style.display = '';
    return element;
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
    return element;
  },

  update: function(element, content) {
    element = $(element);
    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) return element.update().insert(content);
    content = Object.toHTML(content);
    element.innerHTML = content.stripScripts();
    content.evalScripts.bind(content).defer();
    return element;
  },

  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('parentNode');
  },

  descendants: function(element) {
    return $(element).select("*");
  },

  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('previousSibling');
  },

  nextSiblings: function(element) {
    return $(element).recursivelyCollect('nextSibling');
  },

  siblings: function(element) {
    element = $(element);
    return element.previousSiblings().reverse().concat(element.nextSiblings());
  },

  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();
    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();
    return Object.isNumber(expression) ? element.descendants()[expression] :
      element.select(expression)[index || 0];
  },

  previous: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
    var previousSiblings = element.previousSiblings();
    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();
    return Object.isNumber(expression) ? nextSiblings[expression] :
      Selector.findElement(nextSiblings, expression, index);
  },

  select: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element, args);
  },

  adjacent: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element.parentNode, args).without(element);
  },

  identify: function(element) {
    element = $(element);
    var id = element.readAttribute('id'), self = arguments.callee;
    if (id) return id;
    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
    element.writeAttribute('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().height;
  },

  getWidth: function(element) {
    return $(element).getDimensions().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(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(className) ?
      'removeClassName' : 'addClassName'](className);
  },

  // removes whitespace-only text node children
  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);
    var originalAncestor = ancestor;

    if (element.compareDocumentPosition)
      return (element.compareDocumentPosition(ancestor) & 8) === 8;

    if (element.sourceIndex && !Prototype.Browser.Opera) {
      var e = element.sourceIndex, a = ancestor.sourceIndex,
       nextAncestor = ancestor.nextSibling;
      if (!nextAncestor) {
        do { ancestor = ancestor.parentNode; }
        while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
      }
      if (nextAncestor && nextAncestor.sourceIndex)
       return (e > a && e < nextAncestor.sourceIndex);
    }

    while (element = element.parentNode)
      if (element == originalAncestor) return true;
    return false;
  },

  scrollTo: function(element) {
    element = $(element);
    var pos = element.cumulativeOffset();
    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) {
      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('display');
    if (display != 'none' && display != null) // Safari bug
      return {width: element.offsetWidth, height: element.offsetHeight};

    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    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';
      // Opera returns the offset relative to the positioning context, when an
      // element is position relative but top and left have not been defined
      if (window.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 == '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('position') == 'absolute') return;
    // Position.prepare(); // To be done manually by Scripty when it needs it.

    var offsets = element.positionedOffset();
    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('position') == 'relative') return;
    // Position.prepare(); // To be done manually by Scripty when it needs it.

    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);

    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;

      // Safari fix
      if (element.offsetParent == document.body &&
        Element.getStyle(element, 'position') == 'absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      if (!Prototype.Browser.Opera || element.tagName == '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] || { });

    // find page position of source
    source = $(source);
    var p = source.viewportOffset();

    // find coordinate system to use
    element = $(element);
    var delta = [0, 0];
    var parent = null;
    // delta [0,0] will do fine with position: fixed elements,
    // position:absolute needs offsetParent deltas
    if (Element.getStyle(element, 'position') == 'absolute') {
      parent = element.getOffsetParent();
      delta = parent.viewportOffset();
    }

    // correct by body offsets (fixes Safari)
    if (parent == document.body) {
      delta[0] -= document.body.offsetLeft;
      delta[1] -= document.body.offsetTop;
    }

    // set position
    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;
  }
};

Element.Methods.identify.counter = 1;

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':
          // returns '0px' for hidden elements; we want it to return null
          if (!Element.visible(element)) return null;

          // returns the border-box dimensions rather than the content-box
          // dimensions, so we subtract padding and borders from the value
          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) {
  // IE doesn't report offsets correctly for static elements, so we change them
  // to "relative" to get the values, then change them back.
  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
    function(proceed, element) {
      element = $(element);
      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);
        var position = element.getStyle('position');
        if (position !== 'static') return proceed(element);
        // Trigger hasLayout on the offset parent so that IE6 reports
        // accurate offsetTop and offsetLeft values for position: fixed.
        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.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 = {
    read: {
      names: {
        'class': 'className',
        'for':   'htmlFor'
      },
      values: {
        _getAttr: function(element, attribute) {
          return element.getAttribute(attribute, 2);
        },
        _getAttrNode: function(element, attribute) {
          var node = element.getAttributeNode(attribute);
          return node ? node.value : "";
        },
        _getEv: function(element, attribute) {
          attribute = element.getAttribute(attribute);
          return attribute ? attribute.toString().slice(23, -2) : null;
        },
        _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').each(function(attr) {
    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
  });

  (function(v) {
    Object.extend(v, {
      href:        v._getAttr,
      src:         v._getAttr,
      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);
}

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 == 'IMG' && element.width) {
        element.width++; element.width--;
      } else try {
        var n = document.createTextNode(' ');
        element.appendChild(n);
        element.removeChild(n);
      } catch (e) { }

    return element;
  };

  // Safari returns margins on body which is incorrect if the child is absolutely
  // positioned.  For performance reasons, redefine Element#cumulativeOffset for
  // KHTML/WebKit only.
  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 (Prototype.Browser.IE || Prototype.Browser.Opera) {
  // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
  Element.Methods.update = function(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 in Element._insertionTranslations.tags) {
      $A(element.childNodes).each(function(node) { element.removeChild(node) });
      Element._getContentFromAnonymousElement(tagName, content.stripScripts())
        .each(function(node) { element.appendChild(node) });
    }
    else element.innerHTML = content.stripScripts();

    content.evalScripts.bind(content).defer();
    return element;
  };
}

if ('outerHTML' in document.createElement('div')) {
  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() {
  Object.extend(this.tags, {
    THEAD: this.tags.TBODY,
    TFOOT: this.tags.TBODY,
    TH:    this.tags.TD
  });
}).call(Element._insertionTranslations);

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);

if (!Prototype.BrowserFeatures.ElementExtensions &&
    document.createElement('div').__proto__) {
  window.HTMLElement = { };
  window.HTMLElement.prototype = document.createElement('div').__proto__;
  Prototype.BrowserFeatures.ElementExtensions = true;
}

Element.extend = (function() {
  if (Prototype.BrowserFeatures.SpecificElementExtensions)
    return Prototype.K;

  var Methods = { }, ByTag = Element.Methods.ByTag;

  var extend = Object.extend(function(element) {
    if (!element || element._extendedByPrototype ||
        element.nodeType != 1 || element == window) return element;

    var methods = Object.clone(Methods),
      tagName = element.tagName, property, value;

    // extend methods for specific tags
    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);

    for (property in methods) {
      value = methods[property];
      if (Object.isFunction(value) && !(property in element))
        element[property] = value.methodize();
    }

    element._extendedByPrototype = Prototype.emptyFunction;
    return element;

  }, {
    refresh: function() {
      // extend methods for all tags (Safari doesn't need this)
      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];

    window[klass] = { };
    window[klass].prototype = document.createElement(tagName).__proto__;
    return window[klass];
  }

  if (F.ElementExtensions) {
    copy(Element.Methods, HTMLElement.prototype);
    copy(Element.Methods.Simulated, HTMLElement.prototype, 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() {
    var dimensions = { };
    var B = Prototype.Browser;
    $w('width height').each(function(d) {
      var D = d.capitalize();
      dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
        (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
    });
    return dimensions;
  },

  getWidth: function() {
    return this.getDimensions().width;
  },

  getHeight: function() {
    return this.getDimensions().height;
  },

  getScrollOffsets: function() {
    return Element._returnOffset(
      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
  }
};
/* 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();
    this.compileMatcher();
  },

  shouldUseXPath: function() {
    if (!Prototype.BrowserFeatures.XPath) return false;

    var e = this.expression;

    // Safari 3 chokes on :*-of-type and :empty
    if (Prototype.Browser.WebKit &&
     (e.include("-of-type") || e.include(":empty")))
      return false;

    // XPath can't do namespaced attributes, nor can it read
    // the "checked" property from DOM nodes
    if ((/(\[[\w-]*?:|:checked)/).test(this.expression))
      return false;

    return true;
  },

  compileMatcher: function() {
    if (this.shouldUseXPath())
      return this.compileXPathMatcher();

    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
        c = Selector.criteria, le, p, m;

    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 in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
    	      new Template(c[i]).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;

    if (Selector._cache[e]) {
      this.xpath = Selector._cache[e]; return;
    }

    this.matcher = ['.//*'];
    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        if (m = e.match(ps[i])) {
          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
            new Template(x[i]).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;
    if (this.xpath) return document._getElementsByXPath(this.xpath, root);
    return this.matcher(root);
  },

  match: function(element) {
    this.tokens = [];

    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
    var le, p, m;

    while (e && le !== e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          // use the Selector.assertions methods unless the selector
          // is too complex.
          if (as[i]) {
            this.tokens.push([i, Object.clone(m)]);
            e = e.replace(m[0], '');
          } else {
            // reluctantly do a document-wide search
            // and look for a match in the array
            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() + ">";
  }
});

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 or translate(text(), ' \t\r\n', '') = '')]",
      'checked':     "[@checked]",
      'disabled':    "[@disabled]",
      'enabled':     "[not(@disabled)]",
      'not': function(m) {
        var e = m[6], p = Selector.patterns,
            x = Selector.xpath, le, v;

        var exclusion = [];
        while (e && le != e && (/\S/).test(e)) {
          le = e;
          for (var i in p) {
            if (m = e.match(p[i])) {
              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).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: {
    // combinators must be listed first
    // (and descendant needs to be last combinator)
    laterSibling: /^\s*~\s*/,
    child:        /^\s*>\s*/,
    adjacent:     /^\s*\+\s*/,
    descendant:   /^\s/,

    // selectors follow
    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
    id:           /^#([\w\-\*]+)(\b|$)/,
    className:    /^\.([\w\-\*]+)(\b|$)/,
    pseudo:
/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
    attrPresence: /^\[([\w]+)\]/,
    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
  },

  // for Selector.match and Element#match
  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: {
    // UTILITY FUNCTIONS
    // joins two collections
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        a.push(node);
      return a;
    },

    // marks an array of nodes for counting
    mark: function(nodes) {
      var _true = Prototype.emptyFunction;
      for (var i = 0, node; node = nodes[i]; i++)
        node._countedByPrototype = _true;
      return nodes;
    },

    unmark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._countedByPrototype = undefined;
      return nodes;
    },

    // mark each child node with its position (for nth calls)
    // "ofType" flag indicates whether we're indexing for nth-of-type
    // rather than nth-child
    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++;
      }
    },

    // filters out duplicates and extends all nodes
    unique: function(nodes) {
      if (nodes.length == 0) return nodes;
      var results = [], n;
      for (var i = 0, l = nodes.length; i < l; i++)
        if (!(n = nodes[i])._countedByPrototype) {
          n._countedByPrototype = Prototype.emptyFunction;
          results.push(Element.extend(n));
        }
      return Selector.handlers.unmark(results);
    },

    // COMBINATOR FUNCTIONS
    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;
    },

    // TOKEN FUNCTIONS
    tagName: function(nodes, root, tagName, combinator) {
      var uTagName = tagName.toUpperCase();
      var results = [], h = Selector.handlers;
      if (nodes) {
        if (combinator) {
          // fastlane for ordinary descendant combinators
          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 (!targetNode) return [];
      if (!nodes && root == document) return [targetNode];
      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);
    },

    // handles the an+b logic
    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;
      });
    },

    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
    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++) {
        // IE treats comments as element nodes
        if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) 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) 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.startsWith(v); },
    '$=': function(nv, v) { return nv.endsWith(v); },
    '*=': function(nv, v) { return 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, {
    // IE returns comment nodes on getElementsByTagName("*").
    // Filter them out.
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        if (node.tagName !== "!") a.push(node);
      return a;
    },

    // IE improperly serializes _countedByPrototype in (inner|outer)HTML.
    unmark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node.removeAttribute('_countedByPrototype');
      return nodes;
    }
  });
}

function $$() {
  return Selector.findChildElements(document, $A(arguments));
}
var Form = {
  reset: function(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 != 'submit' || (!submitted &&
            submit !== false && (!submit || key == submit) && (submitted = true)))) {
          if (key in result) {
            // a key is already present; construct an array of values
            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) {
    return $A($(form).getElementsByTagName('*')).inject([],
      function(elements, child) {
        if (Form.Element.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'].include(element.tagName.toLowerCase());
    });
  },

  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'].include(element.type)))
        element.select();
    } catch (e) { }
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.blur();
    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, index) {
    if (Object.isUndefined(index))
      return this[element.type == 'select-one' ?
        'selectOne' : 'selectMany'](element);
    else {
      var opt, value, single = !Object.isArray(index);
      for (var i = 0, length = element.length; i < length; i++) {
        opt = element.options[i];
        value = this.optionValue(opt);
        if (single) {
          if (value == index) {
            opt.selected = true;
            return;
          }
        }
        else opt.selected = index.include(value);
      }
    }
  },

  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) {
    // extend element because hasAttribute may not be native
    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);
  }
});
if (!window.Event) var Event = { };

Object.extend(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: { },

  relatedTarget: function(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);
  }
});

Event.Methods = (function() {
  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);
    };
  }

  return {
    isLeftClick:   function(event) { return isButton(event, 0) },
    isMiddleClick: function(event) { return isButton(event, 1) },
    isRightClick:  function(event) { return isButton(event, 2) },

    element: function(event) {
      var node = Event.extend(event).target;
      return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
    },

    findElement: function(event, expression) {
      var element = Event.element(event);
      if (!expression) return element;
      var elements = [element].concat(element.ancestors());
      return Selector.findElement(elements, expression, 0);
    },

    pointer: function(event) {
      return {
        x: event.pageX || (event.clientX +
          (document.documentElement.scrollLeft || document.body.scrollLeft)),
        y: event.pageY || (event.clientY +
          (document.documentElement.scrollTop || document.body.scrollTop))
      };
    },

    pointerX: function(event) { return Event.pointer(event).x },
    pointerY: function(event) { return Event.pointer(event).y },

    stop: function(event) {
      Event.extend(event);
      event.preventDefault();
      event.stopPropagation();
      event.stopped = true;
    }
  };
})();

Event.extend = (function() {
  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
    m[name] = Event.Methods[name].methodize();
    return m;
  });

  if (Prototype.Browser.IE) {
    Object.extend(methods, {
      stopPropagation: function() { this.cancelBubble = true },
      preventDefault:  function() { this.returnValue = false },
      inspect: function() { return "[object Event]" }
    });

    return function(event) {
      if (!event) return false;
      if (event._extendedByPrototype) return event;

      event._extendedByPrototype = Prototype.emptyFunction;
      var pointer = Event.pointer(event);
      Object.extend(event, {
        target: event.srcElement,
        relatedTarget: Event.relatedTarget(event),
        pageX:  pointer.x,
        pageY:  pointer.y
      });
      return Object.extend(event, methods);
    };

  } else {
    Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
    Object.extend(Event.prototype, methods);
    return Prototype.K;
  }
})();

Object.extend(Event, (function() {
  var cache = Event.cache;

  function getEventID(element) {
    if (element._prototypeEventID) return element._prototypeEventID[0];
    arguments.callee.id = arguments.callee.id || 1;
    return element._prototypeEventID = [++arguments.callee.id];
  }

  function getDOMEventName(eventName) {
    if (eventName && eventName.include(':')) return "dataavailable";
    return eventName;
  }

  function getCacheForID(id) {
    return cache[id] = cache[id] || { };
  }

  function getWrappersForEventName(id, eventName) {
    var c = getCacheForID(id);
    return c[eventName] = c[eventName] || [];
  }

  function createWrapper(element, eventName, handler) {
    var id = getEventID(element);
    var c = getWrappersForEventName(id, eventName);
    if (c.pluck("handler").include(handler)) return false;

    var wrapper = function(event) {
      if (!Event || !Event.extend ||
        (event.eventName && event.eventName != eventName))
          return false;

      Event.extend(event);
      handler.call(element, event);
    };

    wrapper.handler = handler;
    c.push(wrapper);
    return wrapper;
  }

  function findWrapper(id, eventName, handler) {
    var c = getWrappersForEventName(id, eventName);
    return c.find(function(wrapper) { return wrapper.handler == handler });
  }

  function destroyWrapper(id, eventName, handler) {
    var c = getCacheForID(id);
    if (!c[eventName]) return false;
    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
  }

  function destroyCache() {
    for (var id in cache)
      for (var eventName in cache[id])
        cache[id][eventName] = null;
  }

  if (window.attachEvent) {
    window.attachEvent("onunload", destroyCache);
  }

  return {
    observe: function(element, eventName, handler) {
      element = $(element);
      var name = getDOMEventName(eventName);

      var wrapper = createWrapper(element, eventName, handler);
      if (!wrapper) return element;

      if (element.addEventListener) {
        element.addEventListener(name, wrapper, false);
      } else {
        element.attachEvent("on" + name, wrapper);
      }

      return element;
    },

    stopObserving: function(element, eventName, handler) {
      element = $(element);
      var id = getEventID(element), name = getDOMEventName(eventName);

      if (!handler && eventName) {
        getWrappersForEventName(id, eventName).each(function(wrapper) {
          element.stopObserving(eventName, wrapper.handler);
        });
        return element;

      } else if (!eventName) {
        Object.keys(getCacheForID(id)).each(function(eventName) {
          element.stopObserving(eventName);
        });
        return element;
      }

      var wrapper = findWrapper(id, eventName, handler);
      if (!wrapper) return element;

      if (element.removeEventListener) {
        element.removeEventListener(name, wrapper, false);
      } else {
        element.detachEvent("on" + name, wrapper);
      }

      destroyWrapper(id, eventName, handler);

      return element;
    },

    fire: function(element, eventName, memo) {
      element = $(element);
      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 = "ondataavailable";
      }

      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);

Element.addMethods({
  fire:          Event.fire,
  observe:       Event.observe,
  stopObserving: Event.stopObserving
});

Object.extend(document, {
  fire:          Element.Methods.fire.methodize(),
  observe:       Element.Methods.observe.methodize(),
  stopObserving: Element.Methods.stopObserving.methodize(),
  loaded:        false
});

(function() {
  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
     Matthias Miller, Dean Edwards and John Resig. */

  var timer;

  function fireContentLoadedEvent() {
    if (document.loaded) return;
    if (timer) window.clearInterval(timer);
    document.fire("dom:loaded");
    document.loaded = true;
  }

  if (document.addEventListener) {
    if (Prototype.Browser.WebKit) {
      timer = window.setInterval(function() {
        if (/loaded|complete/.test(document.readyState))
          fireContentLoadedEvent();
      }, 0);

      Event.observe(window, "load", fireContentLoadedEvent);

    } else {
      document.addEventListener("DOMContentLoaded",
        fireContentLoadedEvent, false);
    }

  } else {
    document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
    $("__onDOMContentLoaded").onreadystatechange = function() {
      if (this.readyState == "complete") {
        this.onreadystatechange = null;
        fireContentLoadedEvent();
      }
    };
  }
})();
/*------------------------------- 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');

// This should be moved to script.aculo.us; notice the deprecated methods
// further below, that map to the newer Element methods.
var Position = {
  // set to true if needed, warning: firefox performance problems
  // NOT neeeded for page scrolling, only if draggable contained in
  // scrollable elements
  includeScrollOffsets: false,

  // must be called before calling withinIncludingScrolloffset, every time the
  // page is scrolled
  prepare: function() {
    this.deltaX =  window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0;
    this.deltaY =  window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0;
  },

  // caches x/y coordinate pair to use with overlap
  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);
  },

  // within must be called directly before
  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;
  },

  // Deprecation layer -- use newer Element methods now (1.5.2).

  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);

/*--------------------------------------------------------------------------*/

Element.addMethods();

// LiveValidation 1.3 (prototype.js version)
// Copyright (c) 2007-2008 Alec Hill (www.livevalidation.com)
// LiveValidation is licensed under the terms of the MIT License
var LiveValidation=Class.create();Object.extend(LiveValidation,{VERSION:"1.3 prototype",TEXTAREA:1,TEXT:2,PASSWORD:3,CHECKBOX:4,SELECT:5,FILE:6,massValidate:function(C){var D=true;for(var B=0,A=C.length;B<A;++B){var E=C[B].validate();if(D){D=E;}}return D;}});LiveValidation.prototype={validClass:"LV_valid",invalidClass:"LV_invalid",messageClass:"LV_validation_message",validFieldClass:"LV_valid_field",invalidFieldClass:"LV_invalid_field",initialize:function(B,A){if(!B){throw new Error("LiveValidation::initialize - No element reference or element id has been provided!");}this.element=$(B);if(!this.element){throw new Error("LiveValidation::initialize - No element with reference or id of '"+B+"' exists!");}this.elementType=this.getElementType();this.validations=[];this.form=this.element.form;this.options=Object.extend({validMessage:"Thankyou!",onValid:function(){this.insertMessage(this.createMessageSpan());this.addFieldClass();},onInvalid:function(){this.insertMessage(this.createMessageSpan());this.addFieldClass();},insertAfterWhatNode:this.element,onlyOnBlur:false,wait:0,onlyOnSubmit:false},A||{});var C=this.options.insertAfterWhatNode||this.element;this.options.insertAfterWhatNode=$(C);Object.extend(this,this.options);if(this.form){this.formObj=LiveValidationForm.getInstance(this.form);this.formObj.addField(this);}this.boundFocus=this.doOnFocus.bindAsEventListener(this);Event.observe(this.element,"focus",this.boundFocus);if(!this.onlyOnSubmit){switch(this.elementType){case LiveValidation.CHECKBOX:this.boundClick=this.validate.bindAsEventListener(this);Event.observe(this.element,"click",this.boundClick);case LiveValidation.SELECT:case LiveValidation.FILE:this.boundChange=this.validate.bindAsEventListener(this);Event.observe(this.element,"change",this.boundChange);break;default:if(!this.onlyOnBlur){this.boundKeyup=this.deferValidation.bindAsEventListener(this);Event.observe(this.element,"keyup",this.boundKeyup);}this.boundBlur=this.validate.bindAsEventListener(this);Event.observe(this.element,"blur",this.boundBlur);}}},destroy:function(){if(this.formObj){this.formObj.removeField(this);this.formObj.destroy();}Event.stopObserving(this.element,"focus",this.boundFocus);if(!this.onlyOnSubmit){switch(this.elementType){case LiveValidation.CHECKBOX:Event.stopObserving(this.element,"click",this.boundClick);case LiveValidation.SELECT:case LiveValidation.FILE:Event.stopObserving(this.element,"change",this.boundChange);break;default:if(!this.onlyOnBlur){Event.stopObserving(this.element,"keyup",this.boundKeyup);}Event.stopObserving(this.element,"blur",this.boundBlur);}}this.validations=[];this.removeMessageAndFieldClass();},add:function(A,B){this.validations.push({type:A,params:B||{}});return this;},remove:function(A,B){this.validations=this.validations.reject(function(C){return(C.type==A&&C.params==B);});return this;},deferValidation:function(A){if(this.wait>=300){this.removeMessageAndFieldClass();}if(this.timeout){clearTimeout(this.timeout);}this.timeout=setTimeout(this.validate.bind(this),this.wait);},doOnBlur:function(){this.focused=false;this.validate();},doOnFocus:function(){this.focused=true;this.removeMessageAndFieldClass();},getElementType:function(){switch(true){case (this.element.nodeName.toUpperCase()=="TEXTAREA"):return LiveValidation.TEXTAREA;case (this.element.nodeName.toUpperCase()=="INPUT"&&this.element.type.toUpperCase()=="TEXT"):return LiveValidation.TEXT;case (this.element.nodeName.toUpperCase()=="INPUT"&&this.element.type.toUpperCase()=="PASSWORD"):return LiveValidation.PASSWORD;case (this.element.nodeName.toUpperCase()=="INPUT"&&this.element.type.toUpperCase()=="CHECKBOX"):return LiveValidation.CHECKBOX;case (this.element.nodeName.toUpperCase()=="INPUT"&&this.element.type.toUpperCase()=="FILE"):return LiveValidation.FILE;case (this.element.nodeName.toUpperCase()=="SELECT"):return LiveValidation.SELECT;case (this.element.nodeName.toUpperCase()=="INPUT"):throw new Error("LiveValidation::getElementType - Cannot use LiveValidation on an "+this.element.type+" input!");default:throw new Error("LiveValidation::getElementType - Element must be an input, select, or textarea!");}},doValidations:function(){this.validationFailed=false;for(var C=0,A=this.validations.length;C<A;++C){var B=this.validations[C];switch(B.type){case Validate.Presence:case Validate.Confirmation:case Validate.Acceptance:this.displayMessageWhenEmpty=true;this.validationFailed=!this.validateElement(B.type,B.params);break;default:this.validationFailed=!this.validateElement(B.type,B.params);break;}if(this.validationFailed){return false;}}this.message=this.validMessage;return true;},validateElement:function(A,C){var D=(this.elementType==LiveValidation.SELECT)?this.element.options[this.element.selectedIndex].value:this.element.value;if(A==Validate.Acceptance){if(this.elementType!=LiveValidation.CHECKBOX){throw new Error("LiveValidation::validateElement - Element to validate acceptance must be a checkbox!");}D=this.element.checked;}var E=true;try{A(D,C);}catch(B){if(B instanceof Validate.Error){if(D!==""||(D===""&&this.displayMessageWhenEmpty)){this.validationFailed=true;this.message=B.message;E=false;}}else{throw B;}}finally{return E;}},validate:function(){if(!this.element.disabled){var A=this.doValidations();if(A){this.onValid();return true;}else{this.onInvalid();return false;}}else{return true;}},enable:function(){this.element.disabled=false;return this;},disable:function(){this.element.disabled=true;this.removeMessageAndFieldClass();return this;},createMessageSpan:function(){var A=document.createElement("span");var B=document.createTextNode(this.message);A.appendChild(B);return A;},insertMessage:function(B){this.removeMessage();var A=this.validationFailed?this.invalidClass:this.validClass;if((this.displayMessageWhenEmpty&&(this.elementType==LiveValidation.CHECKBOX||this.element.value==""))||this.element.value!=""){$(B).addClassName(this.messageClass+(" "+A));if(nxtSibling=this.insertAfterWhatNode.nextSibling){this.insertAfterWhatNode.parentNode.insertBefore(B,nxtSibling);}else{this.insertAfterWhatNode.parentNode.appendChild(B);}}},addFieldClass:function(){this.removeFieldClass();if(!this.validationFailed){if(this.displayMessageWhenEmpty||this.element.value!=""){if(!this.element.hasClassName(this.validFieldClass)){this.element.addClassName(this.validFieldClass);}}}else{if(!this.element.hasClassName(this.invalidFieldClass)){this.element.addClassName(this.invalidFieldClass);}}},removeMessage:function(){if(nxtEl=this.insertAfterWhatNode.next("."+this.messageClass)){nxtEl.remove();}},removeFieldClass:function(){this.element.removeClassName(this.invalidFieldClass);this.element.removeClassName(this.validFieldClass);},removeMessageAndFieldClass:function(){this.removeMessage();this.removeFieldClass();}};var LiveValidationForm=Class.create();Object.extend(LiveValidationForm,{instances:{},getInstance:function(A){var B=Math.random()*Math.random();if(!A.id){A.id="formId_"+B.toString().replace(/\./,"")+new Date().valueOf();}if(!LiveValidationForm.instances[A.id]){LiveValidationForm.instances[A.id]=new LiveValidationForm(A);}return LiveValidationForm.instances[A.id];}});LiveValidationForm.prototype={initialize:function(A){this.element=$(A);this.fields=[];this.oldOnSubmit=this.element.onsubmit||function(){};this.element.onsubmit=function(C){var B=(LiveValidation.massValidate(this.fields))?this.oldOnSubmit.call(this.element,C)!==false:false;if(!B){Event.stop(C);}}.bindAsEventListener(this);},addField:function(A){this.fields.push(A);},removeField:function(A){this.fields=this.fields.without(A);},destroy:function(A){if(this.fields.length!=0&&!A){return false;}this.element.onsubmit=this.oldOnSubmit;LiveValidationForm.instances[this.element.id]=null;return true;}};var Validate={Presence:function(A,B){var C=Object.extend({failureMessage:"Can't be empty!"},B||{});if(A===""||A===null||A===undefined){Validate.fail(C.failureMessage);}return true;},Numericality:function(B,C){var A=B;var B=Number(B);var C=C||{};var D={notANumberMessage:C.notANumberMessage||"Must be a number!",notAnIntegerMessage:C.notAnIntegerMessage||"Must be an integer!",wrongNumberMessage:C.wrongNumberMessage||"Must be "+C.is+"!",tooLowMessage:C.tooLowMessage||"Must not be less than "+C.minimum+"!",tooHighMessage:C.tooHighMessage||"Must not be more than "+C.maximum+"!",is:((C.is)||(C.is==0))?C.is:null,minimum:((C.minimum)||(C.minimum==0))?C.minimum:null,maximum:((C.maximum)||(C.maximum==0))?C.maximum:null,onlyInteger:C.onlyInteger||false};if(!isFinite(B)){Validate.fail(D.notANumberMessage);}if(D.onlyInteger&&((/\.0+$|\.$/.test(String(A)))||(B!=parseInt(B)))){Validate.fail(D.notAnIntegerMessage);}switch(true){case (D.is!==null):if(B!=Number(D.is)){Validate.fail(D.wrongNumberMessage);}break;case (D.minimum!==null&&D.maximum!==null):Validate.Numericality(B,{tooLowMessage:D.tooLowMessage,minimum:D.minimum});Validate.Numericality(B,{tooHighMessage:D.tooHighMessage,maximum:D.maximum});break;case (D.minimum!==null):if(B<Number(D.minimum)){Validate.fail(D.tooLowMessage);}break;case (D.maximum!==null):if(B>Number(D.maximum)){Validate.fail(D.tooHighMessage);}break;}return true;},Format:function(A,B){var A=String(A);var C=Object.extend({failureMessage:"Not valid!",pattern:/./,negate:false},B||{});if(!C.negate&&!C.pattern.test(A)){Validate.fail(C.failureMessage);}if(C.negate&&C.pattern.test(A)){Validate.fail(C.failureMessage);}return true;},Email:function(A,B){var C=Object.extend({failureMessage:"Must be a valid email address!"},B||{});Validate.Format(A,{failureMessage:C.failureMessage,pattern:/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i});return true;},Length:function(A,B){var A=String(A);var B=B||{};var C={wrongLengthMessage:B.wrongLengthMessage||"Must be "+B.is+" characters long!",tooShortMessage:B.tooShortMessage||"Must not be less than "+B.minimum+" characters long!",tooLongMessage:B.tooLongMessage||"Must not be more than "+B.maximum+" characters long!",is:((B.is)||(B.is==0))?B.is:null,minimum:((B.minimum)||(B.minimum==0))?B.minimum:null,maximum:((B.maximum)||(B.maximum==0))?B.maximum:null};switch(true){case (C.is!==null):if(A.length!=Number(C.is)){Validate.fail(C.wrongLengthMessage);}break;case (C.minimum!==null&&C.maximum!==null):Validate.Length(A,{tooShortMessage:C.tooShortMessage,minimum:C.minimum});Validate.Length(A,{tooLongMessage:C.tooLongMessage,maximum:C.maximum});break;case (C.minimum!==null):if(A.length<Number(C.minimum)){Validate.fail(C.tooShortMessage);}break;case (C.maximum!==null):if(A.length>Number(C.maximum)){Validate.fail(C.tooLongMessage);}break;default:throw new Error("Validate::Length - Length(s) to validate against must be provided!");}return true;},Inclusion:function(C,D){var E=Object.extend({failureMessage:"Must be included in the list!",within:[],allowNull:false,partialMatch:false,caseSensitive:true,negate:false},D||{});if(E.allowNull&&C==null){return true;}if(!E.allowNull&&C==null){Validate.fail(E.failureMessage);}if(!E.caseSensitive){var A=[];E.within.each(function(F){if(typeof F=="string"){F=F.toLowerCase();}A.push(F);});E.within=A;if(typeof C=="string"){C=C.toLowerCase();}}var B=(E.within.indexOf(C)==-1)?false:true;if(E.partialMatch){B=false;E.within.each(function(F){if(C.indexOf(F)!=-1){B=true;}});}if((!E.negate&&!B)||(E.negate&&B)){Validate.fail(E.failureMessage);}return true;},Exclusion:function(A,B){var C=Object.extend({failureMessage:"Must not be included in the list!",within:[],allowNull:false,partialMatch:false,caseSensitive:true},B||{});C.negate=true;Validate.Inclusion(A,C);return true;},Confirmation:function(A,B){if(!B.match){throw new Error("Validate::Confirmation - Error validating confirmation: Id of element to match must be provided!");}var C=Object.extend({failureMessage:"Does not match!",match:null},B||{});C.match=$(B.match);if(!C.match){throw new Error("Validate::Confirmation - There is no reference with name of, or element with id of '"+C.match+"'!");}if(A!=C.match.value){Validate.fail(C.failureMessage);}return true;},Acceptance:function(A,B){var C=Object.extend({failureMessage:"Must be accepted!"},B||{});if(!A){Validate.fail(C.failureMessage);}return true;},Custom:function(A,B){var C=Object.extend({against:function(){return true;},args:{},failureMessage:"Not valid!"},B||{});if(!C.against(A,C.args)){Validate.fail(C.failureMessage);}return true;},now:function(A,D,C){if(!A){throw new Error("Validate::now - Validation function must be provided!");}var E=true;try{A(D,C||{});}catch(B){if(B instanceof Validate.Error){E=false;}else{throw B;}}finally{return E;}},Error:function(A){this.message=A;this.name="ValidationError";},fail:function(A){throw new Validate.Error(A);}};


CSI.Localisation = {
	'Welcome to' : 'Bienvenido a',	'Home' : 'Inicio',	'Categories' : 'Categorias',	'Documents' : 'Documentos',	'Articles' : 'Artículos',	'Permissions' : 'Permisos',	'No expire' : 'No expira',	'Module Manager' : 'Gestor de módulos',	'Config Manager' : 'Gestor de configuración',	'config info successfully updated' : 'Configuración actualizada correctamente',	'Execution Time' : 'Tiempo de ejecución',	'seconds' : 'segundos',	'ms' : 'ms',	'queries' : 'consultas',	'allocated' : 'asignado',	'Powered by' : 'Impulsado por',	'Seagull framework homepage' : 'Seagull framework homepage',	'Seagull Framework' : 'Seagull Framework',	'insufficient rights' : 'No tienes suficientes privilegios para ver esta area.',	'authorization required' : 'Tienes que estar registrado para usar esta funcionalidad.  Rellena tu nombre de usuario y contraseña abajo.',	'authorisation failed' : 'No tiene permisos para ejecutar esta acción',	'session timeout' : 'La session ha caducado, por favor registrate otra vez',	'You have been successfully logged out' : 'Has salido correctamente',	'password emailed out' : 'Una nueva contraseña ha sido enviada a la dirección de correo electronico con el que te registraste',	'email not in system' : 'Las credenciales que has introducido no pueden ser reconocidas, por favor vuelve a intentarlo',	'email submitted successfully' : 'Tu email ha sido enviado correctamente',	'There was a problem sending the email' : 'Hubo un problema enviando el mensaje',	'message ID not recognised' : 'ID del mensaje no reconocido',	'Please fill in the indicated fields' : 'Por favor, complete los campos indicados.',	'Your alert has been sent successfully' : 'Tu alerta ha sido enviada correctamente',	'Are you sure you want to delete this' : 'Estas seguro de que quieres borrar esto',	'your request is pending' : 'Su socilitud está pendiente de ser aceptada. No puede solicitar de momento un recordatorio de contraseña',	'Module' : 'Módulo',	'Active' : 'Habilitado',	'module successfully updated' : 'Información del módulo actualizada correctamente',	'module successfully removed' : 'Módulo borrado correctamente',	'E-mail' : 'Correo electrónico',	'Lists' : 'Listas',	'Subscribe' : 'Suscribirse',	'Unsubscribe' : 'Desuscribirse',	'Send' : 'Enviar',	'Editor type' : 'Tipo de editor WYSIWYG',	'user' : 'usuario',	'User' : 'Usuario',	'Username' : 'Usuario',	'Action' : 'Acción',	'Select' : 'Seleccione',	'delete' : 'borrar',	'Edit' : 'Editar',	'View' : 'Ver',	'move up' : 'mover arriba',	'move down' : 'mover abajo',	'finished' : 'terminado',	'back to top' : 'volver al inicio',	'currently_logged_on_as' : 'usuario',	'guest' : 'invitado',	'login' : 'acceder',	'logout' : 'salir',	'Logout' : 'Salir',	'session started at' : 'sesión abierta a las',	'logged in at' : 'registrado a las',	'displaying results' : 'mostrando resultados',	'to' : 'para',	'from a total of' : 'de un total de',	'back' : 'anterior',	'next' : 'siguiente',	'finish' : 'último',	'yes' : 'si',	'no' : 'no',	'Send it' : 'Enviar',	'Submit' : 'Enviar',	'Cancel' : 'Cancelar',	'Reset' : 'Borrar',	'reset' : 'borrar',	'Save' : 'Guardar',	'add' : 'añadir',	'edit' : 'editar',	'move' : 'mover',	'Manage' : 'Gestionar',	'Title' : 'Título',	'Status' : 'Estado',	'ID' : 'ID',	'Name' : 'Nombre',	'check to activate' : 'marcar para activar',	'Password' : 'Contraseña',	'Login' : 'Acceder',	'Forgot Password' : 'Olvidaste tu contraseña',	'Not Registered' : '¿No estas registrado?',	'Email' : 'Email',	'Remember me' : 'Recuérdame',	'Authorisation Requerida' : 'Si ya es usuario registrado, introduzca usuario y contraseña',	'Introduzca los siguientes datos' : 'Si no es usuario registrado, introduzca su nombre completo y su dirección de correo electrónico',	'Send Petition' : 'Enviar Peticion',	'Name Lastname' : 'Nombre y Apellidos',	'Bug Report' : 'Informar de un "Bug" (error de programación)',	'send bug report' : 'enviar informe de error',	'First Name' : 'Nombre',	'Last Name' : 'Apellidos',	'You must fill in your description' : 'Debes introducir una descripción',	'You must fill in your comment' : 'Debes introducir un comentario',	'Your email is not correctly formatted' : 'El formato de su email no es correcto',	'You must enter your email' : 'Debe introducir un email',	'Enabled' : 'Habilitado',	'Disabled' : 'Deshabilitado',	'You must select an element to delete' : 'Debes seleccionar un elemento a borrar',	'no results found' : 'ningún resultado encontrado',	'You have been banned' : 'Has sido expulsado de este sitio. Contacta con el administrador para más información',	'Invalid POST source' : 'El formulario parece haber sido enviado desde una fuente no autorizada',	'You are here' : 'Tu estas aqui',	'whats this?' : '¿ Que es esto ?',	'denotes required field' : 'indica campo obligatorio',	'at time' : 'a las',	'Return to browse' : 'Volver a navegar',	'ModuleManager Mgr' : 'Gestor de módulos',	'Add' : 'Añadir',	'Delete' : 'Eliminar',	'With selected module(s)' : 'Con los módulos seleccionados',	'Add a module' : 'Añadir un modulo',	'Module successfully added to the manager.' : 'Módulo añadido correctamente al gestor.',	'Module(s) successfully removed.' : 'Módulo(s) eliminado correctamente.',	'Configurable' : 'Configurable',	'Description' : 'Descripción',	'Admin URI' : 'URI administración',	'Icon' : 'Icono',	'Please, specify a name' : 'Por favor, especifique un nombre',	'Please, specify a title' : 'Por favor. especifique un título',	'Please, specify a description' : 'Por favor. especifique una descripción',	'Please, specify the url to link to' : 'Por favor, especifique la url a donde enlaza',	'Please, specify the name of the icon-file' : 'Por favor, especifique el nombre del archivo con el icono',	'you do not have perms' : 'No tienes los permisos suficientes para realizar esta acción',	'you are not allowed to access this data' : 'No tienes los permisos suficientes para interactuar con estos datos',	'this element has been deleted' : 'Este elemento ha sido borrado',	'Please use the following form to edit your config file' : 'Por favor utiliza el siguiente formulario para editar tus archivos de configuración',	'General Site Options' : 'Opciones generales del sitio',	'Base URL' : 'URL Base',	'Session max lifetime (secs)' : 'Máximo tiempo de vida de la sesión (segs)',	'Site name' : 'Nombre del sitio',	'Show logo' : 'Mostrar logo',	'Gzip compression' : 'Compresión Gzip',	'Output buffering' : 'Bufferinf de la salida',	'Enable IP banning' : 'Habilitar expulsión de IP\'s',	'Enable Tidy html cleaning' : 'Habilitar limpieza de Html',	'Session handler' : 'Controlador de sesión',	'Extended Session' : 'Sesión extendia',	'Enforce Single User' : 'Forzar un único usuario',	'You are allowed to connect from one computer at a time, other sessions were terminated!' : 'Tienes permmiso para conectar desde un ordenador cada vez, las otras sesiones finalizarán!',	'You have multiple sessions on this site!' : 'Tienes multiples sesiones en este sitio!',	'Enables extended session API when using database sessions. This allows the site to enforce one session per user.' : 'Habilita la API para sesiones extendidas cuando se usa la base de datos para almacenarlas. Esto permite al sitio obligar a tener una unica sesión por usuario.',	'Enforces one session per user on this site (requires database session handling, and extended session to be on).' : 'Obliga a tener una sesión por usuario en este sitio (requiere usar como manejador de sesiones la base de datos, y activar las sesiones extendidas).',	'Guests' : 'Invitados',	'Members' : 'Miembros',	'Total' : 'Total',	'Enable Blocks' : 'Habilitar bloques',	'Default article view type' : 'Vista por defecto para articulos',	'Front controller script name' : 'Nombre del script \'Front controller\'',	'Default module' : 'Módulo por defecto',	'Default manager' : 'Gestor por defecto',	'Navigation Options' : 'Opciones de navegación',	'Enable Navigation' : 'Habilitar navegación',	'Navigation type (driver)' : 'Tipo de navegación (controlador)',	'Navigation menu stylesheet' : 'Estilo del menú de navegación',	'Debugging Options' : 'Opciones de depuración',	'Enable authentication' : 'Habilitar autentificación',	'Enable custom error handler' : 'Habilitar manejador de error personalizado',	'Enable debug session' : 'Habilitar depuración de sesiones',	'Production website' : 'Sitio en producción',	'Show backtrace' : 'Mostrar backtrace',	'Enable Profiling' : 'Habilitar perfiles',	'Email admin threshold' : 'Umbral del correo de administración',	'Mark words which were not translated' : 'Marcar las palabras que no estan traducidas',	'Caching Options' : 'Opciones de cacheo',	'Enable caching' : 'Habilitar caché',	'Cache lifetime (secs)' : 'Tiempo de vida de la caché (segs)',	'Database Options' : 'Opciones de base de datos',	'Type' : 'Tipo',	'Host' : 'Servidor',	'Port' : 'Puerto',	'Protocol' : 'Protocolo',	'DB username' : 'Nombre de usuario BD',	'DB password' : 'Contraseña BD',	'DB name' : 'Nombre BD',	'Post-connection query' : 'Consulta post-conexión',	'Database Table Mappings' : 'Mapeo de la base de datos',	'Logging options' : 'Opciones de log',	'Enable logs' : 'Habilitar logs',	'Log name' : 'Nombre del log',	'Priority' : 'Prioridad',	'Identifier' : 'Identificador',	'Target username' : 'Nombre de usuario',	'Target password' : 'Contraseña',	'Email options' : 'Opciones de correo',	'Admin contact' : 'Contacto administrador',	'Support contact' : 'Contacto soporte',	'Info contact' : 'Contacto información',	'Popup window options' : 'Popup window options',	'Default popup window height' : 'Default popup window height',	'Default popup window width' : 'Default popup window width',	'Cookie options' : 'Opciones Cookies',	'Path' : 'Ruta',	'Domain' : 'Dominio',	'Secure' : 'Segura',	'Censorship' : 'Censura',	'Mode' : 'Modo',	'Replace word with' : 'Cambiar palabra por',	'Disallowed word' : 'Palabra no permitida',	'P3P privacy policy' : 'Política de privacidad P3P',	'Policies' : 'Políticas',	'Policy location' : 'Localización de la política',	'Compact policy' : 'Política compacta',	'Zero means until the browser is closed' : 'Cero significa \'hasta que se cierre el navegador\'',	'If path to image is specified, image will be shown; if left blank, Site name from above will appear as text' : 'Si se indica una ruta para la imagén, esta  será mostrada; si se deja en blanco, \'Nombre del sitio\' de arriba aparecera como texto.',	'Handy if you dont have access to Apache configuration' : 'Interesante si no tienes acceso a la configuración de Apache',	'This way no content items are really deleting from DB, just marked as deleted' : 'De esta manera ningún contenido se eliminará realmente de la BD, solo se marcará como borrado',	'Requires the tidy extension to be installed' : 'Requiere que la extensión \'tidy\' (limpieza) este instalada',	'Use the database session handler if youre running a load-balanced environment' : 'Utiliza la base de datos como manejador de sesiones si estas corriendo la aplicación en un entorno con balanceo de carga',	'You can turn the blocks off globally' : 'Puedes deshabilitar los bloques globalmente',	'This options allows you to change the default type of article displayed. Default Article View Type: Html Articles (2)' : 'Esta opción te permite cambiar el tipo de articulo mostrado por defecto. El tipo de articulo por defecto: Html Articles (2)',	'The name of your Seagull index file' : 'El nombre de tu archivo índice de Seagull',	'Currently supported editors are xinha, fck and htmlarea, and you must have the relevant libs in your www dir' : 'Los editores actualmente soportados son xinha, fck y htmlarea, debes tener las librerias necesarias en el directorio www',	'This is the module that will be loaded if none are specified, ie, when you call index.php (FC only)' : 'Este es el módulo que será cargado si no se especifica ninguno, ej, cuando llamas index.php (solo FC)',	'This is the manager class that will be loaded if none are specified (FC only)' : 'Este es el gestor que se cargará por defecto si no se especifica ninguno (solo FC)',	'Disable navigation altogether with this switch' : 'Desactivar navegación conjuntamente con esta opción',	'Use this option to choose from various menu types - currently only 1 provided' : 'Usa esta opción para elegir entre los diferentes tipos de menú - actualmente solo 1 disponible',	'Defines the appearance of the navigation menu. Preview and make additional changes in the navigation module manager' : 'Define la pariencia del menú de navegación. Vista previa y hacer cambios adicionales en el módulo de navegación',	'Debugging easier when this is disabled' : 'Debugg más sencillo cuando esto esta deshabilitado',	'Customise the way errors are handled' : 'Configurar el modo en que los errores serán tratados',	'If your IP appears in the TRUSTED_IPS array, you will be able to view system errors on screen even in production mode (see below)' : 'Si tu IP aparece en el array TRUSTED_IPS, podrás ver los mensajes de error incluso en modo producción (mirar abajo)',	'Setting this to true will disable all screen-based error messages' : 'Poniendo esto a true desahibilitará todos los mensajes de error por pantalla',	'Requires to Xdebug extension to be installed' : 'Requiere que la extensión Xdebug este instalada',	'Errors must be >= this level before they are emailed to the site admin' : 'Los errores deben ser >= a este nivel antes de ser enviados a el admin del sitio',	'It is recommended to disable this while developing' : 'Es recomendable desahabilitar durante el desarrollo',	'Default is 24 hours' : 'Por defecto es 24 horas',	'Make sure you load the relevant schema' : 'Comprueba que cargas el esquema correcto - "mysql_SGL" mantiene todas las sequencias en la misma tabla (menos lioso) mientras que "mysql" usa una tabla por secuencia multiplicando por dos el numero de tablas (mejor por rendimiento)',	'It is recommended to disable logging if you are running < PHP 4.3.x' : 'Es recomendable deshabilitar el logging si estas ejecutando < PHP 4.3.x',	'If sql is used, use log_table as the log table name below' : 'Si se pone \'sql\', usará \'log_table\' como la tabla de log arriba',	'Use an absolute path or one relative to the Seagull root dir' : 'Usa una ruta absoluta o una relativa a el directorio root de Seagull',	'Error messages get sent here' : 'Los mensajes de error seran enviados aqui',	'Contact us enquiries get sent here' : 'Los mensajes del módulo \'Contact us\' se enviaran aqui',	'This will be your session identifier' : 'Esto sera tu identificador de sesión',	'Disallowed words' : 'Palabras no permitidas',	'Enable Safe deleting' : 'Habilitar borrado seguro',	'Default params' : 'Parametros por defecto',	'Use these params to specify, eg, a static article for your homepage' : 'Usa estos parametros para especificar, ej, un artículo estático para tu página de inicio',	'file' : 'archivo',	'database' : 'base de datos',	'never' : 'nunca',	'Show debug reporting link' : 'Mostrar debug reportando enlace',	'Send feedback to project for bugs' : 'Enviar retroalimentación al proyecto mediante bugs',	'Words which system was unable to translate will be enclosed in "> <" marks' : 'Las palabras que el sistema sea incapaz de traducir se mostrarán entre las marcas "> <"',	'URL handler' : 'Manejadir de URL',	'What format would you like your URLs, Seagull Search Engine Friendly is the default' : 'Que formato quieres para tus URL\'s, Seagull Search Engine Friendly es el método por defecto',	'The classic URL handler has not been implemented yet' : 'El manejadir de URL clásico no ha sido implementado aún',	'Template Engine' : 'Motor de plantillas',	'Seagull allows you to use the template engine of your choice' : 'Seagull te permite usar el motor de plantillas de tu elección',	'The Smarty template hooks have not been implemented yet' : 'Las anclas de las plantillas Smarty no han sido implementadas aún',	'This query is used to set the default character set for the current connection (MySQL 4.1 or higher). For example: SET NAMES utf8' : 'Esta consulta se usa como juego de caracteres por defecto para la conexión actual (MySQL 4.1 o mayor). Por ejemplo: SET NAMES utf8',	'true' : 'sí',	'false' : 'no',	'MTA options' : 'Opciones MTA',	'Backend' : 'Backend',	'PEAR::Mail backend' : 'PEAR::Mail backend',	'Sendmail path' : 'Ruta Sendmail',	'Mandatory if you use Sendmail as Backend' : 'Obligatorio si usas \'Sendmail\' como Backend',	'Sendmail arguments' : 'Argumentos Sendmail',	'Optional if you use Sendmail as Backend' : 'Opcional si usas \'Sendmail\' como Backend',	'SMTP host' : 'SMTP host',	'Optional if you use SMTP as Backend. Default: localhost' : 'Opcional si usas \'SMTP\' como Backend. Por defecto: localhost',	'SMTP port' : 'SMTP port',	'Optional if you use SMTP as Backend. Default: 25' : 'Opcional si usas \'SMTP\' como Backend. Por defecto: 25',	'Use SMTP authentication' : 'Usar autentificación SMTP',	'SMTP username' : 'SMTP username',	'SMTP password' : 'SMTP password',	'Mandatory if you use SMTP as Backend and SMTP authentication is enabled' : 'Obligatorio si usas \'SMTP\' como Backend y \'Autentificación SMTP\' esta habilitado',	'If users have cookies disabled, this will allow them to use sessions with Seagull' : 'Si los usuarios tienen las cookies deshabilitadas, esto les permitirá usar sesiones con Seagull',	'Allow Session in URL' : 'Permitir sesiones en la URL',	'Check for Latest Version' : 'Comprobar si hay una versión nueva',	'Check Now' : 'Comprobar ahora',	'Your current version is up to date' : 'La versión actual esta actualizada',	'remote interface problem' : 'Hubo un problema llamando a la interfaz remota',	'Maintenance' : 'Mantenimiento',	'Maintenance Manager' : 'Gestor mantenimiento',	'Back to Maintenance' : 'Volver a mantenimiento',	'Congratulations, the target translation appears to be up to date' : 'Felicidades, la traducción seleccionada parece actulizada',	'translation successfully updated' : 'traducción actualizada correctamente',	'There was a problem updating the translation' : 'Hubo un problema actualizando la traducción',	'Data Objects rebuilt successfully' : 'Data Objects reconstruidos correctamente',	'Cache files successfully deleted' : 'Archivos cache borrados correctamente',	'Manage Translations' : 'Gestionar traducciones',	'Check all modules' : 'Comprobar todos los módulos',	'check all modules' : 'comprobar todos los módulos',	'update' : 'Actualizar',	'Module Name' : 'Nombre del módulo',	'ok' : 'ok',	'no file' : 'sin archivo',	'new strings' : 'nuevas cadenas',	'old strings' : 'cadenas antiguas',	'File not writeable' : 'Archivo no escribible',	'Sequences rebuilt successfully' : 'Secuencias reconstruidas correctamente',	'Rebuild DB Sequences' : 'Reconstruir secuencias BD ',	'Rebuild Sequences Now' : 'Reconstruir secuencias ahora',	'validate' : 'validar',	'Process' : 'Procesar',	'Manage Caches' : 'Gestionar Caches',	'Templates' : 'Plantillas',	'navigation' : 'navegación',	'blocks' : 'bloques',	'categories' : 'categorías',	'permissions' : 'permisos',	'Clear Selected Caches Now' : 'Limpiar Caches seleccionadas ahora',	'Rebuild Data Objects' : 'Reconstruir Data Objects',	'Rebuild Dataobjects Now' : 'Reconstruir Dataobjects ahora',	'You are editing: Module' : 'Estas editando: Módulo',	'You are updating: Module' : 'Estas actualizando: Módulo',	'Master Value' : 'Valor "Master"',	'Translated Value' : 'Valor traducción',	'Save Translation' : 'Salvar traducción',	'Create a module' : 'Crear un módulo',	'Manager Name' : 'Nombre gestor',	'Create Templates' : 'Crear plantillas',	'Create ini file' : 'Crear archivo ini',	'Create language files' : 'Crear archivos de lenguaje',	'Create Module Now' : 'Crear Módulo ahora',	'Module files successfully created' : 'Archivos del módulo creados correctamente',	'The source translation has' : 'La traducción de origen tiene',	'elements' : 'elementos',	'The target translation has' : 'La traducción destino tiene',	'Please add' : 'Por favor, añade',	'values for the following keys which appear to be missing from the' : 'valores para las siguientes claves que parecen faltar de',	'module' : 'módulo',	'please specify an option' : 'por favor, especifique una opción',	'please check at least one box' : 'por favor, selecciona al menos una opción',	'please enter module name' : 'por favor, introduzca el nombre del módulo',	'please enter manager name' : 'por favor, introduzca el nombre del gestor',	'Extended locale support' : 'Soporte de locales extendido',	'locale support info' : 'Habilitando esta caraterística da acceso al I18Nv2 API pero a costa de una bajada en el rendimiento',	'Locale category' : 'Categoría Locale',	'Paths' : 'Rutas',	'Install Root' : 'Raiz intalación',	'Web Root' : 'Raiz web',	'With selected record(s)' : 'Registros seleccionados',	'config options' : 'Opciones de configuración',	'action' : 'Acción',	'preferences' : 'preferencias',	'Section ID' : 'ID Sección',	'Manager' : 'Gestor',	'None' : 'Ninguno',	'Please supply full nav info' : 'Por favor, introduzca info navegación completa',	'Admin Menu Manager :: Edit' : 'Gestor menú administración :: Editar',	'Admin Menu Manager :: Browse' : 'Gestor menú administración :: Navegar',	'Add module' : 'Añadir módulo',	'New section' : 'Nueva sección',	'manage' : 'Gestionar',	'BodyHtml' : 'Cuerpo',	'Article Manager :: Edit' : 'Gestor artículos :: Editar',	'Translation options' : 'Opciones traducción',	'Container' : 'Container',	'Fallback Language' : 'Language por defecto',	'Add Missing Translations' : 'Añadir traducciones que falten',	'aMonths' : 'Array',	'first page' : 'Primera página',	'last page' : 'Última página',	'(public obs.) ' : '(obs. pública) ',	'(private obs.) ' : '(obs. privada) ',	'Your search - %value - did not match any serial' : 'Su búsqueda - %value - no encontró ninguna revista',	'Form' : 'Formulario',	'altPrev' : 'Anterior',	'altNext' : 'Siguiente',	'altPage' : 'Página',	'prevImg' : '&laquo; anterior',	'nextImg' : 'siguiente &raquo;',	'altFirst' : 'Página Inicio',	'altLast' : 'Página Final',	'Your subscription to' : 'Su acceso al módulo',	'expires in' : 'finaliza dentro de',	'User id not found' : 'User id no encontrado',	'Can not build session' : 'No se puede crear la sesión',	'Full name' : 'Nombre y apellidos',	'Enter' : 'Enter',	'Select your user and click Enter' : 'Selecciona tu usuario y pulsa Enter',	'List of non downloaded petitions' : 'Lista de artículos sin descargar',	'Enter your email and click Send to access petition forms' : 'Introduzca su email y haga click en Enviar para acceder a los formularios de petición',	'Enter your email and click Send to receive an email with your non downloaded articles' : 'Introduzca su email para recibir relación peticiones sin descargar',	'Required parameters are missing' : 'No están todos los parámetros requeridos',	'Wrong enviroment' : 'Ámbito inválido',	'There is no user with that email address on the database' : 'No existe ningún usuario con ese email',	'Only ILL17 users allowed' : 'Sólo se permiten usuarios ILL',	'The email does not belong to any organisation from the enviroment' : 'La dirección de email no pertenece a ninguna organización del ámbito',	'No direct access allowed' : 'No se permite el acceso directo',	'No email has been sent. You have no articles pending' : 'No se envió ningún email porque no tiene ningún artículo pendiente de descargar',	'An email has been sent to your inbox folder' : 'Se ha enviado un email a su dirección de correo',	'The serials seems to be not identified. We can perform a holding search based on ISSN' : 'Esta petición ha sido realizada a través del formulario libre, sin ser contrastada con los fondos del C17. Si lo desea, puede realizar una búsqueda de fondos por ISSN pulsando el botón Búsqueda',	'Access to Ill Users Form' : 'Acceso al formulario de alta de usuarios',	'The user has been successfully added' : 'Usuario dado de alta correctamente',	'Accept' : 'Aceptar',	'Accepted' : 'Aceptada',	'Rejecting' : 'Rechazada',	'Pending' : 'Pendiente',	'Accept User Request' : 'Acepta la solicitud de su usuario',	'Reject User Request' : 'Rechaza la solicitud de su usuario',	'Confirm user request' : 'Pulse para confirmar el estado de la solicitud',	'Add Note' : 'Añadir mensaje',	'Add Note to Confirm Request' : 'Añadir mensaje a la confirmación de la solicitud',	'Note will be sent to the user with the confirmation' : 'El mensaje será enviado al usuario con la confirmación de su solicitud',	'Your request has been accepted' : 'SU SOLICITUD DE USUARIO ILL HA SIDO ACEPTADA',	'Your request has been rejected' : 'SU SOLICITUD DE USUARIO ILL HA SIDO RECHAZADA',	'Your request has been delivered' : 'SU SOLICITUD DE USUARIO ILL HA SIDO ENVIADA',	'You must enter an email address' : 'Introduzca una dirección de correo',	'Service' : 'Servicio',	'Cargo' : 'Cargo',	'Genre' : 'Género',	'Statistics' : 'Estadisticas',	'Export to PDF' : 'Exportar a PDF',	'Choose statistic type' : 'Elija el tipo de estadistica a generar',	'Choose place' : 'Elija la comunidad',	'Choose library' : 'Elija biblioteca',	'Total Links' : 'Número de enlaces',	'Invalid configuration file' : 'Fichero de configuración inválido',	'Invalid role' : 'Rol inválido',	'Your search did not match any serial with holdings' : 'No se encontró ninguna revista con fondos.',	'The serial is on C17 catalog' : 'La revista está en el catálogo C17',	'The serial is not on C17 catalog' : 'No se encontraron resultados en el catálogo C17',	'There are no holdings for this serial mathing your filter criteria' : 'No se encontraron fondos para esta búsqueda filtrada',	'There are no holdings for this serial' : 'No se encontraron fondos para esta revista',	'Your search did not match any organisation' : 'No se encontró ninguna biblioteca',	'Authentication failed. Wrong username or password' : 'No se ha autenticado correctamente: Usuario o Contraseña no válidos.',	'You must authenticate before making the petition' : 'Debe iniciar sesión antes de realizar una petición',	'Your petition has been created successfully' : 'Su petición se ha realizado con éxito.',	'C17' : 'C17',	'The following words has been ignored' : 'Las siguientes palabras han sido ignoradas.',	'Search' : 'Búsqueda',	'Paper ISSN' : 'ISSN papel',	'Electronic ISSN' : 'ISSN electrónico',	'Publication Place' : 'Lugar de publicación',	'Pubmed' : 'Pubmed',	'Locate Article' : 'Localizar artículo',	'Querying pubmed' : 'Consulta pubmed',	'This may take a while' : 'Esta acción puede tardar unos segundos...',	'Search results' : 'Resultados de la búsqueda',	'DOI' : 'DOI',	'Article title' : 'Título del artículo',	'Authors' : 'Autores',	'Date' : 'Fecha',	'Volume' : 'Volumen',	'Issue' : 'Fascículo',	'Start page' : 'Página de inicio',	'PMID' : 'PMID',	'End page' : 'Página fin',	'Serial title' : 'Título de la revista',	'State' : 'Estado',	'Single Citation Matcher' : 'Single Citation Matcher',	'Year' : 'Año',	'Organisations' : 'Bibliotecas',	'Name, code or city' : 'Nombre, código o localidad',	'Title, ISSN' : 'Título, ISSN',	'Title, ISSN or PubMed ID' : 'Título, ISSN or Id medline',	'Code' : 'Código',	'City' : 'Ciudad/Localidad',	'My collections' : 'Mis colecciones',	'Own collection' : 'Colección propia',	'Free Collection' : 'Colecciones Libres',	'Add like free package' : 'Añadir como colección libre',	'Add new free package' : 'Añadir nueva colección libre',	'Select free collections for organisation' : 'Seleccione las colecciones libres',	'Filters' : 'Filtros',	'Applying filters' : 'Aplicando filtros',	'National' : 'National',	'Region' : 'Region',	'Electronic only' : 'Sólo fondos electrónicos',	'Filter' : 'Filtro',	'Organisation' : 'Biblioteca',	'Holdings' : 'Fondos',	'Alert' : 'Alerta',	'Petition' : 'Petición',	'No service' : 'Sin servicio',	'Make petition' : 'Realizar petición',	'You can send the petition to the library of your choice as well' : 'También puedes enviar la petición a la biblioteca que desees.',	'Petition form' : 'Formulario de petición',	'Select the organisation for sending the petition' : 'Selecciona la biblioteca para enviar la petición',	'Retrieving Linkout information' : 'Obteniendo datos Linkout',	'Retrieving DOI information' : 'Obteniendo datos DOI ',	'Note' : 'Nota',	'Type in the user first or last name' : 'Teclee el nombre o apellido del usuario',	'Currently assigned to' : 'Asignado actualmente a',	'Querying C17' : 'Consulta C17',	'User reference' : 'Referencia de usuario',	'Requester user of own library' : 'Usuario peticionario de nuestra biblioteca',	'Not is an registered user' : 'Usuario no registrado. Click aquí para rellenar datos.',	'Center name/Department' : 'Centro / Departamento',	'You must fill all the user not registered fields' : 'Si asigna la petición a un usuario no registrado, debe rellenar todos los campos solicitados.',	'Identification' : 'Identificación',	'Library included in C17 catalog' : 'Biblioteca perteneciente al catálogo del c17',	'Library not included in C17 catalog' : 'Biblioteca no incluída en el catálogo del C17',	'Center name' : 'Nombre de la biblioteca',	'Person to contact with' : 'Persona de contacto',	'Telephone number' : 'Teléfono',	'Article data' : 'Datos del artículo',	'Starting page' : 'Página de inicio',	'Ending page' : 'Página fin',	'Empty value inserted' : 'Valor vacío',	'See organisation info' : 'Ver datos biblioteca',	'Help' : 'Leyenda',	'Opened holdings' : 'Fondos abiertos',	'Closed holdings' : 'Fondos cerrados',	'Starred' : 'Destacada',	'You can send the petition to the library you want. Only showing librarys with borrowing services' : 'Puede realizar la petición a la biblioteca que desee. Sólo se muestran bibliotecas con servicio de préstamo.',	'days' : 'días',	'The following words has been ignored:' : 'Las siguientes palabras han sido ignoradas:',	' Título, ISSN or Id Medline' : ' Título, ISSN o Id Medline',	'Link' : 'Enlace',	'Issues' : 'Fasciculos',	'Retrieving kardex information' : 'Obteniendo datos del kardex',	'Tip Ficha Kardex' : 'Ficha Kardex',	'Free form' : 'Formulario libre',	'Department' : 'Departamento',	'Cannot retrieve the ISSN for the PMID' : 'No se puede recuperar el ISSN para este PMID',	'I accept the followings terms and conditions' : 'Acepto los términos y condiciones descritas',	'New search' : 'Nueva búsqueda',	'You are not allowed to make PMID searches' : 'No puede realizar búsquedas por PMID',	'Invalid query terms. Try to change them and repeat your search' : 'Términos de búsqueda inválidos. Intente cambiarlos y repetir la búsqueda',	'Your search can not be processed. Try to change them query terms and repeat your search' : 'Su búsqueda no puede ser procesada. Intente cambiar los términos de búsqueda y repetirla',	'Year must be four characters long' : 'El año debe tener 4 caracteres de longitud',	'Must be a number' : 'Debe ser un número',	'The number must be a year representation' : 'El número debe ser una representación de un año',	'Alternative download' : 'Descarga alternativa',	'The file is available through other petition. Click to download.' : 'El fichero está disponible a través de otra petición. Haga click aquí para descargar el fichero.',	'Holdings lists' : 'Listado de Fondos',	'Please fill the indicated identification fields' : 'Por favor, rellene los campos solicitados de identificación',	'Fasciculos faltantes' : 'Fascículos faltantes',	'K' : 'K',	'There is no notes.' : 'No hay notas.',	'No matches' : 'No se produjeron resultados',	'Organisation info' : 'Datos de la biblioteca',	'Phone Number' : 'Teléfono',	'Website' : 'URL',	'See more info' : 'Ver más información',	'Logo' : 'Logo',	'Photo' : 'Foto',	'Address' : 'Dirección',	'Post code' : 'Código Postal',	'Email Organisation' : 'Email Biblioteca',	'Email Notification' : 'Email Notificación',	'Serial data' : 'Datos de los títulos',	'Abreviated Title' : 'Título abreviado',	'Variant Titles' : 'Variantes de título',	'Cancelled ISSNs' : 'ISSNs cancelados',	'Publication place' : 'Lugar de publicación',	'Publication years' : 'Años de publicación',	'Electronic publication only' : 'sólo edición electrónica',	'Actual frequency' : 'Periodicidad actual',	'Historical Notes' : 'Notas historicas',	'Since' : 'Desde',	'Kardex data will be erased.' : 'Los datos del kardex serán eliminados.',	'Holdings will be modified.' : 'Los fondos serán modificados.',	'Holdings line will be modified.' : 'La línea de fondos será modificada.',	' does not belong to your holdings: modify holdings and send.' : 'Este año no pertenece a los fondos: modifíquelos y envíelos.',	'Holdings added successfully' : 'Fondos añadidos correctamente',	'Seems you want make an edit, not an insert' : 'Parece que quieres editar, no insertar',	'Holdings updated successfully' : 'Fondos actualizados correctamente',	'Seems you want make an insert, not an edit' : 'Parece que quieres realizar una inserción, no editar',	'Holdings deleted successfully' : 'Fondos eliminados correctamente',	'Missing serial ID' : 'Falta ID de revista',	'Kardex - Ficha general' : 'Kardex - Ficha general',	'Open' : 'Abierta',	'Closed' : 'Cerrada',	'Add Notes' : 'Añadir nota',	'View Notes' : 'Ver notas',	'Holdings :: Listing Own Collection' : 'Fondos :: Listado Colección Propia',	'Choose the listing type' : 'Tipo de listado',	'listing HTML' : 'HTML',	'listing CSV' : 'CSV',	'List' : 'Acceder al listado',	'serials founded' : 'revistas encontradas',	'Complete collection' : 'Colección completa',	'Holdings :: Search' : 'Fondos :: Buscar',	'Error in update. Received issue in year(s) %value' : 'Error en la actualización. Existen fascículos recibidos para año(s) %value',	'Holdings :: Add' : 'Fondos :: Añadir',	'Holdings :: Edit' : 'Fondos :: Editar',	'Holdings :: Printouts :: Own paper holdings' : 'Fondos :: Listados :: Listado de los fondos de papel propios de tu biblioteca',	'Holdings :: Printouts :: Own electronic holdings' : 'Fondos :: Listados :: Listado de los fondos electrónicos propios de tu biblioteca',	'Holdings :: Printouts :: Own paper holdings with open holding line' : 'Fondos :: Listados :: Listado de los fondos de papel propios de tu biblioteca con cobertura abierta',	'Holdings :: Printouts :: Own paper holdings with open holding line and serials with ending year' : 'Fondos :: Listados :: Listado de los fondos de papel propios de tu biblioteca con cobertura abierta para revistas que tienen año fin',	'Holdings :: Printouts :: Holdings Today' : 'Fondos :: Listados :: Listado de los fondos a día de hoy',	'Total Holdings' : 'Fondos Totales',	'Open Holdings' : 'Fondos Abiertos',	'Own Holdings' : 'Colecciones Propias',	'Electronic holdings' : 'Fondos electrónicos',	'Embargo' : 'Embargo',	'Journal Link Provider' : 'Proveedor de enlaces',	'Not in list' : 'No está en la lista',	'URL' : 'URL',	'Paper holdings' : 'Fondos en papel',	'Go back' : 'Volver',	'Kardex' : 'Kardex',	'Provider' : 'Suministrador',	'The following words has been ignored: ' : 'Las siguientes palabras han sido ignoradas: ',	'Only in my holdings: ' : 'Sólo en mis fondos: ',	'Only open paper holdings: ' : 'Sólo fondos de papel abiertos: ',	'Only paper holdings: ' : 'Sólo fondos de papel: ',	'Enable this to search only in your serials with open paper holdings' : 'Permitir buscar sólo en tus revistas con fondos de papel abiertos.',	'Enable this to search only in your serials with paper holdings' : 'Permitir buscar sólo en tus revistas con fondos de papel.',	'Add new holdigs' : 'Añadir fondos',	'Template' : 'Plantilla',	'Are you sure you want to delete this holding line?' : '¿Está seguro que desea eliminar esta línea de fondos?',	'[ILL17] Unrecognized SOD email' : '[ILL17] Email SOD no reconocido',	'Email ID not defined' : 'Email ID no definido',	'There was a problem getting the Email from the DB. Please, try again later.' : 'Error accediendo al Email en la BD. Por favor, inténtelo de nuevo más tarde.',	'You have no permission to view this email' : 'No tiene permisos para ver este email.',	'Requester organisation' : 'Organización peticionaria',	'Article title is empty' : 'El título del artículo está vacío',	'Year is not a numeric value' : 'El año no es un valor numérico',	'You must fill the serial title or one issn at least' : 'Debe rellenar el título de la revista o uno de los dos ISSNs',	'You must select a library' : 'Debe seleccionar una biblioteca',	'This organisation will show up as the requester one. Only showing librarys with borrowing services' : 'Está biblioteca se mostrará como la peticionaria. Sólo se muestran bibliotecas con servicios de préstamo.',	'Generate petition' : 'Generar nueva petición',	'Petition successfully created. It will show up in Pending folder' : 'Petición registrada correctamente. Puede verla en la bandeja de "Pendientes"',	'Petition successfully created. It will show up in Pending folder. The email has been successfully deleted' : 'Petición registrada correctamente. Puede verla en la bandeja de "Pendientes". El email se ha eliminado correctamente',	'Delete email' : 'Eliminar email',	'If the checkbox is marked, the email will be deleted after creating the petition' : 'Si se marca la casilla, el email será eliminado después de crear la petición',	'The email has been deleted successfully' : 'El email se ha eliminado correctamente',	'There is no emails to select' : 'No hay ningún email para seleccionar',	'You must select one email at least' : 'Debe seleccionar al menos un email',	'Are you sure you want to delete this emails?' : '¿Está seguro que desea eliminar estos emails?',	'Delete selected emails' : 'Eliminar emails seleccionados',	'Clear selected' : 'Limpiar selección',	'Can not find the requester organisation' : 'No se pudo determinar el peticionario a partir del correo',	'Can not find the responder organisation' : 'No se pudo determinar la organización que debería atender la petición a partir de los datos del correo',	'Can not get the requester organisation from the email address' : 'No se pudo determinar el peticionario a partir de la dirección de email',	'Can not insert the Mail' : 'No se pudo insertar el email',	'Can not process the email' : 'No se pudo procesar el email',	'Your user has been added to the system' : 'HA SIDO DADO DE ALTA COMO USUARIO ILL17',	'Unread' : 'NO LEIDO',	'Not Read' : 'LEIDO',	'No file was added' : 'Fichero adjuntado correctamente.',	'Petition ID not defined' : 'Petition ID no definido',	'There was a problem extracting the petition from the DB. Please try again later.' : 'Error leyendo la petición en base de datos. Por favor, inténtelo más tarde.',	'You have no permission to view the petition.' : 'No tiene permiso para ver la petición.',	'The petition has been successfully served' : 'La petición ha sido servida correctamente',	'You have no permission to download the file!' : 'No tiene permiso para descargar el fichero!',	'You have no permissions to delete this petition!' : 'No tiene permisos para eliminar esta petición!',	'File modified successfully' : 'Fichero modificado correctamente',	'File added successfully' : 'Fichero adjuntado correctamente',	'You have no permission to serve that petition' : 'No tiene permiso para servir la petición',	'Requester' : 'Peticionario',	'Responder' : 'Destinatario',	'Internal notes' : 'Notas internas',	'External notes' : 'Notas externas',	'Automatic system note' : 'Nota automática de sistema',	'The petition was marked as' : 'la petición fue marcada como',	'rejected' : 'rechazada',	'served' : 'servida',	'Resolution code' : 'Código de resolución',	'Unknown' : 'Desconocido',	'by the user' : 'por el usuario',	'of organisation' : 'de la organizacion',	'with date' : 'en fecha',	'Show news only' : 'Mostrar sólo nuevas',	'Community' : 'Comunidad',	'Petition deleted successfully' : 'Petición eliminada correctamente',	'Emails' : 'Emails',	'More operations' : 'Más operaciones',	'The following terms' : 'Los siguientes términos',	'were accepted' : 'fueron aceptados',	'Clean' : 'Limpiar',	'There was no active filters' : 'No hay ningún filtro activo',	'Reclamation done' : 'Reclamación realizada',	'Reclamation text' : 'Texto de la reclamación',	'Reclamation done successfully' : 'Reclamación realizada correctamente',	'Note added successfully' : 'Nota añadida correctamente',	'Internal message' : 'Mensaje interno',	'External message' : 'Mensaje externo',	'Article reclamation from' : 'Reclamación sobre artículo de',	'If you get the file from another external source, you can add it and directly serve the petition. This option must be only used if is not possible to handle the petition on the typical way.' : 'Si obtuvo el fichero de alguna fuente externa, puede añadirlo y servir la petición.',	'Add External File' : 'Añadir fichero externo',	'%value% is not a valid email address' : '%value% no es una dirección de email válida',	'You must select an user' : 'Debe seleccionar un usuario',	'Send by email' : 'Enviar por email',	'Emails sepparated by comma' : 'Emails separados por coma',	'Petition sent to emails successfully' : 'Petición enviada por email correctamente',	'Petition marked as read successfully' : 'Petición marcada como leída correctamente',	'You can add a file to the petition' : 'Puede añadir un fichero a la petición',	'If you have the file, you can add to the petition' : 'Si tiene el fichero, puede adjuntarlo a la petición',	'This petition was sent by email to the followings addresses' : 'Esta petición fue reenviada por email a las siguientes direcciones',	'QuickNav' : 'Menú rápido',	'QuickInfo' : 'Información rápida',	'Add one more file' : 'Añadir un fichero más',	'You have not selected any file' : 'No se ha seleccionado ningún archivo',	'Information' : 'Información',	'This petition was sent by email to CINDOC center. Every messages that CINDOC sends to your library will be received in your confirmation email, if configures on your preferences' : 'Esta petición ha sido cursada a un centro del CINDOC. Todos los mensajes que el centro le envíe a su biblioteca, ya sean de confirmación, cancelación, etc, le llegarán al correo que tuviera configurado como "Correo de cofirmaciones" en las preferencias de su biblioteca',	'Petition to CINDOC are only allowed for registered users' : 'Las peticiones al CINDOC sólo son válidas para usuarios registrados',	'To ask for an article to a CINDOC center, you must set you username and CINDOC password on your preferences. If you don\'t have it, please contact CINDOC to get one.' : 'Para hacer una petición al CINDOC, debe configurar su Cuenta depósito y contraseña en las preferencias de su biblioteca. Si no tiene ninguna cuenta, por favor, contacte con el CINDOC para obtener una.',	'Petition served successfully' : 'Petición servida correctamente',	'ILL17 :: petition list' : 'ILL17 :: Listado de peticiones',	'ILL17 :: Resend petition' : 'ILL17 :: Reenviar petición',	'ILL17 :: Reserve petition' : 'ILL17 :: Volver a servir petición',	'ILL17 :: Serve petition' : 'ILL17 :: Servir petición',	'ILL17 :: Add File' : 'ILL17 :: Añadir fichero',	'ILL17 :: Reject petition' : 'ILL17 :: Rechazar petición',	'ILL17 :: Mark petition' : 'ILL17 :: Marcar peticion',	'ILL17 :: Modify File' : 'ILL17 :: Modificar fichero',	'ILL17 :: View petition' : 'ILL17 :: Ver petición',	'Retrieving Linkout information...' : 'Obteniendo información de Linkout...',	'Are you sure you want to delete this petition' : 'Está seguro que desea eliminar esta petición (esta operación no es reversible)',	'Petition ID' : 'ID de petición',	'Telf' : 'Telf',	'Serial' : 'Revista',	'Started on' : 'Iniciada',	'Resolved on' : 'Resuelta',	'Pags' : 'Págs',	'Dou you want to print the attached messages' : 'Desea imprimir también los mensajes',	'If you want to print the messages, press Accept. Otherwise, press Cancel' : 'Si desea imprimir también los mensajes, pulse Aceptar. Si no, pulse Cancelar.',	'You have not access to this section' : 'No tiene acceso a esta sección, porque no tiene contratado ILL17',	'Petition resend to user successfully' : 'Petición reeviada a usuario correctamente',	'It looks like someone has already serve the petition while you had it open' : 'Parece que alguien ha servido la petición mientras la tenía abierta. Operación cancelada.',	'It looks like someone has already resolve the petition while you had it open' : 'Parece que alguien ha resuelto la petición mientras la tenía abierta. Operación cancelada.',	'Your ILL email' : 'Su email de ILL17',	'UserRef' : 'Ref. Usuario',	'Biblio Reference' : 'Referencia Bibliográfica',	'Ill' : 'ILL',	'New' : 'Nuevo',	'Served read' : 'Servida Leída',	'Copy sent' : 'Copia enviada',	'User petition' : 'Petición recibida de usuario',	'External petition' : 'Petición recibida de biblioteca externa',	'Sent to library petition' : 'Petición enviada a biblioteca externa',	'Resend to library petition' : ' Recibida de usuario y reenviada a biblioteca externa',	'Article updated successfully' : ' Articulo modificado correctamente',	'Assign user' : 'ASIGNAR USUARIO',	'Modify user' : 'Asignar usuario',	'User modified successfully' : 'Usuario modificado correctamente',	'[ILL17] UNRECOGNIZED ARTICLE REQUESTING MAIL' : '[ILL17] MAIL DE PETICION DE ARTICULO NO RECONOCIDO',	'Totals Sent' : 'Total Enviadas',	'Totals Recieved' : 'Total Recibidas',	'Recieved' : 'Recibidas',	'Total Petitions' : 'Total Peticiones',	'Your article request has been rejected by' : 'Su solicitud de artículo ha sido rechazada por',	'Bibliotecas que nos han rechazado la solicitud' : 'Bibliotecas que nos han rechazado la solicitud',	'Not can resend petition to my library' : 'No puedes reenviar la petición a tu biblioteca.',	'This article has been modified, the previous data before change was:' : 'Ha editado los datos del artículo correspondiente a esta petición. Los datos previos al cambio son: ',	'Received' : 'Recibidas',	'All' : 'Todas',	'Fascicle' : 'Fascículo',	'ILL printouts' : 'Informes ILL',	'Resolved by own library' : 'Resueltas por su biblioteca',	'Linkout/DOI resolved' : 'Resueltas por Linkout/DOI',	'Total user petitions' : 'Total de peticiones de usuario',	'Sent to other lybraries' : 'Cursadas a otras bibliotecas',	'Date picker' : 'Selector de fecha',	'Number of petitions' : 'Número de peticiones',	'Petitions sent to other librarys' : 'Títulos que hemos solicitado fuera',	'Petitions made from other librarys to ours' : 'Títulos que nos han solicitado',	'Statistic type' : 'Tipo de estadística',	'ILL printouts :: Petition list' : 'Informes ILL :: Listado de peticiones',	'ILL printouts :: User statistics' : 'Informes ILL :: Listado de peticiones de usuario',	'ILL printouts :: Internal and External petitions statistics' : 'Informes ILL :: Listado de peticiones enviadas y recibidas',	'Search user' : 'Buscar usuario',	'ILL printouts :: Serial statistics' : 'Informes ILL :: Listado de peticiones por revista',	'ILL printouts :: Internal petitions statistics' : 'Informes ILL :: Listado de peticiones enviadas a otras bibliotecas',	'ILL printouts :: External petitions statistics' : 'Informes ILL :: Listado de peticiones recibidas de otras bibliotecass',	'By library' : 'Por biblioteca',	'By rejection mode' : 'Por tipo de rechazo',	'By service mode' : 'Por vía de servicio',	'Library' : 'Biblioteca',	'Other states' : 'Otros estados',	'Sent by' : 'Vía de servicio',	'Rejected  by' : 'Tipo de rechazo',	'Petition number' : 'Numero de peticiones',	'Average time (in days)' : 'Tiempo medio (en días)',	'Totals' : 'Totales',	'Other' : 'Otras',	'Rejected by' : 'Motivo de rechazo',	'ILL17 :: Printouts' : 'ILL17 :: Informes',	'Balance' : 'Balance',	'ILL printouts :: Summary Table' : 'Informes ILL :: Listado resumen de peticiones',	'Ill17 Petitions' : 'Peticiones Ill17',	'Total petition count' : 'Total de peticiones',	'Subscription stored successfully. You will receive an email with the statistics tomorrow' : 'Su petición se ha procesado correctamente. Recibirá la estadística en su correo de confirmaciones mañana.',	'Request All users statistics' : 'Solicitar las estadísticas de todos los usuarios',	'Export to CSV' : 'Exportar a CSV',	'Export Summary table' : 'Exportar tabla resumen',	'You can not request two user reports' : 'No puede solicitar dos estadísticas completas de usuario',	'Your statistic request is stored and will be processed tomorrow' : 'Su petición de estadística está almacenada y será procesada mañana',	'Cancel request' : 'Cancelar solicitud',	'Request deleted successfully.' : 'Solicitud cancelada correctamente.',	'You have no ILL17 users in your system' : 'No tiene ningún usuario ILL en su sistema',	'Totals from' : 'Total de',	'ILL printouts :: Billing statistics' : 'ILL Listados:: Facturación bibliotecas',	'Billed Send' : 'Con Precio (ENVIADAS)',	'Billed Recieved' : 'Con precio (RECIBIDAS)',	'Total Send' : ' TOTAL ENVIADAS',	'Total Recieved' : 'TOTAL RECIBIDAS',	'Not billed' : 'Sin precio',	'CSV' : 'CSV',	'Import Send' : 'Importe ENVIADAS',	'Pages Send' : 'Paginas ENVIADAS',	'Import Recieved' : 'Importe RECIBIDAS',	'Pages Recieved' : 'Paginas RECIBIDAS',	'Import' : 'Importe',	'Pages' : 'Páginas',	'Billed' : 'Con Precio',	'ILL printouts :: User Billing statistics' : 'ILL Listados:: Facturación a Usuarios',	'No se ha reconocido al usuario con estos datos como usuario registrado en el sistema. Puede modificarlo a continuación' : 'No se ha reconocido al usuario con estos datos como usuario registrado en el sistema. Puede modificarlo a continuación',	'Edit user' : 'Registrar Usuario',	'Graphics' : 'Gráficas',	'Serialized Journals' : 'Peticiones de revistas con datos no normalizados',	'Anio' : 'Año',	'ILL printouts :: Comunnity statistics' : 'ILL printouts :: Listado de peticiones por comunidad autónoma',	'sent_to' : 'Enviadas A:',	'recieved_from' : 'Recibidas De:',	'Comunnity' : 'Comunidad Autónoma',	'By all comunity' : 'Desglose todas comunidades',	'My community and rest' : 'Acumulado mi comunidad y el resto',	'Only my comunity' : 'Desglose mi grupo',	'my_comunity' : 'Mi comunidad',	'rest' : 'Resto de Comunidades',	'Totals sent' : 'Total enviadas a:',	'Totals recieved' : 'Total recibidos de:',	'Users not registered' : 'Usuarios no registrados',	'From date' : 'Fecha de inicio',	'To date' : 'Fecha de fin',	'There is no petition with that ID' : 'No hay ninguna petición con ese ID',	'Locate by ID' : 'Localizar por ID',	'Locate by multiple search criteria' : 'Localizar por otros términos de búsqueda',	'Ill :: Petition search' : 'Ill :: Buscador de peticiones',	'Others' : 'Otros',	'Fax' : 'Fax',	'Mail' : 'Correo ordinario',	'On hand' : 'En mano',	'Serial is not on our catalog' : 'La revista no está en nuestro catálogo',	'Pending number' : 'Número pendiente',	'No holdings for the indicated year' : 'Sin fondos para el año indicado',	'Unreceived number' : 'Número no recibido',	'No access to electronic publication' : 'Sin acceso a la publicación electrónica',	'On embargo yet' : 'Todavía en embargo',	'On binding' : 'En encuadernación',	'Wrong citation' : 'Cita errónea',	'On requester demand' : 'A petición del peticionario',	'Your search did not match any article on your repository' : 'No se encontró ningún artículo en su repositorio',	'Error: You have not selected a file. Operation cancelled' : 'Error: fichero no seleccionado. Operación cancelada',	'Success: The article has been added to your repository' : 'El artículo fue añadido a su repositorio correctamente',	'Success: The file has been updated.' : 'Fichero actualizado correctamente',	'There was a problem searching in Pubmed database. Please, try again later' : 'Hubo un problema en la búsqueda sobre Pubmed. Inténtelo de nuevo más tarde',	'Type in a PMID number and click Search button to start adding an article to your repository' : 'Introduzca un Id medline y pulse el botón de buscar para añadir un fichero a su repositorio',	'This action will locate articles in your repository matching indicated PMID. To add a new PMID to your repository, click Add new article button' : 'Esta acción localizará el artículo de su repositorio con el PMID indicado. Para añadir un nuevo artículo, haga click en el botón Añadir nuevo artículo',	'Add new article' : 'Añadir nuevo artículo',	'Ill - Repository' : 'Ill - Repositorio',	'Ill - Repository :: Search' : 'Ill - Repositorio :: Búsqueda',	'Ill - Repository :: Edit article' : 'Ill - Repositorio :: Editar artículo',	'Ill - Repository :: Add new article' : 'Ill - Repositorio :: Añadir nuevo artículo',	'Ill :: Editar artículo' : 'Ill:: Editar artículo',	'No results' : 'NO HAY RESULTADOS QUE MOSTRAR',	'There was a problem searching in Pubmed database' : 'Se ha producido un error consultando la base de datos de Pubmed',	'There was a problem searching in ILL17 email. Try again later' : 'Se ha producido un error consultando el correo ILL17. Inténtelo de nuevo más tarde',	'The article is already on your repository. Operation cancelled' : 'Este artículo ya existe en su repositorio. Operación cancelada',	'There was a problem searching in pubmed. Please, try again later.' : 'Se ha producido un error consultado Pubmed. Por favor, inténtelo de nuevo más tarde.',	'The search didn\'t return any matches' : 'Su búsqueda no produjo ningún resultado',	'There was an error getting the linkout. PLease try again later.' : 'Hubo un error accediendo al linkout. Por favor, inténtelo de nuevo más tarde.',	'Linkout' : 'Linkout',	'There is no Linkout links for this PMID' : 'No hay enlaces Linkout para este Id medline',	'There is no DOI link for this DOI number' : 'No hay enlace DOI para este número DOI',	'In process' : 'En proceso',	'Served' : 'Servidas',	'Rejected' : 'Rechazadas',	'Error: You must fill price and number of pages.' : 'Error: debe completar el precio y el número de páginas.',	'Notification billed successfully' : 'Notificación facturada correctamente',	'You have no permissions to bill this notification' : 'No tiene permisos para facturar esta notificación',	'Can\'t create the temporary file' : 'No se puede crear el fichero temporal',	'Petition blocked successfully' : 'Petición bloquedada correctamente',	'Error: Can not block the petition' : 'Error bloqueando la petición',	'Error: petition is not blockable' : 'Error: La petición no se puede bloquear',	'Petition unblocked successfully' : 'Petición desbloqueada correctamente',	'Error: Can not unblock the petition' : 'Error desbloqueando la petición',	'Error: petition is not unblockable' : 'Error: La petición no se puede desbloquear',	'Your request has been saved. Thanks.' : 'Sus datos han sido guardados correctamente. Gracias.',	'There was a problem saving your request. Please, try again later' : 'Error al guardar sus datos. Por favor, inténtelo de nuevo más tarde',	'Serial Title' : 'Título de la revista',	'Actions' : 'Acciones',	'Internal' : 'Interna',	'Internals' : 'Internas',	'Externa' : 'Externa',	'Sent' : 'Enviadas',	'External' : 'Externa',	'Only showing general actions' : 'Sólo acciones generales',	'For more specific ones, like sending messages or block the petition,' : 'Para más específicos, como envío de mensajes o bloquear la petición,',	'you should open the petition' : 'debería abrir la petición',	'Quick menu' : 'Salir del menú',	'Class' : 'Clase',	'Creation Date' : 'Fecha Creación',	'Requester user' : 'Solicitante',	'Article' : 'Artículo',	'Send to' : 'Cursada a',	'Messages' : 'Mensajes',	'Go' : 'Ir',	'DOI Link' : 'Enlace DOI',	'Authorization' : 'Autorizacion',	'Resend to User' : 'Reenviar al usuario',	'Type in first or last name' : 'Teclee su nombre o apellido',	'The email will show up here...' : 'El email se mostrará aquí...',	'Loading' : 'Cargando',	'Unblock petition' : 'Desbloquear petición',	'Block petition' : 'Bloquear petición',	'The petition has been blocked by your librarian. Contact him for further details' : 'La petición ha sido bloqueada por tu bibliotecario. Contacte con él para más detalles',	'Author' : 'Autor',	'Read' : 'Leer',	'Message' : 'Mensaje',	'No' : 'No',	'Yes' : 'Sí',	'Billing' : 'Facturación',	'Price' : 'Precio',	'total' : 'total',	'Number of pages' : 'Número de páginas',	'Historical' : 'Histórico',	'Incoming from user' : 'Solicitante',	'Sent to organisation' : 'Cursada a',	'sent to organisation' : 'cursada a',	'Incoming from organisation' : 'Biblioteca',	'Print' : 'Imprimir',	'Make reclamation' : 'Realizar reclamación',	'Add message' : 'Añadir mensaje',	'Serve' : 'Servir',	'Reserve' : 'Volver a servir',	'Reject' : 'Rechazar',	'Mark as served' : 'Marcar como servida',	'Mark as rejected' : 'Marcar como rechazada',	'Mark as read' : 'Marcar como leída',	'to historic' : 'Histórico',	'Resend to user' : 'Reenviar al usuario',	'Bill' : 'Facturar',	'Block' : 'Bloquear',	'Blocked' : 'Bloqueada',	'Download file' : 'Descargar archivo',	'Add file' : 'Añadir archivo',	'Modify file' : 'Modificar archivo',	'Edit article' : 'Editar artículo',	'Resend to library' : 'Reenviar a la biblioteca',	'Send rejected' : 'Envio rechazado',	'The petition has been successfully rejected' : 'La petición ha sido rechazada con éxito',	'Your petition has been successfully sent' : 'La petición ha sido enviada con éxito',	'Petition marked successfully' : 'La petición ha sido marcada con éxito',	'New message in' : 'Nuevo mensaje',	'ILL17' : 'ILL17',	'Direct Access' : 'Acceso directo',	'Is this the article you were looking for?' : '¿Es éste el artículo que buscaba?',	'Saving' : 'Guardando',	'Select the file to add' : 'Seleccione el fichero a adjuntar',	'Back to list' : 'Volver a la lista',	'Comunity' : 'Comunidad',	'Delete All' : 'Eliminar todas',	'Querying C17...' : 'Consultando C17...',	'Email view' : 'Vista email',	'Email info' : 'Datos email',	'From' : 'Remitente',	'Subject' : 'Asunto',	'Email data' : 'Contenido email',	'Hubo un problema en la búsqueda sobre ILL17. Inténtelo de nuevo más tarde' : 'Hubo un problema en la búsqueda sobre ILL17. Inténtelo de nuevo más tarde',	'File information' : 'Datos archivo',	'File name' : 'Nombre del archivo',	'Size' : 'Tamaño',	'Download' : 'Descargar',	'File exists?' : '¿Existe el archivo?',	'The file exists' : 'El archivo existe',	'The file does not exists' : 'El archivo no existe',	'Querying Ill17 for pending petitions...Please wait.' : 'Consultando peticiones pendientes en ILL17... Espere, por favor.',	'Querying Ill17 for petitions in process...Please wait.' : 'Consultando peticiones en proceso en ILL17... Espere, por favor.',	'Querying Ill17 for served petitions...Please wait.' : 'Consultando peticiones servidas en ILL17... Espere, por favor.',	'Querying Ill17 for rejected petitions...Please wait.' : 'Consultando peticiones rechazadas en ILL17... Espere, por favor.',	'Querying Ill17 for historical petitions...Please wait.' : 'Consultado histórico de peticiones en  Ill17... Espere, por favor.',	'Mails' : 'Emails',	'Querying Ill17 for email petitions...Please wait.' : 'Consultando peticiones por email en ILL17... Espere, por favor.',	'Mark petition as' : 'Marcar petición como',	'Please, select one' : 'Por favor, seleccione una',	'Modify File' : 'Modificar archivo',	'Select the file to replace the original' : 'Seleccione el archivo para sustituir el original',	'User data' : 'Datos del usuario',	'Organisation data' : 'Datos de la biblioteca',	'Operations' : 'Operaciones',	'Rejection form' : 'Formulario rechazar',	'Locate File' : 'Localizar fichero',	'Querying pubmed...' : 'Consultando pubmed...',	'Search Results' : 'Resultados de la búsqueda',	'Article Title' : 'Título del artículo',	'StartPage' : 'Página de inicio',	'End Page' : 'Página fin',	'Select the file to ADD' : 'Seleccione el archivo a adjuntar',	'Edit file' : 'Editar archivo',	'Locate by PMID' : 'Localizar PMID',	'Serial title or ISSN' : 'Título de la revista o ISSN',	'Serial title or ISSN only search in serials into the C17 catalog' : 'La búsqueda por título de revista o ISSN sólo se realizará en revistas pertenecientes al catálogo del C17',	'Article ID' : 'ID de artículo',	'Resend form' : 'Formulario de reenvío',	'Service form' : 'Formulario servir',	'Querying Ill17 for pendings petitions' : 'Consultando peticiones pendientes en ILL17',	'Querying Ill17 for served petitions' : 'Consultando peticiones servidas en ILL17',	'Querying Ill17 for rejected petitions' : 'Consultando peticiones rechazadas en ILL17',	'Short version' : 'Version reducida',	'Folder' : 'Bandeja',	'Petition type' : 'Tipo de petición',	'Created in' : 'Creada el',	'and solved in' : 'y resuelta el',	'Repository' : 'Repositorio',	'Repository access' : 'Acceso al repositorio',	'The file is available trough your ILL repository' : 'El fichero está disponible a través de su repositorio. Descargar aquí',	'Requester data' : 'Datos del peticionario',	'Owned' : 'Propia',	'Searching in your holdings...' : 'Buscando en sus fondos...',	'No holdings' : 'Sin fondos',	'Querying C17 for holdings...' : 'Buscando fondos en el C17...',	'Organisation list' : 'Lista de bibliotecas',	'You can send the petition to the library you want' : 'Puedes enviar la petición a la biblioteca que quieras',	'Serve File' : 'Servir archivo',	'Succesfull: Template created and assigned!!!' : 'Plantilla creada y asignada con éxito!!!',	'Succesfull: Template updated!!!' : 'Plantilla actualizada con éxito!!!',	'Succesfull: Template unassigned!!!' : 'Plantilla desasignada con éxito!!!',	'Template updated successfully' : 'Plantilla actualizada con éxito',	'back ficha general' : 'Volver Ficha General',	'new search' : 'Nueva búsqueda',	'Kardex - Ficha Anual' : 'Kardex - Ficha Anual',	'Kardex - Edition Template' : 'Kardex - Edición Plantilla',	'Suppliers' : 'Suministradores',	'Kardex create fasc template' : 'Kardex - Creación Plantilla Fascículos',	'Kardex create text template' : 'Kardex - Creación Plantilla Texto',	'Vol field must be completed' : 'El campo volumen debe ser completado',	'Fasc field must be completed' : 'El campo Fs debe ser completado',	'Test field must be completed' : 'El campo texto debe ser completado',	'field must be completed' : 'Este campo debe ser completado',	'first_fasc field or renumbering field must be completed' : 'El campo \'reiniciar numeración\' o \'primer fascículo\' debe ser completado',	'Templates approvation' : 'Plantillas :: Aprobación',	'Days left' : 'Recepción en los próximos ',	'Invalid ISSN' : 'ISSN inválido',	'Inexistent year in fondos' : 'No hay fondos para este año',	'asigned template' : 'Plantilla asignada',	'current template' : 'Existe plantilla',	'You must fill every publication date' : 'Debe rellenar todas las fechas de publicación',	'fecha_publicacion field must be completed' : 'El campo Fecha publicación debe ser completado',	'Be careful with this template' : '¡Atención! \\n Esta revista tiene asociado un suplemento. NO dé de alta fascículos del suplemento en la plantilla de la revista',	'Collection' : 'Colección',	'Holding type' : 'Tipo de fondo',	'Holding' : 'Fondo',	'Not to claim' : 'No reclamación',	'Kardex printouts' : 'Kardex :: Informes',	'Kardex :: Printouts :: Open paper holdings without record for current year' : 'Kardex :: Listados :: Fondos abiertos en papel sin plantilla en año actual',	'Kardex :: Printouts :: Fascicles marked as not to claim anymore' : 'Kardex :: Listados :: Fasciculos marcados para no volver a reclamar',	'Kardex :: Printouts :: Fascicles not received yet' : 'Kardex :: Listados :: Fascículos pendientes de recepción',	' doesn\'t belong to your holdings: modify holdings and send.' : ' Este año no pertenece a los fondos: modifíquelos y envíelos.',	'Template approved successfully' : 'Plantilla aprobada con éxito',	'Template deleted successfully' : 'Plantilla eliminada con éxito',	'Template saved successfully' : 'Plantilla guardada con éxito',	'Claim' : 'Reclamación',	'Claims' : 'Reclamaciones',	'Claims generated successfully' : 'Reclamación generada con éxito',	'Claim sent successfully' : 'Reclamación enviada con éxito',	'Please print and send this claim to the supplier. We have already marked it as sent' : 'Por favor, imprima y envíe esta reclamación al suministrador. Ya ha sido marcada como enviada',	'Claim deleted successfully' : 'Reclamación eliminada con éxito',	'Days to add to the current date for setting the estimated reception date for the claimed issues' : 'Número de días a añadir a la fecha actual para actualizar la fecha estimada de reclamación para los fascículos reclamados',	'Claim data' : 'Carta de Reclamación',	'Pleas, click the print button' : 'Por favor, pinche en el botón Imprimir',	'No issues to claim' : 'Debe seleccionar al menos un fascículo para generar una reclamación',	'not exist issues to claim' : 'No existen fascículos para reclamar',	'Unknown provider' : 'Suministrador desconocido',	'Can no edit a template for assigning provider without year AND serial' : 'No se puede asignar un suministrador sin un año y una revista',	'Supplier saved successfully' : 'Suministrador guardado con éxito',	'Supplier deleted successfully' : 'Suministrador eliminado con éxito',	'Your search did not match any serial with paper holdings from your current organisation' : 'No se encontró ninguna revista con fondos en papel para tu biblioteca actual.',	'Success: Providers updated successfully' : 'Suministradores actualizados con éxito',	'You have no kardex records for the selected date range' : 'No existe información kardex para el rango de fechas elegido',	'You are trying to assign providers to records not present in anual data' : 'Estás intentando asignar suministradores a fascículos que no pertenecen a la ficha anual',	'kardex - Add Suministradores' : 'kardex - Alta Suministradores',	'Kardex - Assign Supplier' : 'Kardex - Asignación Suministradores',	'Kardex create template' : 'Kardex Creación Plantillas',	'Assign this supply type to all records selected' : 'Asignar este tipo de suministro a todos los fascísculos selecionados',	'Assign provider between two dates' : 'Asignar proveedor entre dos fechas',	'Starting date' : 'Fecha de inicio',	'Ending date' : 'Fecha de fin',	'Can not be empty' : 'No puede ser vacío',	'You must select a provider' : 'Debe seleccionar un proveedor',	'Only showing years with any record created' : 'Sólo se muestran años con alguna ficha creada',	'Supply type' : 'Tipo de suministro',	'Kardex - Assign Supplier By Default' : 'Kardex - Asignación de suministradores por defecto',	'Assign provider by default' : 'Asignar suministrador por defecto',	'Interval' : 'Intervalo',	'Assigned provider by default' : 'Suministrador asignado por defecto',	'Template for' : 'Plantilla para',	'Choose the template type' : 'Elige el tipo de plantilla',	'Fascicle template' : 'Plantilla kardex-fascículos',	'Text template' : 'Plantilla kardex-texto',	'Create selected template' : 'Crear plantilla seleccionada',	'start numeration' : 'Reiniciar numeración',	'first vol' : 'Primer volumen',	'first fasc' : 'Primer fascículo',	'regular recurrence' : 'Periodicidad',	'language' : 'Idioma',	'number vols' : 'Número de volúmenes',	'renumbering' : 'Reiniciar numeración',	'Vol' : 'Vol',	'Fs' : 'Fs',	'Cover date' : 'Fecha portada',	'Publication date' : 'Fecha publicación',	'Expected date' : 'Fecha estimada recep.',	'Receipt date' : 'Fecha recepción',	'Start' : 'Pág.Ini',	'End' : 'Pág.Fin',	'Num Recl' : 'Num Recl',	'Do not claim' : 'No volver reclamar',	'Notes' : 'Notas',	'Receipt all' : 'Recepcionar todos',	'Are you sure to receipt all' : '¿Desea recepcionar TODOS los fascísculos?',	'Are you sure to unassign template' : '¿Desea desasignar la plantilla?',	'Do not claim anyone' : 'No volver reclamar',	'Not to assign' : 'Desasignar plantilla',	'Previous year' : 'Año anterior',	'Next year' : 'Año siguiente',	'Edit template' : 'Editar plantilla',	'Text' : 'Texto',	'Publishing Date' : 'Fecha publicación',	'Add issue' : 'Añadir fascículo',	'Delete issue' : 'Eliminar fascículo',	'Add_issue' : 'Añadir registro',	'Del_issue' : 'Eliminar registro',	'Approve' : 'Aprobar',	'Organisations using this template' : 'Bibliotecas que tienen asignada esta plantilla',	'Approved' : 'Aprobada',	'Generic template' : 'Plantilla genérica',	'Day' : 'Día',	'Month' : 'Mes',	'Estimated reception date' : 'Fecha estimada recepción',	'Claim selected issues' : 'Reclamar los fasciculos seleccionados',	'Issues to claim' : 'Fascículos a reclamar',	'Issues without supplier' : 'Fascículos sin suministrador',	'Not implemented' : 'No implementado',	'Not sent' : 'No enviadas',	'Supplier' : 'Suministrador',	'Generation date' : 'Fecha generación',	'Isues count' : 'Número de fascículos',	'Send date' : 'Enviar fecha',	'Generate new claims' : 'Generar nueva reclamación',	'You must enter a numeric value' : 'Debes introducir un valor numérico',	'How many days from today want you to add to estimated recpetion day for claimed issues?' : '¿Cuántos días desde hoy quieres sumar a la fecha estimada de recepción para fascículos reclamados?',	'Reception date' : 'Fecha de recepción',	'back claims' : 'Volver a reclamaciones',	'Helpers' : 'Asistentes',	'Assign this provider to all records selected' : 'Assignar este suministrador a todos los fascículos seleccionados',	'Select All' : 'Seleccionar todo',	'Assign' : 'Asignar',	'CIF' : 'CIF',	'Postal code' : 'Código Postal',	'Telephone' : 'Teléfono',	'Contact person' : 'Persona de contacto',	'Claim type' : 'Tipo de reclamación',	'Supplier data' : 'Información del suministrador',	'Code or Name' : 'Código o nombre',	'Assign to serials' : 'Asignar a revistas',	'Search in my paper holdings' : 'Buscar en mis fondos de papel',	'You have no record created for this year. If you want to create a new one, click' : 'No tienes ningún registro creado para este año. Si quieres crear uno, pulsa ',	'here' : 'aquí',	'Edit provider for' : 'Editar suministrador para',	'Edit provider for several years' : 'Editar suministrador para varios años',	'**** EXAMPLE TEXT TEMPLATE ****' : '**** EJEMPLO PLANTILLA TEXTO ****',	'Need fascs 5 y 6 ' : 'Faltan fascículos 5 y 6 ',	'Kardex card for' : 'Ficha kardex para',	'delete template' : 'Eliminar plantilla',	'Extra data' : 'Información adicional',	'Rebiun code' : 'Código Rebiun',	'Departament' : 'Departamento',	'Alert!' : '¡¡ Alerta !!',	'Advice!' : '¡¡ Aviso !!',	'Advice' : 'Aviso',	'Alert shown until' : 'Mostrar alerta hasta',	'Acceso' : 'Acceso',	'Precio' : 'Precio',	'Email address' : 'Email',	'Cindoc' : 'Cindoc',	'Cindoc data' : 'Datos Cindoc',	'Ill17 email address' : 'Email Ill17',	'SOD' : 'SOD',	'SOD email address' : 'Email SOD',	'Organisation updated successfully' : 'Biblioteca actualizada correctamente',	'Success: Librarian in charge updated.' : 'Biblioteca actualizada correctamente.',	'Success: Librarian in charge registered.' : 'Biblioteca registrada correctamente.',	'Success: Librarian in charge deleted.' : 'Biblioteca eliminada correctamente.',	'Preferences updated successfully' : 'Preferencias actualizadas correctamente',	'Services' : 'Servicios de Préstamo',	'There was a problem changing the notification service' : 'Hubo un problema cambiando la notificación del servicio',	'Notification service changed successfully' : 'Notificación del servicio modificada correctamente',	'Master organisation' : 'Biblioteca directora',	'Your organisation does not belong to any organisation' : 'Tu biblioteca no pertenece a ningún consorcio',	'C17+' : 'C17+',	'K17' : 'K17',	'P17+' : 'P17+',	'P17' : 'P17',	'Details' : 'Detalles',	'Location' : 'Localidad',	'Address 1' : 'Dirección',	'ZIP/Postal Code' : 'ZIP/Código Postal',	'Country' : 'País',	'Contact' : 'Contacto',	'Organisation Responsables' : 'Responsables biblioteca',	'Make peticion' : 'Realizar petición',	'Notification email' : 'Email de notificación',	'Logo image' : 'Logo',	'Organisation logo' : 'Logo de la biblioteca',	'Photo image' : 'Foto',	'Organisation foto' : 'Foto de la biblioteca',	'CINDOC' : 'CINDOC',	'CINDOC account' : 'Cuenta CINDOC',	'CINDOC password' : 'Contraseña CINDOC',	'C17 PLUS' : 'C17 PLUS',	'Borrowing services' : 'Servicios de préstamo',	'Library code/name' : 'Código/Nombre Biblioteca',	'Library order' : 'Orden biblioteca',	'Up' : 'Arriba',	'Down' : 'Abajo',	'Remove' : 'Eliminar',	'Show serial and supplements issues merged' : 'Mostrar fascículos de revistas y suplementos mezclados',	'Days to claim issues after publication' : 'Número de días después de la fecha de publicación para reclamar fascículos',	'Receive new article notification' : 'Recibir notificación de nuevo artículo',	'Text to appear on your claims' : 'Texto que aparecerá en sus reclamaciones',	'Type responsable' : 'Tipo de responsable',	'Is User' : 'Es usuario',	'Are you sure want to delete this person in charge?' : '¿Estás seguro que deseas eliminar este responsable?',	'Librarian in charge' : 'Biblioteca a cargo',	'Select type' : 'Selecciona tipo responsable',	'Is the user registered in the system?' : '¿Está registrado este usuario en el sistema?',	'User registered' : 'Usuario registrado',	'Current user is: ' : 'El usuario actual es: ',	'User not registered' : 'Usuario no registrado',	'First surname' : 'Primer apellido',	'Add responsable' : 'Añadir responsable',	'Currently assigned service' : 'Servicio asignado actualmente',	'No service assigned' : 'Sin servicio asignado',	'To change your current sevice, please select from the box bellow and click' : 'Para cambiar tu servicio actual, selecciónalo abajo y pulsa.',	'Next' : 'Siguiente',	'Services availables' : 'Servicios disponibles',	'Can not read the file' : 'Error: no se puede leer el fichero',	'A ISSN and a holding string must be in the document' : 'Al menos un ISSN y una línea de fondos deben ir en el documento',	'WARNING:' : 'ALERTA:',	'The field' : 'El campo',	' will be ignored' : ' será ignorado',	'There was a problem inserting the collection' : 'Hubo un problema insertando la colección',	'No holdings will be deleted' : 'No se eliminará ningún fondo',	'There was a problem updating the collection' : 'Hubo un problema actualizando la colección',	'Both ISSNs missing' : 'Faltan los dos ISSNs',	'There is no serial in our DB with this ISSNs' : 'No hay ninguna revista en nuestra base de datos con estos ISSNs',	'Missing holding string' : 'Falta línea de fondos',	'Embargo must be an integer value' : 'Embargo debe ser un campo numérico',	'Errors' : 'Errores',	'You have no collections to update' : 'No tiene colecciones a actualizar',	'Success: The collection has been correctly updated' : 'La colección ha sido actualizada correctamente',	'Success: The collection has been correctly imported' : 'La colección ha sido importada correctamente',	'Select own collection' : 'Seleccionar la colección propia',	'Add new collection' : 'Añadir nueva colección',	'Add collection' : 'Añadir colección',	'Subscribible collections' : 'Colecciones suscribibles',	'Select the file to upload' : 'Seleccione el fichero',	'Collection importer' : 'Importador de la colección',	'Collection name' : 'Nombre de la colección',	'The package file is on our systems. Everything seems ok' : 'El archivo del paquete está en nuestro sistema. Todo parece correcto',	'By pressing Send button, the importation process will start' : 'Pulsando el botón enviar, se iniciará el proceso de importación.',	'Importing results' : 'Resultados de la importación',	'Download full report with problem locations' : 'Descargar informe completo con anotación de errores',	'Select the action' : 'Seleccione la acción',	'Update' : 'Actualizar',	'Replace' : 'Reemplazar',	'Select the collection' : 'Seleccione colección a tratar',	'Working with collection' : 'Trabajando con la colección',	'Please select the package file from your computer' : 'Por favor, seleccione el fichero de actualización',	'A ISSN or Title and a holding string must be in the document' : 'Un título o un ISSN y una línea de fondos deben estar en el documento',	'Wrong CSV headings. Check help for more information' : 'Encabezados de CSV erróneos. Comprueba la ayuda para más detalles sobre como organizar el fichero de importación.',	'Download addings report' : 'Descargar informe de inserciones',	'I want to finish the import process, ignoring errors' : 'Quiero finalizar el proceso de importación, ignorando los errores',	'Import checking results' : 'Resultado del chequeo de importación',	'Updating collection' : 'Actualizando colección',	'Number of insertions' : 'Número de fondos que se añadirán',	'Updating reason' : 'Motivo de actualización',	'Collection successfully updated' : 'Colección actualizada correctamente',	'successfully updated' : 'actualizada correctamente',	'Full report' : 'Informe completo',	'Download full report' : 'Descargar informe completo',	'Please notice that this action will REPLACE all the holdings from one type (paper or electronic) from the package with the file ones' : 'Por favor, tenga en cuenta que esta acción REEMPLAZARÁ todos los fondos de un tipo (electrónico o papel) de la colección por los del fichero',	'Wrong CSV headings. In a replacement operation, the column holding type MUST be present (heading "tipo_de_fondo" with column value P or E)' : 'Cabeceras CSV inválidas. En una operación de reemplazo, la columna Tipo de fondo es OBLIGATORIA (cabecera "tipo_de_fondo" con "P" o "E" como valores de columna, todo sin comillas)',	'Paper' : 'Papel',	'Electronic' : 'Electrónico',	'Download deletion report' : 'Descargar el informe de eliminaciones',	'Replacing collection' : 'Reemplazando colección',	'successfully replaced' : 'reemplazada correctamente',	'Collection successfully replaced' : 'Colección reemplazada correctamente',	'You have no subscribible collections to update' : 'No tiene colecciones suscribibles para actualizar',	'Holding string' : 'La línea de fondos',	'was deleted' : 'se borra',	'Holding string changed from' : 'La línea de fondos pasa de',	'was added' : 'se añade',	'URL changed from' : 'La URL pasa de',	'Download updates report' : 'Descargar informe de actualizaciones',	'Can not save the holding. URL and Provider ID can not be filled at the same time.' : 'No se pueden guardar los fondos. La URL y el id del suministrador no pueden ser completados al mismo tiempo.',	'Can not save the holding. Please, fill the missing data.' : 'No se pueden guardar los fondos. Por favor, complete la información que falta.',	'The collection has no holdings. You can add serials performing a search and clicking Add button on the desired serial.' : 'La colección no tiene fondos. Puede añadir revistas realizando una búsqueda y pulsando el botón añadir sobre la revista deseada.',	'Error: You are master organisation of no consortium' : 'Error: eres biblioteca directora de ningún consorcio',	'Success: Collection updated successfully' : 'Colección actualizada con éxito',	'Your search did not match any serial' : 'No se encontró ninguna revista.',	'The holding has been added succesfully' : 'Los fondos han sido añadidos correctamente.',	'Holding updated succesfully' : 'Fondos actualizados correctamente',	'Missing package name' : 'Error: falta el nombre del paquete',	'Packages' : 'Paquetes',	'Free Collections in OPAC' : 'Colecciones libres en el OPAC ',	'package - editHolding' : 'Paquetes - Edición de fondos',	'Package - addHoldings' : 'Paquetes - Inserción de fondos',	'This package name already exists' : 'Ya existe un paquete con este nombre',	'P17 :: Package view' : 'P17 :: Ver paquete',	'P17 :: Package edit' : 'P17 :: Editar paquete',	'P17 :: Package management' : 'P17 :: Gestión de paquetes',	'Edit visibility' : 'Editar visibilidad',	'Holding not found!' : 'Fondos no encontrados!',	'Error: No serial ID received' : 'Error: Ningún ID de revista recibido',	'There is no library with holdings for that serial' : 'No hay ninguna biblioteca con fondos para esta revista',	'There is no holdings for this serial and organisation' : 'No hay fondos para esta revista y biblioteca',	'You have no permission to modify this collection.' : 'No tienes permiso para modificar esta colección.',	'The holding is not present on the collection.' : 'Los fondos no pertenecen a la colección.',	'Multiple holdings for one serial.' : 'Varios fondos para una revista.',	'There was a problem deleting the holding. Operation aborted.' : 'Hubo un problema eliminando los fondos. Operación abortada.',	'Holding deleted successfully' : 'Fondos eliminados correctamente',	'months' : 'Meses',	'Electronic Holdings' : 'Fondos electrónicos',	'Paper Holdings' : 'Fondos en papel',	'Importer' : 'Importador',	'Your subscription request has queued successfully. The suscription will be complete on 24h' : 'Tus peticiones de suscripcion se ha agregado a la cola de procesos correctamente. La suscripción será completada en 24h.',	'Total holdings' : 'Fondos totales',	'Package suscription' : 'Suscripción de paquetes',	'Request' : 'Petición',	'P17 :: Package suscription' : 'P17 :: Suscripción de paquetes',	'Total organisations' : 'Total bibliotecas',	'Editing visibility of collection' : 'Editando visibilidad de la colección',	'for consortium' : 'para el consorcio',	'Visible' : 'Visible',	'Subscribed' : 'Suscrita',	'Mark All as visible' : 'Marcar todo como visible',	'Mark All as subscribed' : 'Marcar todo como subscrito',	'Search serial' : 'Búsqueda de una revista',	'Title or ISSN' : 'Título o ISSN',	'Only in the current package: ' : 'Sólo en el paquete actual: ',	'Disable this to search any serial' : 'Deshabilitar ésto para buscar cualquier revista',	'Serials in collection' : 'Revistas de la colección',	'Inherited' : 'Heredado',	'Adding holding to collection: ' : 'Editando la colección: ',	'Editing collection: ' : 'Colección: ',	'Resource Holdings' : 'Origen de los fondos',	'Holding data: ' : 'Datos fondos: ',	'Number of insertions will be made' : 'Número de inserciones a realizar',	'Number of errors detected' : 'Número de errores detectados',	'If you want to check the errors detected, you can download the following CSV file for further details' : 'Si quiere comprobar los errores detectados, puede descargar el fichero CSV para más detalles',	'Select the collection from the list and the package file from your computer' : 'Selecciona la colección de la lista y el archivo del paquete de tu ordenador',	'Select the file' : 'Selecciona el archivo',	'Please notice that this action will REPLACE all the holdings from the package with the file ones' : 'Esta acción SUSTITUIRÁ todos los fondos del paquete con los del archivo.',	'By pressing Send button, the replace process will start' : 'Pulsando el botón enviar iniciará el proceso de sustitución',	'CAUTION:' : 'PRECAUCIÓN:',	'Notice that this process will replace all the holdings from the collection with the file ones' : 'Este proceso reemplazará todos los fondos de la colección con los del archivo',	'Number of holdings deleted' : 'Número de fondos eliminados',	'Please notice that this action will only add new holdings to the collection and update the holdings line already present on the package' : 'Esta acción sólo añadirá a la colección los fondos nuevos y actualizará aquellos que ya existían en el paquete.',	'By pressing Send button, the updating process will start' : 'Pulsando el botón de enviar se iniciará el proceso de actualización',	'Number of holdings detected but not changed' : 'Número de fondos detectados pero no modificados',	'Number of updates will be made' : 'Número de actualizaciones que se realizarán',	'Add new package' : 'Añadir un paquete nuevo',	'Packages list' : 'Lista de paquetes',	'Edit Visibility' : 'Editar visibilidad',	'You must fill this field' : 'Debe completar este campo',	'Choose the consortium you wat to edit the visibility of' : 'Elige el consorcio para el que quieras editar la visibilidad',	'collection' : 'Colección',	'Select the consortium' : 'Selecciona el consorcio',	'Consortium' : 'Consorcio',	'Collections visible to your organisation' : 'Colecciones visibles por su biblioteca',	'You have no collections to subscribe' : 'No tiene colecciones para subscribirse',	'Serial approved successfully' : 'Revista aprobada con éxito',	'There is no serials to aprove' : 'No hay revistas por aprobar',	'Url' : 'Url',	'Publicacion place saved successfully' : 'Lugar de publicación guardado correctamente',	'There is no serial with historical notes pending' : 'No hay ninguna revista con notas históricas pendientes',	'Historical notes saved successfully' : 'Notas históricas guardadas con éxito',	'Historical notes deleted successfully' : 'Notas históricas eliminadas correctamente',	'Relationship type' : 'Tipo de relación',	'Serial added successfully' : 'Revista añadida correctamente',	'Serial updated successfully' : 'Revista actualizada correctamente',	'Serials' : 'Revistas',	'Value is empty, but a non-empty value is required' : 'Debe completar este campo',	'Add new variant title' : 'Añadir nueva variante de título',	'Add new variant cancelled ISSN' : 'Añadir nueva variante ISSN cancelado',	'Serials approvation' : 'Aprobación revistas',	'Serials :: Search' : 'Revistas :: Buscar',	'Serials :: View' : 'Revistas :: Ver',	'Serials :: Add' : 'Revistas :: Añadir',	'Serials :: Edit' : 'Revistas :: Editar',	'Serial added successfully. Now you can edit the holdings for it' : 'Revista añadida correctamente. Ahora puede añadir los fondos si lo desea',	'Invalid anio_fin' : 'No puede ser inferior al año de inicio',	'Invalid anio_electronico' : 'No puede ser inferior al año de inicio',	'Titles' : 'Títulos',	'ISSNs' : 'ISSNs',	'Publication info' : 'Información de publicación',	'No publicaction place was defined' : 'El lugar de publicación no fue definido',	'First year' : 'Año de inicio',	'Last year' : 'Año fin',	'Year of electronic publication only' : 'Año de sólo publicación electrónica',	'Catalogs' : 'Catálogos',	'Catalog' : 'Catálogo',	'Original' : 'Original',	'Approved copy' : 'Copia aprobada',	'Historical notes' : 'Notas históricas',	'Add new serial' : 'Añadir nueva revista',	'Country selection' : 'Selección del país',	'Add new publication place' : 'Añadir nuevo lugar de publicación',	'Insert' : 'Insertar',	'Checking for duplicate' : 'Comprobando duplicados',	'please wait' : 'espere, por favor',	'There is no publication places for this country' : 'No hay lugares de publicación para este país',	'Ese lugar de publicación ya existe. Operación abortada' : 'Ese lugar de publicación ya existe. Operación abortada',	'Edit tree' : 'Editar árbol',	'Insert new branch' : 'Insertar nueva rama',	'Delete selected branch' : 'Eliminar rama seleccionada',	'Global subject trees' : 'Árboles de materias globales',	'Consortium subject trees' : 'Árboles de materias de consorcio',	'Your organisation subject tree' : 'Árbol de materias de su biblioteca',	'Your organisation tree' : 'Árbol de su biblioteca',	'Do you want to create a new subject tree?' : '¿Desea crear algún árbol de materia nuevo?',	'C17 subjects' : 'Materias C17',	'Group subjects' : 'Materias de grupo',	'Organisations subjects' : 'Materias de bibliotecas',	'Add note' : 'Añadir nota',	'Text note' : 'Texto',	'Public' : 'Pública',	'user successfully added' : 'Usuario añadido correctamente',	'Selected email is available' : 'Dirección de correo disponible',	'Your search' : 'Su búsqueda',	'User details successfully updated' : 'Usuario actualizado correctamente',	'This username already exist in the DB, please choose another' : 'Este usuario ya existe en la base de datos, por favor elija otro',	'This email already exist in the DB, please choose another' : 'Este email ya existe en la base de datos, por favor elija otro',	'You must enter a password' : 'Debe introducir una contraseña',	'Password must be more than 5 characters' : 'La contraseña debe tener más de 5 caracteres',	'Please confirm password' : 'Por favor, escriba de nuevo la contraseña',	'Passwords are not the same' : 'Las contraseñas no coinciden',	'You must enter a username' : 'Debe introducir un usuario',	'username min length' : 'Longitud mínima usuario',	'You must select at least one role' : 'Debe seleccionar al menos un rol',	'First Name, Last Name, Username, Email' : 'Nombre, Apellidos, Usuario, Email',	'Inactive' : 'Deshabilitado',	'Deactivate' : 'Deshabilitar',	'Activate' : 'Habilitar',	'Activate/Deactivate' : 'Habilitar/Deshabilitar',	'Add new user' : 'Añadir nuevo usuario',	'authentication required' : 'Por favor, introduzca su usuario y contraseña',	'Managers' : 'Gestores',	'Users' : 'Usuarios',	'Services MD' : 'Servicios',	'Roles MD' : 'Cargos',	'Services enabled for organisation' : 'Servicios disponibles para asignar a los usuarios',	'Roles enabled for organisation' : 'Roles disponibles para asignar a los usuarios',	'Type here service name' : 'Edite aquí el nombre del servicio existente o escriba el nombre del nuevo servicio',	'Type here role name' : 'Edite aquí el nombre del cargo existente o escriba el nombre del nuevo cargo',	'Your email is invalid at this time. You should change it as soon as possible. To do that, click' : 'Su email no es válido en estos momentos. Debería cambiarlo lo antes posible. Para hacerlo, haga click',	'There is no resposible for your organisation' : 'No hay ningún responsable para tu biblioteca',	'You must fill in this field' : 'Debe completar este campo',	'Email Service' : 'Email Préstamo',	'Show left blocks by default?' : '¿Mostrar bloque de información?',	'Default org' : 'Biblioteca por defecto',	'Check Availability' : 'Comprobar disponibilidad',	'Organisation name' : 'Nombre Biblioteca',	'Role' : 'Rol',	'role' : 'rol',	'Hiring' : 'Contratación',	'Publication Places' : 'Lugares de publicación',	'Generic Templates' : 'Plantillas genéricas',	'Your current organisation is now ' : 'Tu biblioteca actual es ahora ',	'change current organisation' : 'Cambio biblioteca actual',	'Change organisation' : 'Cambiar biblioteca',	'select organisation' : 'Seleccionar biblioteca',	'Organisation Manager' : 'Biblioteca: gestor',	'Access' : 'Acceso',	'Can not notify messages between two only C17 librarys' : 'No se pueden notificar mensajes entre dos bibliotecas sólo con C17+',	'Organisation ID is empty' : 'No se encuentra el ID de biblioteca',	'Can not build the message. Unknown type' : 'No se puede construir el mensaje. Tipo desconocido.',	'Can not resend a non existing file' : 'No se puede reenviar un fichero inexistente',	'User and org can not be filled out at the same time' : 'El usuario y la biblioteca no se pueden rellenar al mismo tiempo',	'You have not set the operation mode yet' : 'No se ha establecido el modo de operación',	'A new message incoming from' : 'Nuevo mensaje de',	'New incoming petition from' : 'Nueva petición de ',	'Can not notify a served petition un full C17 mode' : 'No se puede notificar una petición el modo C17 total.',	'Your article request has been resolved by' : 'Su petición de artículo ha sido resuelta por',	'Your article request has been resolved' : 'Su solicitud de artículo ha sido resuelta',	'Can not set the operation mode' : 'No se puede establecer el modo de operación',	'The organisation has no notification service assigned' : 'La biblioteca no tiene ningún servicio de notificación asignado.',	'The responder organisation can not be notified. No confirmation mail configured yet.' : 'La biblioteca destinataria no puede ser notificada. No tiene configurado ningún email de confirmación todavía.',	'New incoming petition to your ILL17' : 'Nueva petición a su bandeja de ILL17',	'Confirmation email' : 'Email de confirmaciones',	'Confirm' : 'Confirmar',	'Preferences' : 'Preferencias',	'Preferences :: Organisation' : 'Preferencias :: Biblioteca',	'Legal advice' : 'Aviso legal',	'Alert for your OPAC' : 'Alerta OPAC',	'You must fill in date field' : 'Debe completar este campo con la fecha',	'Balance year from' : 'Mostrar balance desde',	'Select messages alternative view' : 'Mostrar vista alternativa de los mensajes',	'Assign journals to subjects' : 'Asignar revistas a materias',	'Service/Department' : 'Servicio/Departamento',	'Place of work' : 'Centro de Trabajo',	'Solicitud de Documentos' : 'Solicitud de documentos',	'Select your reference centre' : 'Seleccione su centro de referencia',	'Password Reminder' : 'Recordatorio de contraseña',	'Successfull update' : 'Actualización realizada con éxito',	'Are you sure?' : '¿Está seguro?',	'organisation_id is empty' : 'Error: identificador de biblioteca vacío',	'How to query C17' : 'Cómo consultar el C17',	'How often is C17 data updated' : 'Con qué periodicidad se actualizan los datos del C17',	'Which are the requirements to join C17 catalog' : 'Qué requisitos han de cumplir las bibliotecas del C17',	'How can I include a new library into C17 catalog' : 'Cómo incluir una nueva biblioteca en el C17',	'How much cost belongs to C17' : 'Cuánto cuesta pertenecer al C17',	'Which are the free services for C17 members' : 'Qué servicios pueden obtener de forma gratuita las bibliotecas participantes en el C17',	'How can I update my C17 data' : 'Cómo actualizar los datos del C17',	'Wich are C17 rules' : 'Qué normas se emplean en el C17',	'The CD version can be queried as well' : 'También se puede consultar en la versión en soporte CD-ROM',	'The C17 catalog is updated online by the librarys. Universities and other centers with a high number of collections, update their catalog once a year at least, trough ISO standard complaint files' : 'Cada biblioteca puede actualizar sus datos online. En el caso de Universidades u otros Centros que mantienen un número elevado de colecciones, la actualización debe realizarse al menos una vez al año por medio de ficheros ISO compatibles.',	'To be part of C17 catalog, you must guarantee you will make inter library loan of your collections included into C17 catalog' : 'Para estar incluído en el C17 se requiere, en primer lugar, garantizar que se realizará préstamo interbibliotecario de las colecciones que cada biblioteca incluya en el C17',	'The library must provide the proper technical, professional support, to make the loan service works into this terms' : 'La biblioteca ha de contar con la infraestructura necesaria, de personal y equipo, para poder realizar este servicio dentro de los siguientes plazos máximos',	'Rejection answer: Two working days' : 'Envío de contestación negativa: 2 días laborables',	'Requested article delivery: Four working days' : 'Envío del material solicitado: 4 días laborables',	'You must activate a petition reception system compatible through email or any other of our C17 systems' : 'Tener habilitado un sistema de recepción de peticiones a través de correo electrónico o cualquier servicio compatible con el sistema C17',	'The library must update their own data every time they change, and perfom collections updates once a year at least' : 'La biblioteca debe ademas comprometerse a actualizar los datos administrativos de su centro cada vez que se produzcan cambios y actualizar las colecciones una vez al año como mínimo.',	'The librays that wants to enter into C17 catalog and acomplish the requirements, must request their inclusion through their Community representative, or to CSI, who will report to such representative' : 'Las bibliotecas que deseen ser incluidas en el C17 y cumplan los requisitos indicados anteriormente, deberán solicitar su ingreso a través del representante de su Comunidad, o directamente a CSi, quien remitirá la solicitud a dicho representante.',	'Beyond the hard requirements, every new library must have at least 20 collections, or have Health Science serials wich no other librarys in it community had' : 'Además de los requisitos indispensables, toda nueva biblioteca debe contar con un número de colecciones de Ciencias de la Salud mayor de 20 títulos, o contar con títulos de Ciencias de la Salud que no tenga ninguna otra biblioteca de su Autonomía.',	'Belonging to C17 catalog is completely free of charge' : 'El Instituto de Salud Carlos III financia actualmente una consulta gratuita al C17 que permite ofrecer la pertenencia de forma totalmente gratuita.',	'The main service is the query to the catalog, making the document petitions so much easier.' : 'El principal servicio es formar parte del Catalogo de Ciencias de la Salud más prestigioso y consultado de España, facilitando  el préstamo interbibliotecario entre las bibliotecas que integran el C17.',	'Can verify and complete records of their journals with the C17 database.' : 'Poder verificar y completar los registros de sus revistas con la base de datos del C17.',	'You will also get your own collections list to make you own catalog.' : 'Puede además obtener los listados de las colecciones que mantiene para crearse su propio Catálogo.',	'In C17 catalog, we have 3 different data types to update' : 'En el C17 hay tres tipos de datos a actualizar',	'Library data' : 'Datos administrativos de las bibliotecas',	'Collection data' : 'Datos de las colecciones',	'For the first two of them, the fastest way is through updating page over the internet, accessing it with your own username and password' : 'Para los dos primeros apartados, el método mas eficaz es a través de la página de actualización en Internet, a la que cada biblioteca participante accede mediante una clave y contraseña',	'C17 catalog update' : 'Actualización de las colecciones en el catálogo C17',	'To collections update, we have three different ways' : 'Para la actualización de las colecciones, existen tres formas de actualizar los datos',	'Through internet address we tell about before' : 'Online a través de Internet en la dirección anteriormente citada',	'Through a file generated by own library management software, wich must contain the proper data to do the update' : 'A través de un fichero generado por el programa de gestión que tenga cada biblioteca, y que lleve los datos necesarios para dicha actualización',	'Updating holdings on CVS files generated by C17' : 'Modificación de los datos de las colecciones sobre ficheros CSV generados por el C17.',	'Title: The key title from ISSN International Center or the Adriadna bibliographic catalog from the Biblioteca Nacional de España is used' : 'Título: se emplea el título clave asignado por el ISSN International Center, Locator Plus de la NLM,  o el que figura en el catálogo bibliográfico Ariadna de la Biblioteca Nacional de España.',	'Abreviated Title: The key title from ISSN International Center is used as well, obtained from the title abbreviation list, complaining ISO-4 normative' : 'Título abreviado: Se emplea el incluido en la base de datos del ISSN International Center, el cual se obtiene a partir de la Lista de abreviaturas de las palabras de los títulos de las publicaciones seriadas, conforme a la norma ISO-4',	'Countries are represented throug a three word code (Alpha 3) , accordding ISO-3166' : 'Los países se han representado por los códigos de tres letras (Alpha-3) según ISO-3166',	'Starting, and, in many cases, ending years, have been obtained from Biblioteca Nacional de España or ISSN International Center' : 'Los años de inicio y, en su caso, de fin, se han obtenido del ISSN international Center, Locator Plus de NLM, Biblioteca Nacional de España…',	'Holding normalization process' : 'Normalización de los fondos',	'For each library, we have two differents holdings lines, representing paper and electronic collections of a given title. Paper collection shows up in top position, and a blue font color. Electronic collections shows up in bottom position, on red color and cursive font, showing the month embargo period between brackets, if applicable' : 'Para cada biblioteca existen dos lineas diferenciadas que muestran la colección en papel y la electrónica a un título. La colección en papel aparece en la línea superior, en azul y letra redonda. La colección electrónica aparece en segundo lugar, en color rojo, letra cursiva, indicando, entre paréntesis el período de embargo en meses, si es que la colección tiene esa limitación.',	'Every serial title collection of each library, is preceeded by a two differents parts key. The first part have one or two letters, matching the province code (as showed in old car enrollments). The second one is the library key, and may have up to seven letters; we try to meake it as mnemonicly as we could, of follows some rules. For example, hospital keys start by a H key, and Universities do it by U key' : 'La colección de cada título en cada biblioteca, va precedida de una clave que consta de dos partes, la primera parte formada por una o dos letras, corresponde al código de la provincia en que se encuentre (el que figura en la antigua matrícula de los vehículos de dicha provincia). La segunda parte es propiamente la clave de la biblioteca y puede constar de hasta siete letras; se intenta que sea nemotécnica o siga ciertas reglas, como que las correspondientes a hospitales empiecen por H y las de Universidades por U',	'Dash [-] has two functions, when enclosed between years, indicate collection continuity between those years. When positiones behind the last year, indicates the collection is being recieved continuedly as long as the fascicles are published' : 'El guión [-] tiene dos funciones, cuando va entre dos años, indica continuidad de la colección entre esos años. Cuando el guión está detrás del último año que figura en la colección, indica que desde ese año la colección se continúa recibiendo interrumpidamente según se van publicándo los fascículos.',	'Comma [,] indicates collection break up between comma years separated' : 'La coma [,] expresa interrupción de la colección entre los años separados por ella',	'Brackets [( )] encloses incomplete collection years. A collection may be incomplete a year, or more than one' : 'Los paréntesis [( )] encierran los años en que la colección está incompleta. Una colección puede estar incompleta un año, o un periodo de mas de un año',	'Dot [.] ending a collection indicates a closed serial subscription for the preceeding year, or a cancelled publishing' : 'El punto [.] al final de una colección indica el cierre de la colección, la recepción de esa revista se ha suspendido en el año que precede al punto, bien por cancelación de la suscripción o por que ha dejado de publicarse.',	'C17 :: Bibliography' : 'C17 :: Bibliografía',	'C17 :: Comite' : 'C17 :: Comité',	'C17 :: Faq' : 'C17 :: Preguntas frecuentes',	'Frequently asked questions' : 'Preguntas más frecuentes',	'Technical comite' : 'Comité técnico',	'Bibliography' : 'Bibliografía',	'Selected username is available' : 'Nombre de usuario disponible',	'layout' : 'Ubicación',	'shelve' : 'Estantería',	'Cover' : 'Portada',	'modify' : 'modificar',	'insert' : 'insertar',	'Succesfull: template updated!!!' : 'Ficha modifica correctamente!',	'Succesfull: Template deleted!!!' : 'Plantilla eliminada correctamente',	'Your request cannot be processed. A bug report has been submitted automatically to the application maintainers' : 'Su operación no ha podido ser procesada. Se ha enviado una notificación a los desarrolladores de la aplicación.',	'Wrong holdings string' : 'Línea de fondos errónea',	'Opac' : 'Opac',	'The C17 catalog is free online accesible by ' : 'El catálogo C17 puede consultarse gratuitamente a través de ',	'What is C17' : 'Qué es el C17',	'C17 is a union catalog that combines the collections of periodicals of 538 Spanish Health Sciences Libraries...' : 'El C17 es un catálogo colectivo que agrupa las colecciones de publicaciones periódicas de ciencias de la salud de 538 bibliotecas españolas. Su primera edición en CD-ROM fue en 1996. En la actualidad, se trata de un catálogo centralizado y es consultado a través de internet.',	'Holdings standarization process' : 'Normalización de los fondos',	'There are other advanced query functions which require payment: C17 Plus and ILL17' : '. Existen consultas avanzadas de pago: C17 Plus e ILL17 ',	'issn_papel' : 'issn_papel',	'issn_electronico' : 'issn_electronico',	'tipo_de_fondo' : 'tipo_de_fondo',	'titulo_de_la_revista' : 'titulo_de_la_revista',	'fondo' : 'fondo',	'Subjects' : 'Materias',	'Select the subject tree' : 'Seleccione el árbol de materias',	'Trees' : 'Árboles',	'OPAC' : 'OPAC',	'Select the subject tree for your OPAC' : 'Seleccione el arbol de materias para su OPAC',	'links' : 'enlaces',	'Links' : 'Enlaces',	'view' : 'ver',	'Subject review' : 'Materia',	'ISCIII :: Printouts' : 'ISCIII :: Informes',	'comunidad' : 'Comunidad',	'titulo' : 'Título',	'issnp' : 'ISSNp',	'issne' : 'ISSNe',	'total_colecciones' : 'Total colecciones',	'Conversor Fondos Complu' : 'Conversor Fondos Complu',	'Conversor Fondos Complutense' : 'Conversor Fondos Complutense',	'ISSNp' : 'issn_papel',	'ISSNe' : 'issn_electronico',	'embargo' : 'embargo',	'url' : 'url',	'suministrador' : 'suministrador',	'coleccion' : 'coleccion',	'revista_id' : 'revista_id',	'fondo_complu' : 'fondo_complu',	'Faltas' : 'faltas',	'bib' : 'bib'}