Commit 3a52b7e427c69f983b8443a2ea6a7ae7c31d14b0

Authored by Antonio Terceiro
1 parent e0af828c

Remove prototype.js \o/

Showing 1 changed file with 0 additions and 4221 deletions   Show diff stats
public/javascripts/prototype.js
@@ -1,4221 +0,0 @@ @@ -1,4221 +0,0 @@
1 -/* Prototype JavaScript framework, version 1.6.0.2  
2 - * (c) 2005-2008 Sam Stephenson  
3 - *  
4 - * Prototype is freely distributable under the terms of an MIT-style license.  
5 - * For details, see the Prototype web site: http://www.prototypejs.org/  
6 - *  
7 - *--------------------------------------------------------------------------*/  
8 -  
9 -var Prototype = {  
10 - Version: '1.6.0.2',  
11 -  
12 - Browser: {  
13 - IE: !!(window.attachEvent && !window.opera),  
14 - Opera: !!window.opera,  
15 - WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,  
16 - Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,  
17 - MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)  
18 - },  
19 -  
20 - BrowserFeatures: {  
21 - XPath: !!document.evaluate,  
22 - ElementExtensions: !!window.HTMLElement,  
23 - SpecificElementExtensions:  
24 - document.createElement('div').__proto__ &&  
25 - document.createElement('div').__proto__ !==  
26 - document.createElement('form').__proto__  
27 - },  
28 -  
29 - ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',  
30 - JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,  
31 -  
32 - emptyFunction: function() { },  
33 - K: function(x) { return x }  
34 -};  
35 -  
36 -if (Prototype.Browser.MobileSafari)  
37 - Prototype.BrowserFeatures.SpecificElementExtensions = false;  
38 -  
39 -  
40 -/* Based on Alex Arnell's inheritance implementation. */  
41 -var Class = {  
42 - create: function() {  
43 - var parent = null, properties = $A(arguments);  
44 - if (Object.isFunction(properties[0]))  
45 - parent = properties.shift();  
46 -  
47 - function klass() {  
48 - this.initialize.apply(this, arguments);  
49 - }  
50 -  
51 - Object.extend(klass, Class.Methods);  
52 - klass.superclass = parent;  
53 - klass.subclasses = [];  
54 -  
55 - if (parent) {  
56 - var subclass = function() { };  
57 - subclass.prototype = parent.prototype;  
58 - klass.prototype = new subclass;  
59 - parent.subclasses.push(klass);  
60 - }  
61 -  
62 - for (var i = 0; i < properties.length; i++)  
63 - klass.addMethods(properties[i]);  
64 -  
65 - if (!klass.prototype.initialize)  
66 - klass.prototype.initialize = Prototype.emptyFunction;  
67 -  
68 - klass.prototype.constructor = klass;  
69 -  
70 - return klass;  
71 - }  
72 -};  
73 -  
74 -Class.Methods = {  
75 - addMethods: function(source) {  
76 - var ancestor = this.superclass && this.superclass.prototype;  
77 - var properties = Object.keys(source);  
78 -  
79 - if (!Object.keys({ toString: true }).length)  
80 - properties.push("toString", "valueOf");  
81 -  
82 - for (var i = 0, length = properties.length; i < length; i++) {  
83 - var property = properties[i], value = source[property];  
84 - if (ancestor && Object.isFunction(value) &&  
85 - value.argumentNames().first() == "$super") {  
86 - var method = value, value = Object.extend((function(m) {  
87 - return function() { return ancestor[m].apply(this, arguments) };  
88 - })(property).wrap(method), {  
89 - valueOf: function() { return method },  
90 - toString: function() { return method.toString() }  
91 - });  
92 - }  
93 - this.prototype[property] = value;  
94 - }  
95 -  
96 - return this;  
97 - }  
98 -};  
99 -  
100 -var Abstract = { };  
101 -  
102 -Object.extend = function(destination, source) {  
103 - for (var property in source)  
104 - destination[property] = source[property];  
105 - return destination;  
106 -};  
107 -  
108 -Object.extend(Object, {  
109 - inspect: function(object) {  
110 - try {  
111 - if (Object.isUndefined(object)) return 'undefined';  
112 - if (object === null) return 'null';  
113 - return object.inspect ? object.inspect() : String(object);  
114 - } catch (e) {  
115 - if (e instanceof RangeError) return '...';  
116 - throw e;  
117 - }  
118 - },  
119 -  
120 - toJSON: function(object) {  
121 - var type = typeof object;  
122 - switch (type) {  
123 - case 'undefined':  
124 - case 'function':  
125 - case 'unknown': return;  
126 - case 'boolean': return object.toString();  
127 - }  
128 -  
129 - if (object === null) return 'null';  
130 - if (object.toJSON) return object.toJSON();  
131 - if (Object.isElement(object)) return;  
132 -  
133 - var results = [];  
134 - for (var property in object) {  
135 - var value = Object.toJSON(object[property]);  
136 - if (!Object.isUndefined(value))  
137 - results.push(property.toJSON() + ': ' + value);  
138 - }  
139 -  
140 - return '{' + results.join(', ') + '}';  
141 - },  
142 -  
143 - toQueryString: function(object) {  
144 - return $H(object).toQueryString();  
145 - },  
146 -  
147 - toHTML: function(object) {  
148 - return object && object.toHTML ? object.toHTML() : String.interpret(object);  
149 - },  
150 -  
151 - keys: function(object) {  
152 - var keys = [];  
153 - for (var property in object)  
154 - keys.push(property);  
155 - return keys;  
156 - },  
157 -  
158 - values: function(object) {  
159 - var values = [];  
160 - for (var property in object)  
161 - values.push(object[property]);  
162 - return values;  
163 - },  
164 -  
165 - clone: function(object) {  
166 - return Object.extend({ }, object);  
167 - },  
168 -  
169 - isElement: function(object) {  
170 - return object && object.nodeType == 1;  
171 - },  
172 -  
173 - isArray: function(object) {  
174 - return object != null && typeof object == "object" &&  
175 - 'splice' in object && 'join' in object;  
176 - },  
177 -  
178 - isHash: function(object) {  
179 - return object instanceof Hash;  
180 - },  
181 -  
182 - isFunction: function(object) {  
183 - return typeof object == "function";  
184 - },  
185 -  
186 - isString: function(object) {  
187 - return typeof object == "string";  
188 - },  
189 -  
190 - isNumber: function(object) {  
191 - return typeof object == "number";  
192 - },  
193 -  
194 - isUndefined: function(object) {  
195 - return typeof object == "undefined";  
196 - }  
197 -});  
198 -  
199 -Object.extend(Function.prototype, {  
200 - argumentNames: function() {  
201 - var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");  
202 - return names.length == 1 && !names[0] ? [] : names;  
203 - },  
204 -  
205 - bind: function() {  
206 - if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;  
207 - var __method = this, args = $A(arguments), object = args.shift();  
208 - return function() {  
209 - return __method.apply(object, args.concat($A(arguments)));  
210 - }  
211 - },  
212 -  
213 - bindAsEventListener: function() {  
214 - var __method = this, args = $A(arguments), object = args.shift();  
215 - return function(event) {  
216 - return __method.apply(object, [event || window.event].concat(args));  
217 - }  
218 - },  
219 -  
220 - curry: function() {  
221 - if (!arguments.length) return this;  
222 - var __method = this, args = $A(arguments);  
223 - return function() {  
224 - return __method.apply(this, args.concat($A(arguments)));  
225 - }  
226 - },  
227 -  
228 - delay: function() {  
229 - var __method = this, args = $A(arguments), timeout = args.shift() * 1000;  
230 - return window.setTimeout(function() {  
231 - return __method.apply(__method, args);  
232 - }, timeout);  
233 - },  
234 -  
235 - wrap: function(wrapper) {  
236 - var __method = this;  
237 - return function() {  
238 - return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));  
239 - }  
240 - },  
241 -  
242 - methodize: function() {  
243 - if (this._methodized) return this._methodized;  
244 - var __method = this;  
245 - return this._methodized = function() {  
246 - return __method.apply(null, [this].concat($A(arguments)));  
247 - };  
248 - }  
249 -});  
250 -  
251 -Function.prototype.defer = Function.prototype.delay.curry(0.01);  
252 -  
253 -Date.prototype.toJSON = function() {  
254 - return '"' + this.getUTCFullYear() + '-' +  
255 - (this.getUTCMonth() + 1).toPaddedString(2) + '-' +  
256 - this.getUTCDate().toPaddedString(2) + 'T' +  
257 - this.getUTCHours().toPaddedString(2) + ':' +  
258 - this.getUTCMinutes().toPaddedString(2) + ':' +  
259 - this.getUTCSeconds().toPaddedString(2) + 'Z"';  
260 -};  
261 -  
262 -var Try = {  
263 - these: function() {  
264 - var returnValue;  
265 -  
266 - for (var i = 0, length = arguments.length; i < length; i++) {  
267 - var lambda = arguments[i];  
268 - try {  
269 - returnValue = lambda();  
270 - break;  
271 - } catch (e) { }  
272 - }  
273 -  
274 - return returnValue;  
275 - }  
276 -};  
277 -  
278 -RegExp.prototype.match = RegExp.prototype.test;  
279 -  
280 -RegExp.escape = function(str) {  
281 - return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');  
282 -};  
283 -  
284 -/*--------------------------------------------------------------------------*/  
285 -  
286 -var PeriodicalExecuter = Class.create({  
287 - initialize: function(callback, frequency) {  
288 - this.callback = callback;  
289 - this.frequency = frequency;  
290 - this.currentlyExecuting = false;  
291 -  
292 - this.registerCallback();  
293 - },  
294 -  
295 - registerCallback: function() {  
296 - this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);  
297 - },  
298 -  
299 - execute: function() {  
300 - this.callback(this);  
301 - },  
302 -  
303 - stop: function() {  
304 - if (!this.timer) return;  
305 - clearInterval(this.timer);  
306 - this.timer = null;  
307 - },  
308 -  
309 - onTimerEvent: function() {  
310 - if (!this.currentlyExecuting) {  
311 - try {  
312 - this.currentlyExecuting = true;  
313 - this.execute();  
314 - } finally {  
315 - this.currentlyExecuting = false;  
316 - }  
317 - }  
318 - }  
319 -});  
320 -Object.extend(String, {  
321 - interpret: function(value) {  
322 - return value == null ? '' : String(value);  
323 - },  
324 - specialChar: {  
325 - '\b': '\\b',  
326 - '\t': '\\t',  
327 - '\n': '\\n',  
328 - '\f': '\\f',  
329 - '\r': '\\r',  
330 - '\\': '\\\\'  
331 - }  
332 -});  
333 -  
334 -Object.extend(String.prototype, {  
335 - gsub: function(pattern, replacement) {  
336 - var result = '', source = this, match;  
337 - replacement = arguments.callee.prepareReplacement(replacement);  
338 -  
339 - while (source.length > 0) {  
340 - if (match = source.match(pattern)) {  
341 - result += source.slice(0, match.index);  
342 - result += String.interpret(replacement(match));  
343 - source = source.slice(match.index + match[0].length);  
344 - } else {  
345 - result += source, source = '';  
346 - }  
347 - }  
348 - return result;  
349 - },  
350 -  
351 - sub: function(pattern, replacement, count) {  
352 - replacement = this.gsub.prepareReplacement(replacement);  
353 - count = Object.isUndefined(count) ? 1 : count;  
354 -  
355 - return this.gsub(pattern, function(match) {  
356 - if (--count < 0) return match[0];  
357 - return replacement(match);  
358 - });  
359 - },  
360 -  
361 - scan: function(pattern, iterator) {  
362 - this.gsub(pattern, iterator);  
363 - return String(this);  
364 - },  
365 -  
366 - truncate: function(length, truncation) {  
367 - length = length || 30;  
368 - truncation = Object.isUndefined(truncation) ? '...' : truncation;  
369 - return this.length > length ?  
370 - this.slice(0, length - truncation.length) + truncation : String(this);  
371 - },  
372 -  
373 - strip: function() {  
374 - return this.replace(/^\s+/, '').replace(/\s+$/, '');  
375 - },  
376 -  
377 - stripTags: function() {  
378 - return this.replace(/<\/?[^>]+>/gi, '');  
379 - },  
380 -  
381 - stripScripts: function() {  
382 - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');  
383 - },  
384 -  
385 - extractScripts: function() {  
386 - var matchAll = new RegExp(Prototype.ScriptFragment, 'img');  
387 - var matchOne = new RegExp(Prototype.ScriptFragment, 'im');  
388 - return (this.match(matchAll) || []).map(function(scriptTag) {  
389 - return (scriptTag.match(matchOne) || ['', ''])[1];  
390 - });  
391 - },  
392 -  
393 - evalScripts: function() {  
394 - return this.extractScripts().map(function(script) { return eval(script) });  
395 - },  
396 -  
397 - escapeHTML: function() {  
398 - var self = arguments.callee;  
399 - self.text.data = this;  
400 - return self.div.innerHTML;  
401 - },  
402 -  
403 - unescapeHTML: function() {  
404 - var div = new Element('div');  
405 - div.innerHTML = this.stripTags();  
406 - return div.childNodes[0] ? (div.childNodes.length > 1 ?  
407 - $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :  
408 - div.childNodes[0].nodeValue) : '';  
409 - },  
410 -  
411 - toQueryParams: function(separator) {  
412 - var match = this.strip().match(/([^?#]*)(#.*)?$/);  
413 - if (!match) return { };  
414 -  
415 - return match[1].split(separator || '&').inject({ }, function(hash, pair) {  
416 - if ((pair = pair.split('='))[0]) {  
417 - var key = decodeURIComponent(pair.shift());  
418 - var value = pair.length > 1 ? pair.join('=') : pair[0];  
419 - if (value != undefined) value = decodeURIComponent(value);  
420 -  
421 - if (key in hash) {  
422 - if (!Object.isArray(hash[key])) hash[key] = [hash[key]];  
423 - hash[key].push(value);  
424 - }  
425 - else hash[key] = value;  
426 - }  
427 - return hash;  
428 - });  
429 - },  
430 -  
431 - toArray: function() {  
432 - return this.split('');  
433 - },  
434 -  
435 - succ: function() {  
436 - return this.slice(0, this.length - 1) +  
437 - String.fromCharCode(this.charCodeAt(this.length - 1) + 1);  
438 - },  
439 -  
440 - times: function(count) {  
441 - return count < 1 ? '' : new Array(count + 1).join(this);  
442 - },  
443 -  
444 - camelize: function() {  
445 - var parts = this.split('-'), len = parts.length;  
446 - if (len == 1) return parts[0];  
447 -  
448 - var camelized = this.charAt(0) == '-'  
449 - ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)  
450 - : parts[0];  
451 -  
452 - for (var i = 1; i < len; i++)  
453 - camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);  
454 -  
455 - return camelized;  
456 - },  
457 -  
458 - capitalize: function() {  
459 - return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();  
460 - },  
461 -  
462 - underscore: function() {  
463 - return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();  
464 - },  
465 -  
466 - dasherize: function() {  
467 - return this.gsub(/_/,'-');  
468 - },  
469 -  
470 - inspect: function(useDoubleQuotes) {  
471 - var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {  
472 - var character = String.specialChar[match[0]];  
473 - return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);  
474 - });  
475 - if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';  
476 - return "'" + escapedString.replace(/'/g, '\\\'') + "'";  
477 - },  
478 -  
479 - toJSON: function() {  
480 - return this.inspect(true);  
481 - },  
482 -  
483 - unfilterJSON: function(filter) {  
484 - return this.sub(filter || Prototype.JSONFilter, '#{1}');  
485 - },  
486 -  
487 - isJSON: function() {  
488 - var str = this;  
489 - if (str.blank()) return false;  
490 - str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');  
491 - return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);  
492 - },  
493 -  
494 - evalJSON: function(sanitize) {  
495 - var json = this.unfilterJSON();  
496 - try {  
497 - if (!sanitize || json.isJSON()) return eval('(' + json + ')');  
498 - } catch (e) { }  
499 - throw new SyntaxError('Badly formed JSON string: ' + this.inspect());  
500 - },  
501 -  
502 - include: function(pattern) {  
503 - return this.indexOf(pattern) > -1;  
504 - },  
505 -  
506 - startsWith: function(pattern) {  
507 - return this.indexOf(pattern) === 0;  
508 - },  
509 -  
510 - endsWith: function(pattern) {  
511 - var d = this.length - pattern.length;  
512 - return d >= 0 && this.lastIndexOf(pattern) === d;  
513 - },  
514 -  
515 - empty: function() {  
516 - return this == '';  
517 - },  
518 -  
519 - blank: function() {  
520 - return /^\s*$/.test(this);  
521 - },  
522 -  
523 - interpolate: function(object, pattern) {  
524 - return new Template(this, pattern).evaluate(object);  
525 - }  
526 -});  
527 -  
528 -if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {  
529 - escapeHTML: function() {  
530 - return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');  
531 - },  
532 - unescapeHTML: function() {  
533 - return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');  
534 - }  
535 -});  
536 -  
537 -String.prototype.gsub.prepareReplacement = function(replacement) {  
538 - if (Object.isFunction(replacement)) return replacement;  
539 - var template = new Template(replacement);  
540 - return function(match) { return template.evaluate(match) };  
541 -};  
542 -  
543 -String.prototype.parseQuery = String.prototype.toQueryParams;  
544 -  
545 -Object.extend(String.prototype.escapeHTML, {  
546 - div: document.createElement('div'),  
547 - text: document.createTextNode('')  
548 -});  
549 -  
550 -with (String.prototype.escapeHTML) div.appendChild(text);  
551 -  
552 -var Template = Class.create({  
553 - initialize: function(template, pattern) {  
554 - this.template = template.toString();  
555 - this.pattern = pattern || Template.Pattern;  
556 - },  
557 -  
558 - evaluate: function(object) {  
559 - if (Object.isFunction(object.toTemplateReplacements))  
560 - object = object.toTemplateReplacements();  
561 -  
562 - return this.template.gsub(this.pattern, function(match) {  
563 - if (object == null) return '';  
564 -  
565 - var before = match[1] || '';  
566 - if (before == '\\') return match[2];  
567 -  
568 - var ctx = object, expr = match[3];  
569 - var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;  
570 - match = pattern.exec(expr);  
571 - if (match == null) return before;  
572 -  
573 - while (match != null) {  
574 - var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];  
575 - ctx = ctx[comp];  
576 - if (null == ctx || '' == match[3]) break;  
577 - expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);  
578 - match = pattern.exec(expr);  
579 - }  
580 -  
581 - return before + String.interpret(ctx);  
582 - });  
583 - }  
584 -});  
585 -Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;  
586 -  
587 -var $break = { };  
588 -  
589 -var Enumerable = {  
590 - each: function(iterator, context) {  
591 - var index = 0;  
592 - iterator = iterator.bind(context);  
593 - try {  
594 - this._each(function(value) {  
595 - iterator(value, index++);  
596 - });  
597 - } catch (e) {  
598 - if (e != $break) throw e;  
599 - }  
600 - return this;  
601 - },  
602 -  
603 - eachSlice: function(number, iterator, context) {  
604 - iterator = iterator ? iterator.bind(context) : Prototype.K;  
605 - var index = -number, slices = [], array = this.toArray();  
606 - while ((index += number) < array.length)  
607 - slices.push(array.slice(index, index+number));  
608 - return slices.collect(iterator, context);  
609 - },  
610 -  
611 - all: function(iterator, context) {  
612 - iterator = iterator ? iterator.bind(context) : Prototype.K;  
613 - var result = true;  
614 - this.each(function(value, index) {  
615 - result = result && !!iterator(value, index);  
616 - if (!result) throw $break;  
617 - });  
618 - return result;  
619 - },  
620 -  
621 - any: function(iterator, context) {  
622 - iterator = iterator ? iterator.bind(context) : Prototype.K;  
623 - var result = false;  
624 - this.each(function(value, index) {  
625 - if (result = !!iterator(value, index))  
626 - throw $break;  
627 - });  
628 - return result;  
629 - },  
630 -  
631 - collect: function(iterator, context) {  
632 - iterator = iterator ? iterator.bind(context) : Prototype.K;  
633 - var results = [];  
634 - this.each(function(value, index) {  
635 - results.push(iterator(value, index));  
636 - });  
637 - return results;  
638 - },  
639 -  
640 - detect: function(iterator, context) {  
641 - iterator = iterator.bind(context);  
642 - var result;  
643 - this.each(function(value, index) {  
644 - if (iterator(value, index)) {  
645 - result = value;  
646 - throw $break;  
647 - }  
648 - });  
649 - return result;  
650 - },  
651 -  
652 - findAll: function(iterator, context) {  
653 - iterator = iterator.bind(context);  
654 - var results = [];  
655 - this.each(function(value, index) {  
656 - if (iterator(value, index))  
657 - results.push(value);  
658 - });  
659 - return results;  
660 - },  
661 -  
662 - grep: function(filter, iterator, context) {  
663 - iterator = iterator ? iterator.bind(context) : Prototype.K;  
664 - var results = [];  
665 -  
666 - if (Object.isString(filter))  
667 - filter = new RegExp(filter);  
668 -  
669 - this.each(function(value, index) {  
670 - if (filter.match(value))  
671 - results.push(iterator(value, index));  
672 - });  
673 - return results;  
674 - },  
675 -  
676 - include: function(object) {  
677 - if (Object.isFunction(this.indexOf))  
678 - if (this.indexOf(object) != -1) return true;  
679 -  
680 - var found = false;  
681 - this.each(function(value) {  
682 - if (value == object) {  
683 - found = true;  
684 - throw $break;  
685 - }  
686 - });  
687 - return found;  
688 - },  
689 -  
690 - inGroupsOf: function(number, fillWith) {  
691 - fillWith = Object.isUndefined(fillWith) ? null : fillWith;  
692 - return this.eachSlice(number, function(slice) {  
693 - while(slice.length < number) slice.push(fillWith);  
694 - return slice;  
695 - });  
696 - },  
697 -  
698 - inject: function(memo, iterator, context) {  
699 - iterator = iterator.bind(context);  
700 - this.each(function(value, index) {  
701 - memo = iterator(memo, value, index);  
702 - });  
703 - return memo;  
704 - },  
705 -  
706 - invoke: function(method) {  
707 - var args = $A(arguments).slice(1);  
708 - return this.map(function(value) {  
709 - return value[method].apply(value, args);  
710 - });  
711 - },  
712 -  
713 - max: function(iterator, context) {  
714 - iterator = iterator ? iterator.bind(context) : Prototype.K;  
715 - var result;  
716 - this.each(function(value, index) {  
717 - value = iterator(value, index);  
718 - if (result == null || value >= result)  
719 - result = value;  
720 - });  
721 - return result;  
722 - },  
723 -  
724 - min: function(iterator, context) {  
725 - iterator = iterator ? iterator.bind(context) : Prototype.K;  
726 - var result;  
727 - this.each(function(value, index) {  
728 - value = iterator(value, index);  
729 - if (result == null || value < result)  
730 - result = value;  
731 - });  
732 - return result;  
733 - },  
734 -  
735 - partition: function(iterator, context) {  
736 - iterator = iterator ? iterator.bind(context) : Prototype.K;  
737 - var trues = [], falses = [];  
738 - this.each(function(value, index) {  
739 - (iterator(value, index) ?  
740 - trues : falses).push(value);  
741 - });  
742 - return [trues, falses];  
743 - },  
744 -  
745 - pluck: function(property) {  
746 - var results = [];  
747 - this.each(function(value) {  
748 - results.push(value[property]);  
749 - });  
750 - return results;  
751 - },  
752 -  
753 - reject: function(iterator, context) {  
754 - iterator = iterator.bind(context);  
755 - var results = [];  
756 - this.each(function(value, index) {  
757 - if (!iterator(value, index))  
758 - results.push(value);  
759 - });  
760 - return results;  
761 - },  
762 -  
763 - sortBy: function(iterator, context) {  
764 - iterator = iterator.bind(context);  
765 - return this.map(function(value, index) {  
766 - return {value: value, criteria: iterator(value, index)};  
767 - }).sort(function(left, right) {  
768 - var a = left.criteria, b = right.criteria;  
769 - return a < b ? -1 : a > b ? 1 : 0;  
770 - }).pluck('value');  
771 - },  
772 -  
773 - toArray: function() {  
774 - return this.map();  
775 - },  
776 -  
777 - zip: function() {  
778 - var iterator = Prototype.K, args = $A(arguments);  
779 - if (Object.isFunction(args.last()))  
780 - iterator = args.pop();  
781 -  
782 - var collections = [this].concat(args).map($A);  
783 - return this.map(function(value, index) {  
784 - return iterator(collections.pluck(index));  
785 - });  
786 - },  
787 -  
788 - size: function() {  
789 - return this.toArray().length;  
790 - },  
791 -  
792 - inspect: function() {  
793 - return '#<Enumerable:' + this.toArray().inspect() + '>';  
794 - }  
795 -};  
796 -  
797 -Object.extend(Enumerable, {  
798 - map: Enumerable.collect,  
799 - find: Enumerable.detect,  
800 - select: Enumerable.findAll,  
801 - filter: Enumerable.findAll,  
802 - member: Enumerable.include,  
803 - entries: Enumerable.toArray,  
804 - every: Enumerable.all,  
805 - some: Enumerable.any  
806 -});  
807 -function $A(iterable) {  
808 - if (!iterable) return [];  
809 - if (iterable.toArray) return iterable.toArray();  
810 - var length = iterable.length || 0, results = new Array(length);  
811 - while (length--) results[length] = iterable[length];  
812 - return results;  
813 -}  
814 -  
815 -if (Prototype.Browser.WebKit) {  
816 - $A = function(iterable) {  
817 - if (!iterable) return [];  
818 - if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&  
819 - iterable.toArray) return iterable.toArray();  
820 - var length = iterable.length || 0, results = new Array(length);  
821 - while (length--) results[length] = iterable[length];  
822 - return results;  
823 - };  
824 -}  
825 -  
826 -Array.from = $A;  
827 -  
828 -Object.extend(Array.prototype, Enumerable);  
829 -  
830 -if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;  
831 -  
832 -Object.extend(Array.prototype, {  
833 - _each: function(iterator) {  
834 - for (var i = 0, length = this.length; i < length; i++)  
835 - iterator(this[i]);  
836 - },  
837 -  
838 - clear: function() {  
839 - this.length = 0;  
840 - return this;  
841 - },  
842 -  
843 - first: function() {  
844 - return this[0];  
845 - },  
846 -  
847 - last: function() {  
848 - return this[this.length - 1];  
849 - },  
850 -  
851 - compact: function() {  
852 - return this.select(function(value) {  
853 - return value != null;  
854 - });  
855 - },  
856 -  
857 - flatten: function() {  
858 - return this.inject([], function(array, value) {  
859 - return array.concat(Object.isArray(value) ?  
860 - value.flatten() : [value]);  
861 - });  
862 - },  
863 -  
864 - without: function() {  
865 - var values = $A(arguments);  
866 - return this.select(function(value) {  
867 - return !values.include(value);  
868 - });  
869 - },  
870 -  
871 - reverse: function(inline) {  
872 - return (inline !== false ? this : this.toArray())._reverse();  
873 - },  
874 -  
875 - reduce: function() {  
876 - return this.length > 1 ? this : this[0];  
877 - },  
878 -  
879 - uniq: function(sorted) {  
880 - return this.inject([], function(array, value, index) {  
881 - if (0 == index || (sorted ? array.last() != value : !array.include(value)))  
882 - array.push(value);  
883 - return array;  
884 - });  
885 - },  
886 -  
887 - intersect: function(array) {  
888 - return this.uniq().findAll(function(item) {  
889 - return array.detect(function(value) { return item === value });  
890 - });  
891 - },  
892 -  
893 - clone: function() {  
894 - return [].concat(this);  
895 - },  
896 -  
897 - size: function() {  
898 - return this.length;  
899 - },  
900 -  
901 - inspect: function() {  
902 - return '[' + this.map(Object.inspect).join(', ') + ']';  
903 - },  
904 -  
905 - toJSON: function() {  
906 - var results = [];  
907 - this.each(function(object) {  
908 - var value = Object.toJSON(object);  
909 - if (!Object.isUndefined(value)) results.push(value);  
910 - });  
911 - return '[' + results.join(', ') + ']';  
912 - }  
913 -});  
914 -  
915 -// use native browser JS 1.6 implementation if available  
916 -if (Object.isFunction(Array.prototype.forEach))  
917 - Array.prototype._each = Array.prototype.forEach;  
918 -  
919 -if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {  
920 - i || (i = 0);  
921 - var length = this.length;  
922 - if (i < 0) i = length + i;  
923 - for (; i < length; i++)  
924 - if (this[i] === item) return i;  
925 - return -1;  
926 -};  
927 -  
928 -if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {  
929 - i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;  
930 - var n = this.slice(0, i).reverse().indexOf(item);  
931 - return (n < 0) ? n : i - n - 1;  
932 -};  
933 -  
934 -Array.prototype.toArray = Array.prototype.clone;  
935 -  
936 -function $w(string) {  
937 - if (!Object.isString(string)) return [];  
938 - string = string.strip();  
939 - return string ? string.split(/\s+/) : [];  
940 -}  
941 -  
942 -if (Prototype.Browser.Opera){  
943 - Array.prototype.concat = function() {  
944 - var array = [];  
945 - for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);  
946 - for (var i = 0, length = arguments.length; i < length; i++) {  
947 - if (Object.isArray(arguments[i])) {  
948 - for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)  
949 - array.push(arguments[i][j]);  
950 - } else {  
951 - array.push(arguments[i]);  
952 - }  
953 - }  
954 - return array;  
955 - };  
956 -}  
957 -Object.extend(Number.prototype, {  
958 - toColorPart: function() {  
959 - return this.toPaddedString(2, 16);  
960 - },  
961 -  
962 - succ: function() {  
963 - return this + 1;  
964 - },  
965 -  
966 - times: function(iterator) {  
967 - $R(0, this, true).each(iterator);  
968 - return this;  
969 - },  
970 -  
971 - toPaddedString: function(length, radix) {  
972 - var string = this.toString(radix || 10);  
973 - return '0'.times(length - string.length) + string;  
974 - },  
975 -  
976 - toJSON: function() {  
977 - return isFinite(this) ? this.toString() : 'null';  
978 - }  
979 -});  
980 -  
981 -$w('abs round ceil floor').each(function(method){  
982 - Number.prototype[method] = Math[method].methodize();  
983 -});  
984 -function $H(object) {  
985 - return new Hash(object);  
986 -};  
987 -  
988 -var Hash = Class.create(Enumerable, (function() {  
989 -  
990 - function toQueryPair(key, value) {  
991 - if (Object.isUndefined(value)) return key;  
992 - return key + '=' + encodeURIComponent(String.interpret(value));  
993 - }  
994 -  
995 - return {  
996 - initialize: function(object) {  
997 - this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);  
998 - },  
999 -  
1000 - _each: function(iterator) {  
1001 - for (var key in this._object) {  
1002 - var value = this._object[key], pair = [key, value];  
1003 - pair.key = key;  
1004 - pair.value = value;  
1005 - iterator(pair);  
1006 - }  
1007 - },  
1008 -  
1009 - set: function(key, value) {  
1010 - return this._object[key] = value;  
1011 - },  
1012 -  
1013 - get: function(key) {  
1014 - return this._object[key];  
1015 - },  
1016 -  
1017 - unset: function(key) {  
1018 - var value = this._object[key];  
1019 - delete this._object[key];  
1020 - return value;  
1021 - },  
1022 -  
1023 - toObject: function() {  
1024 - return Object.clone(this._object);  
1025 - },  
1026 -  
1027 - keys: function() {  
1028 - return this.pluck('key');  
1029 - },  
1030 -  
1031 - values: function() {  
1032 - return this.pluck('value');  
1033 - },  
1034 -  
1035 - index: function(value) {  
1036 - var match = this.detect(function(pair) {  
1037 - return pair.value === value;  
1038 - });  
1039 - return match && match.key;  
1040 - },  
1041 -  
1042 - merge: function(object) {  
1043 - return this.clone().update(object);  
1044 - },  
1045 -  
1046 - update: function(object) {  
1047 - return new Hash(object).inject(this, function(result, pair) {  
1048 - result.set(pair.key, pair.value);  
1049 - return result;  
1050 - });  
1051 - },  
1052 -  
1053 - toQueryString: function() {  
1054 - return this.map(function(pair) {  
1055 - var key = encodeURIComponent(pair.key), values = pair.value;  
1056 -  
1057 - if (values && typeof values == 'object') {  
1058 - if (Object.isArray(values))  
1059 - return values.map(toQueryPair.curry(key)).join('&');  
1060 - }  
1061 - return toQueryPair(key, values);  
1062 - }).join('&');  
1063 - },  
1064 -  
1065 - inspect: function() {  
1066 - return '#<Hash:{' + this.map(function(pair) {  
1067 - return pair.map(Object.inspect).join(': ');  
1068 - }).join(', ') + '}>';  
1069 - },  
1070 -  
1071 - toJSON: function() {  
1072 - return Object.toJSON(this.toObject());  
1073 - },  
1074 -  
1075 - clone: function() {  
1076 - return new Hash(this);  
1077 - }  
1078 - }  
1079 -})());  
1080 -  
1081 -Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;  
1082 -Hash.from = $H;  
1083 -var ObjectRange = Class.create(Enumerable, {  
1084 - initialize: function(start, end, exclusive) {  
1085 - this.start = start;  
1086 - this.end = end;  
1087 - this.exclusive = exclusive;  
1088 - },  
1089 -  
1090 - _each: function(iterator) {  
1091 - var value = this.start;  
1092 - while (this.include(value)) {  
1093 - iterator(value);  
1094 - value = value.succ();  
1095 - }  
1096 - },  
1097 -  
1098 - include: function(value) {  
1099 - if (value < this.start)  
1100 - return false;  
1101 - if (this.exclusive)  
1102 - return value < this.end;  
1103 - return value <= this.end;  
1104 - }  
1105 -});  
1106 -  
1107 -var $R = function(start, end, exclusive) {  
1108 - return new ObjectRange(start, end, exclusive);  
1109 -};  
1110 -  
1111 -var Ajax = {  
1112 - getTransport: function() {  
1113 - return Try.these(  
1114 - function() {return new XMLHttpRequest()},  
1115 - function() {return new ActiveXObject('Msxml2.XMLHTTP')},  
1116 - function() {return new ActiveXObject('Microsoft.XMLHTTP')}  
1117 - ) || false;  
1118 - },  
1119 -  
1120 - activeRequestCount: 0  
1121 -};  
1122 -  
1123 -Ajax.Responders = {  
1124 - responders: [],  
1125 -  
1126 - _each: function(iterator) {  
1127 - this.responders._each(iterator);  
1128 - },  
1129 -  
1130 - register: function(responder) {  
1131 - if (!this.include(responder))  
1132 - this.responders.push(responder);  
1133 - },  
1134 -  
1135 - unregister: function(responder) {  
1136 - this.responders = this.responders.without(responder);  
1137 - },  
1138 -  
1139 - dispatch: function(callback, request, transport, json) {  
1140 - this.each(function(responder) {  
1141 - if (Object.isFunction(responder[callback])) {  
1142 - try {  
1143 - responder[callback].apply(responder, [request, transport, json]);  
1144 - } catch (e) { }  
1145 - }  
1146 - });  
1147 - }  
1148 -};  
1149 -  
1150 -Object.extend(Ajax.Responders, Enumerable);  
1151 -  
1152 -Ajax.Responders.register({  
1153 - onCreate: function() { Ajax.activeRequestCount++ },  
1154 - onComplete: function() { Ajax.activeRequestCount-- }  
1155 -});  
1156 -  
1157 -Ajax.Base = Class.create({  
1158 - initialize: function(options) {  
1159 - this.options = {  
1160 - method: 'post',  
1161 - asynchronous: true,  
1162 - contentType: 'application/x-www-form-urlencoded',  
1163 - encoding: 'UTF-8',  
1164 - parameters: '',  
1165 - evalJSON: true,  
1166 - evalJS: true  
1167 - };  
1168 - Object.extend(this.options, options || { });  
1169 -  
1170 - this.options.method = this.options.method.toLowerCase();  
1171 -  
1172 - if (Object.isString(this.options.parameters))  
1173 - this.options.parameters = this.options.parameters.toQueryParams();  
1174 - else if (Object.isHash(this.options.parameters))  
1175 - this.options.parameters = this.options.parameters.toObject();  
1176 - }  
1177 -});  
1178 -  
1179 -Ajax.Request = Class.create(Ajax.Base, {  
1180 - _complete: false,  
1181 -  
1182 - initialize: function($super, url, options) {  
1183 - $super(options);  
1184 - this.transport = Ajax.getTransport();  
1185 - this.request(url);  
1186 - },  
1187 -  
1188 - request: function(url) {  
1189 - this.url = url;  
1190 - this.method = this.options.method;  
1191 - var params = Object.clone(this.options.parameters);  
1192 -  
1193 - if (!['get', 'post'].include(this.method)) {  
1194 - // simulate other verbs over post  
1195 - params['_method'] = this.method;  
1196 - this.method = 'post';  
1197 - }  
1198 -  
1199 - this.parameters = params;  
1200 -  
1201 - if (params = Object.toQueryString(params)) {  
1202 - // when GET, append parameters to URL  
1203 - if (this.method == 'get')  
1204 - this.url += (this.url.include('?') ? '&' : '?') + params;  
1205 - else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))  
1206 - params += '&_=';  
1207 - }  
1208 -  
1209 - try {  
1210 - var response = new Ajax.Response(this);  
1211 - if (this.options.onCreate) this.options.onCreate(response);  
1212 - Ajax.Responders.dispatch('onCreate', this, response);  
1213 -  
1214 - this.transport.open(this.method.toUpperCase(), this.url,  
1215 - this.options.asynchronous);  
1216 -  
1217 - if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);  
1218 -  
1219 - this.transport.onreadystatechange = this.onStateChange.bind(this);  
1220 - this.setRequestHeaders();  
1221 -  
1222 - this.body = this.method == 'post' ? (this.options.postBody || params) : null;  
1223 - this.transport.send(this.body);  
1224 -  
1225 - /* Force Firefox to handle ready state 4 for synchronous requests */  
1226 - if (!this.options.asynchronous && this.transport.overrideMimeType)  
1227 - this.onStateChange();  
1228 -  
1229 - }  
1230 - catch (e) {  
1231 - this.dispatchException(e);  
1232 - }  
1233 - },  
1234 -  
1235 - onStateChange: function() {  
1236 - var readyState = this.transport.readyState;  
1237 - if (readyState > 1 && !((readyState == 4) && this._complete))  
1238 - this.respondToReadyState(this.transport.readyState);  
1239 - },  
1240 -  
1241 - setRequestHeaders: function() {  
1242 - var headers = {  
1243 - 'X-Requested-With': 'XMLHttpRequest',  
1244 - 'X-Prototype-Version': Prototype.Version,  
1245 - 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'  
1246 - };  
1247 -  
1248 - if (this.method == 'post') {  
1249 - headers['Content-type'] = this.options.contentType +  
1250 - (this.options.encoding ? '; charset=' + this.options.encoding : '');  
1251 -  
1252 - /* Force "Connection: close" for older Mozilla browsers to work  
1253 - * around a bug where XMLHttpRequest sends an incorrect  
1254 - * Content-length header. See Mozilla Bugzilla #246651.  
1255 - */  
1256 - if (this.transport.overrideMimeType &&  
1257 - (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)  
1258 - headers['Connection'] = 'close';  
1259 - }  
1260 -  
1261 - // user-defined headers  
1262 - if (typeof this.options.requestHeaders == 'object') {  
1263 - var extras = this.options.requestHeaders;  
1264 -  
1265 - if (Object.isFunction(extras.push))  
1266 - for (var i = 0, length = extras.length; i < length; i += 2)  
1267 - headers[extras[i]] = extras[i+1];  
1268 - else  
1269 - $H(extras).each(function(pair) { headers[pair.key] = pair.value });  
1270 - }  
1271 -  
1272 - for (var name in headers)  
1273 - this.transport.setRequestHeader(name, headers[name]);  
1274 - },  
1275 -  
1276 - success: function() {  
1277 - var status = this.getStatus();  
1278 - return !status || (status >= 200 && status < 300);  
1279 - },  
1280 -  
1281 - getStatus: function() {  
1282 - try {  
1283 - return this.transport.status || 0;  
1284 - } catch (e) { return 0 }  
1285 - },  
1286 -  
1287 - respondToReadyState: function(readyState) {  
1288 - var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);  
1289 -  
1290 - if (state == 'Complete') {  
1291 - try {  
1292 - this._complete = true;  
1293 - (this.options['on' + response.status]  
1294 - || this.options['on' + (this.success() ? 'Success' : 'Failure')]  
1295 - || Prototype.emptyFunction)(response, response.headerJSON);  
1296 - } catch (e) {  
1297 - this.dispatchException(e);  
1298 - }  
1299 -  
1300 - var contentType = response.getHeader('Content-type');  
1301 - if (this.options.evalJS == 'force'  
1302 - || (this.options.evalJS && this.isSameOrigin() && contentType  
1303 - && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))  
1304 - this.evalResponse();  
1305 - }  
1306 -  
1307 - try {  
1308 - (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);  
1309 - Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);  
1310 - } catch (e) {  
1311 - this.dispatchException(e);  
1312 - }  
1313 -  
1314 - if (state == 'Complete') {  
1315 - // avoid memory leak in MSIE: clean up  
1316 - this.transport.onreadystatechange = Prototype.emptyFunction;  
1317 - }  
1318 - },  
1319 -  
1320 - isSameOrigin: function() {  
1321 - var m = this.url.match(/^\s*https?:\/\/[^\/]*/);  
1322 - return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({  
1323 - protocol: location.protocol,  
1324 - domain: document.domain,  
1325 - port: location.port ? ':' + location.port : ''  
1326 - }));  
1327 - },  
1328 -  
1329 - getHeader: function(name) {  
1330 - try {  
1331 - return this.transport.getResponseHeader(name) || null;  
1332 - } catch (e) { return null }  
1333 - },  
1334 -  
1335 - evalResponse: function() {  
1336 - try {  
1337 - return eval((this.transport.responseText || '').unfilterJSON());  
1338 - } catch (e) {  
1339 - this.dispatchException(e);  
1340 - }  
1341 - },  
1342 -  
1343 - dispatchException: function(exception) {  
1344 - (this.options.onException || Prototype.emptyFunction)(this, exception);  
1345 - Ajax.Responders.dispatch('onException', this, exception);  
1346 - }  
1347 -});  
1348 -  
1349 -Ajax.Request.Events =  
1350 - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];  
1351 -  
1352 -Ajax.Response = Class.create({  
1353 - initialize: function(request){  
1354 - this.request = request;  
1355 - var transport = this.transport = request.transport,  
1356 - readyState = this.readyState = transport.readyState;  
1357 -  
1358 - if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {  
1359 - this.status = this.getStatus();  
1360 - this.statusText = this.getStatusText();  
1361 - this.responseText = String.interpret(transport.responseText);  
1362 - this.headerJSON = this._getHeaderJSON();  
1363 - }  
1364 -  
1365 - if(readyState == 4) {  
1366 - var xml = transport.responseXML;  
1367 - this.responseXML = Object.isUndefined(xml) ? null : xml;  
1368 - this.responseJSON = this._getResponseJSON();  
1369 - }  
1370 - },  
1371 -  
1372 - status: 0,  
1373 - statusText: '',  
1374 -  
1375 - getStatus: Ajax.Request.prototype.getStatus,  
1376 -  
1377 - getStatusText: function() {  
1378 - try {  
1379 - return this.transport.statusText || '';  
1380 - } catch (e) { return '' }  
1381 - },  
1382 -  
1383 - getHeader: Ajax.Request.prototype.getHeader,  
1384 -  
1385 - getAllHeaders: function() {  
1386 - try {  
1387 - return this.getAllResponseHeaders();  
1388 - } catch (e) { return null }  
1389 - },  
1390 -  
1391 - getResponseHeader: function(name) {  
1392 - return this.transport.getResponseHeader(name);  
1393 - },  
1394 -  
1395 - getAllResponseHeaders: function() {  
1396 - return this.transport.getAllResponseHeaders();  
1397 - },  
1398 -  
1399 - _getHeaderJSON: function() {  
1400 - var json = this.getHeader('X-JSON');  
1401 - if (!json) return null;  
1402 - json = decodeURIComponent(escape(json));  
1403 - try {  
1404 - return json.evalJSON(this.request.options.sanitizeJSON ||  
1405 - !this.request.isSameOrigin());  
1406 - } catch (e) {  
1407 - this.request.dispatchException(e);  
1408 - }  
1409 - },  
1410 -  
1411 - _getResponseJSON: function() {  
1412 - var options = this.request.options;  
1413 - if (!options.evalJSON || (options.evalJSON != 'force' &&  
1414 - !(this.getHeader('Content-type') || '').include('application/json')) ||  
1415 - this.responseText.blank())  
1416 - return null;  
1417 - try {  
1418 - return this.responseText.evalJSON(options.sanitizeJSON ||  
1419 - !this.request.isSameOrigin());  
1420 - } catch (e) {  
1421 - this.request.dispatchException(e);  
1422 - }  
1423 - }  
1424 -});  
1425 -  
1426 -Ajax.Updater = Class.create(Ajax.Request, {  
1427 - initialize: function($super, container, url, options) {  
1428 - this.container = {  
1429 - success: (container.success || container),  
1430 - failure: (container.failure || (container.success ? null : container))  
1431 - };  
1432 -  
1433 - options = Object.clone(options);  
1434 - var onComplete = options.onComplete;  
1435 - options.onComplete = (function(response, json) {  
1436 - this.updateContent(response.responseText);  
1437 - if (Object.isFunction(onComplete)) onComplete(response, json);  
1438 - }).bind(this);  
1439 -  
1440 - $super(url, options);  
1441 - },  
1442 -  
1443 - updateContent: function(responseText) {  
1444 - var receiver = this.container[this.success() ? 'success' : 'failure'],  
1445 - options = this.options;  
1446 -  
1447 - if (!options.evalScripts) responseText = responseText.stripScripts();  
1448 -  
1449 - if (receiver = $(receiver)) {  
1450 - if (options.insertion) {  
1451 - if (Object.isString(options.insertion)) {  
1452 - var insertion = { }; insertion[options.insertion] = responseText;  
1453 - receiver.insert(insertion);  
1454 - }  
1455 - else options.insertion(receiver, responseText);  
1456 - }  
1457 - else receiver.update(responseText);  
1458 - }  
1459 - }  
1460 -});  
1461 -  
1462 -Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {  
1463 - initialize: function($super, container, url, options) {  
1464 - $super(options);  
1465 - this.onComplete = this.options.onComplete;  
1466 -  
1467 - this.frequency = (this.options.frequency || 2);  
1468 - this.decay = (this.options.decay || 1);  
1469 -  
1470 - this.updater = { };  
1471 - this.container = container;  
1472 - this.url = url;  
1473 -  
1474 - this.start();  
1475 - },  
1476 -  
1477 - start: function() {  
1478 - this.options.onComplete = this.updateComplete.bind(this);  
1479 - this.onTimerEvent();  
1480 - },  
1481 -  
1482 - stop: function() {  
1483 - this.updater.options.onComplete = undefined;  
1484 - clearTimeout(this.timer);  
1485 - (this.onComplete || Prototype.emptyFunction).apply(this, arguments);  
1486 - },  
1487 -  
1488 - updateComplete: function(response) {  
1489 - if (this.options.decay) {  
1490 - this.decay = (response.responseText == this.lastText ?  
1491 - this.decay * this.options.decay : 1);  
1492 -  
1493 - this.lastText = response.responseText;  
1494 - }  
1495 - this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);  
1496 - },  
1497 -  
1498 - onTimerEvent: function() {  
1499 - this.updater = new Ajax.Updater(this.container, this.url, this.options);  
1500 - }  
1501 -});  
1502 -function $(element) {  
1503 - if (arguments.length > 1) {  
1504 - for (var i = 0, elements = [], length = arguments.length; i < length; i++)  
1505 - elements.push($(arguments[i]));  
1506 - return elements;  
1507 - }  
1508 - if (Object.isString(element))  
1509 - element = document.getElementById(element);  
1510 - return Element.extend(element);  
1511 -}  
1512 -  
1513 -if (Prototype.BrowserFeatures.XPath) {  
1514 - document._getElementsByXPath = function(expression, parentElement) {  
1515 - var results = [];  
1516 - var query = document.evaluate(expression, $(parentElement) || document,  
1517 - null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);  
1518 - for (var i = 0, length = query.snapshotLength; i < length; i++)  
1519 - results.push(Element.extend(query.snapshotItem(i)));  
1520 - return results;  
1521 - };  
1522 -}  
1523 -  
1524 -/*--------------------------------------------------------------------------*/  
1525 -  
1526 -if (!window.Node) var Node = { };  
1527 -  
1528 -if (!Node.ELEMENT_NODE) {  
1529 - // DOM level 2 ECMAScript Language Binding  
1530 - Object.extend(Node, {  
1531 - ELEMENT_NODE: 1,  
1532 - ATTRIBUTE_NODE: 2,  
1533 - TEXT_NODE: 3,  
1534 - CDATA_SECTION_NODE: 4,  
1535 - ENTITY_REFERENCE_NODE: 5,  
1536 - ENTITY_NODE: 6,  
1537 - PROCESSING_INSTRUCTION_NODE: 7,  
1538 - COMMENT_NODE: 8,  
1539 - DOCUMENT_NODE: 9,  
1540 - DOCUMENT_TYPE_NODE: 10,  
1541 - DOCUMENT_FRAGMENT_NODE: 11,  
1542 - NOTATION_NODE: 12  
1543 - });  
1544 -}  
1545 -  
1546 -(function() {  
1547 - var element = this.Element;  
1548 - this.Element = function(tagName, attributes) {  
1549 - attributes = attributes || { };  
1550 - tagName = tagName.toLowerCase();  
1551 - var cache = Element.cache;  
1552 - if (Prototype.Browser.IE && attributes.name) {  
1553 - tagName = '<' + tagName + ' name="' + attributes.name + '">';  
1554 - delete attributes.name;  
1555 - return Element.writeAttribute(document.createElement(tagName), attributes);  
1556 - }  
1557 - if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));  
1558 - return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);  
1559 - };  
1560 - Object.extend(this.Element, element || { });  
1561 -}).call(window);  
1562 -  
1563 -Element.cache = { };  
1564 -  
1565 -Element.Methods = {  
1566 - visible: function(element) {  
1567 - return $(element).style.display != 'none';  
1568 - },  
1569 -  
1570 - toggle: function(element) {  
1571 - element = $(element);  
1572 - Element[Element.visible(element) ? 'hide' : 'show'](element);  
1573 - return element;  
1574 - },  
1575 -  
1576 - hide: function(element) {  
1577 - $(element).style.display = 'none';  
1578 - return element;  
1579 - },  
1580 -  
1581 - show: function(element) {  
1582 - $(element).style.display = '';  
1583 - return element;  
1584 - },  
1585 -  
1586 - remove: function(element) {  
1587 - element = $(element);  
1588 - element.parentNode.removeChild(element);  
1589 - return element;  
1590 - },  
1591 -  
1592 - update: function(element, content) {  
1593 - element = $(element);  
1594 - if (content && content.toElement) content = content.toElement();  
1595 - if (Object.isElement(content)) return element.update().insert(content);  
1596 - content = Object.toHTML(content);  
1597 - element.innerHTML = content.stripScripts();  
1598 - content.evalScripts.bind(content).defer();  
1599 - return element;  
1600 - },  
1601 -  
1602 - replace: function(element, content) {  
1603 - element = $(element);  
1604 - if (content && content.toElement) content = content.toElement();  
1605 - else if (!Object.isElement(content)) {  
1606 - content = Object.toHTML(content);  
1607 - var range = element.ownerDocument.createRange();  
1608 - range.selectNode(element);  
1609 - content.evalScripts.bind(content).defer();  
1610 - content = range.createContextualFragment(content.stripScripts());  
1611 - }  
1612 - element.parentNode.replaceChild(content, element);  
1613 - return element;  
1614 - },  
1615 -  
1616 - insert: function(element, insertions) {  
1617 - element = $(element);  
1618 -  
1619 - if (Object.isString(insertions) || Object.isNumber(insertions) ||  
1620 - Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))  
1621 - insertions = {bottom:insertions};  
1622 -  
1623 - var content, insert, tagName, childNodes;  
1624 -  
1625 - for (var position in insertions) {  
1626 - content = insertions[position];  
1627 - position = position.toLowerCase();  
1628 - insert = Element._insertionTranslations[position];  
1629 -  
1630 - if (content && content.toElement) content = content.toElement();  
1631 - if (Object.isElement(content)) {  
1632 - insert(element, content);  
1633 - continue;  
1634 - }  
1635 -  
1636 - content = Object.toHTML(content);  
1637 -  
1638 - tagName = ((position == 'before' || position == 'after')  
1639 - ? element.parentNode : element).tagName.toUpperCase();  
1640 -  
1641 - childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());  
1642 -  
1643 - if (position == 'top' || position == 'after') childNodes.reverse();  
1644 - childNodes.each(insert.curry(element));  
1645 -  
1646 - content.evalScripts.bind(content).defer();  
1647 - }  
1648 -  
1649 - return element;  
1650 - },  
1651 -  
1652 - wrap: function(element, wrapper, attributes) {  
1653 - element = $(element);  
1654 - if (Object.isElement(wrapper))  
1655 - $(wrapper).writeAttribute(attributes || { });  
1656 - else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);  
1657 - else wrapper = new Element('div', wrapper);  
1658 - if (element.parentNode)  
1659 - element.parentNode.replaceChild(wrapper, element);  
1660 - wrapper.appendChild(element);  
1661 - return wrapper;  
1662 - },  
1663 -  
1664 - inspect: function(element) {  
1665 - element = $(element);  
1666 - var result = '<' + element.tagName.toLowerCase();  
1667 - $H({'id': 'id', 'className': 'class'}).each(function(pair) {  
1668 - var property = pair.first(), attribute = pair.last();  
1669 - var value = (element[property] || '').toString();  
1670 - if (value) result += ' ' + attribute + '=' + value.inspect(true);  
1671 - });  
1672 - return result + '>';  
1673 - },  
1674 -  
1675 - recursivelyCollect: function(element, property) {  
1676 - element = $(element);  
1677 - var elements = [];  
1678 - while (element = element[property])  
1679 - if (element.nodeType == 1)  
1680 - elements.push(Element.extend(element));  
1681 - return elements;  
1682 - },  
1683 -  
1684 - ancestors: function(element) {  
1685 - return $(element).recursivelyCollect('parentNode');  
1686 - },  
1687 -  
1688 - descendants: function(element) {  
1689 - return $(element).select("*");  
1690 - },  
1691 -  
1692 - firstDescendant: function(element) {  
1693 - element = $(element).firstChild;  
1694 - while (element && element.nodeType != 1) element = element.nextSibling;  
1695 - return $(element);  
1696 - },  
1697 -  
1698 - immediateDescendants: function(element) {  
1699 - if (!(element = $(element).firstChild)) return [];  
1700 - while (element && element.nodeType != 1) element = element.nextSibling;  
1701 - if (element) return [element].concat($(element).nextSiblings());  
1702 - return [];  
1703 - },  
1704 -  
1705 - previousSiblings: function(element) {  
1706 - return $(element).recursivelyCollect('previousSibling');  
1707 - },  
1708 -  
1709 - nextSiblings: function(element) {  
1710 - return $(element).recursivelyCollect('nextSibling');  
1711 - },  
1712 -  
1713 - siblings: function(element) {  
1714 - element = $(element);  
1715 - return element.previousSiblings().reverse().concat(element.nextSiblings());  
1716 - },  
1717 -  
1718 - match: function(element, selector) {  
1719 - if (Object.isString(selector))  
1720 - selector = new Selector(selector);  
1721 - return selector.match($(element));  
1722 - },  
1723 -  
1724 - up: function(element, expression, index) {  
1725 - element = $(element);  
1726 - if (arguments.length == 1) return $(element.parentNode);  
1727 - var ancestors = element.ancestors();  
1728 - return Object.isNumber(expression) ? ancestors[expression] :  
1729 - Selector.findElement(ancestors, expression, index);  
1730 - },  
1731 -  
1732 - down: function(element, expression, index) {  
1733 - element = $(element);  
1734 - if (arguments.length == 1) return element.firstDescendant();  
1735 - return Object.isNumber(expression) ? element.descendants()[expression] :  
1736 - element.select(expression)[index || 0];  
1737 - },  
1738 -  
1739 - previous: function(element, expression, index) {  
1740 - element = $(element);  
1741 - if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));  
1742 - var previousSiblings = element.previousSiblings();  
1743 - return Object.isNumber(expression) ? previousSiblings[expression] :  
1744 - Selector.findElement(previousSiblings, expression, index);  
1745 - },  
1746 -  
1747 - next: function(element, expression, index) {  
1748 - element = $(element);  
1749 - if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));  
1750 - var nextSiblings = element.nextSiblings();  
1751 - return Object.isNumber(expression) ? nextSiblings[expression] :  
1752 - Selector.findElement(nextSiblings, expression, index);  
1753 - },  
1754 -  
1755 - select: function() {  
1756 - var args = $A(arguments), element = $(args.shift());  
1757 - return Selector.findChildElements(element, args);  
1758 - },  
1759 -  
1760 - adjacent: function() {  
1761 - var args = $A(arguments), element = $(args.shift());  
1762 - return Selector.findChildElements(element.parentNode, args).without(element);  
1763 - },  
1764 -  
1765 - identify: function(element) {  
1766 - element = $(element);  
1767 - var id = element.readAttribute('id'), self = arguments.callee;  
1768 - if (id) return id;  
1769 - do { id = 'anonymous_element_' + self.counter++ } while ($(id));  
1770 - element.writeAttribute('id', id);  
1771 - return id;  
1772 - },  
1773 -  
1774 - readAttribute: function(element, name) {  
1775 - element = $(element);  
1776 - if (Prototype.Browser.IE) {  
1777 - var t = Element._attributeTranslations.read;  
1778 - if (t.values[name]) return t.values[name](element, name);  
1779 - if (t.names[name]) name = t.names[name];  
1780 - if (name.include(':')) {  
1781 - return (!element.attributes || !element.attributes[name]) ? null :  
1782 - element.attributes[name].value;  
1783 - }  
1784 - }  
1785 - return element.getAttribute(name);  
1786 - },  
1787 -  
1788 - writeAttribute: function(element, name, value) {  
1789 - element = $(element);  
1790 - var attributes = { }, t = Element._attributeTranslations.write;  
1791 -  
1792 - if (typeof name == 'object') attributes = name;  
1793 - else attributes[name] = Object.isUndefined(value) ? true : value;  
1794 -  
1795 - for (var attr in attributes) {  
1796 - name = t.names[attr] || attr;  
1797 - value = attributes[attr];  
1798 - if (t.values[attr]) name = t.values[attr](element, value);  
1799 - if (value === false || value === null)  
1800 - element.removeAttribute(name);  
1801 - else if (value === true)  
1802 - element.setAttribute(name, name);  
1803 - else element.setAttribute(name, value);  
1804 - }  
1805 - return element;  
1806 - },  
1807 -  
1808 - getHeight: function(element) {  
1809 - return $(element).getDimensions().height;  
1810 - },  
1811 -  
1812 - getWidth: function(element) {  
1813 - return $(element).getDimensions().width;  
1814 - },  
1815 -  
1816 - classNames: function(element) {  
1817 - return new Element.ClassNames(element);  
1818 - },  
1819 -  
1820 - hasClassName: function(element, className) {  
1821 - if (!(element = $(element))) return;  
1822 - var elementClassName = element.className;  
1823 - return (elementClassName.length > 0 && (elementClassName == className ||  
1824 - new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));  
1825 - },  
1826 -  
1827 - addClassName: function(element, className) {  
1828 - if (!(element = $(element))) return;  
1829 - if (!element.hasClassName(className))  
1830 - element.className += (element.className ? ' ' : '') + className;  
1831 - return element;  
1832 - },  
1833 -  
1834 - removeClassName: function(element, className) {  
1835 - if (!(element = $(element))) return;  
1836 - element.className = element.className.replace(  
1837 - new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();  
1838 - return element;  
1839 - },  
1840 -  
1841 - toggleClassName: function(element, className) {  
1842 - if (!(element = $(element))) return;  
1843 - return element[element.hasClassName(className) ?  
1844 - 'removeClassName' : 'addClassName'](className);  
1845 - },  
1846 -  
1847 - // removes whitespace-only text node children  
1848 - cleanWhitespace: function(element) {  
1849 - element = $(element);  
1850 - var node = element.firstChild;  
1851 - while (node) {  
1852 - var nextNode = node.nextSibling;  
1853 - if (node.nodeType == 3 && !/\S/.test(node.nodeValue))  
1854 - element.removeChild(node);  
1855 - node = nextNode;  
1856 - }  
1857 - return element;  
1858 - },  
1859 -  
1860 - empty: function(element) {  
1861 - return $(element).innerHTML.blank();  
1862 - },  
1863 -  
1864 - descendantOf: function(element, ancestor) {  
1865 - element = $(element), ancestor = $(ancestor);  
1866 - var originalAncestor = ancestor;  
1867 -  
1868 - if (element.compareDocumentPosition)  
1869 - return (element.compareDocumentPosition(ancestor) & 8) === 8;  
1870 -  
1871 - if (element.sourceIndex && !Prototype.Browser.Opera) {  
1872 - var e = element.sourceIndex, a = ancestor.sourceIndex,  
1873 - nextAncestor = ancestor.nextSibling;  
1874 - if (!nextAncestor) {  
1875 - do { ancestor = ancestor.parentNode; }  
1876 - while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);  
1877 - }  
1878 - if (nextAncestor && nextAncestor.sourceIndex)  
1879 - return (e > a && e < nextAncestor.sourceIndex);  
1880 - }  
1881 -  
1882 - while (element = element.parentNode)  
1883 - if (element == originalAncestor) return true;  
1884 - return false;  
1885 - },  
1886 -  
1887 - scrollTo: function(element) {  
1888 - element = $(element);  
1889 - var pos = element.cumulativeOffset();  
1890 - window.scrollTo(pos[0], pos[1]);  
1891 - return element;  
1892 - },  
1893 -  
1894 - getStyle: function(element, style) {  
1895 - element = $(element);  
1896 - style = style == 'float' ? 'cssFloat' : style.camelize();  
1897 - var value = element.style[style];  
1898 - if (!value) {  
1899 - var css = document.defaultView.getComputedStyle(element, null);  
1900 - value = css ? css[style] : null;  
1901 - }  
1902 - if (style == 'opacity') return value ? parseFloat(value) : 1.0;  
1903 - return value == 'auto' ? null : value;  
1904 - },  
1905 -  
1906 - getOpacity: function(element) {  
1907 - return $(element).getStyle('opacity');  
1908 - },  
1909 -  
1910 - setStyle: function(element, styles) {  
1911 - element = $(element);  
1912 - var elementStyle = element.style, match;  
1913 - if (Object.isString(styles)) {  
1914 - element.style.cssText += ';' + styles;  
1915 - return styles.include('opacity') ?  
1916 - element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;  
1917 - }  
1918 - for (var property in styles)  
1919 - if (property == 'opacity') element.setOpacity(styles[property]);  
1920 - else  
1921 - elementStyle[(property == 'float' || property == 'cssFloat') ?  
1922 - (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :  
1923 - property] = styles[property];  
1924 -  
1925 - return element;  
1926 - },  
1927 -  
1928 - setOpacity: function(element, value) {  
1929 - element = $(element);  
1930 - element.style.opacity = (value == 1 || value === '') ? '' :  
1931 - (value < 0.00001) ? 0 : value;  
1932 - return element;  
1933 - },  
1934 -  
1935 - getDimensions: function(element) {  
1936 - element = $(element);  
1937 - var display = $(element).getStyle('display');  
1938 - if (display != 'none' && display != null) // Safari bug  
1939 - return {width: element.offsetWidth, height: element.offsetHeight};  
1940 -  
1941 - // All *Width and *Height properties give 0 on elements with display none,  
1942 - // so enable the element temporarily  
1943 - var els = element.style;  
1944 - var originalVisibility = els.visibility;  
1945 - var originalPosition = els.position;  
1946 - var originalDisplay = els.display;  
1947 - els.visibility = 'hidden';  
1948 - els.position = 'absolute';  
1949 - els.display = 'block';  
1950 - var originalWidth = element.clientWidth;  
1951 - var originalHeight = element.clientHeight;  
1952 - els.display = originalDisplay;  
1953 - els.position = originalPosition;  
1954 - els.visibility = originalVisibility;  
1955 - return {width: originalWidth, height: originalHeight};  
1956 - },  
1957 -  
1958 - makePositioned: function(element) {  
1959 - element = $(element);  
1960 - var pos = Element.getStyle(element, 'position');  
1961 - if (pos == 'static' || !pos) {  
1962 - element._madePositioned = true;  
1963 - element.style.position = 'relative';  
1964 - // Opera returns the offset relative to the positioning context, when an  
1965 - // element is position relative but top and left have not been defined  
1966 - if (window.opera) {  
1967 - element.style.top = 0;  
1968 - element.style.left = 0;  
1969 - }  
1970 - }  
1971 - return element;  
1972 - },  
1973 -  
1974 - undoPositioned: function(element) {  
1975 - element = $(element);  
1976 - if (element._madePositioned) {  
1977 - element._madePositioned = undefined;  
1978 - element.style.position =  
1979 - element.style.top =  
1980 - element.style.left =  
1981 - element.style.bottom =  
1982 - element.style.right = '';  
1983 - }  
1984 - return element;  
1985 - },  
1986 -  
1987 - makeClipping: function(element) {  
1988 - element = $(element);  
1989 - if (element._overflow) return element;  
1990 - element._overflow = Element.getStyle(element, 'overflow') || 'auto';  
1991 - if (element._overflow !== 'hidden')  
1992 - element.style.overflow = 'hidden';  
1993 - return element;  
1994 - },  
1995 -  
1996 - undoClipping: function(element) {  
1997 - element = $(element);  
1998 - if (!element._overflow) return element;  
1999 - element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;  
2000 - element._overflow = null;  
2001 - return element;  
2002 - },  
2003 -  
2004 - cumulativeOffset: function(element) {  
2005 - var valueT = 0, valueL = 0;  
2006 - do {  
2007 - valueT += element.offsetTop || 0;  
2008 - valueL += element.offsetLeft || 0;  
2009 - element = element.offsetParent;  
2010 - } while (element);  
2011 - return Element._returnOffset(valueL, valueT);  
2012 - },  
2013 -  
2014 - positionedOffset: function(element) {  
2015 - var valueT = 0, valueL = 0;  
2016 - do {  
2017 - valueT += element.offsetTop || 0;  
2018 - valueL += element.offsetLeft || 0;  
2019 - element = element.offsetParent;  
2020 - if (element) {  
2021 - if (element.tagName == 'BODY') break;  
2022 - var p = Element.getStyle(element, 'position');  
2023 - if (p !== 'static') break;  
2024 - }  
2025 - } while (element);  
2026 - return Element._returnOffset(valueL, valueT);  
2027 - },  
2028 -  
2029 - absolutize: function(element) {  
2030 - element = $(element);  
2031 - if (element.getStyle('position') == 'absolute') return;  
2032 - // Position.prepare(); // To be done manually by Scripty when it needs it.  
2033 -  
2034 - var offsets = element.positionedOffset();  
2035 - var top = offsets[1];  
2036 - var left = offsets[0];  
2037 - var width = element.clientWidth;  
2038 - var height = element.clientHeight;  
2039 -  
2040 - element._originalLeft = left - parseFloat(element.style.left || 0);  
2041 - element._originalTop = top - parseFloat(element.style.top || 0);  
2042 - element._originalWidth = element.style.width;  
2043 - element._originalHeight = element.style.height;  
2044 -  
2045 - element.style.position = 'absolute';  
2046 - element.style.top = top + 'px';  
2047 - element.style.left = left + 'px';  
2048 - element.style.width = width + 'px';  
2049 - element.style.height = height + 'px';  
2050 - return element;  
2051 - },  
2052 -  
2053 - relativize: function(element) {  
2054 - element = $(element);  
2055 - if (element.getStyle('position') == 'relative') return;  
2056 - // Position.prepare(); // To be done manually by Scripty when it needs it.  
2057 -  
2058 - element.style.position = 'relative';  
2059 - var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);  
2060 - var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);  
2061 -  
2062 - element.style.top = top + 'px';  
2063 - element.style.left = left + 'px';  
2064 - element.style.height = element._originalHeight;  
2065 - element.style.width = element._originalWidth;  
2066 - return element;  
2067 - },  
2068 -  
2069 - cumulativeScrollOffset: function(element) {  
2070 - var valueT = 0, valueL = 0;  
2071 - do {  
2072 - valueT += element.scrollTop || 0;  
2073 - valueL += element.scrollLeft || 0;  
2074 - element = element.parentNode;  
2075 - } while (element);  
2076 - return Element._returnOffset(valueL, valueT);  
2077 - },  
2078 -  
2079 - getOffsetParent: function(element) {  
2080 - if (element.offsetParent) return $(element.offsetParent);  
2081 - if (element == document.body) return $(element);  
2082 -  
2083 - while ((element = element.parentNode) && element != document.body)  
2084 - if (Element.getStyle(element, 'position') != 'static')  
2085 - return $(element);  
2086 -  
2087 - return $(document.body);  
2088 - },  
2089 -  
2090 - viewportOffset: function(forElement) {  
2091 - var valueT = 0, valueL = 0;  
2092 -  
2093 - var element = forElement;  
2094 - do {  
2095 - valueT += element.offsetTop || 0;  
2096 - valueL += element.offsetLeft || 0;  
2097 -  
2098 - // Safari fix  
2099 - if (element.offsetParent == document.body &&  
2100 - Element.getStyle(element, 'position') == 'absolute') break;  
2101 -  
2102 - } while (element = element.offsetParent);  
2103 -  
2104 - element = forElement;  
2105 - do {  
2106 - if (!Prototype.Browser.Opera || element.tagName == 'BODY') {  
2107 - valueT -= element.scrollTop || 0;  
2108 - valueL -= element.scrollLeft || 0;  
2109 - }  
2110 - } while (element = element.parentNode);  
2111 -  
2112 - return Element._returnOffset(valueL, valueT);  
2113 - },  
2114 -  
2115 - clonePosition: function(element, source) {  
2116 - var options = Object.extend({  
2117 - setLeft: true,  
2118 - setTop: true,  
2119 - setWidth: true,  
2120 - setHeight: true,  
2121 - offsetTop: 0,  
2122 - offsetLeft: 0  
2123 - }, arguments[2] || { });  
2124 -  
2125 - // find page position of source  
2126 - source = $(source);  
2127 - var p = source.viewportOffset();  
2128 -  
2129 - // find coordinate system to use  
2130 - element = $(element);  
2131 - var delta = [0, 0];  
2132 - var parent = null;  
2133 - // delta [0,0] will do fine with position: fixed elements,  
2134 - // position:absolute needs offsetParent deltas  
2135 - if (Element.getStyle(element, 'position') == 'absolute') {  
2136 - parent = element.getOffsetParent();  
2137 - delta = parent.viewportOffset();  
2138 - }  
2139 -  
2140 - // correct by body offsets (fixes Safari)  
2141 - if (parent == document.body) {  
2142 - delta[0] -= document.body.offsetLeft;  
2143 - delta[1] -= document.body.offsetTop;  
2144 - }  
2145 -  
2146 - // set position  
2147 - if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';  
2148 - if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';  
2149 - if (options.setWidth) element.style.width = source.offsetWidth + 'px';  
2150 - if (options.setHeight) element.style.height = source.offsetHeight + 'px';  
2151 - return element;  
2152 - }  
2153 -};  
2154 -  
2155 -Element.Methods.identify.counter = 1;  
2156 -  
2157 -Object.extend(Element.Methods, {  
2158 - getElementsBySelector: Element.Methods.select,  
2159 - childElements: Element.Methods.immediateDescendants  
2160 -});  
2161 -  
2162 -Element._attributeTranslations = {  
2163 - write: {  
2164 - names: {  
2165 - className: 'class',  
2166 - htmlFor: 'for'  
2167 - },  
2168 - values: { }  
2169 - }  
2170 -};  
2171 -  
2172 -if (Prototype.Browser.Opera) {  
2173 - Element.Methods.getStyle = Element.Methods.getStyle.wrap(  
2174 - function(proceed, element, style) {  
2175 - switch (style) {  
2176 - case 'left': case 'top': case 'right': case 'bottom':  
2177 - if (proceed(element, 'position') === 'static') return null;  
2178 - case 'height': case 'width':  
2179 - // returns '0px' for hidden elements; we want it to return null  
2180 - if (!Element.visible(element)) return null;  
2181 -  
2182 - // returns the border-box dimensions rather than the content-box  
2183 - // dimensions, so we subtract padding and borders from the value  
2184 - var dim = parseInt(proceed(element, style), 10);  
2185 -  
2186 - if (dim !== element['offset' + style.capitalize()])  
2187 - return dim + 'px';  
2188 -  
2189 - var properties;  
2190 - if (style === 'height') {  
2191 - properties = ['border-top-width', 'padding-top',  
2192 - 'padding-bottom', 'border-bottom-width'];  
2193 - }  
2194 - else {  
2195 - properties = ['border-left-width', 'padding-left',  
2196 - 'padding-right', 'border-right-width'];  
2197 - }  
2198 - return properties.inject(dim, function(memo, property) {  
2199 - var val = proceed(element, property);  
2200 - return val === null ? memo : memo - parseInt(val, 10);  
2201 - }) + 'px';  
2202 - default: return proceed(element, style);  
2203 - }  
2204 - }  
2205 - );  
2206 -  
2207 - Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(  
2208 - function(proceed, element, attribute) {  
2209 - if (attribute === 'title') return element.title;  
2210 - return proceed(element, attribute);  
2211 - }  
2212 - );  
2213 -}  
2214 -  
2215 -else if (Prototype.Browser.IE) {  
2216 - // IE doesn't report offsets correctly for static elements, so we change them  
2217 - // to "relative" to get the values, then change them back.  
2218 - Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(  
2219 - function(proceed, element) {  
2220 - element = $(element);  
2221 - var position = element.getStyle('position');  
2222 - if (position !== 'static') return proceed(element);  
2223 - element.setStyle({ position: 'relative' });  
2224 - var value = proceed(element);  
2225 - element.setStyle({ position: position });  
2226 - return value;  
2227 - }  
2228 - );  
2229 -  
2230 - $w('positionedOffset viewportOffset').each(function(method) {  
2231 - Element.Methods[method] = Element.Methods[method].wrap(  
2232 - function(proceed, element) {  
2233 - element = $(element);  
2234 - var position = element.getStyle('position');  
2235 - if (position !== 'static') return proceed(element);  
2236 - // Trigger hasLayout on the offset parent so that IE6 reports  
2237 - // accurate offsetTop and offsetLeft values for position: fixed.  
2238 - var offsetParent = element.getOffsetParent();  
2239 - if (offsetParent && offsetParent.getStyle('position') === 'fixed')  
2240 - offsetParent.setStyle({ zoom: 1 });  
2241 - element.setStyle({ position: 'relative' });  
2242 - var value = proceed(element);  
2243 - element.setStyle({ position: position });  
2244 - return value;  
2245 - }  
2246 - );  
2247 - });  
2248 -  
2249 - Element.Methods.getStyle = function(element, style) {  
2250 - element = $(element);  
2251 - style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();  
2252 - var value = element.style[style];  
2253 - if (!value && element.currentStyle) value = element.currentStyle[style];  
2254 -  
2255 - if (style == 'opacity') {  
2256 - if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))  
2257 - if (value[1]) return parseFloat(value[1]) / 100;  
2258 - return 1.0;  
2259 - }  
2260 -  
2261 - if (value == 'auto') {  
2262 - if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))  
2263 - return element['offset' + style.capitalize()] + 'px';  
2264 - return null;  
2265 - }  
2266 - return value;  
2267 - };  
2268 -  
2269 - Element.Methods.setOpacity = function(element, value) {  
2270 - function stripAlpha(filter){  
2271 - return filter.replace(/alpha\([^\)]*\)/gi,'');  
2272 - }  
2273 - element = $(element);  
2274 - var currentStyle = element.currentStyle;  
2275 - if ((currentStyle && !currentStyle.hasLayout) ||  
2276 - (!currentStyle && element.style.zoom == 'normal'))  
2277 - element.style.zoom = 1;  
2278 -  
2279 - var filter = element.getStyle('filter'), style = element.style;  
2280 - if (value == 1 || value === '') {  
2281 - (filter = stripAlpha(filter)) ?  
2282 - style.filter = filter : style.removeAttribute('filter');  
2283 - return element;  
2284 - } else if (value < 0.00001) value = 0;  
2285 - style.filter = stripAlpha(filter) +  
2286 - 'alpha(opacity=' + (value * 100) + ')';  
2287 - return element;  
2288 - };  
2289 -  
2290 - Element._attributeTranslations = {  
2291 - read: {  
2292 - names: {  
2293 - 'class': 'className',  
2294 - 'for': 'htmlFor'  
2295 - },  
2296 - values: {  
2297 - _getAttr: function(element, attribute) {  
2298 - return element.getAttribute(attribute, 2);  
2299 - },  
2300 - _getAttrNode: function(element, attribute) {  
2301 - var node = element.getAttributeNode(attribute);  
2302 - return node ? node.value : "";  
2303 - },  
2304 - _getEv: function(element, attribute) {  
2305 - attribute = element.getAttribute(attribute);  
2306 - return attribute ? attribute.toString().slice(23, -2) : null;  
2307 - },  
2308 - _flag: function(element, attribute) {  
2309 - return $(element).hasAttribute(attribute) ? attribute : null;  
2310 - },  
2311 - style: function(element) {  
2312 - return element.style.cssText.toLowerCase();  
2313 - },  
2314 - title: function(element) {  
2315 - return element.title;  
2316 - }  
2317 - }  
2318 - }  
2319 - };  
2320 -  
2321 - Element._attributeTranslations.write = {  
2322 - names: Object.extend({  
2323 - cellpadding: 'cellPadding',  
2324 - cellspacing: 'cellSpacing'  
2325 - }, Element._attributeTranslations.read.names),  
2326 - values: {  
2327 - checked: function(element, value) {  
2328 - element.checked = !!value;  
2329 - },  
2330 -  
2331 - style: function(element, value) {  
2332 - element.style.cssText = value ? value : '';  
2333 - }  
2334 - }  
2335 - };  
2336 -  
2337 - Element._attributeTranslations.has = {};  
2338 -  
2339 - $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +  
2340 - 'encType maxLength readOnly longDesc').each(function(attr) {  
2341 - Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;  
2342 - Element._attributeTranslations.has[attr.toLowerCase()] = attr;  
2343 - });  
2344 -  
2345 - (function(v) {  
2346 - Object.extend(v, {  
2347 - href: v._getAttr,  
2348 - src: v._getAttr,  
2349 - type: v._getAttr,  
2350 - action: v._getAttrNode,  
2351 - disabled: v._flag,  
2352 - checked: v._flag,  
2353 - readonly: v._flag,  
2354 - multiple: v._flag,  
2355 - onload: v._getEv,  
2356 - onunload: v._getEv,  
2357 - onclick: v._getEv,  
2358 - ondblclick: v._getEv,  
2359 - onmousedown: v._getEv,  
2360 - onmouseup: v._getEv,  
2361 - onmouseover: v._getEv,  
2362 - onmousemove: v._getEv,  
2363 - onmouseout: v._getEv,  
2364 - onfocus: v._getEv,  
2365 - onblur: v._getEv,  
2366 - onkeypress: v._getEv,  
2367 - onkeydown: v._getEv,  
2368 - onkeyup: v._getEv,  
2369 - onsubmit: v._getEv,  
2370 - onreset: v._getEv,  
2371 - onselect: v._getEv,  
2372 - onchange: v._getEv  
2373 - });  
2374 - })(Element._attributeTranslations.read.values);  
2375 -}  
2376 -  
2377 -else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {  
2378 - Element.Methods.setOpacity = function(element, value) {  
2379 - element = $(element);  
2380 - element.style.opacity = (value == 1) ? 0.999999 :  
2381 - (value === '') ? '' : (value < 0.00001) ? 0 : value;  
2382 - return element;  
2383 - };  
2384 -}  
2385 -  
2386 -else if (Prototype.Browser.WebKit) {  
2387 - Element.Methods.setOpacity = function(element, value) {  
2388 - element = $(element);  
2389 - element.style.opacity = (value == 1 || value === '') ? '' :  
2390 - (value < 0.00001) ? 0 : value;  
2391 -  
2392 - if (value == 1)  
2393 - if(element.tagName == 'IMG' && element.width) {  
2394 - element.width++; element.width--;  
2395 - } else try {  
2396 - var n = document.createTextNode(' ');  
2397 - element.appendChild(n);  
2398 - element.removeChild(n);  
2399 - } catch (e) { }  
2400 -  
2401 - return element;  
2402 - };  
2403 -  
2404 - // Safari returns margins on body which is incorrect if the child is absolutely  
2405 - // positioned. For performance reasons, redefine Element#cumulativeOffset for  
2406 - // KHTML/WebKit only.  
2407 - Element.Methods.cumulativeOffset = function(element) {  
2408 - var valueT = 0, valueL = 0;  
2409 - do {  
2410 - valueT += element.offsetTop || 0;  
2411 - valueL += element.offsetLeft || 0;  
2412 - if (element.offsetParent == document.body)  
2413 - if (Element.getStyle(element, 'position') == 'absolute') break;  
2414 -  
2415 - element = element.offsetParent;  
2416 - } while (element);  
2417 -  
2418 - return Element._returnOffset(valueL, valueT);  
2419 - };  
2420 -}  
2421 -  
2422 -if (Prototype.Browser.IE || Prototype.Browser.Opera) {  
2423 - // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements  
2424 - Element.Methods.update = function(element, content) {  
2425 - element = $(element);  
2426 -  
2427 - if (content && content.toElement) content = content.toElement();  
2428 - if (Object.isElement(content)) return element.update().insert(content);  
2429 -  
2430 - content = Object.toHTML(content);  
2431 - var tagName = element.tagName.toUpperCase();  
2432 -  
2433 - if (tagName in Element._insertionTranslations.tags) {  
2434 - $A(element.childNodes).each(function(node) { element.removeChild(node) });  
2435 - Element._getContentFromAnonymousElement(tagName, content.stripScripts())  
2436 - .each(function(node) { element.appendChild(node) });  
2437 - }  
2438 - else element.innerHTML = content.stripScripts();  
2439 -  
2440 - content.evalScripts.bind(content).defer();  
2441 - return element;  
2442 - };  
2443 -}  
2444 -  
2445 -if ('outerHTML' in document.createElement('div')) {  
2446 - Element.Methods.replace = function(element, content) {  
2447 - element = $(element);  
2448 -  
2449 - if (content && content.toElement) content = content.toElement();  
2450 - if (Object.isElement(content)) {  
2451 - element.parentNode.replaceChild(content, element);  
2452 - return element;  
2453 - }  
2454 -  
2455 - content = Object.toHTML(content);  
2456 - var parent = element.parentNode, tagName = parent.tagName.toUpperCase();  
2457 -  
2458 - if (Element._insertionTranslations.tags[tagName]) {  
2459 - var nextSibling = element.next();  
2460 - var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());  
2461 - parent.removeChild(element);  
2462 - if (nextSibling)  
2463 - fragments.each(function(node) { parent.insertBefore(node, nextSibling) });  
2464 - else  
2465 - fragments.each(function(node) { parent.appendChild(node) });  
2466 - }  
2467 - else element.outerHTML = content.stripScripts();  
2468 -  
2469 - content.evalScripts.bind(content).defer();  
2470 - return element;  
2471 - };  
2472 -}  
2473 -  
2474 -Element._returnOffset = function(l, t) {  
2475 - var result = [l, t];  
2476 - result.left = l;  
2477 - result.top = t;  
2478 - return result;  
2479 -};  
2480 -  
2481 -Element._getContentFromAnonymousElement = function(tagName, html) {  
2482 - var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];  
2483 - if (t) {  
2484 - div.innerHTML = t[0] + html + t[1];  
2485 - t[2].times(function() { div = div.firstChild });  
2486 - } else div.innerHTML = html;  
2487 - return $A(div.childNodes);  
2488 -};  
2489 -  
2490 -Element._insertionTranslations = {  
2491 - before: function(element, node) {  
2492 - element.parentNode.insertBefore(node, element);  
2493 - },  
2494 - top: function(element, node) {  
2495 - element.insertBefore(node, element.firstChild);  
2496 - },  
2497 - bottom: function(element, node) {  
2498 - element.appendChild(node);  
2499 - },  
2500 - after: function(element, node) {  
2501 - element.parentNode.insertBefore(node, element.nextSibling);  
2502 - },  
2503 - tags: {  
2504 - TABLE: ['<table>', '</table>', 1],  
2505 - TBODY: ['<table><tbody>', '</tbody></table>', 2],  
2506 - TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3],  
2507 - TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],  
2508 - SELECT: ['<select>', '</select>', 1]  
2509 - }  
2510 -};  
2511 -  
2512 -(function() {  
2513 - Object.extend(this.tags, {  
2514 - THEAD: this.tags.TBODY,  
2515 - TFOOT: this.tags.TBODY,  
2516 - TH: this.tags.TD  
2517 - });  
2518 -}).call(Element._insertionTranslations);  
2519 -  
2520 -Element.Methods.Simulated = {  
2521 - hasAttribute: function(element, attribute) {  
2522 - attribute = Element._attributeTranslations.has[attribute] || attribute;  
2523 - var node = $(element).getAttributeNode(attribute);  
2524 - return node && node.specified;  
2525 - }  
2526 -};  
2527 -  
2528 -Element.Methods.ByTag = { };  
2529 -  
2530 -Object.extend(Element, Element.Methods);  
2531 -  
2532 -if (!Prototype.BrowserFeatures.ElementExtensions &&  
2533 - document.createElement('div').__proto__) {  
2534 - window.HTMLElement = { };  
2535 - window.HTMLElement.prototype = document.createElement('div').__proto__;  
2536 - Prototype.BrowserFeatures.ElementExtensions = true;  
2537 -}  
2538 -  
2539 -Element.extend = (function() {  
2540 - if (Prototype.BrowserFeatures.SpecificElementExtensions)  
2541 - return Prototype.K;  
2542 -  
2543 - var Methods = { }, ByTag = Element.Methods.ByTag;  
2544 -  
2545 - var extend = Object.extend(function(element) {  
2546 - if (!element || element._extendedByPrototype ||  
2547 - element.nodeType != 1 || element == window) return element;  
2548 -  
2549 - var methods = Object.clone(Methods),  
2550 - tagName = element.tagName, property, value;  
2551 -  
2552 - // extend methods for specific tags  
2553 - if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);  
2554 -  
2555 - for (property in methods) {  
2556 - value = methods[property];  
2557 - if (Object.isFunction(value) && !(property in element))  
2558 - element[property] = value.methodize();  
2559 - }  
2560 -  
2561 - element._extendedByPrototype = Prototype.emptyFunction;  
2562 - return element;  
2563 -  
2564 - }, {  
2565 - refresh: function() {  
2566 - // extend methods for all tags (Safari doesn't need this)  
2567 - if (!Prototype.BrowserFeatures.ElementExtensions) {  
2568 - Object.extend(Methods, Element.Methods);  
2569 - Object.extend(Methods, Element.Methods.Simulated);  
2570 - }  
2571 - }  
2572 - });  
2573 -  
2574 - extend.refresh();  
2575 - return extend;  
2576 -})();  
2577 -  
2578 -Element.hasAttribute = function(element, attribute) {  
2579 - if (element.hasAttribute) return element.hasAttribute(attribute);  
2580 - return Element.Methods.Simulated.hasAttribute(element, attribute);  
2581 -};  
2582 -  
2583 -Element.addMethods = function(methods) {  
2584 - var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;  
2585 -  
2586 - if (!methods) {  
2587 - Object.extend(Form, Form.Methods);  
2588 - Object.extend(Form.Element, Form.Element.Methods);  
2589 - Object.extend(Element.Methods.ByTag, {  
2590 - "FORM": Object.clone(Form.Methods),  
2591 - "INPUT": Object.clone(Form.Element.Methods),  
2592 - "SELECT": Object.clone(Form.Element.Methods),  
2593 - "TEXTAREA": Object.clone(Form.Element.Methods)  
2594 - });  
2595 - }  
2596 -  
2597 - if (arguments.length == 2) {  
2598 - var tagName = methods;  
2599 - methods = arguments[1];  
2600 - }  
2601 -  
2602 - if (!tagName) Object.extend(Element.Methods, methods || { });  
2603 - else {  
2604 - if (Object.isArray(tagName)) tagName.each(extend);  
2605 - else extend(tagName);  
2606 - }  
2607 -  
2608 - function extend(tagName) {  
2609 - tagName = tagName.toUpperCase();  
2610 - if (!Element.Methods.ByTag[tagName])  
2611 - Element.Methods.ByTag[tagName] = { };  
2612 - Object.extend(Element.Methods.ByTag[tagName], methods);  
2613 - }  
2614 -  
2615 - function copy(methods, destination, onlyIfAbsent) {  
2616 - onlyIfAbsent = onlyIfAbsent || false;  
2617 - for (var property in methods) {  
2618 - var value = methods[property];  
2619 - if (!Object.isFunction(value)) continue;  
2620 - if (!onlyIfAbsent || !(property in destination))  
2621 - destination[property] = value.methodize();  
2622 - }  
2623 - }  
2624 -  
2625 - function findDOMClass(tagName) {  
2626 - var klass;  
2627 - var trans = {  
2628 - "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",  
2629 - "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",  
2630 - "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",  
2631 - "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",  
2632 - "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":  
2633 - "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":  
2634 - "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":  
2635 - "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":  
2636 - "FrameSet", "IFRAME": "IFrame"  
2637 - };  
2638 - if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';  
2639 - if (window[klass]) return window[klass];  
2640 - klass = 'HTML' + tagName + 'Element';  
2641 - if (window[klass]) return window[klass];  
2642 - klass = 'HTML' + tagName.capitalize() + 'Element';  
2643 - if (window[klass]) return window[klass];  
2644 -  
2645 - window[klass] = { };  
2646 - window[klass].prototype = document.createElement(tagName).__proto__;  
2647 - return window[klass];  
2648 - }  
2649 -  
2650 - if (F.ElementExtensions) {  
2651 - copy(Element.Methods, HTMLElement.prototype);  
2652 - copy(Element.Methods.Simulated, HTMLElement.prototype, true);  
2653 - }  
2654 -  
2655 - if (F.SpecificElementExtensions) {  
2656 - for (var tag in Element.Methods.ByTag) {  
2657 - var klass = findDOMClass(tag);  
2658 - if (Object.isUndefined(klass)) continue;  
2659 - copy(T[tag], klass.prototype);  
2660 - }  
2661 - }  
2662 -  
2663 - Object.extend(Element, Element.Methods);  
2664 - delete Element.ByTag;  
2665 -  
2666 - if (Element.extend.refresh) Element.extend.refresh();  
2667 - Element.cache = { };  
2668 -};  
2669 -  
2670 -document.viewport = {  
2671 - getDimensions: function() {  
2672 - var dimensions = { };  
2673 - var B = Prototype.Browser;  
2674 - $w('width height').each(function(d) {  
2675 - var D = d.capitalize();  
2676 - dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :  
2677 - (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];  
2678 - });  
2679 - return dimensions;  
2680 - },  
2681 -  
2682 - getWidth: function() {  
2683 - return this.getDimensions().width;  
2684 - },  
2685 -  
2686 - getHeight: function() {  
2687 - return this.getDimensions().height;  
2688 - },  
2689 -  
2690 - getScrollOffsets: function() {  
2691 - return Element._returnOffset(  
2692 - window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,  
2693 - window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);  
2694 - }  
2695 -};  
2696 -/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,  
2697 - * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style  
2698 - * license. Please see http://www.yui-ext.com/ for more information. */  
2699 -  
2700 -var Selector = Class.create({  
2701 - initialize: function(expression) {  
2702 - this.expression = expression.strip();  
2703 - this.compileMatcher();  
2704 - },  
2705 -  
2706 - shouldUseXPath: function() {  
2707 - if (!Prototype.BrowserFeatures.XPath) return false;  
2708 -  
2709 - var e = this.expression;  
2710 -  
2711 - // Safari 3 chokes on :*-of-type and :empty  
2712 - if (Prototype.Browser.WebKit &&  
2713 - (e.include("-of-type") || e.include(":empty")))  
2714 - return false;  
2715 -  
2716 - // XPath can't do namespaced attributes, nor can it read  
2717 - // the "checked" property from DOM nodes  
2718 - if ((/(\[[\w-]*?:|:checked)/).test(this.expression))  
2719 - return false;  
2720 -  
2721 - return true;  
2722 - },  
2723 -  
2724 - compileMatcher: function() {  
2725 - if (this.shouldUseXPath())  
2726 - return this.compileXPathMatcher();  
2727 -  
2728 - var e = this.expression, ps = Selector.patterns, h = Selector.handlers,  
2729 - c = Selector.criteria, le, p, m;  
2730 -  
2731 - if (Selector._cache[e]) {  
2732 - this.matcher = Selector._cache[e];  
2733 - return;  
2734 - }  
2735 -  
2736 - this.matcher = ["this.matcher = function(root) {",  
2737 - "var r = root, h = Selector.handlers, c = false, n;"];  
2738 -  
2739 - while (e && le != e && (/\S/).test(e)) {  
2740 - le = e;  
2741 - for (var i in ps) {  
2742 - p = ps[i];  
2743 - if (m = e.match(p)) {  
2744 - this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :  
2745 - new Template(c[i]).evaluate(m));  
2746 - e = e.replace(m[0], '');  
2747 - break;  
2748 - }  
2749 - }  
2750 - }  
2751 -  
2752 - this.matcher.push("return h.unique(n);\n}");  
2753 - eval(this.matcher.join('\n'));  
2754 - Selector._cache[this.expression] = this.matcher;  
2755 - },  
2756 -  
2757 - compileXPathMatcher: function() {  
2758 - var e = this.expression, ps = Selector.patterns,  
2759 - x = Selector.xpath, le, m;  
2760 -  
2761 - if (Selector._cache[e]) {  
2762 - this.xpath = Selector._cache[e]; return;  
2763 - }  
2764 -  
2765 - this.matcher = ['.//*'];  
2766 - while (e && le != e && (/\S/).test(e)) {  
2767 - le = e;  
2768 - for (var i in ps) {  
2769 - if (m = e.match(ps[i])) {  
2770 - this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :  
2771 - new Template(x[i]).evaluate(m));  
2772 - e = e.replace(m[0], '');  
2773 - break;  
2774 - }  
2775 - }  
2776 - }  
2777 -  
2778 - this.xpath = this.matcher.join('');  
2779 - Selector._cache[this.expression] = this.xpath;  
2780 - },  
2781 -  
2782 - findElements: function(root) {  
2783 - root = root || document;  
2784 - if (this.xpath) return document._getElementsByXPath(this.xpath, root);  
2785 - return this.matcher(root);  
2786 - },  
2787 -  
2788 - match: function(element) {  
2789 - this.tokens = [];  
2790 -  
2791 - var e = this.expression, ps = Selector.patterns, as = Selector.assertions;  
2792 - var le, p, m;  
2793 -  
2794 - while (e && le !== e && (/\S/).test(e)) {  
2795 - le = e;  
2796 - for (var i in ps) {  
2797 - p = ps[i];  
2798 - if (m = e.match(p)) {  
2799 - // use the Selector.assertions methods unless the selector  
2800 - // is too complex.  
2801 - if (as[i]) {  
2802 - this.tokens.push([i, Object.clone(m)]);  
2803 - e = e.replace(m[0], '');  
2804 - } else {  
2805 - // reluctantly do a document-wide search  
2806 - // and look for a match in the array  
2807 - return this.findElements(document).include(element);  
2808 - }  
2809 - }  
2810 - }  
2811 - }  
2812 -  
2813 - var match = true, name, matches;  
2814 - for (var i = 0, token; token = this.tokens[i]; i++) {  
2815 - name = token[0], matches = token[1];  
2816 - if (!Selector.assertions[name](element, matches)) {  
2817 - match = false; break;  
2818 - }  
2819 - }  
2820 -  
2821 - return match;  
2822 - },  
2823 -  
2824 - toString: function() {  
2825 - return this.expression;  
2826 - },  
2827 -  
2828 - inspect: function() {  
2829 - return "#<Selector:" + this.expression.inspect() + ">";  
2830 - }  
2831 -});  
2832 -  
2833 -Object.extend(Selector, {  
2834 - _cache: { },  
2835 -  
2836 - xpath: {  
2837 - descendant: "//*",  
2838 - child: "/*",  
2839 - adjacent: "/following-sibling::*[1]",  
2840 - laterSibling: '/following-sibling::*',  
2841 - tagName: function(m) {  
2842 - if (m[1] == '*') return '';  
2843 - return "[local-name()='" + m[1].toLowerCase() +  
2844 - "' or local-name()='" + m[1].toUpperCase() + "']";  
2845 - },  
2846 - className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",  
2847 - id: "[@id='#{1}']",  
2848 - attrPresence: function(m) {  
2849 - m[1] = m[1].toLowerCase();  
2850 - return new Template("[@#{1}]").evaluate(m);  
2851 - },  
2852 - attr: function(m) {  
2853 - m[1] = m[1].toLowerCase();  
2854 - m[3] = m[5] || m[6];  
2855 - return new Template(Selector.xpath.operators[m[2]]).evaluate(m);  
2856 - },  
2857 - pseudo: function(m) {  
2858 - var h = Selector.xpath.pseudos[m[1]];  
2859 - if (!h) return '';  
2860 - if (Object.isFunction(h)) return h(m);  
2861 - return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);  
2862 - },  
2863 - operators: {  
2864 - '=': "[@#{1}='#{3}']",  
2865 - '!=': "[@#{1}!='#{3}']",  
2866 - '^=': "[starts-with(@#{1}, '#{3}')]",  
2867 - '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",  
2868 - '*=': "[contains(@#{1}, '#{3}')]",  
2869 - '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",  
2870 - '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"  
2871 - },  
2872 - pseudos: {  
2873 - 'first-child': '[not(preceding-sibling::*)]',  
2874 - 'last-child': '[not(following-sibling::*)]',  
2875 - 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',  
2876 - 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",  
2877 - 'checked': "[@checked]",  
2878 - 'disabled': "[@disabled]",  
2879 - 'enabled': "[not(@disabled)]",  
2880 - 'not': function(m) {  
2881 - var e = m[6], p = Selector.patterns,  
2882 - x = Selector.xpath, le, v;  
2883 -  
2884 - var exclusion = [];  
2885 - while (e && le != e && (/\S/).test(e)) {  
2886 - le = e;  
2887 - for (var i in p) {  
2888 - if (m = e.match(p[i])) {  
2889 - v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);  
2890 - exclusion.push("(" + v.substring(1, v.length - 1) + ")");  
2891 - e = e.replace(m[0], '');  
2892 - break;  
2893 - }  
2894 - }  
2895 - }  
2896 - return "[not(" + exclusion.join(" and ") + ")]";  
2897 - },  
2898 - 'nth-child': function(m) {  
2899 - return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);  
2900 - },  
2901 - 'nth-last-child': function(m) {  
2902 - return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);  
2903 - },  
2904 - 'nth-of-type': function(m) {  
2905 - return Selector.xpath.pseudos.nth("position() ", m);  
2906 - },  
2907 - 'nth-last-of-type': function(m) {  
2908 - return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);  
2909 - },  
2910 - 'first-of-type': function(m) {  
2911 - m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);  
2912 - },  
2913 - 'last-of-type': function(m) {  
2914 - m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);  
2915 - },  
2916 - 'only-of-type': function(m) {  
2917 - var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);  
2918 - },  
2919 - nth: function(fragment, m) {  
2920 - var mm, formula = m[6], predicate;  
2921 - if (formula == 'even') formula = '2n+0';  
2922 - if (formula == 'odd') formula = '2n+1';  
2923 - if (mm = formula.match(/^(\d+)$/)) // digit only  
2924 - return '[' + fragment + "= " + mm[1] + ']';  
2925 - if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b  
2926 - if (mm[1] == "-") mm[1] = -1;  
2927 - var a = mm[1] ? Number(mm[1]) : 1;  
2928 - var b = mm[2] ? Number(mm[2]) : 0;  
2929 - predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +  
2930 - "((#{fragment} - #{b}) div #{a} >= 0)]";  
2931 - return new Template(predicate).evaluate({  
2932 - fragment: fragment, a: a, b: b });  
2933 - }  
2934 - }  
2935 - }  
2936 - },  
2937 -  
2938 - criteria: {  
2939 - tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',  
2940 - className: 'n = h.className(n, r, "#{1}", c); c = false;',  
2941 - id: 'n = h.id(n, r, "#{1}", c); c = false;',  
2942 - attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',  
2943 - attr: function(m) {  
2944 - m[3] = (m[5] || m[6]);  
2945 - return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);  
2946 - },  
2947 - pseudo: function(m) {  
2948 - if (m[6]) m[6] = m[6].replace(/"/g, '\\"');  
2949 - return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);  
2950 - },  
2951 - descendant: 'c = "descendant";',  
2952 - child: 'c = "child";',  
2953 - adjacent: 'c = "adjacent";',  
2954 - laterSibling: 'c = "laterSibling";'  
2955 - },  
2956 -  
2957 - patterns: {  
2958 - // combinators must be listed first  
2959 - // (and descendant needs to be last combinator)  
2960 - laterSibling: /^\s*~\s*/,  
2961 - child: /^\s*>\s*/,  
2962 - adjacent: /^\s*\+\s*/,  
2963 - descendant: /^\s/,  
2964 -  
2965 - // selectors follow  
2966 - tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,  
2967 - id: /^#([\w\-\*]+)(\b|$)/,  
2968 - className: /^\.([\w\-\*]+)(\b|$)/,  
2969 - pseudo:  
2970 -/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,  
2971 - attrPresence: /^\[([\w]+)\]/,  
2972 - attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/  
2973 - },  
2974 -  
2975 - // for Selector.match and Element#match  
2976 - assertions: {  
2977 - tagName: function(element, matches) {  
2978 - return matches[1].toUpperCase() == element.tagName.toUpperCase();  
2979 - },  
2980 -  
2981 - className: function(element, matches) {  
2982 - return Element.hasClassName(element, matches[1]);  
2983 - },  
2984 -  
2985 - id: function(element, matches) {  
2986 - return element.id === matches[1];  
2987 - },  
2988 -  
2989 - attrPresence: function(element, matches) {  
2990 - return Element.hasAttribute(element, matches[1]);  
2991 - },  
2992 -  
2993 - attr: function(element, matches) {  
2994 - var nodeValue = Element.readAttribute(element, matches[1]);  
2995 - return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);  
2996 - }  
2997 - },  
2998 -  
2999 - handlers: {  
3000 - // UTILITY FUNCTIONS  
3001 - // joins two collections  
3002 - concat: function(a, b) {  
3003 - for (var i = 0, node; node = b[i]; i++)  
3004 - a.push(node);  
3005 - return a;  
3006 - },  
3007 -  
3008 - // marks an array of nodes for counting  
3009 - mark: function(nodes) {  
3010 - var _true = Prototype.emptyFunction;  
3011 - for (var i = 0, node; node = nodes[i]; i++)  
3012 - node._countedByPrototype = _true;  
3013 - return nodes;  
3014 - },  
3015 -  
3016 - unmark: function(nodes) {  
3017 - for (var i = 0, node; node = nodes[i]; i++)  
3018 - node._countedByPrototype = undefined;  
3019 - return nodes;  
3020 - },  
3021 -  
3022 - // mark each child node with its position (for nth calls)  
3023 - // "ofType" flag indicates whether we're indexing for nth-of-type  
3024 - // rather than nth-child  
3025 - index: function(parentNode, reverse, ofType) {  
3026 - parentNode._countedByPrototype = Prototype.emptyFunction;  
3027 - if (reverse) {  
3028 - for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {  
3029 - var node = nodes[i];  
3030 - if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;  
3031 - }  
3032 - } else {  
3033 - for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)  
3034 - if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;  
3035 - }  
3036 - },  
3037 -  
3038 - // filters out duplicates and extends all nodes  
3039 - unique: function(nodes) {  
3040 - if (nodes.length == 0) return nodes;  
3041 - var results = [], n;  
3042 - for (var i = 0, l = nodes.length; i < l; i++)  
3043 - if (!(n = nodes[i])._countedByPrototype) {  
3044 - n._countedByPrototype = Prototype.emptyFunction;  
3045 - results.push(Element.extend(n));  
3046 - }  
3047 - return Selector.handlers.unmark(results);  
3048 - },  
3049 -  
3050 - // COMBINATOR FUNCTIONS  
3051 - descendant: function(nodes) {  
3052 - var h = Selector.handlers;  
3053 - for (var i = 0, results = [], node; node = nodes[i]; i++)  
3054 - h.concat(results, node.getElementsByTagName('*'));  
3055 - return results;  
3056 - },  
3057 -  
3058 - child: function(nodes) {  
3059 - var h = Selector.handlers;  
3060 - for (var i = 0, results = [], node; node = nodes[i]; i++) {  
3061 - for (var j = 0, child; child = node.childNodes[j]; j++)  
3062 - if (child.nodeType == 1 && child.tagName != '!') results.push(child);  
3063 - }  
3064 - return results;  
3065 - },  
3066 -  
3067 - adjacent: function(nodes) {  
3068 - for (var i = 0, results = [], node; node = nodes[i]; i++) {  
3069 - var next = this.nextElementSibling(node);  
3070 - if (next) results.push(next);  
3071 - }  
3072 - return results;  
3073 - },  
3074 -  
3075 - laterSibling: function(nodes) {  
3076 - var h = Selector.handlers;  
3077 - for (var i = 0, results = [], node; node = nodes[i]; i++)  
3078 - h.concat(results, Element.nextSiblings(node));  
3079 - return results;  
3080 - },  
3081 -  
3082 - nextElementSibling: function(node) {  
3083 - while (node = node.nextSibling)  
3084 - if (node.nodeType == 1) return node;  
3085 - return null;  
3086 - },  
3087 -  
3088 - previousElementSibling: function(node) {  
3089 - while (node = node.previousSibling)  
3090 - if (node.nodeType == 1) return node;  
3091 - return null;  
3092 - },  
3093 -  
3094 - // TOKEN FUNCTIONS  
3095 - tagName: function(nodes, root, tagName, combinator) {  
3096 - var uTagName = tagName.toUpperCase();  
3097 - var results = [], h = Selector.handlers;  
3098 - if (nodes) {  
3099 - if (combinator) {  
3100 - // fastlane for ordinary descendant combinators  
3101 - if (combinator == "descendant") {  
3102 - for (var i = 0, node; node = nodes[i]; i++)  
3103 - h.concat(results, node.getElementsByTagName(tagName));  
3104 - return results;  
3105 - } else nodes = this[combinator](nodes);  
3106 - if (tagName == "*") return nodes;  
3107 - }  
3108 - for (var i = 0, node; node = nodes[i]; i++)  
3109 - if (node.tagName.toUpperCase() === uTagName) results.push(node);  
3110 - return results;  
3111 - } else return root.getElementsByTagName(tagName);  
3112 - },  
3113 -  
3114 - id: function(nodes, root, id, combinator) {  
3115 - var targetNode = $(id), h = Selector.handlers;  
3116 - if (!targetNode) return [];  
3117 - if (!nodes && root == document) return [targetNode];  
3118 - if (nodes) {  
3119 - if (combinator) {  
3120 - if (combinator == 'child') {  
3121 - for (var i = 0, node; node = nodes[i]; i++)  
3122 - if (targetNode.parentNode == node) return [targetNode];  
3123 - } else if (combinator == 'descendant') {  
3124 - for (var i = 0, node; node = nodes[i]; i++)  
3125 - if (Element.descendantOf(targetNode, node)) return [targetNode];  
3126 - } else if (combinator == 'adjacent') {  
3127 - for (var i = 0, node; node = nodes[i]; i++)  
3128 - if (Selector.handlers.previousElementSibling(targetNode) == node)  
3129 - return [targetNode];  
3130 - } else nodes = h[combinator](nodes);  
3131 - }  
3132 - for (var i = 0, node; node = nodes[i]; i++)  
3133 - if (node == targetNode) return [targetNode];  
3134 - return [];  
3135 - }  
3136 - return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];  
3137 - },  
3138 -  
3139 - className: function(nodes, root, className, combinator) {  
3140 - if (nodes && combinator) nodes = this[combinator](nodes);  
3141 - return Selector.handlers.byClassName(nodes, root, className);  
3142 - },  
3143 -  
3144 - byClassName: function(nodes, root, className) {  
3145 - if (!nodes) nodes = Selector.handlers.descendant([root]);  
3146 - var needle = ' ' + className + ' ';  
3147 - for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {  
3148 - nodeClassName = node.className;  
3149 - if (nodeClassName.length == 0) continue;  
3150 - if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))  
3151 - results.push(node);  
3152 - }  
3153 - return results;  
3154 - },  
3155 -  
3156 - attrPresence: function(nodes, root, attr, combinator) {  
3157 - if (!nodes) nodes = root.getElementsByTagName("*");  
3158 - if (nodes && combinator) nodes = this[combinator](nodes);  
3159 - var results = [];  
3160 - for (var i = 0, node; node = nodes[i]; i++)  
3161 - if (Element.hasAttribute(node, attr)) results.push(node);  
3162 - return results;  
3163 - },  
3164 -  
3165 - attr: function(nodes, root, attr, value, operator, combinator) {  
3166 - if (!nodes) nodes = root.getElementsByTagName("*");  
3167 - if (nodes && combinator) nodes = this[combinator](nodes);  
3168 - var handler = Selector.operators[operator], results = [];  
3169 - for (var i = 0, node; node = nodes[i]; i++) {  
3170 - var nodeValue = Element.readAttribute(node, attr);  
3171 - if (nodeValue === null) continue;  
3172 - if (handler(nodeValue, value)) results.push(node);  
3173 - }  
3174 - return results;  
3175 - },  
3176 -  
3177 - pseudo: function(nodes, name, value, root, combinator) {  
3178 - if (nodes && combinator) nodes = this[combinator](nodes);  
3179 - if (!nodes) nodes = root.getElementsByTagName("*");  
3180 - return Selector.pseudos[name](nodes, value, root);  
3181 - }  
3182 - },  
3183 -  
3184 - pseudos: {  
3185 - 'first-child': function(nodes, value, root) {  
3186 - for (var i = 0, results = [], node; node = nodes[i]; i++) {  
3187 - if (Selector.handlers.previousElementSibling(node)) continue;  
3188 - results.push(node);  
3189 - }  
3190 - return results;  
3191 - },  
3192 - 'last-child': function(nodes, value, root) {  
3193 - for (var i = 0, results = [], node; node = nodes[i]; i++) {  
3194 - if (Selector.handlers.nextElementSibling(node)) continue;  
3195 - results.push(node);  
3196 - }  
3197 - return results;  
3198 - },  
3199 - 'only-child': function(nodes, value, root) {  
3200 - var h = Selector.handlers;  
3201 - for (var i = 0, results = [], node; node = nodes[i]; i++)  
3202 - if (!h.previousElementSibling(node) && !h.nextElementSibling(node))  
3203 - results.push(node);  
3204 - return results;  
3205 - },  
3206 - 'nth-child': function(nodes, formula, root) {  
3207 - return Selector.pseudos.nth(nodes, formula, root);  
3208 - },  
3209 - 'nth-last-child': function(nodes, formula, root) {  
3210 - return Selector.pseudos.nth(nodes, formula, root, true);  
3211 - },  
3212 - 'nth-of-type': function(nodes, formula, root) {  
3213 - return Selector.pseudos.nth(nodes, formula, root, false, true);  
3214 - },  
3215 - 'nth-last-of-type': function(nodes, formula, root) {  
3216 - return Selector.pseudos.nth(nodes, formula, root, true, true);  
3217 - },  
3218 - 'first-of-type': function(nodes, formula, root) {  
3219 - return Selector.pseudos.nth(nodes, "1", root, false, true);  
3220 - },  
3221 - 'last-of-type': function(nodes, formula, root) {  
3222 - return Selector.pseudos.nth(nodes, "1", root, true, true);  
3223 - },  
3224 - 'only-of-type': function(nodes, formula, root) {  
3225 - var p = Selector.pseudos;  
3226 - return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);  
3227 - },  
3228 -  
3229 - // handles the an+b logic  
3230 - getIndices: function(a, b, total) {  
3231 - if (a == 0) return b > 0 ? [b] : [];  
3232 - return $R(1, total).inject([], function(memo, i) {  
3233 - if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);  
3234 - return memo;  
3235 - });  
3236 - },  
3237 -  
3238 - // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type  
3239 - nth: function(nodes, formula, root, reverse, ofType) {  
3240 - if (nodes.length == 0) return [];  
3241 - if (formula == 'even') formula = '2n+0';  
3242 - if (formula == 'odd') formula = '2n+1';  
3243 - var h = Selector.handlers, results = [], indexed = [], m;  
3244 - h.mark(nodes);  
3245 - for (var i = 0, node; node = nodes[i]; i++) {  
3246 - if (!node.parentNode._countedByPrototype) {  
3247 - h.index(node.parentNode, reverse, ofType);  
3248 - indexed.push(node.parentNode);  
3249 - }  
3250 - }  
3251 - if (formula.match(/^\d+$/)) { // just a number  
3252 - formula = Number(formula);  
3253 - for (var i = 0, node; node = nodes[i]; i++)  
3254 - if (node.nodeIndex == formula) results.push(node);  
3255 - } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b  
3256 - if (m[1] == "-") m[1] = -1;  
3257 - var a = m[1] ? Number(m[1]) : 1;  
3258 - var b = m[2] ? Number(m[2]) : 0;  
3259 - var indices = Selector.pseudos.getIndices(a, b, nodes.length);  
3260 - for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {  
3261 - for (var j = 0; j < l; j++)  
3262 - if (node.nodeIndex == indices[j]) results.push(node);  
3263 - }  
3264 - }  
3265 - h.unmark(nodes);  
3266 - h.unmark(indexed);  
3267 - return results;  
3268 - },  
3269 -  
3270 - 'empty': function(nodes, value, root) {  
3271 - for (var i = 0, results = [], node; node = nodes[i]; i++) {  
3272 - // IE treats comments as element nodes  
3273 - if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;  
3274 - results.push(node);  
3275 - }  
3276 - return results;  
3277 - },  
3278 -  
3279 - 'not': function(nodes, selector, root) {  
3280 - var h = Selector.handlers, selectorType, m;  
3281 - var exclusions = new Selector(selector).findElements(root);  
3282 - h.mark(exclusions);  
3283 - for (var i = 0, results = [], node; node = nodes[i]; i++)  
3284 - if (!node._countedByPrototype) results.push(node);  
3285 - h.unmark(exclusions);  
3286 - return results;  
3287 - },  
3288 -  
3289 - 'enabled': function(nodes, value, root) {  
3290 - for (var i = 0, results = [], node; node = nodes[i]; i++)  
3291 - if (!node.disabled) results.push(node);  
3292 - return results;  
3293 - },  
3294 -  
3295 - 'disabled': function(nodes, value, root) {  
3296 - for (var i = 0, results = [], node; node = nodes[i]; i++)  
3297 - if (node.disabled) results.push(node);  
3298 - return results;  
3299 - },  
3300 -  
3301 - 'checked': function(nodes, value, root) {  
3302 - for (var i = 0, results = [], node; node = nodes[i]; i++)  
3303 - if (node.checked) results.push(node);  
3304 - return results;  
3305 - }  
3306 - },  
3307 -  
3308 - operators: {  
3309 - '=': function(nv, v) { return nv == v; },  
3310 - '!=': function(nv, v) { return nv != v; },  
3311 - '^=': function(nv, v) { return nv.startsWith(v); },  
3312 - '$=': function(nv, v) { return nv.endsWith(v); },  
3313 - '*=': function(nv, v) { return nv.include(v); },  
3314 - '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },  
3315 - '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }  
3316 - },  
3317 -  
3318 - split: function(expression) {  
3319 - var expressions = [];  
3320 - expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {  
3321 - expressions.push(m[1].strip());  
3322 - });  
3323 - return expressions;  
3324 - },  
3325 -  
3326 - matchElements: function(elements, expression) {  
3327 - var matches = $$(expression), h = Selector.handlers;  
3328 - h.mark(matches);  
3329 - for (var i = 0, results = [], element; element = elements[i]; i++)  
3330 - if (element._countedByPrototype) results.push(element);  
3331 - h.unmark(matches);  
3332 - return results;  
3333 - },  
3334 -  
3335 - findElement: function(elements, expression, index) {  
3336 - if (Object.isNumber(expression)) {  
3337 - index = expression; expression = false;  
3338 - }  
3339 - return Selector.matchElements(elements, expression || '*')[index || 0];  
3340 - },  
3341 -  
3342 - findChildElements: function(element, expressions) {  
3343 - expressions = Selector.split(expressions.join(','));  
3344 - var results = [], h = Selector.handlers;  
3345 - for (var i = 0, l = expressions.length, selector; i < l; i++) {  
3346 - selector = new Selector(expressions[i].strip());  
3347 - h.concat(results, selector.findElements(element));  
3348 - }  
3349 - return (l > 1) ? h.unique(results) : results;  
3350 - }  
3351 -});  
3352 -  
3353 -if (Prototype.Browser.IE) {  
3354 - Object.extend(Selector.handlers, {  
3355 - // IE returns comment nodes on getElementsByTagName("*").  
3356 - // Filter them out.  
3357 - concat: function(a, b) {  
3358 - for (var i = 0, node; node = b[i]; i++)  
3359 - if (node.tagName !== "!") a.push(node);  
3360 - return a;  
3361 - },  
3362 -  
3363 - // IE improperly serializes _countedByPrototype in (inner|outer)HTML.  
3364 - unmark: function(nodes) {  
3365 - for (var i = 0, node; node = nodes[i]; i++)  
3366 - node.removeAttribute('_countedByPrototype');  
3367 - return nodes;  
3368 - }  
3369 - });  
3370 -}  
3371 -  
3372 -function $$() {  
3373 - return Selector.findChildElements(document, $A(arguments));  
3374 -}  
3375 -var Form = {  
3376 - reset: function(form) {  
3377 - $(form).reset();  
3378 - return form;  
3379 - },  
3380 -  
3381 - serializeElements: function(elements, options) {  
3382 - if (typeof options != 'object') options = { hash: !!options };  
3383 - else if (Object.isUndefined(options.hash)) options.hash = true;  
3384 - var key, value, submitted = false, submit = options.submit;  
3385 -  
3386 - var data = elements.inject({ }, function(result, element) {  
3387 - if (!element.disabled && element.name) {  
3388 - key = element.name; value = $(element).getValue();  
3389 - if (value != null && (element.type != 'submit' || (!submitted &&  
3390 - submit !== false && (!submit || key == submit) && (submitted = true)))) {  
3391 - if (key in result) {  
3392 - // a key is already present; construct an array of values  
3393 - if (!Object.isArray(result[key])) result[key] = [result[key]];  
3394 - result[key].push(value);  
3395 - }  
3396 - else result[key] = value;  
3397 - }  
3398 - }  
3399 - return result;  
3400 - });  
3401 -  
3402 - return options.hash ? data : Object.toQueryString(data);  
3403 - }  
3404 -};  
3405 -  
3406 -Form.Methods = {  
3407 - serialize: function(form, options) {  
3408 - return Form.serializeElements(Form.getElements(form), options);  
3409 - },  
3410 -  
3411 - getElements: function(form) {  
3412 - return $A($(form).getElementsByTagName('*')).inject([],  
3413 - function(elements, child) {  
3414 - if (Form.Element.Serializers[child.tagName.toLowerCase()])  
3415 - elements.push(Element.extend(child));  
3416 - return elements;  
3417 - }  
3418 - );  
3419 - },  
3420 -  
3421 - getInputs: function(form, typeName, name) {  
3422 - form = $(form);  
3423 - var inputs = form.getElementsByTagName('input');  
3424 -  
3425 - if (!typeName && !name) return $A(inputs).map(Element.extend);  
3426 -  
3427 - for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {  
3428 - var input = inputs[i];  
3429 - if ((typeName && input.type != typeName) || (name && input.name != name))  
3430 - continue;  
3431 - matchingInputs.push(Element.extend(input));  
3432 - }  
3433 -  
3434 - return matchingInputs;  
3435 - },  
3436 -  
3437 - disable: function(form) {  
3438 - form = $(form);  
3439 - Form.getElements(form).invoke('disable');  
3440 - return form;  
3441 - },  
3442 -  
3443 - enable: function(form) {  
3444 - form = $(form);  
3445 - Form.getElements(form).invoke('enable');  
3446 - return form;  
3447 - },  
3448 -  
3449 - findFirstElement: function(form) {  
3450 - var elements = $(form).getElements().findAll(function(element) {  
3451 - return 'hidden' != element.type && !element.disabled;  
3452 - });  
3453 - var firstByIndex = elements.findAll(function(element) {  
3454 - return element.hasAttribute('tabIndex') && element.tabIndex >= 0;  
3455 - }).sortBy(function(element) { return element.tabIndex }).first();  
3456 -  
3457 - return firstByIndex ? firstByIndex : elements.find(function(element) {  
3458 - return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());  
3459 - });  
3460 - },  
3461 -  
3462 - focusFirstElement: function(form) {  
3463 - form = $(form);  
3464 - form.findFirstElement().activate();  
3465 - return form;  
3466 - },  
3467 -  
3468 - request: function(form, options) {  
3469 - form = $(form), options = Object.clone(options || { });  
3470 -  
3471 - var params = options.parameters, action = form.readAttribute('action') || '';  
3472 - if (action.blank()) action = window.location.href;  
3473 - options.parameters = form.serialize(true);  
3474 -  
3475 - if (params) {  
3476 - if (Object.isString(params)) params = params.toQueryParams();  
3477 - Object.extend(options.parameters, params);  
3478 - }  
3479 -  
3480 - if (form.hasAttribute('method') && !options.method)  
3481 - options.method = form.method;  
3482 -  
3483 - return new Ajax.Request(action, options);  
3484 - }  
3485 -};  
3486 -  
3487 -/*--------------------------------------------------------------------------*/  
3488 -  
3489 -Form.Element = {  
3490 - focus: function(element) {  
3491 - $(element).focus();  
3492 - return element;  
3493 - },  
3494 -  
3495 - select: function(element) {  
3496 - $(element).select();  
3497 - return element;  
3498 - }  
3499 -};  
3500 -  
3501 -Form.Element.Methods = {  
3502 - serialize: function(element) {  
3503 - element = $(element);  
3504 - if (!element.disabled && element.name) {  
3505 - var value = element.getValue();  
3506 - if (value != undefined) {  
3507 - var pair = { };  
3508 - pair[element.name] = value;  
3509 - return Object.toQueryString(pair);  
3510 - }  
3511 - }  
3512 - return '';  
3513 - },  
3514 -  
3515 - getValue: function(element) {  
3516 - element = $(element);  
3517 - var method = element.tagName.toLowerCase();  
3518 - return Form.Element.Serializers[method](element);  
3519 - },  
3520 -  
3521 - setValue: function(element, value) {  
3522 - element = $(element);  
3523 - var method = element.tagName.toLowerCase();  
3524 - Form.Element.Serializers[method](element, value);  
3525 - return element;  
3526 - },  
3527 -  
3528 - clear: function(element) {  
3529 - $(element).value = '';  
3530 - return element;  
3531 - },  
3532 -  
3533 - present: function(element) {  
3534 - return $(element).value != '';  
3535 - },  
3536 -  
3537 - activate: function(element) {  
3538 - element = $(element);  
3539 - try {  
3540 - element.focus();  
3541 - if (element.select && (element.tagName.toLowerCase() != 'input' ||  
3542 - !['button', 'reset', 'submit'].include(element.type)))  
3543 - element.select();  
3544 - } catch (e) { }  
3545 - return element;  
3546 - },  
3547 -  
3548 - disable: function(element) {  
3549 - element = $(element);  
3550 - element.blur();  
3551 - element.disabled = true;  
3552 - return element;  
3553 - },  
3554 -  
3555 - enable: function(element) {  
3556 - element = $(element);  
3557 - element.disabled = false;  
3558 - return element;  
3559 - }  
3560 -};  
3561 -  
3562 -/*--------------------------------------------------------------------------*/  
3563 -  
3564 -var Field = Form.Element;  
3565 -var $F = Form.Element.Methods.getValue;  
3566 -  
3567 -/*--------------------------------------------------------------------------*/  
3568 -  
3569 -Form.Element.Serializers = {  
3570 - input: function(element, value) {  
3571 - switch (element.type.toLowerCase()) {  
3572 - case 'checkbox':  
3573 - case 'radio':  
3574 - return Form.Element.Serializers.inputSelector(element, value);  
3575 - default:  
3576 - return Form.Element.Serializers.textarea(element, value);  
3577 - }  
3578 - },  
3579 -  
3580 - inputSelector: function(element, value) {  
3581 - if (Object.isUndefined(value)) return element.checked ? element.value : null;  
3582 - else element.checked = !!value;  
3583 - },  
3584 -  
3585 - textarea: function(element, value) {  
3586 - if (Object.isUndefined(value)) return element.value;  
3587 - else element.value = value;  
3588 - },  
3589 -  
3590 - select: function(element, index) {  
3591 - if (Object.isUndefined(index))  
3592 - return this[element.type == 'select-one' ?  
3593 - 'selectOne' : 'selectMany'](element);  
3594 - else {  
3595 - var opt, value, single = !Object.isArray(index);  
3596 - for (var i = 0, length = element.length; i < length; i++) {  
3597 - opt = element.options[i];  
3598 - value = this.optionValue(opt);  
3599 - if (single) {  
3600 - if (value == index) {  
3601 - opt.selected = true;  
3602 - return;  
3603 - }  
3604 - }  
3605 - else opt.selected = index.include(value);  
3606 - }  
3607 - }  
3608 - },  
3609 -  
3610 - selectOne: function(element) {  
3611 - var index = element.selectedIndex;  
3612 - return index >= 0 ? this.optionValue(element.options[index]) : null;  
3613 - },  
3614 -  
3615 - selectMany: function(element) {  
3616 - var values, length = element.length;  
3617 - if (!length) return null;  
3618 -  
3619 - for (var i = 0, values = []; i < length; i++) {  
3620 - var opt = element.options[i];  
3621 - if (opt.selected) values.push(this.optionValue(opt));  
3622 - }  
3623 - return values;  
3624 - },  
3625 -  
3626 - optionValue: function(opt) {  
3627 - // extend element because hasAttribute may not be native  
3628 - return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;  
3629 - }  
3630 -};  
3631 -  
3632 -/*--------------------------------------------------------------------------*/  
3633 -  
3634 -Abstract.TimedObserver = Class.create(PeriodicalExecuter, {  
3635 - initialize: function($super, element, frequency, callback) {  
3636 - $super(callback, frequency);  
3637 - this.element = $(element);  
3638 - this.lastValue = this.getValue();  
3639 - },  
3640 -  
3641 - execute: function() {  
3642 - var value = this.getValue();  
3643 - if (Object.isString(this.lastValue) && Object.isString(value) ?  
3644 - this.lastValue != value : String(this.lastValue) != String(value)) {  
3645 - this.callback(this.element, value);  
3646 - this.lastValue = value;  
3647 - }  
3648 - }  
3649 -});  
3650 -  
3651 -Form.Element.Observer = Class.create(Abstract.TimedObserver, {  
3652 - getValue: function() {  
3653 - return Form.Element.getValue(this.element);  
3654 - }  
3655 -});  
3656 -  
3657 -Form.Observer = Class.create(Abstract.TimedObserver, {  
3658 - getValue: function() {  
3659 - return Form.serialize(this.element);  
3660 - }  
3661 -});  
3662 -  
3663 -/*--------------------------------------------------------------------------*/  
3664 -  
3665 -Abstract.EventObserver = Class.create({  
3666 - initialize: function(element, callback) {  
3667 - this.element = $(element);  
3668 - this.callback = callback;  
3669 -  
3670 - this.lastValue = this.getValue();  
3671 - if (this.element.tagName.toLowerCase() == 'form')  
3672 - this.registerFormCallbacks();  
3673 - else  
3674 - this.registerCallback(this.element);  
3675 - },  
3676 -  
3677 - onElementEvent: function() {  
3678 - var value = this.getValue();  
3679 - if (this.lastValue != value) {  
3680 - this.callback(this.element, value);  
3681 - this.lastValue = value;  
3682 - }  
3683 - },  
3684 -  
3685 - registerFormCallbacks: function() {  
3686 - Form.getElements(this.element).each(this.registerCallback, this);  
3687 - },  
3688 -  
3689 - registerCallback: function(element) {  
3690 - if (element.type) {  
3691 - switch (element.type.toLowerCase()) {  
3692 - case 'checkbox':  
3693 - case 'radio':  
3694 - Event.observe(element, 'click', this.onElementEvent.bind(this));  
3695 - break;  
3696 - default:  
3697 - Event.observe(element, 'change', this.onElementEvent.bind(this));  
3698 - break;  
3699 - }  
3700 - }  
3701 - }  
3702 -});  
3703 -  
3704 -Form.Element.EventObserver = Class.create(Abstract.EventObserver, {  
3705 - getValue: function() {  
3706 - return Form.Element.getValue(this.element);  
3707 - }  
3708 -});  
3709 -  
3710 -Form.EventObserver = Class.create(Abstract.EventObserver, {  
3711 - getValue: function() {  
3712 - return Form.serialize(this.element);  
3713 - }  
3714 -});  
3715 -if (!window.Event) var Event = { };  
3716 -  
3717 -Object.extend(Event, {  
3718 - KEY_BACKSPACE: 8,  
3719 - KEY_TAB: 9,  
3720 - KEY_RETURN: 13,  
3721 - KEY_ESC: 27,  
3722 - KEY_LEFT: 37,  
3723 - KEY_UP: 38,  
3724 - KEY_RIGHT: 39,  
3725 - KEY_DOWN: 40,  
3726 - KEY_DELETE: 46,  
3727 - KEY_HOME: 36,  
3728 - KEY_END: 35,  
3729 - KEY_PAGEUP: 33,  
3730 - KEY_PAGEDOWN: 34,  
3731 - KEY_INSERT: 45,  
3732 -  
3733 - cache: { },  
3734 -  
3735 - relatedTarget: function(event) {  
3736 - var element;  
3737 - switch(event.type) {  
3738 - case 'mouseover': element = event.fromElement; break;  
3739 - case 'mouseout': element = event.toElement; break;  
3740 - default: return null;  
3741 - }  
3742 - return Element.extend(element);  
3743 - }  
3744 -});  
3745 -  
3746 -Event.Methods = (function() {  
3747 - var isButton;  
3748 -  
3749 - if (Prototype.Browser.IE) {  
3750 - var buttonMap = { 0: 1, 1: 4, 2: 2 };  
3751 - isButton = function(event, code) {  
3752 - return event.button == buttonMap[code];  
3753 - };  
3754 -  
3755 - } else if (Prototype.Browser.WebKit) {  
3756 - isButton = function(event, code) {  
3757 - switch (code) {  
3758 - case 0: return event.which == 1 && !event.metaKey;  
3759 - case 1: return event.which == 1 && event.metaKey;  
3760 - default: return false;  
3761 - }  
3762 - };  
3763 -  
3764 - } else {  
3765 - isButton = function(event, code) {  
3766 - return event.which ? (event.which === code + 1) : (event.button === code);  
3767 - };  
3768 - }  
3769 -  
3770 - return {  
3771 - isLeftClick: function(event) { return isButton(event, 0) },  
3772 - isMiddleClick: function(event) { return isButton(event, 1) },  
3773 - isRightClick: function(event) { return isButton(event, 2) },  
3774 -  
3775 - element: function(event) {  
3776 - var node = Event.extend(event).target;  
3777 - return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);  
3778 - },  
3779 -  
3780 - findElement: function(event, expression) {  
3781 - var element = Event.element(event);  
3782 - if (!expression) return element;  
3783 - var elements = [element].concat(element.ancestors());  
3784 - return Selector.findElement(elements, expression, 0);  
3785 - },  
3786 -  
3787 - pointer: function(event) {  
3788 - return {  
3789 - x: event.pageX || (event.clientX +  
3790 - (document.documentElement.scrollLeft || document.body.scrollLeft)),  
3791 - y: event.pageY || (event.clientY +  
3792 - (document.documentElement.scrollTop || document.body.scrollTop))  
3793 - };  
3794 - },  
3795 -  
3796 - pointerX: function(event) { return Event.pointer(event).x },  
3797 - pointerY: function(event) { return Event.pointer(event).y },  
3798 -  
3799 - stop: function(event) {  
3800 - Event.extend(event);  
3801 - event.preventDefault();  
3802 - event.stopPropagation();  
3803 - event.stopped = true;  
3804 - }  
3805 - };  
3806 -})();  
3807 -  
3808 -Event.extend = (function() {  
3809 - var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {  
3810 - m[name] = Event.Methods[name].methodize();  
3811 - return m;  
3812 - });  
3813 -  
3814 - if (Prototype.Browser.IE) {  
3815 - Object.extend(methods, {  
3816 - stopPropagation: function() { this.cancelBubble = true },  
3817 - preventDefault: function() { this.returnValue = false },  
3818 - inspect: function() { return "[object Event]" }  
3819 - });  
3820 -  
3821 - return function(event) {  
3822 - if (!event) return false;  
3823 - if (event._extendedByPrototype) return event;  
3824 -  
3825 - event._extendedByPrototype = Prototype.emptyFunction;  
3826 - var pointer = Event.pointer(event);  
3827 - Object.extend(event, {  
3828 - target: event.srcElement,  
3829 - relatedTarget: Event.relatedTarget(event),  
3830 - pageX: pointer.x,  
3831 - pageY: pointer.y  
3832 - });  
3833 - return Object.extend(event, methods);  
3834 - };  
3835 -  
3836 - } else {  
3837 - Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;  
3838 - Object.extend(Event.prototype, methods);  
3839 - return Prototype.K;  
3840 - }  
3841 -})();  
3842 -  
3843 -Object.extend(Event, (function() {  
3844 - var cache = Event.cache;  
3845 -  
3846 - function getEventID(element) {  
3847 - if (element._prototypeEventID) return element._prototypeEventID[0];  
3848 - arguments.callee.id = arguments.callee.id || 1;  
3849 - return element._prototypeEventID = [++arguments.callee.id];  
3850 - }  
3851 -  
3852 - function getDOMEventName(eventName) {  
3853 - if (eventName && eventName.include(':')) return "dataavailable";  
3854 - return eventName;  
3855 - }  
3856 -  
3857 - function getCacheForID(id) {  
3858 - return cache[id] = cache[id] || { };  
3859 - }  
3860 -  
3861 - function getWrappersForEventName(id, eventName) {  
3862 - var c = getCacheForID(id);  
3863 - return c[eventName] = c[eventName] || [];  
3864 - }  
3865 -  
3866 - function createWrapper(element, eventName, handler) {  
3867 - var id = getEventID(element);  
3868 - var c = getWrappersForEventName(id, eventName);  
3869 - if (c.pluck("handler").include(handler)) return false;  
3870 -  
3871 - var wrapper = function(event) {  
3872 - if (!Event || !Event.extend ||  
3873 - (event.eventName && event.eventName != eventName))  
3874 - return false;  
3875 -  
3876 - Event.extend(event);  
3877 - handler.call(element, event);  
3878 - };  
3879 -  
3880 - wrapper.handler = handler;  
3881 - c.push(wrapper);  
3882 - return wrapper;  
3883 - }  
3884 -  
3885 - function findWrapper(id, eventName, handler) {  
3886 - var c = getWrappersForEventName(id, eventName);  
3887 - return c.find(function(wrapper) { return wrapper.handler == handler });  
3888 - }  
3889 -  
3890 - function destroyWrapper(id, eventName, handler) {  
3891 - var c = getCacheForID(id);  
3892 - if (!c[eventName]) return false;  
3893 - c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));  
3894 - }  
3895 -  
3896 - function destroyCache() {  
3897 - for (var id in cache)  
3898 - for (var eventName in cache[id])  
3899 - cache[id][eventName] = null;  
3900 - }  
3901 -  
3902 - if (window.attachEvent) {  
3903 - window.attachEvent("onunload", destroyCache);  
3904 - }  
3905 -  
3906 - return {  
3907 - observe: function(element, eventName, handler) {  
3908 - element = $(element);  
3909 - var name = getDOMEventName(eventName);  
3910 -  
3911 - var wrapper = createWrapper(element, eventName, handler);  
3912 - if (!wrapper) return element;  
3913 -  
3914 - if (element.addEventListener) {  
3915 - element.addEventListener(name, wrapper, false);  
3916 - } else {  
3917 - element.attachEvent("on" + name, wrapper);  
3918 - }  
3919 -  
3920 - return element;  
3921 - },  
3922 -  
3923 - stopObserving: function(element, eventName, handler) {  
3924 - element = $(element);  
3925 - var id = getEventID(element), name = getDOMEventName(eventName);  
3926 -  
3927 - if (!handler && eventName) {  
3928 - getWrappersForEventName(id, eventName).each(function(wrapper) {  
3929 - element.stopObserving(eventName, wrapper.handler);  
3930 - });  
3931 - return element;  
3932 -  
3933 - } else if (!eventName) {  
3934 - Object.keys(getCacheForID(id)).each(function(eventName) {  
3935 - element.stopObserving(eventName);  
3936 - });  
3937 - return element;  
3938 - }  
3939 -  
3940 - var wrapper = findWrapper(id, eventName, handler);  
3941 - if (!wrapper) return element;  
3942 -  
3943 - if (element.removeEventListener) {  
3944 - element.removeEventListener(name, wrapper, false);  
3945 - } else {  
3946 - element.detachEvent("on" + name, wrapper);  
3947 - }  
3948 -  
3949 - destroyWrapper(id, eventName, handler);  
3950 -  
3951 - return element;  
3952 - },  
3953 -  
3954 - fire: function(element, eventName, memo) {  
3955 - element = $(element);  
3956 - if (element == document && document.createEvent && !element.dispatchEvent)  
3957 - element = document.documentElement;  
3958 -  
3959 - var event;  
3960 - if (document.createEvent) {  
3961 - event = document.createEvent("HTMLEvents");  
3962 - event.initEvent("dataavailable", true, true);  
3963 - } else {  
3964 - event = document.createEventObject();  
3965 - event.eventType = "ondataavailable";  
3966 - }  
3967 -  
3968 - event.eventName = eventName;  
3969 - event.memo = memo || { };  
3970 -  
3971 - if (document.createEvent) {  
3972 - element.dispatchEvent(event);  
3973 - } else {  
3974 - element.fireEvent(event.eventType, event);  
3975 - }  
3976 -  
3977 - return Event.extend(event);  
3978 - }  
3979 - };  
3980 -})());  
3981 -  
3982 -Object.extend(Event, Event.Methods);  
3983 -  
3984 -Element.addMethods({  
3985 - fire: Event.fire,  
3986 - observe: Event.observe,  
3987 - stopObserving: Event.stopObserving  
3988 -});  
3989 -  
3990 -Object.extend(document, {  
3991 - fire: Element.Methods.fire.methodize(),  
3992 - observe: Element.Methods.observe.methodize(),  
3993 - stopObserving: Element.Methods.stopObserving.methodize(),  
3994 - loaded: false  
3995 -});  
3996 -  
3997 -(function() {  
3998 - /* Support for the DOMContentLoaded event is based on work by Dan Webb,  
3999 - Matthias Miller, Dean Edwards and John Resig. */  
4000 -  
4001 - var timer;  
4002 -  
4003 - function fireContentLoadedEvent() {  
4004 - if (document.loaded) return;  
4005 - if (timer) window.clearInterval(timer);  
4006 - document.fire("dom:loaded");  
4007 - document.loaded = true;  
4008 - }  
4009 -  
4010 - if (document.addEventListener) {  
4011 - if (Prototype.Browser.WebKit) {  
4012 - timer = window.setInterval(function() {  
4013 - if (/loaded|complete/.test(document.readyState))  
4014 - fireContentLoadedEvent();  
4015 - }, 0);  
4016 -  
4017 - Event.observe(window, "load", fireContentLoadedEvent);  
4018 -  
4019 - } else {  
4020 - document.addEventListener("DOMContentLoaded",  
4021 - fireContentLoadedEvent, false);  
4022 - }  
4023 -  
4024 - } else {  
4025 - document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");  
4026 - $("__onDOMContentLoaded").onreadystatechange = function() {  
4027 - if (this.readyState == "complete") {  
4028 - this.onreadystatechange = null;  
4029 - fireContentLoadedEvent();  
4030 - }  
4031 - };  
4032 - }  
4033 -})();  
4034 -/*------------------------------- DEPRECATED -------------------------------*/  
4035 -  
4036 -Hash.toQueryString = Object.toQueryString;  
4037 -  
4038 -var Toggle = { display: Element.toggle };  
4039 -  
4040 -Element.Methods.childOf = Element.Methods.descendantOf;  
4041 -  
4042 -var Insertion = {  
4043 - Before: function(element, content) {  
4044 - return Element.insert(element, {before:content});  
4045 - },  
4046 -  
4047 - Top: function(element, content) {  
4048 - return Element.insert(element, {top:content});  
4049 - },  
4050 -  
4051 - Bottom: function(element, content) {  
4052 - return Element.insert(element, {bottom:content});  
4053 - },  
4054 -  
4055 - After: function(element, content) {  
4056 - return Element.insert(element, {after:content});  
4057 - }  
4058 -};  
4059 -  
4060 -var $continue = new Error('"throw $continue" is deprecated, use "return" instead');  
4061 -  
4062 -// This should be moved to script.aculo.us; notice the deprecated methods  
4063 -// further below, that map to the newer Element methods.  
4064 -var Position = {  
4065 - // set to true if needed, warning: firefox performance problems  
4066 - // NOT neeeded for page scrolling, only if draggable contained in  
4067 - // scrollable elements  
4068 - includeScrollOffsets: false,  
4069 -  
4070 - // must be called before calling withinIncludingScrolloffset, every time the  
4071 - // page is scrolled  
4072 - prepare: function() {  
4073 - this.deltaX = window.pageXOffset  
4074 - || document.documentElement.scrollLeft  
4075 - || document.body.scrollLeft  
4076 - || 0;  
4077 - this.deltaY = window.pageYOffset  
4078 - || document.documentElement.scrollTop  
4079 - || document.body.scrollTop  
4080 - || 0;  
4081 - },  
4082 -  
4083 - // caches x/y coordinate pair to use with overlap  
4084 - within: function(element, x, y) {  
4085 - if (this.includeScrollOffsets)  
4086 - return this.withinIncludingScrolloffsets(element, x, y);  
4087 - this.xcomp = x;  
4088 - this.ycomp = y;  
4089 - this.offset = Element.cumulativeOffset(element);  
4090 -  
4091 - return (y >= this.offset[1] &&  
4092 - y < this.offset[1] + element.offsetHeight &&  
4093 - x >= this.offset[0] &&  
4094 - x < this.offset[0] + element.offsetWidth);  
4095 - },  
4096 -  
4097 - withinIncludingScrolloffsets: function(element, x, y) {  
4098 - var offsetcache = Element.cumulativeScrollOffset(element);  
4099 -  
4100 - this.xcomp = x + offsetcache[0] - this.deltaX;  
4101 - this.ycomp = y + offsetcache[1] - this.deltaY;  
4102 - this.offset = Element.cumulativeOffset(element);  
4103 -  
4104 - return (this.ycomp >= this.offset[1] &&  
4105 - this.ycomp < this.offset[1] + element.offsetHeight &&  
4106 - this.xcomp >= this.offset[0] &&  
4107 - this.xcomp < this.offset[0] + element.offsetWidth);  
4108 - },  
4109 -  
4110 - // within must be called directly before  
4111 - overlap: function(mode, element) {  
4112 - if (!mode) return 0;  
4113 - if (mode == 'vertical')  
4114 - return ((this.offset[1] + element.offsetHeight) - this.ycomp) /  
4115 - element.offsetHeight;  
4116 - if (mode == 'horizontal')  
4117 - return ((this.offset[0] + element.offsetWidth) - this.xcomp) /  
4118 - element.offsetWidth;  
4119 - },  
4120 -  
4121 - // Deprecation layer -- use newer Element methods now (1.5.2).  
4122 -  
4123 - cumulativeOffset: Element.Methods.cumulativeOffset,  
4124 -  
4125 - positionedOffset: Element.Methods.positionedOffset,  
4126 -  
4127 - absolutize: function(element) {  
4128 - Position.prepare();  
4129 - return Element.absolutize(element);  
4130 - },  
4131 -  
4132 - relativize: function(element) {  
4133 - Position.prepare();  
4134 - return Element.relativize(element);  
4135 - },  
4136 -  
4137 - realOffset: Element.Methods.cumulativeScrollOffset,  
4138 -  
4139 - offsetParent: Element.Methods.getOffsetParent,  
4140 -  
4141 - page: Element.Methods.viewportOffset,  
4142 -  
4143 - clone: function(source, target, options) {  
4144 - options = options || { };  
4145 - return Element.clonePosition(target, source, options);  
4146 - }  
4147 -};  
4148 -  
4149 -/*--------------------------------------------------------------------------*/  
4150 -  
4151 -if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){  
4152 - function iter(name) {  
4153 - return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";  
4154 - }  
4155 -  
4156 - instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?  
4157 - function(element, className) {  
4158 - className = className.toString().strip();  
4159 - var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);  
4160 - return cond ? document._getElementsByXPath('.//*' + cond, element) : [];  
4161 - } : function(element, className) {  
4162 - className = className.toString().strip();  
4163 - var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);  
4164 - if (!classNames && !className) return elements;  
4165 -  
4166 - var nodes = $(element).getElementsByTagName('*');  
4167 - className = ' ' + className + ' ';  
4168 -  
4169 - for (var i = 0, child, cn; child = nodes[i]; i++) {  
4170 - if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||  
4171 - (classNames && classNames.all(function(name) {  
4172 - return !name.toString().blank() && cn.include(' ' + name + ' ');  
4173 - }))))  
4174 - elements.push(Element.extend(child));  
4175 - }  
4176 - return elements;  
4177 - };  
4178 -  
4179 - return function(className, parentElement) {  
4180 - return $(parentElement || document.body).getElementsByClassName(className);  
4181 - };  
4182 -}(Element.Methods);  
4183 -  
4184 -/*--------------------------------------------------------------------------*/  
4185 -  
4186 -Element.ClassNames = Class.create();  
4187 -Element.ClassNames.prototype = {  
4188 - initialize: function(element) {  
4189 - this.element = $(element);  
4190 - },  
4191 -  
4192 - _each: function(iterator) {  
4193 - this.element.className.split(/\s+/).select(function(name) {  
4194 - return name.length > 0;  
4195 - })._each(iterator);  
4196 - },  
4197 -  
4198 - set: function(className) {  
4199 - this.element.className = className;  
4200 - },  
4201 -  
4202 - add: function(classNameToAdd) {  
4203 - if (this.include(classNameToAdd)) return;  
4204 - this.set($A(this).concat(classNameToAdd).join(' '));  
4205 - },  
4206 -  
4207 - remove: function(classNameToRemove) {  
4208 - if (!this.include(classNameToRemove)) return;  
4209 - this.set($A(this).without(classNameToRemove).join(' '));  
4210 - },  
4211 -  
4212 - toString: function() {  
4213 - return $A(this).join(' ');  
4214 - }  
4215 -};  
4216 -  
4217 -Object.extend(Element.ClassNames.prototype, Enumerable);  
4218 -  
4219 -/*--------------------------------------------------------------------------*/  
4220 -  
4221 -Element.addMethods();  
4222 \ No newline at end of file 0 \ No newline at end of file