OSDN Git Service

setup spinelz environment
[cloudmanganw/git_repo.git] / src / jp / sourceforge / manganetwork / page / javascripts / spinelz_lib / spinelz_util.js
index 13b6afc..cc869f6 100644 (file)
-// Copyright (c) 2006 spinelz.org (http://script.spinelz.org/)
-// 
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-/**
- * Element class
- */
-Object.extend(Element, {
-
-  getTagNodes: function(element, tree) {
-    return this.getElementsByNodeType(element, 1, tree);
-  },
-  
-  getTextNodes: function(element, tree) {
-    return this.getElementsByNodeType(element, 3, tree);
-  },
-  
-  getElementsByNodeType: function(element, nodeType, tree) {
-    
-    element = ($(element) || document.body);
-    var nodes = element.childNodes;
-    var result = [];
-    
-    for (var i = 0; i < nodes.length; i++) {
-      if (nodes[i].nodeType == nodeType)
-        result.push(nodes[i]);
-      if (tree && (nodes[i].nodeType == 1)) 
-        result = result.concat(this.getElementsByNodeType(nodes[i], nodeType, tree));
-    }
-    
-    return result;
-  },
-  
-  getParentByClassName: function(className, element) {
-    var parent = element.parentNode;
-    if (!parent || (parent.tagName == 'BODY'))
-      return null;
-    else if (!parent.className) 
-      return Element.getParentByClassName(className, parent);
-    else if (Element.hasClassName(parent, className))
-      return parent;
-    else
-      return Element.getParentByClassName(className, parent);
-  },
-  
-  getParentByTagName: function(tagNames, element) {
-    
-    var parent = element.parentNode;
-    if (parent.tagName == 'BODY')
-      return null;
-      
-    var index = tagNames.join('/').toUpperCase().indexOf(parent.tagName.toUpperCase(), 0);
-    if (index >= 0)
-      return parent;
-    else
-      return Element.getParentByTagName(tagNames, parent);
-  },
-  
-  getFirstElementByClassNames: function(element, classNames, tree) {
-    
-    if (!element || 
-        !((typeof(classNames) == 'object') && (classNames.constructor == Array))) {
-      return;  
-    }
-  
-    element = (element || document.body);
-    var nodes = element.childNodes;
-    
-    for (var i = 0; i < nodes.length; i++) {
-      for (var j = 0; j < classNames.length; j++) {
-        if (nodes[i].nodeType != 1) {
-          continue;
-        
-        } else if (Element.hasClassName(nodes[i], classNames[j])) {
-          return nodes[i];
-        
-        } else if (tree) {
-          var result = this.getFirstElementByClassNames(nodes[i], classNames, tree);
-          if (result) return result;
-        }
-      }
-    }
-    
-    return;
-  },
-  
-  getElementsByClassNames: function(element, classNames) {
-    
-    if (!element || 
-        !((typeof(classNames) == 'object') && (classNames.constructor == Array))) {
-      return;  
-    }
-  
-    var nodes = [];
-    classNames.each(function(c) {
-      nodes = nodes.concat(document.getElementsByClassName(c, element));
-    });
-    
-    return nodes;
-  },
-  
-  getWindowHeight: function() {
-      
-    if (window.innerHeight) {
-      return window.innerHeight; // Mozilla, Opera, NN4
-    } else if (document.documentElement && document.documentElement.offsetHeight){ // ?? IE
-      return document.documentElement.offsetHeight;
-    } else if (document.body && document.body.offsetHeight) {
-      return document.body.offsetHeight - 20;
-    }
-    return 0;
-  },
-  
-  getWindowWidth:function() {
-    
-    if(window.innerWidth) {
-      return window.innerWidth; // Mozilla, Opera, NN4
-    } else if (document.documentElement && document.documentElement.offsetWidth){ // ?? IE
-      return document.documentElement.offsetWidth - 20;
-    } else if (document.body && document.body.offsetWidth){
-      return document.body.offsetWidth - 20;
-    }
-    return 0;
-  },
-  
-  getMaxZindex: function(element) {
-    element = $(element);
-    if (!element) {
-      element = document.body;
-    }  
-    if (element.nodeType != 1) return 0;
-
-    var maxZindex = 0;
-    if (element.style) maxZindex = parseInt(Element.getStyle(element, "z-index"));  
-    if (isNaN(maxZindex)) maxZindex = 0;
-
-    var tmpZindex = 0;
-    var elements = element.childNodes;
-    for (var i = 0; i < elements.length; i++) {
-      if (elements[i] && elements[i].tagName) {
-        tmpZindex = Element.getMaxZindex(elements[i]);
-        if (maxZindex < tmpZindex) maxZindex = tmpZindex;
-      }
-    }
-
-    return maxZindex;
-  },
-
-  select: function(element, value) {
-    $A($(element).options).each(function(opt) {
-      if (opt.value == value) {
-        opt.selected = true;
-      } else {
-        opt.selected = false;
-      }
-    });
-  }
-});
-
-
-/**
- * Array
- */
-Object.extend(Array.prototype, {
-  insert : function(index, element) {
-    this.splice(index, 0 , element);
-  },
-  
-  remove : function(index) {
-    this.splice(index, 1);
-  }
-});
-
-
-/**
- * String
- */
-Object.extend(String.prototype, {
-  
-  getPrefix: function(delimiter) {
-  
-    if (!delimiter) delimiter = '_';
-    return this.split(delimiter)[0];
-  },
-  
-  getSuffix: function(delimiter) {
-    
-    if (!delimiter) delimiter = '_';
-    return this.split(delimiter).pop();
-  },
-
-  appendPrefix: function(prefix, delimiter) {
-  
-    if (!delimiter) delimiter = '_';
-    return this + delimiter + prefix;
-  },
-  
-  appendSuffix: function(suffix, delimiter) {
-  
-    if (!delimiter) delimiter = '_';
-    return this + delimiter + suffix;
-  },
-  
-  // for firefox
-  println: function() {
-    dump(this + '\n');
-  }
-});
-
-
-/**
- * CssUtil
- */
-var CssUtil = Class.create();
-
-CssUtil.appendPrefix = function(prefix, suffixes) {
-  var newHash = {};
-  $H(suffixes).each(function(pair) {
-    newHash[pair[0]] = prefix + suffixes[pair[0]];
-  });
-  return newHash;
-}
-
-CssUtil.getCssRules = function(sheet) {
-  return sheet.rules || sheet.cssRules;
-}
-
-CssUtil.getCssRuleBySelectorText = function(selector) {
-  var rule = null;
-  $A(document.styleSheets).each(function(s) {
-    var rules = CssUtil.getCssRules(s);
-    rule =  $A(rules).detect(function(r) {
-      if (!r.selectorText) return false;
-      return r.selectorText.toLowerCase() == selector.toLowerCase();
-    });
-    if (rule) throw $break;
-  });
-  return rule;
-}
-
-/*
-CssUtil.require = function(file, attributes, parent) {
-  var links = document.getElementsByTagName('link');
-  var regex = /^.*\.css/; 
-  var match = file.match(regex)
-  alert(file)
-  regex.compile(match);
-
-  $A(links).each(function(ln) {
-    if (ln.href.match(regex)) {
-    }
-  });
-  
-//  attributes = Object.extend({
-//                  href: file, 
-//                  media: 'screen', 
-//                  rel: 'stylesheet', 
-//                  type: 'text/css'}, attributes);
-//  var node = Builder.node('link', attributes);
-//  if (!parent) parent = document.body;
-//  parent.appendChild(node);
-//  alert(file);
-}
-*/
-
-CssUtil.prototype = {
-  
-  initialize: function(styles) {
-    if (!((typeof(styles) == 'object') && (styles.constructor == Array))) {
-      throw 'CssUtil#initialize: argument must be a Array object!';    
-    }
-    
-    this.styles = styles;
-  },
-
-  getClasses: function(key) {
-    return this.styles.collect(function(s) {
-      return s[key];
-    });
-  },
-  
-  joinClassNames: function(key) {
-    return this.getClasses(key).join(' ');
-  },
-  
-  addClassNames: function(element, key) {
-    this.styles.each(function(s) {
-      Element.addClassName(element, s[key]);
-    });
-  },
-  
-  removeClassNames: function(element, key) {
-    this.styles.each(function(s) {
-      Element.removeClassName(element, s[key]);
-    });
-  },
-  
-  refreshClassNames: function(element, key) {
-    element.className = '';
-    this.addClassNames(element, key);
-  },
-  
-  hasClassName: function(element, key) {
-    return this.styles.any(function(s) {
-      return Element.hasClassName(element, s[key]);
-    });
-  }
-}
-
-
-/** 
- * Hover 
- */
-var Hover = Class.create();
-Hover.prototype = {
-
-  initialize: function(element) {
-    this.options = Object.extend({
-      defaultClass: '',
-      hoverClass: '',
-      cssUtil: '',
-      list: false
-    }, arguments[1] || {});
-    
-    var element = $(element);
-    if (this.options.list) {
-      var nodes = element.childNodes;
-      for (var i = 0; i < nodes.length; i++) {
-        if (nodes[i].nodeType == 1) {
-          this.build(nodes[i]);
-        }
-      }
-    } else {
-      this.build(element);
-    }
-  },
-  
-  build: function(element) {
-    this.normal = this.getNormalClass(element);
-    this.hover = this.getHoverClass(this.normal);
-    
-    if (this.options.cssUtil) {
-      this.normal = this.options.cssUtil.joinClassNames(normal);
-      this.hover = this.options.cssUtil.joinClassNames(hover);    
-    }
-    this.setHoverEvent(element);
-  },
-
-  setHoverEvent: function(element) {
-    Event.observe(element, "mouseout", this.toggle.bindAsEventListener(this, element, this.normal));
-    Event.observe(element, "mouseover", this.toggle.bindAsEventListener(this, element, this.hover));
-  },
-
-  toggle: function(event, element, className) {
-    Event.stop(event);
-    element.className = className;
-  },
-
-  getNormalClass: function(element) {
-    var className = (this.options.defaultClass || element.className);
-    return (className || '');
-  },
-  
-  getHoverClass: function(defaultClass) {
-    var className = this.options.hoverClass;
-    if (!className) {
-      className = defaultClass.split(' ').collect(function(c) {
-        return c + 'Hover';
-      }).join(' ');
-    }  
-     return className;
-  }
-}
-
-
-/**
- * Date
- */
-Object.extend(Date.prototype, {
-  msPerDay: function() {
-    return 24 * 60 * 60 * 1000;
-  },
-
-  advance: function(options) {
-    return new Date(this.getTime() + this.msPerDay() * options.days);
-  },
-
-  days: function() {
-    var date = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
-    return Math.round(date.getTime() / this.msPerDay());
-  },
-
-  toHash: function() {
-    return {
-      year:  this.getFullYear(),
-      month: this.getMonth(),
-      day:   this.getDate(),
-      hour:  this.getHours(),
-      min:   this.getMinutes(),
-      sec:   this.getSeconds()
-    }
-  },
-
-  sameYear: function(date) {
-    return this.getFullYear() == date.getFullYear();
-  },
-
-  sameMonth: function(date) {
-    return this.sameYear(date) && this.getMonth() == date.getMonth();
-  },
-
-  sameDate: function(date) {
-    return this.sameYear(date) && this.sameMonth(date) && this.getDate() == date.getDate();
-  },
-
-  betweenDate: function(start, finish) {
-    var myDays = this.days();
-    return (start.days() <= myDays && myDays <= finish.days());
-  },
-
-  betweenTime: function(start, finish) {
-    var myTime = this.getTime();
-    return (start.getTime() <= myTime && myTime <= finish.getTime());
-  }
-});
-
-
-/**
- * DateUtil
- */
-var DateUtil = {
-
-  dayOfWeek: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
-
-  months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
-
-  daysOfMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
-
-  numberOfDays: function(start, finish) {
-    return finish.days() - start.days();
-  },
-
-  isLeapYear: function(year) {
-    if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
-      return true;
-    return false;
-  }, 
-
-  nextDate: function(date) {
-    return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
-  },
-
-  previousDate: function(date) {
-    return new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1);
-  },
-  
-  afterDays: function(date, after) {
-    return new Date(date.getFullYear(), date.getMonth(), date.getDate() + after);
-  },
-  
-  getLastDate: function(year, month) {
-    var last = this.daysOfMonth[month];
-    if ((month == 1) && this.isLeapYear(year)) {
-      return new Date(year, month, last + 1);
-    }
-    return new Date(year, month, last);
-  },
-  
-  getFirstDate: function(year, month) {
-    if (year.constructor == Date) {
-      return new Date(year.getFullYear(), year.getMonth(), 1);
-    }
-    return new Date(year, month, 1);
-  },
-
-  getWeekTurn: function(date, firstDWeek) {
-    var limit = 6 - firstDWeek + 1;
-    var turn = 0;
-    while (limit < date) {
-      date -= 7;
-      turn++;
-    }
-    return turn;
-  },
-
-  toDateString: function(date) {
-    return date.toDateString();
-  },
-  
-  toLocaleDateString: function(date) {
-    return date.toLocaleDateString();
-  },
-  
-  simpleFormat: function(formatStr) {
-    return function(date) {
-      var formated = formatStr.replace(/M+/g, DateUtil.zerofill((date.getMonth() + 1).toString(), 2));
-      formated = formated.replace(/d+/g, DateUtil.zerofill(date.getDate().toString(), 2));
-      formated = formated.replace(/y{4}/g, date.getFullYear());
-      formated = formated.replace(/y{1,3}/g, new String(date.getFullYear()).substr(2));
-      formated = formated.replace(/E+/g, DateUtil.dayOfWeek[date.getDay()]);
-      
-      return formated;
-    }
-  },
-
-  zerofill: function(date,digit){
-    var result = date;
-    if(date.length < digit){
-      var tmp = digit - date.length;
-      for(i=0; i < tmp; i++){
-        result = "0" + result;
-      }
-    }
-    return result;
-  },
-
-  toDate: function(hash) {
-    return new Date(hash.year, hash.month, hash.day, hash.hour, hash.min, hash.sec || 0);
-  }
-}
-
-
-/**
- * ZindexManager
- */
-var ZindexManager = {
-  zIndex: 1000,
-
-  getIndex: function(zIndex) {
-    if (zIndex) {
-      if (isNaN(zIndex)) {
-        zIndex = Element.getMaxZindex() + 1;
-      } else if (ZindexManager.zIndex > zIndex) {
-        zIndex = ZindexManager.zIndex;
-      }
-    } else {
-      zIndex = ZindexManager.zIndex;
-    }
-    ZindexManager.zIndex = zIndex + 1;
-    return zIndex;
-  }
-}
-
-
-/**
- * Modal
- */
-var Modal = {
-  maskId:         'modalMask',
-  maskClass:      'modal_mask',
-  maskClassIE:    'modal_mask_ie',
-  element:        null,
-  snaps:          null,
-  listener:       null,
-  resizeListener: null,
-  cover:          null,
-  excepteds:      null,
-
-  mask: function(excepted) {
-    var options = Object.extend({
-      cssPrefix: 'custom_',
-      zIndex: null
-    }, arguments[1] || {});
-
-    if (Modal.element) {
-      Modal._snap(excepted);
-      Modal._rebuildMask();
-    } else {
-      Modal.snaps = [];
-      Modal.excepteds = [];
-      Modal._buildMask(options.cssPrefix);
-      Modal.cover = new IECover(Modal.element, {transparent: true});
-    }
-    Modal._setZindex(excepted, options.zIndex);
-    Modal._setFullSize();
-    if (!Modal.hasExcepted(excepted)) Modal.excepteds.push(excepted);
-  },
-
-  unmask: function() {
-    if (Modal.element) {
-      if (Modal.snaps.length == 0) {
-        Element.hide(Modal.element);
-        Modal._removeEvent();
-        Modal.excepteds = [];
-        Element.remove(Modal.element);
-        Modal.element = null;
-      } else {
-        Element.setStyle(Modal.element, {zIndex: Modal.snaps.pop()});
-        Modal.excepteds.pop();
-      }
-    }
-  },
-
-  _addEvent: function() {
-    if (!Modal.listener) {
-      Modal.listener = Modal._handleEvent.bindAsEventListener();
-      Modal.resizeListener = Modal._onResize.bindAsEventListener();
-    }
-    Event.observe(document, "keypress", Modal.listener);
-    Event.observe(document, "keydown", Modal.listener);
-    Event.observe(document, "keyup", Modal.listener);
-    Event.observe(document, "focus", Modal.listener);
-    Event.observe(window, "resize", Modal.resizeListener);
-  },
-
-  _removeEvent: function() {
-    Event.stopObserving(document, "keypress", Modal.listener);
-    Event.stopObserving(document, "keydown", Modal.listener);
-    Event.stopObserving(document, "keyup", Modal.listener);
-    Event.stopObserving(document, "focus", Modal.listener);
-    Event.stopObserving(window, "resize", Modal.resizeListener);
-  },
-
-  _isMasked: function() {
-    return Modal.element && Element.visible(Modal.element);
-  },
-
-  _snap: function(excepted) {
-    var index = Element.getStyle(Modal.element, 'zIndex');
-    if (index && Modal._isMasked() && !Modal.hasExcepted(excepted)) Modal.snaps.push(index);
-  },
-
-  _setZindex: function(excepted, zIndex) {
-    zIndex = ZindexManager.getIndex(zIndex);
-    Element.setStyle(Modal.element, {zIndex:  zIndex});
-    excepted = Element.makePositioned($(excepted));
-    Element.setStyle(excepted, {zIndex: ++zIndex});
-  },
-
-  _setFullSize: function() {
-    Modal.element.setStyle({
-      width:  Element.getWindowWidth() + 'px',
-      height: Element.getWindowHeight() + 'px'
-    });
-    if (Modal.cover) Modal.cover.resetSize();
-  },
-
-  _buildMask: function(cssPrefix) {
-    var mask = Builder.node('div', {id: Modal.maskId});
-    Modal._setClassNames(mask, cssPrefix);
-    document.body.appendChild(mask);
-    Modal.element = mask;
-    Modal._addEvent();
-  },
-
-  _setClassNames: function(element, cssPrefix) {
-    var className = (UserAgent.isIE()) ? Modal.maskClassIE : Modal.maskClass;
-    Element.addClassName(element, className);
-    Element.addClassName(element, cssPrefix + className);
-  },
-
-  _rebuildMask: function() {
-    document.body.appendChild(Modal.element);
-    Element.show(Modal.element);
-  },
-
-  _isOutOfModal: function(src) {
-    var limit = Element.getStyle(Modal.element, 'zIndex');
-    var zIndex = null;
-    while ((src = src.parentNode) && src != document.body) {
-      if (src.style && (zIndex = Element.getStyle(src, 'zIndex'))) {
-        if (zIndex > limit) {
-          return true;
-        } else {
-          return false;
-        }
-      }
-    }
-    return false;
-  },
-
-  _handleEvent: function (event) {
-    var src = Event.element(event);
-    if (!Modal._isOutOfModal(src)) {
-      Event.stop(event);
-    }
-  },
-
-  _onResize: function(event) {
-    Modal._setFullSize();
-  },
-
-  hasExcepted: function(excepted) {
-    return Modal.excepteds && Modal.excepteds.include(excepted);
-  }
-}
-
-
-/**
- * IECover
- */
-var IECover = Class.create();
-IECover.src = '/blank.html';
-IECover.prototype = {
-  idSuffix: 'iecover',
-
-  initialize: function(parent) {
-    this.options = Object.extend({
-      transparent : false,
-      padding     : 0
-    }, arguments[1] || {});
-
-    if (document.all) {
-      parent = $(parent);
-      this.id = parent.id.appendSuffix(this.idSuffix);
-      this._build(parent);
-      this.resetSize();
-    }
-  },
-
-  resetSize: function() {
-    if (this.element) {
-      var parent = this.element.parentNode;
-      var padding = this.options.padding;
-      this.element.width = parent.offsetWidth - padding + 'px';
-      this.element.height = Element.getHeight(parent) - padding + 'px';
-    }
-  },
-
-  _build: function(parent) {
-    var padding = this.options.padding / 2;
-    var styles = {
-      position : 'absolute',
-      top      : padding + 'px',
-      left     : padding + 'px'
-    };
-    if (this.options.transparent) styles.filter = 'alpha(opacity=0)';
-    this.element = Builder.node('iframe', {src: IECover.src, id: this.id, frameborder: 0});
-    Element.setStyle(this.element, styles);
-    var firstNode = Element.down(parent, 0);
-    if (firstNode) Element.makePositioned(firstNode);
-    parent.insertBefore(this.element, parent.firstChild);
-  }
-}
-
-/**
- * UserAgent
- */
-var UserAgent = {
-  getUserAgent: function() {
-    return navigator.userAgent;
-  },
-  isIE: function() {
-    if(document.all && this.getUserAgent().toLowerCase().indexOf('msie') != -1) {
-      return true;
-    }
-  },
-  isIE7: function() {
-    if(document.all && this.getUserAgent().toLowerCase().indexOf('msie 7') != -1) {
-      return true;
-    }
-  }
-}
-
-/**
- * ShortcutManager
- */
-var ShortcutManager = {
-  initialize: function() {
-    var defaultOptions  = {
-      initialStarted:   true,
-      preventDefault:   true
-    }
-    this.options            = Object.extend(defaultOptions, arguments[0] || {});
-    if(this.documentListener) {
-      Event.stopObserving(document, 'keydown', this.documentListener);
-    }
-    this.documentListener   = this.eventKeydown.bindAsEventListener(this);
-    this.functions          = new Object();
-    this.functions['a']     = new Object();
-    this.functions['ac']    = new Object();
-    this.functions['as']    = new Object();
-    this.functions['acs']   = new Object();
-    this.functions['c']     = new Object();
-    this.functions['cs']    = new Object();
-    this.functions['n']     = new Object();
-    this.functions['s']     = new Object();
-    this.keyCode            = {
-      'backspace':      8,
-      'tab':            9,
-      'return':        13,
-      'enter':         13,
-      'pause':         19,
-      'break':         19,
-      'caps':          20,
-      'capslock':      20,
-      'esc':           27,
-      'escape':        27,
-      'space':         32,
-      'pageup':        33,
-      'pgup':          33,
-      'pagedown':      34,
-      'pgdn':          34,
-      'end':           35,
-      'home':          36,
-      'left':          37,
-      'up':            38,
-      'right':         39,
-      'down':          40,
-      'insert':        45,
-      'delete':        46,
-      '0':             48,
-      '1':             49,
-      '2':             50,
-      '3':             51,
-      '4':             52,
-      '5':             53,
-      '6':             54,
-      '7':             55,
-      '8':             56,
-      '9':             57,
-      'a':             65,
-      'b':             66,
-      'c':             67,
-      'd':             68,
-      'e':             69,
-      'f':             70,
-      'g':             71,
-      'h':             72,
-      'i':             73,
-      'j':             74,
-      'k':             75,
-      'l':             76,
-      'm':             77,
-      'n':             78,
-      'o':             79,
-      'p':             80,
-      'q':             81,
-      'r':             82,
-      's':             83,
-      't':             84,
-      'u':             85,
-      'v':             86,
-      'w':             87,
-      'x':             88,
-      'y':             89,
-      'z':             90,
-      'f1':           112,
-      'f2':           113,
-      'f3':           114,
-      'f4':           115,
-      'f5':           116,
-      'f6':           117,
-      'f7':           118,
-      'f8':           119,
-      'f9':           120,
-      'f10':          121,
-      'f11':          122,
-      'f12':          123,
-      'numlock':      144,
-      'nmlk':         144,
-      'scrolllock':   145,
-      'scflk':        145
-    };
-    this.numKeys = {
-      96:   48,
-      97:   49,
-      98:   50,
-      99:   51,
-      100:  52,
-      101:  53,
-      102:  54,
-      103:  55,
-      104:  56,
-      105:  57
-    };
-    if(this.options.initialStarted) {
-      this.start();
-    } else {
-      this.stop();
-    }
-    Event.observe(document, 'keydown', this.documentListener);
-  },
-  add: function(shortcut, callback) {
-    this._add_or_remove_function(shortcut, callback);
-  },
-  destroy: function() {
-    Event.stopObserving(document, 'keydown', this.documentListener);
-  },
-  eventKeydown: function(event) {
-    if(this.executable) {
-      var code;
-      var key = '';
-      event = event || window.event;
-      if(event.keyCode) {
-        if(event.altKey) {
-          key += 'a';
-        }
-        if(event.ctrlKey) {
-          key += 'c';
-        }
-        if(event.shiftKey) {
-          key += 's';
-        }
-        if(key == '') {
-          key = 'n';
-        }
-        code = this._mergeNumKey(event.keyCode);
-        if(this.functions[key][code]) {
-          this.functions[key][code]();
-          if(this.options.preventDefault) {
-            Event.stop(event);
-          }
-        }
-      }
-    }
-  },
-  remove: function(shortcut) {
-    this._add_or_remove_function(shortcut);
-  },
-  start: function() {
-    this.executable = true;
-  },
-  stop: function() {
-    this.executable = false;
-  },
-  _add_or_remove_function: function(shortcut, callback) {
-    var pressed_key_code;
-    var additional_keys = new Array();
-    var self = this;
-    $A(shortcut.toLowerCase().split("+")).each(
-      function(key) {
-        if(key == 'alt') {
-          additional_keys.push('a');
-        } else if(key == 'ctrl') {
-          additional_keys.push('c');
-        } else if(key == 'shift') {
-          additional_keys.push('s');
-        } else {
-          pressed_key_code = self.keyCode[key];
-        }
-      }
-    );
-    var key = additional_keys.sortBy(function(value, index) {return value;}).join('');
-    if(key == '') {
-      key = 'n';
-    }
-    if(callback) {
-      this.functions[key][pressed_key_code] = callback;
-    } else {
-      this.functions[key][pressed_key_code] = null;
-    }
-  },
-  _mergeNumKey: function(code) {
-    return (this.numKeys[code]) ? this.numKeys[code] : code;
-  }
-}
-
-
-/**
- * Function
- */
-Function.prototype.callAfterLoading = function(object) {
-  object = object || this;
-  if (UserAgent.isIE() && document.readyState != 'complete') {
-    Event.observe(window, 'load', this.bind(object));
-  } else {
-    this.call(object);
-  }
-}
+// Copyright (c) 2006 spinelz.org (http://script.spinelz.org/)\r
+// \r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+// \r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+//\r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+\r
+/**\r
+ * Element class\r
+ */\r
+Object.extend(Element, {\r
+\r
+  getTagNodes: function(element, tree) {\r
+    return this.getElementsByNodeType(element, 1, tree);\r
+  },\r
+  \r
+  getTextNodes: function(element, tree) {\r
+    return this.getElementsByNodeType(element, 3, tree);\r
+  },\r
+  \r
+  getElementsByNodeType: function(element, nodeType, tree) {\r
+    \r
+    element = ($(element) || document.body);\r
+    var nodes = element.childNodes;\r
+    var result = [];\r
+    \r
+    for (var i = 0; i < nodes.length; i++) {\r
+      if (nodes[i].nodeType == nodeType)\r
+        result.push(nodes[i]);\r
+      if (tree && (nodes[i].nodeType == 1)) \r
+        result = result.concat(this.getElementsByNodeType(nodes[i], nodeType, tree));\r
+    }\r
+    \r
+    return result;\r
+  },\r
+  \r
+  getParentByClassName: function(className, element) {\r
+    var parent = element.parentNode;\r
+    if (!parent || (parent.tagName == 'BODY'))\r
+      return null;\r
+    else if (!parent.className) \r
+      return Element.getParentByClassName(className, parent);\r
+    else if (Element.hasClassName(parent, className))\r
+      return parent;\r
+    else\r
+      return Element.getParentByClassName(className, parent);\r
+  },\r
+  \r
+  getParentByTagName: function(tagNames, element) {\r
+    \r
+    var parent = element.parentNode;\r
+    if (parent.tagName == 'BODY')\r
+      return null;\r
+      \r
+    var index = tagNames.join('/').toUpperCase().indexOf(parent.tagName.toUpperCase(), 0);\r
+    if (index >= 0)\r
+      return parent;\r
+    else\r
+      return Element.getParentByTagName(tagNames, parent);\r
+  },\r
+  \r
+  getFirstElementByClassNames: function(element, classNames, tree) {\r
+    \r
+    if (!element || \r
+        !((typeof(classNames) == 'object') && (classNames.constructor == Array))) {\r
+      return;  \r
+    }\r
+  \r
+    element = (element || document.body);\r
+    var nodes = element.childNodes;\r
+    \r
+    for (var i = 0; i < nodes.length; i++) {\r
+      for (var j = 0; j < classNames.length; j++) {\r
+        if (nodes[i].nodeType != 1) {\r
+          continue;\r
+        \r
+        } else if (Element.hasClassName(nodes[i], classNames[j])) {\r
+          return nodes[i];\r
+        \r
+        } else if (tree) {\r
+          var result = this.getFirstElementByClassNames(nodes[i], classNames, tree);\r
+          if (result) return result;\r
+        }\r
+      }\r
+    }\r
+    \r
+    return;\r
+  },\r
+  \r
+  getElementsByClassNames: function(element, classNames) {\r
+    \r
+    if (!element || \r
+        !((typeof(classNames) == 'object') && (classNames.constructor == Array))) {\r
+      return;  \r
+    }\r
+  \r
+    var nodes = [];\r
+    classNames.each(function(c) {\r
+      nodes = nodes.concat(document.getElementsByClassName(c, element));\r
+    });\r
+    \r
+    return nodes;\r
+  },\r
+  \r
+  getWindowHeight: function() {\r
+      \r
+    if (window.innerHeight) {\r
+      return window.innerHeight; // Mozilla, Opera, NN4\r
+    } else if (document.documentElement && document.documentElement.offsetHeight){ // ?? IE\r
+      return document.documentElement.offsetHeight;\r
+    } else if (document.body && document.body.offsetHeight) {\r
+      return document.body.offsetHeight - 20;\r
+    }\r
+    return 0;\r
+  },\r
+  \r
+  getWindowWidth:function() {\r
+    \r
+    if(window.innerWidth) {\r
+      return window.innerWidth; // Mozilla, Opera, NN4\r
+    } else if (document.documentElement && document.documentElement.offsetWidth){ // ?? IE\r
+      return document.documentElement.offsetWidth - 20;\r
+    } else if (document.body && document.body.offsetWidth){\r
+      return document.body.offsetWidth - 20;\r
+    }\r
+    return 0;\r
+  },\r
+  \r
+  getMaxZindex: function(element) {\r
+    element = $(element);\r
+    if (!element) {\r
+      element = document.body;\r
+    }  \r
+    if (element.nodeType != 1) return 0;\r
+\r
+    var maxZindex = 0;\r
+    if (element.style) maxZindex = parseInt(Element.getStyle(element, "z-index"));  \r
+    if (isNaN(maxZindex)) maxZindex = 0;\r
+\r
+    var tmpZindex = 0;\r
+    var elements = element.childNodes;\r
+    for (var i = 0; i < elements.length; i++) {\r
+      if (elements[i] && elements[i].tagName) {\r
+        tmpZindex = Element.getMaxZindex(elements[i]);\r
+        if (maxZindex < tmpZindex) maxZindex = tmpZindex;\r
+      }\r
+    }\r
+\r
+    return maxZindex;\r
+  },\r
+\r
+  select: function(element, value) {\r
+    $A($(element).options).each(function(opt) {\r
+      if (opt.value == value) {\r
+        opt.selected = true;\r
+      } else {\r
+        opt.selected = false;\r
+      }\r
+    });\r
+  }\r
+});\r
+\r
+\r
+/**\r
+ * Array\r
+ */\r
+Object.extend(Array.prototype, {\r
+  insert : function(index, element) {\r
+    this.splice(index, 0 , element);\r
+  },\r
+  \r
+  remove : function(index) {\r
+    this.splice(index, 1);\r
+  }\r
+});\r
+\r
+\r
+/**\r
+ * String\r
+ */\r
+Object.extend(String.prototype, {\r
+  \r
+  getPrefix: function(delimiter) {\r
+  \r
+    if (!delimiter) delimiter = '_';\r
+    return this.split(delimiter)[0];\r
+  },\r
+  \r
+  getSuffix: function(delimiter) {\r
+    \r
+    if (!delimiter) delimiter = '_';\r
+    return this.split(delimiter).pop();\r
+  },\r
+\r
+  appendPrefix: function(prefix, delimiter) {\r
+  \r
+    if (!delimiter) delimiter = '_';\r
+    return this + delimiter + prefix;\r
+  },\r
+  \r
+  appendSuffix: function(suffix, delimiter) {\r
+  \r
+    if (!delimiter) delimiter = '_';\r
+    return this + delimiter + suffix;\r
+  },\r
+  \r
+  // for firefox\r
+  println: function() {\r
+    dump(this + '\n');\r
+  }\r
+});\r
+\r
+\r
+/**\r
+ * CssUtil\r
+ */\r
+var CssUtil = Class.create();\r
+\r
+CssUtil.appendPrefix = function(prefix, suffixes) {\r
+  var newHash = {};\r
+  $H(suffixes).each(function(pair) {\r
+    newHash[pair[0]] = prefix + suffixes[pair[0]];\r
+  });\r
+  return newHash;\r
+}\r
+\r
+CssUtil.getCssRules = function(sheet) {\r
+  return sheet.rules || sheet.cssRules;\r
+}\r
+\r
+CssUtil.getCssRuleBySelectorText = function(selector) {\r
+  var rule = null;\r
+  $A(document.styleSheets).each(function(s) {\r
+    var rules = CssUtil.getCssRules(s);\r
+    rule =  $A(rules).detect(function(r) {\r
+      if (!r.selectorText) return false;\r
+      return r.selectorText.toLowerCase() == selector.toLowerCase();\r
+    });\r
+    if (rule) throw $break;\r
+  });\r
+  return rule;\r
+}\r
+\r
+/*\r
+CssUtil.require = function(file, attributes, parent) {\r
+  var links = document.getElementsByTagName('link');\r
+  var regex = /^.*\.css/; \r
+  var match = file.match(regex)\r
+  alert(file)\r
+  regex.compile(match);\r
+\r
+  $A(links).each(function(ln) {\r
+    if (ln.href.match(regex)) {\r
+    }\r
+  });\r
+  \r
+//  attributes = Object.extend({\r
+//                  href: file, \r
+//                  media: 'screen', \r
+//                  rel: 'stylesheet', \r
+//                  type: 'text/css'}, attributes);\r
+//  var node = Builder.node('link', attributes);\r
+//  if (!parent) parent = document.body;\r
+//  parent.appendChild(node);\r
+//  alert(file);\r
+}\r
+*/\r
+\r
+CssUtil.prototype = {\r
+  \r
+  initialize: function(styles) {\r
+    if (!((typeof(styles) == 'object') && (styles.constructor == Array))) {\r
+      throw 'CssUtil#initialize: argument must be a Array object!';    \r
+    }\r
+    \r
+    this.styles = styles;\r
+  },\r
+\r
+  getClasses: function(key) {\r
+    return this.styles.collect(function(s) {\r
+      return s[key];\r
+    });\r
+  },\r
+  \r
+  joinClassNames: function(key) {\r
+    return this.getClasses(key).join(' ');\r
+  },\r
+  \r
+  addClassNames: function(element, key) {\r
+    this.styles.each(function(s) {\r
+      Element.addClassName(element, s[key]);\r
+    });\r
+  },\r
+  \r
+  removeClassNames: function(element, key) {\r
+    this.styles.each(function(s) {\r
+      Element.removeClassName(element, s[key]);\r
+    });\r
+  },\r
+  \r
+  refreshClassNames: function(element, key) {\r
+    element.className = '';\r
+    this.addClassNames(element, key);\r
+  },\r
+  \r
+  hasClassName: function(element, key) {\r
+    return this.styles.any(function(s) {\r
+      return Element.hasClassName(element, s[key]);\r
+    });\r
+  }\r
+}\r
+\r
+\r
+/** \r
+ * Hover \r
+ */\r
+var Hover = Class.create();\r
+Hover.prototype = {\r
+\r
+  initialize: function(element) {\r
+    this.options = Object.extend({\r
+      defaultClass: '',\r
+      hoverClass: '',\r
+      cssUtil: '',\r
+      list: false\r
+    }, arguments[1] || {});\r
+    \r
+    var element = $(element);\r
+    if (this.options.list) {\r
+      var nodes = element.childNodes;\r
+      for (var i = 0; i < nodes.length; i++) {\r
+        if (nodes[i].nodeType == 1) {\r
+          this.build(nodes[i]);\r
+        }\r
+      }\r
+    } else {\r
+      this.build(element);\r
+    }\r
+  },\r
+  \r
+  build: function(element) {\r
+    this.normal = this.getNormalClass(element);\r
+    this.hover = this.getHoverClass(this.normal);\r
+    \r
+    if (this.options.cssUtil) {\r
+      this.normal = this.options.cssUtil.joinClassNames(normal);\r
+      this.hover = this.options.cssUtil.joinClassNames(hover);    \r
+    }\r
+    this.setHoverEvent(element);\r
+  },\r
+\r
+  setHoverEvent: function(element) {\r
+    Event.observe(element, "mouseout", this.toggle.bindAsEventListener(this, element, this.normal));\r
+    Event.observe(element, "mouseover", this.toggle.bindAsEventListener(this, element, this.hover));\r
+  },\r
+\r
+  toggle: function(event, element, className) {\r
+    Event.stop(event);\r
+    element.className = className;\r
+  },\r
+\r
+  getNormalClass: function(element) {\r
+    var className = (this.options.defaultClass || element.className);\r
+    return (className || '');\r
+  },\r
+  \r
+  getHoverClass: function(defaultClass) {\r
+    var className = this.options.hoverClass;\r
+    if (!className) {\r
+      className = defaultClass.split(' ').collect(function(c) {\r
+        return c + 'Hover';\r
+      }).join(' ');\r
+    }  \r
+     return className;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+ * Date\r
+ */\r
+Object.extend(Date.prototype, {\r
+  msPerDay: function() {\r
+    return 24 * 60 * 60 * 1000;\r
+  },\r
+\r
+  advance: function(options) {\r
+    return new Date(this.getTime() + this.msPerDay() * options.days);\r
+  },\r
+\r
+  days: function() {\r
+    var date = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);\r
+    return Math.round(date.getTime() / this.msPerDay());\r
+  },\r
+\r
+  toHash: function() {\r
+    return {\r
+      year:  this.getFullYear(),\r
+      month: this.getMonth(),\r
+      day:   this.getDate(),\r
+      hour:  this.getHours(),\r
+      min:   this.getMinutes(),\r
+      sec:   this.getSeconds()\r
+    }\r
+  },\r
+\r
+  sameYear: function(date) {\r
+    return this.getFullYear() == date.getFullYear();\r
+  },\r
+\r
+  sameMonth: function(date) {\r
+    return this.sameYear(date) && this.getMonth() == date.getMonth();\r
+  },\r
+\r
+  sameDate: function(date) {\r
+    return this.sameYear(date) && this.sameMonth(date) && this.getDate() == date.getDate();\r
+  },\r
+\r
+  betweenDate: function(start, finish) {\r
+    var myDays = this.days();\r
+    return (start.days() <= myDays && myDays <= finish.days());\r
+  },\r
+\r
+  betweenTime: function(start, finish) {\r
+    var myTime = this.getTime();\r
+    return (start.getTime() <= myTime && myTime <= finish.getTime());\r
+  }\r
+});\r
+\r
+\r
+/**\r
+ * DateUtil\r
+ */\r
+var DateUtil = {\r
+\r
+  dayOfWeek: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\r
+\r
+  months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\r
+\r
+  daysOfMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],\r
+\r
+  numberOfDays: function(start, finish) {\r
+    return finish.days() - start.days();\r
+  },\r
+\r
+  isLeapYear: function(year) {\r
+    if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))\r
+      return true;\r
+    return false;\r
+  }, \r
+\r
+  nextDate: function(date) {\r
+    return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);\r
+  },\r
+\r
+  previousDate: function(date) {\r
+    return new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1);\r
+  },\r
+  \r
+  afterDays: function(date, after) {\r
+    return new Date(date.getFullYear(), date.getMonth(), date.getDate() + after);\r
+  },\r
+  \r
+  getLastDate: function(year, month) {\r
+    var last = this.daysOfMonth[month];\r
+    if ((month == 1) && this.isLeapYear(year)) {\r
+      return new Date(year, month, last + 1);\r
+    }\r
+    return new Date(year, month, last);\r
+  },\r
+  \r
+  getFirstDate: function(year, month) {\r
+    if (year.constructor == Date) {\r
+      return new Date(year.getFullYear(), year.getMonth(), 1);\r
+    }\r
+    return new Date(year, month, 1);\r
+  },\r
+\r
+  getWeekTurn: function(date, firstDWeek) {\r
+    var limit = 6 - firstDWeek + 1;\r
+    var turn = 0;\r
+    while (limit < date) {\r
+      date -= 7;\r
+      turn++;\r
+    }\r
+    return turn;\r
+  },\r
+\r
+  toDateString: function(date) {\r
+    return date.toDateString();\r
+  },\r
+  \r
+  toLocaleDateString: function(date) {\r
+    return date.toLocaleDateString();\r
+  },\r
+  \r
+  simpleFormat: function(formatStr) {\r
+    return function(date) {\r
+      var formated = formatStr.replace(/M+/g, DateUtil.zerofill((date.getMonth() + 1).toString(), 2));\r
+      formated = formated.replace(/d+/g, DateUtil.zerofill(date.getDate().toString(), 2));\r
+      formated = formated.replace(/y{4}/g, date.getFullYear());\r
+      formated = formated.replace(/y{1,3}/g, new String(date.getFullYear()).substr(2));\r
+      formated = formated.replace(/E+/g, DateUtil.dayOfWeek[date.getDay()]);\r
+      \r
+      return formated;\r
+    }\r
+  },\r
+\r
+  zerofill: function(date,digit){\r
+    var result = date;\r
+    if(date.length < digit){\r
+      var tmp = digit - date.length;\r
+      for(i=0; i < tmp; i++){\r
+        result = "0" + result;\r
+      }\r
+    }\r
+    return result;\r
+  },\r
+\r
+  toDate: function(hash) {\r
+    return new Date(hash.year, hash.month, hash.day, hash.hour, hash.min, hash.sec || 0);\r
+  }\r
+}\r
+\r
+\r
+/**\r
+ * ZindexManager\r
+ */\r
+var ZindexManager = {\r
+  zIndex: 1000,\r
+\r
+  getIndex: function(zIndex) {\r
+    if (zIndex) {\r
+      if (isNaN(zIndex)) {\r
+        zIndex = Element.getMaxZindex() + 1;\r
+      } else if (ZindexManager.zIndex > zIndex) {\r
+        zIndex = ZindexManager.zIndex;\r
+      }\r
+    } else {\r
+      zIndex = ZindexManager.zIndex;\r
+    }\r
+    ZindexManager.zIndex = zIndex + 1;\r
+    return zIndex;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+ * Modal\r
+ */\r
+var Modal = {\r
+  maskId:         'modalMask',\r
+  maskClass:      'modal_mask',\r
+  maskClassIE:    'modal_mask_ie',\r
+  element:        null,\r
+  snaps:          null,\r
+  listener:       null,\r
+  resizeListener: null,\r
+  cover:          null,\r
+  excepteds:      null,\r
+\r
+  mask: function(excepted) {\r
+    var options = Object.extend({\r
+      cssPrefix: 'custom_',\r
+      zIndex: null\r
+    }, arguments[1] || {});\r
+\r
+    if (Modal.element) {\r
+      Modal._snap(excepted);\r
+      Modal._rebuildMask();\r
+    } else {\r
+      Modal.snaps = [];\r
+      Modal.excepteds = [];\r
+      Modal._buildMask(options.cssPrefix);\r
+      Modal.cover = new IECover(Modal.element, {transparent: true});\r
+    }\r
+    Modal._setZindex(excepted, options.zIndex);\r
+    Modal._setFullSize();\r
+    if (!Modal.hasExcepted(excepted)) Modal.excepteds.push(excepted);\r
+  },\r
+\r
+  unmask: function() {\r
+    if (Modal.element) {\r
+      if (Modal.snaps.length == 0) {\r
+        Element.hide(Modal.element);\r
+        Modal._removeEvent();\r
+        Modal.excepteds = [];\r
+        Element.remove(Modal.element);\r
+        Modal.element = null;\r
+      } else {\r
+        Element.setStyle(Modal.element, {zIndex: Modal.snaps.pop()});\r
+        Modal.excepteds.pop();\r
+      }\r
+    }\r
+  },\r
+\r
+  _addEvent: function() {\r
+    if (!Modal.listener) {\r
+      Modal.listener = Modal._handleEvent.bindAsEventListener();\r
+      Modal.resizeListener = Modal._onResize.bindAsEventListener();\r
+    }\r
+    Event.observe(document, "keypress", Modal.listener);\r
+    Event.observe(document, "keydown", Modal.listener);\r
+    Event.observe(document, "keyup", Modal.listener);\r
+    Event.observe(document, "focus", Modal.listener);\r
+    Event.observe(window, "resize", Modal.resizeListener);\r
+  },\r
+\r
+  _removeEvent: function() {\r
+    Event.stopObserving(document, "keypress", Modal.listener);\r
+    Event.stopObserving(document, "keydown", Modal.listener);\r
+    Event.stopObserving(document, "keyup", Modal.listener);\r
+    Event.stopObserving(document, "focus", Modal.listener);\r
+    Event.stopObserving(window, "resize", Modal.resizeListener);\r
+  },\r
+\r
+  _isMasked: function() {\r
+    return Modal.element && Element.visible(Modal.element);\r
+  },\r
+\r
+  _snap: function(excepted) {\r
+    var index = Element.getStyle(Modal.element, 'zIndex');\r
+    if (index && Modal._isMasked() && !Modal.hasExcepted(excepted)) Modal.snaps.push(index);\r
+  },\r
+\r
+  _setZindex: function(excepted, zIndex) {\r
+    zIndex = ZindexManager.getIndex(zIndex);\r
+    Element.setStyle(Modal.element, {zIndex:  zIndex});\r
+    excepted = Element.makePositioned($(excepted));\r
+    Element.setStyle(excepted, {zIndex: ++zIndex});\r
+  },\r
+\r
+  _setFullSize: function() {\r
+    Modal.element.setStyle({\r
+      width:  Element.getWindowWidth() + 'px',\r
+      height: Element.getWindowHeight() + 'px'\r
+    });\r
+    if (Modal.cover) Modal.cover.resetSize();\r
+  },\r
+\r
+  _buildMask: function(cssPrefix) {\r
+    var mask = Builder.node('div', {id: Modal.maskId});\r
+    Modal._setClassNames(mask, cssPrefix);\r
+    document.body.appendChild(mask);\r
+    Modal.element = mask;\r
+    Modal._addEvent();\r
+  },\r
+\r
+  _setClassNames: function(element, cssPrefix) {\r
+    var className = (UserAgent.isIE()) ? Modal.maskClassIE : Modal.maskClass;\r
+    Element.addClassName(element, className);\r
+    Element.addClassName(element, cssPrefix + className);\r
+  },\r
+\r
+  _rebuildMask: function() {\r
+    document.body.appendChild(Modal.element);\r
+    Element.show(Modal.element);\r
+  },\r
+\r
+  _isOutOfModal: function(src) {\r
+    var limit = Element.getStyle(Modal.element, 'zIndex');\r
+    var zIndex = null;\r
+    while ((src = src.parentNode) && src != document.body) {\r
+      if (src.style && (zIndex = Element.getStyle(src, 'zIndex'))) {\r
+        if (zIndex > limit) {\r
+          return true;\r
+        } else {\r
+          return false;\r
+        }\r
+      }\r
+    }\r
+    return false;\r
+  },\r
+\r
+  _handleEvent: function (event) {\r
+    var src = Event.element(event);\r
+    if (!Modal._isOutOfModal(src)) {\r
+      Event.stop(event);\r
+    }\r
+  },\r
+\r
+  _onResize: function(event) {\r
+    Modal._setFullSize();\r
+  },\r
+\r
+  hasExcepted: function(excepted) {\r
+    return Modal.excepteds && Modal.excepteds.include(excepted);\r
+  }\r
+}\r
+\r
+\r
+/**\r
+ * IECover\r
+ */\r
+var IECover = Class.create();\r
+IECover.src = '/blank.html';\r
+IECover.prototype = {\r
+  idSuffix: 'iecover',\r
+\r
+  initialize: function(parent) {\r
+    this.options = Object.extend({\r
+      transparent : false,\r
+      padding     : 0\r
+    }, arguments[1] || {});\r
+\r
+    if (document.all) {\r
+      parent = $(parent);\r
+      this.id = parent.id.appendSuffix(this.idSuffix);\r
+      this._build(parent);\r
+      this.resetSize();\r
+    }\r
+  },\r
+\r
+  resetSize: function() {\r
+    if (this.element) {\r
+      var parent = this.element.parentNode;\r
+      var padding = this.options.padding;\r
+      this.element.width = parent.offsetWidth - padding + 'px';\r
+      this.element.height = Element.getHeight(parent) - padding + 'px';\r
+    }\r
+  },\r
+\r
+  _build: function(parent) {\r
+    var padding = this.options.padding / 2;\r
+    var styles = {\r
+      position : 'absolute',\r
+      top      : padding + 'px',\r
+      left     : padding + 'px'\r
+    };\r
+    if (this.options.transparent) styles.filter = 'alpha(opacity=0)';\r
+    this.element = Builder.node('iframe', {src: IECover.src, id: this.id, frameborder: 0});\r
+    Element.setStyle(this.element, styles);\r
+    var firstNode = Element.down(parent, 0);\r
+    if (firstNode) Element.makePositioned(firstNode);\r
+    parent.insertBefore(this.element, parent.firstChild);\r
+  }\r
+}\r
+\r
+/**\r
+ * UserAgent\r
+ */\r
+var UserAgent = {\r
+  getUserAgent: function() {\r
+    return navigator.userAgent;\r
+  },\r
+  isIE: function() {\r
+    if(document.all && this.getUserAgent().toLowerCase().indexOf('msie') != -1) {\r
+      return true;\r
+    }\r
+  },\r
+  isIE7: function() {\r
+    if(document.all && this.getUserAgent().toLowerCase().indexOf('msie 7') != -1) {\r
+      return true;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+ * ShortcutManager\r
+ */\r
+var ShortcutManager = {\r
+  initialize: function() {\r
+    var defaultOptions  = {\r
+      initialStarted:   true,\r
+      preventDefault:   true\r
+    }\r
+    this.options            = Object.extend(defaultOptions, arguments[0] || {});\r
+    if(this.documentListener) {\r
+      Event.stopObserving(document, 'keydown', this.documentListener);\r
+    }\r
+    this.documentListener   = this.eventKeydown.bindAsEventListener(this);\r
+    this.functions          = new Object();\r
+    this.functions['a']     = new Object();\r
+    this.functions['ac']    = new Object();\r
+    this.functions['as']    = new Object();\r
+    this.functions['acs']   = new Object();\r
+    this.functions['c']     = new Object();\r
+    this.functions['cs']    = new Object();\r
+    this.functions['n']     = new Object();\r
+    this.functions['s']     = new Object();\r
+    this.keyCode            = {\r
+      'backspace':      8,\r
+      'tab':            9,\r
+      'return':        13,\r
+      'enter':         13,\r
+      'pause':         19,\r
+      'break':         19,\r
+      'caps':          20,\r
+      'capslock':      20,\r
+      'esc':           27,\r
+      'escape':        27,\r
+      'space':         32,\r
+      'pageup':        33,\r
+      'pgup':          33,\r
+      'pagedown':      34,\r
+      'pgdn':          34,\r
+      'end':           35,\r
+      'home':          36,\r
+      'left':          37,\r
+      'up':            38,\r
+      'right':         39,\r
+      'down':          40,\r
+      'insert':        45,\r
+      'delete':        46,\r
+      '0':             48,\r
+      '1':             49,\r
+      '2':             50,\r
+      '3':             51,\r
+      '4':             52,\r
+      '5':             53,\r
+      '6':             54,\r
+      '7':             55,\r
+      '8':             56,\r
+      '9':             57,\r
+      'a':             65,\r
+      'b':             66,\r
+      'c':             67,\r
+      'd':             68,\r
+      'e':             69,\r
+      'f':             70,\r
+      'g':             71,\r
+      'h':             72,\r
+      'i':             73,\r
+      'j':             74,\r
+      'k':             75,\r
+      'l':             76,\r
+      'm':             77,\r
+      'n':             78,\r
+      'o':             79,\r
+      'p':             80,\r
+      'q':             81,\r
+      'r':             82,\r
+      's':             83,\r
+      't':             84,\r
+      'u':             85,\r
+      'v':             86,\r
+      'w':             87,\r
+      'x':             88,\r
+      'y':             89,\r
+      'z':             90,\r
+      'f1':           112,\r
+      'f2':           113,\r
+      'f3':           114,\r
+      'f4':           115,\r
+      'f5':           116,\r
+      'f6':           117,\r
+      'f7':           118,\r
+      'f8':           119,\r
+      'f9':           120,\r
+      'f10':          121,\r
+      'f11':          122,\r
+      'f12':          123,\r
+      'numlock':      144,\r
+      'nmlk':         144,\r
+      'scrolllock':   145,\r
+      'scflk':        145\r
+    };\r
+    this.numKeys = {\r
+      96:   48,\r
+      97:   49,\r
+      98:   50,\r
+      99:   51,\r
+      100:  52,\r
+      101:  53,\r
+      102:  54,\r
+      103:  55,\r
+      104:  56,\r
+      105:  57\r
+    };\r
+    if(this.options.initialStarted) {\r
+      this.start();\r
+    } else {\r
+      this.stop();\r
+    }\r
+    Event.observe(document, 'keydown', this.documentListener);\r
+  },\r
+  add: function(shortcut, callback) {\r
+    this._add_or_remove_function(shortcut, callback);\r
+  },\r
+  destroy: function() {\r
+    Event.stopObserving(document, 'keydown', this.documentListener);\r
+  },\r
+  eventKeydown: function(event) {\r
+    if(this.executable) {\r
+      var code;\r
+      var key = '';\r
+      event = event || window.event;\r
+      if(event.keyCode) {\r
+        if(event.altKey) {\r
+          key += 'a';\r
+        }\r
+        if(event.ctrlKey) {\r
+          key += 'c';\r
+        }\r
+        if(event.shiftKey) {\r
+          key += 's';\r
+        }\r
+        if(key == '') {\r
+          key = 'n';\r
+        }\r
+        code = this._mergeNumKey(event.keyCode);\r
+        if(this.functions[key][code]) {\r
+          this.functions[key][code]();\r
+          if(this.options.preventDefault) {\r
+            Event.stop(event);\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  remove: function(shortcut) {\r
+    this._add_or_remove_function(shortcut);\r
+  },\r
+  start: function() {\r
+    this.executable = true;\r
+  },\r
+  stop: function() {\r
+    this.executable = false;\r
+  },\r
+  _add_or_remove_function: function(shortcut, callback) {\r
+    var pressed_key_code;\r
+    var additional_keys = new Array();\r
+    var self = this;\r
+    $A(shortcut.toLowerCase().split("+")).each(\r
+      function(key) {\r
+        if(key == 'alt') {\r
+          additional_keys.push('a');\r
+        } else if(key == 'ctrl') {\r
+          additional_keys.push('c');\r
+        } else if(key == 'shift') {\r
+          additional_keys.push('s');\r
+        } else {\r
+          pressed_key_code = self.keyCode[key];\r
+        }\r
+      }\r
+    );\r
+    var key = additional_keys.sortBy(function(value, index) {return value;}).join('');\r
+    if(key == '') {\r
+      key = 'n';\r
+    }\r
+    if(callback) {\r
+      this.functions[key][pressed_key_code] = callback;\r
+    } else {\r
+      this.functions[key][pressed_key_code] = null;\r
+    }\r
+  },\r
+  _mergeNumKey: function(code) {\r
+    return (this.numKeys[code]) ? this.numKeys[code] : code;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+ * Function\r
+ */\r
+Function.prototype.callAfterLoading = function(object) {\r
+  object = object || this;\r
+  if (UserAgent.isIE() && document.readyState != 'complete') {\r
+    Event.observe(window, 'load', this.bind(object));\r
+  } else {\r
+    this.call(object);\r
+  }\r
+}\r