Revision 1298:4f746d8966dd .svn/pristine/16

View differences:

.svn/pristine/16/160ac2451e31892432ba296457c74729e5d47d98.svn-base
1
<%= l(:text_issue_updated, :id => "##{@issue.id}", :author => @journal.user) %>
2

  
3
<% for detail in @journal.details -%>
4
<%= show_detail(detail, true) %>
5
<% end -%>
6

  
7
<%= @journal.notes if @journal.notes? %>
8
----------------------------------------
9
<%= render :partial => "issue.text.erb", :locals => { :issue => @issue, :issue_url => @issue_url } %>
.svn/pristine/16/1665bbb2717b49de68649a3ba32e9deb6f26e40f.svn-base
1
/*  Prototype JavaScript framework, version 1.7
2
 *  (c) 2005-2010 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

  
11
  Version: '1.7',
12

  
13
  Browser: (function(){
14
    var ua = navigator.userAgent;
15
    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
16
    return {
17
      IE:             !!window.attachEvent && !isOpera,
18
      Opera:          isOpera,
19
      WebKit:         ua.indexOf('AppleWebKit/') > -1,
20
      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
21
      MobileSafari:   /Apple.*Mobile/.test(ua)
22
    }
23
  })(),
24

  
25
  BrowserFeatures: {
26
    XPath: !!document.evaluate,
27

  
28
    SelectorsAPI: !!document.querySelector,
29

  
30
    ElementExtensions: (function() {
31
      var constructor = window.Element || window.HTMLElement;
32
      return !!(constructor && constructor.prototype);
33
    })(),
34
    SpecificElementExtensions: (function() {
35
      if (typeof window.HTMLDivElement !== 'undefined')
36
        return true;
37

  
38
      var div = document.createElement('div'),
39
          form = document.createElement('form'),
40
          isSupported = false;
41

  
42
      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
43
        isSupported = true;
44
      }
45

  
46
      div = form = null;
47

  
48
      return isSupported;
49
    })()
50
  },
51

  
52
  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
53
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
54

  
55
  emptyFunction: function() { },
56

  
57
  K: function(x) { return x }
58
};
59

  
60
if (Prototype.Browser.MobileSafari)
61
  Prototype.BrowserFeatures.SpecificElementExtensions = false;
62

  
63

  
64
var Abstract = { };
65

  
66

  
67
var Try = {
68
  these: function() {
69
    var returnValue;
70

  
71
    for (var i = 0, length = arguments.length; i < length; i++) {
72
      var lambda = arguments[i];
73
      try {
74
        returnValue = lambda();
75
        break;
76
      } catch (e) { }
77
    }
78

  
79
    return returnValue;
80
  }
81
};
82

  
83
/* Based on Alex Arnell's inheritance implementation. */
84

  
85
var Class = (function() {
86

  
87
  var IS_DONTENUM_BUGGY = (function(){
88
    for (var p in { toString: 1 }) {
89
      if (p === 'toString') return false;
90
    }
91
    return true;
92
  })();
93

  
94
  function subclass() {};
95
  function create() {
96
    var parent = null, properties = $A(arguments);
97
    if (Object.isFunction(properties[0]))
98
      parent = properties.shift();
99

  
100
    function klass() {
101
      this.initialize.apply(this, arguments);
102
    }
103

  
104
    Object.extend(klass, Class.Methods);
105
    klass.superclass = parent;
106
    klass.subclasses = [];
107

  
108
    if (parent) {
109
      subclass.prototype = parent.prototype;
110
      klass.prototype = new subclass;
111
      parent.subclasses.push(klass);
112
    }
113

  
114
    for (var i = 0, length = properties.length; i < length; i++)
115
      klass.addMethods(properties[i]);
116

  
117
    if (!klass.prototype.initialize)
118
      klass.prototype.initialize = Prototype.emptyFunction;
119

  
120
    klass.prototype.constructor = klass;
121
    return klass;
122
  }
123

  
124
  function addMethods(source) {
125
    var ancestor   = this.superclass && this.superclass.prototype,
126
        properties = Object.keys(source);
127

  
128
    if (IS_DONTENUM_BUGGY) {
129
      if (source.toString != Object.prototype.toString)
130
        properties.push("toString");
131
      if (source.valueOf != Object.prototype.valueOf)
132
        properties.push("valueOf");
133
    }
134

  
135
    for (var i = 0, length = properties.length; i < length; i++) {
136
      var property = properties[i], value = source[property];
137
      if (ancestor && Object.isFunction(value) &&
138
          value.argumentNames()[0] == "$super") {
139
        var method = value;
140
        value = (function(m) {
141
          return function() { return ancestor[m].apply(this, arguments); };
142
        })(property).wrap(method);
143

  
144
        value.valueOf = method.valueOf.bind(method);
145
        value.toString = method.toString.bind(method);
146
      }
147
      this.prototype[property] = value;
148
    }
149

  
150
    return this;
151
  }
152

  
153
  return {
154
    create: create,
155
    Methods: {
156
      addMethods: addMethods
157
    }
158
  };
159
})();
160
(function() {
161

  
162
  var _toString = Object.prototype.toString,
163
      NULL_TYPE = 'Null',
164
      UNDEFINED_TYPE = 'Undefined',
165
      BOOLEAN_TYPE = 'Boolean',
166
      NUMBER_TYPE = 'Number',
167
      STRING_TYPE = 'String',
168
      OBJECT_TYPE = 'Object',
169
      FUNCTION_CLASS = '[object Function]',
170
      BOOLEAN_CLASS = '[object Boolean]',
171
      NUMBER_CLASS = '[object Number]',
172
      STRING_CLASS = '[object String]',
173
      ARRAY_CLASS = '[object Array]',
174
      DATE_CLASS = '[object Date]',
175
      NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
176
        typeof JSON.stringify === 'function' &&
177
        JSON.stringify(0) === '0' &&
178
        typeof JSON.stringify(Prototype.K) === 'undefined';
179

  
180
  function Type(o) {
181
    switch(o) {
182
      case null: return NULL_TYPE;
183
      case (void 0): return UNDEFINED_TYPE;
184
    }
185
    var type = typeof o;
186
    switch(type) {
187
      case 'boolean': return BOOLEAN_TYPE;
188
      case 'number':  return NUMBER_TYPE;
189
      case 'string':  return STRING_TYPE;
190
    }
191
    return OBJECT_TYPE;
192
  }
193

  
194
  function extend(destination, source) {
195
    for (var property in source)
196
      destination[property] = source[property];
197
    return destination;
198
  }
199

  
200
  function inspect(object) {
201
    try {
202
      if (isUndefined(object)) return 'undefined';
203
      if (object === null) return 'null';
204
      return object.inspect ? object.inspect() : String(object);
205
    } catch (e) {
206
      if (e instanceof RangeError) return '...';
207
      throw e;
208
    }
209
  }
210

  
211
  function toJSON(value) {
212
    return Str('', { '': value }, []);
213
  }
214

  
215
  function Str(key, holder, stack) {
216
    var value = holder[key],
217
        type = typeof value;
218

  
219
    if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
220
      value = value.toJSON(key);
221
    }
222

  
223
    var _class = _toString.call(value);
224

  
225
    switch (_class) {
226
      case NUMBER_CLASS:
227
      case BOOLEAN_CLASS:
228
      case STRING_CLASS:
229
        value = value.valueOf();
230
    }
231

  
232
    switch (value) {
233
      case null: return 'null';
234
      case true: return 'true';
235
      case false: return 'false';
236
    }
237

  
238
    type = typeof value;
239
    switch (type) {
240
      case 'string':
241
        return value.inspect(true);
242
      case 'number':
243
        return isFinite(value) ? String(value) : 'null';
244
      case 'object':
245

  
246
        for (var i = 0, length = stack.length; i < length; i++) {
247
          if (stack[i] === value) { throw new TypeError(); }
248
        }
249
        stack.push(value);
250

  
251
        var partial = [];
252
        if (_class === ARRAY_CLASS) {
253
          for (var i = 0, length = value.length; i < length; i++) {
254
            var str = Str(i, value, stack);
255
            partial.push(typeof str === 'undefined' ? 'null' : str);
256
          }
257
          partial = '[' + partial.join(',') + ']';
258
        } else {
259
          var keys = Object.keys(value);
260
          for (var i = 0, length = keys.length; i < length; i++) {
261
            var key = keys[i], str = Str(key, value, stack);
262
            if (typeof str !== "undefined") {
263
               partial.push(key.inspect(true)+ ':' + str);
264
             }
265
          }
266
          partial = '{' + partial.join(',') + '}';
267
        }
268
        stack.pop();
269
        return partial;
270
    }
271
  }
272

  
273
  function stringify(object) {
274
    return JSON.stringify(object);
275
  }
276

  
277
  function toQueryString(object) {
278
    return $H(object).toQueryString();
279
  }
280

  
281
  function toHTML(object) {
282
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
283
  }
284

  
285
  function keys(object) {
286
    if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
287
    var results = [];
288
    for (var property in object) {
289
      if (object.hasOwnProperty(property)) {
290
        results.push(property);
291
      }
292
    }
293
    return results;
294
  }
295

  
296
  function values(object) {
297
    var results = [];
298
    for (var property in object)
299
      results.push(object[property]);
300
    return results;
301
  }
302

  
303
  function clone(object) {
304
    return extend({ }, object);
305
  }
306

  
307
  function isElement(object) {
308
    return !!(object && object.nodeType == 1);
309
  }
310

  
311
  function isArray(object) {
312
    return _toString.call(object) === ARRAY_CLASS;
313
  }
314

  
315
  var hasNativeIsArray = (typeof Array.isArray == 'function')
316
    && Array.isArray([]) && !Array.isArray({});
317

  
318
  if (hasNativeIsArray) {
319
    isArray = Array.isArray;
320
  }
321

  
322
  function isHash(object) {
323
    return object instanceof Hash;
324
  }
325

  
326
  function isFunction(object) {
327
    return _toString.call(object) === FUNCTION_CLASS;
328
  }
329

  
330
  function isString(object) {
331
    return _toString.call(object) === STRING_CLASS;
332
  }
333

  
334
  function isNumber(object) {
335
    return _toString.call(object) === NUMBER_CLASS;
336
  }
337

  
338
  function isDate(object) {
339
    return _toString.call(object) === DATE_CLASS;
340
  }
341

  
342
  function isUndefined(object) {
343
    return typeof object === "undefined";
344
  }
345

  
346
  extend(Object, {
347
    extend:        extend,
348
    inspect:       inspect,
349
    toJSON:        NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
350
    toQueryString: toQueryString,
351
    toHTML:        toHTML,
352
    keys:          Object.keys || keys,
353
    values:        values,
354
    clone:         clone,
355
    isElement:     isElement,
356
    isArray:       isArray,
357
    isHash:        isHash,
358
    isFunction:    isFunction,
359
    isString:      isString,
360
    isNumber:      isNumber,
361
    isDate:        isDate,
362
    isUndefined:   isUndefined
363
  });
364
})();
365
Object.extend(Function.prototype, (function() {
366
  var slice = Array.prototype.slice;
367

  
368
  function update(array, args) {
369
    var arrayLength = array.length, length = args.length;
370
    while (length--) array[arrayLength + length] = args[length];
371
    return array;
372
  }
373

  
374
  function merge(array, args) {
375
    array = slice.call(array, 0);
376
    return update(array, args);
377
  }
378

  
379
  function argumentNames() {
380
    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
381
      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
382
      .replace(/\s+/g, '').split(',');
383
    return names.length == 1 && !names[0] ? [] : names;
384
  }
385

  
386
  function bind(context) {
387
    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
388
    var __method = this, args = slice.call(arguments, 1);
389
    return function() {
390
      var a = merge(args, arguments);
391
      return __method.apply(context, a);
392
    }
393
  }
394

  
395
  function bindAsEventListener(context) {
396
    var __method = this, args = slice.call(arguments, 1);
397
    return function(event) {
398
      var a = update([event || window.event], args);
399
      return __method.apply(context, a);
400
    }
401
  }
402

  
403
  function curry() {
404
    if (!arguments.length) return this;
405
    var __method = this, args = slice.call(arguments, 0);
406
    return function() {
407
      var a = merge(args, arguments);
408
      return __method.apply(this, a);
409
    }
410
  }
411

  
412
  function delay(timeout) {
413
    var __method = this, args = slice.call(arguments, 1);
414
    timeout = timeout * 1000;
415
    return window.setTimeout(function() {
416
      return __method.apply(__method, args);
417
    }, timeout);
418
  }
419

  
420
  function defer() {
421
    var args = update([0.01], arguments);
422
    return this.delay.apply(this, args);
423
  }
424

  
425
  function wrap(wrapper) {
426
    var __method = this;
427
    return function() {
428
      var a = update([__method.bind(this)], arguments);
429
      return wrapper.apply(this, a);
430
    }
431
  }
432

  
433
  function methodize() {
434
    if (this._methodized) return this._methodized;
435
    var __method = this;
436
    return this._methodized = function() {
437
      var a = update([this], arguments);
438
      return __method.apply(null, a);
439
    };
440
  }
441

  
442
  return {
443
    argumentNames:       argumentNames,
444
    bind:                bind,
445
    bindAsEventListener: bindAsEventListener,
446
    curry:               curry,
447
    delay:               delay,
448
    defer:               defer,
449
    wrap:                wrap,
450
    methodize:           methodize
451
  }
452
})());
453

  
454

  
455

  
456
(function(proto) {
457

  
458

  
459
  function toISOString() {
460
    return this.getUTCFullYear() + '-' +
461
      (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
462
      this.getUTCDate().toPaddedString(2) + 'T' +
463
      this.getUTCHours().toPaddedString(2) + ':' +
464
      this.getUTCMinutes().toPaddedString(2) + ':' +
465
      this.getUTCSeconds().toPaddedString(2) + 'Z';
466
  }
467

  
468

  
469
  function toJSON() {
470
    return this.toISOString();
471
  }
472

  
473
  if (!proto.toISOString) proto.toISOString = toISOString;
474
  if (!proto.toJSON) proto.toJSON = toJSON;
475

  
476
})(Date.prototype);
477

  
478

  
479
RegExp.prototype.match = RegExp.prototype.test;
480

  
481
RegExp.escape = function(str) {
482
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
483
};
484
var PeriodicalExecuter = Class.create({
485
  initialize: function(callback, frequency) {
486
    this.callback = callback;
487
    this.frequency = frequency;
488
    this.currentlyExecuting = false;
489

  
490
    this.registerCallback();
491
  },
492

  
493
  registerCallback: function() {
494
    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
495
  },
496

  
497
  execute: function() {
498
    this.callback(this);
499
  },
500

  
501
  stop: function() {
502
    if (!this.timer) return;
503
    clearInterval(this.timer);
504
    this.timer = null;
505
  },
506

  
507
  onTimerEvent: function() {
508
    if (!this.currentlyExecuting) {
509
      try {
510
        this.currentlyExecuting = true;
511
        this.execute();
512
        this.currentlyExecuting = false;
513
      } catch(e) {
514
        this.currentlyExecuting = false;
515
        throw e;
516
      }
517
    }
518
  }
519
});
520
Object.extend(String, {
521
  interpret: function(value) {
522
    return value == null ? '' : String(value);
523
  },
524
  specialChar: {
525
    '\b': '\\b',
526
    '\t': '\\t',
527
    '\n': '\\n',
528
    '\f': '\\f',
529
    '\r': '\\r',
530
    '\\': '\\\\'
531
  }
532
});
533

  
534
Object.extend(String.prototype, (function() {
535
  var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
536
    typeof JSON.parse === 'function' &&
537
    JSON.parse('{"test": true}').test;
538

  
539
  function prepareReplacement(replacement) {
540
    if (Object.isFunction(replacement)) return replacement;
541
    var template = new Template(replacement);
542
    return function(match) { return template.evaluate(match) };
543
  }
544

  
545
  function gsub(pattern, replacement) {
546
    var result = '', source = this, match;
547
    replacement = prepareReplacement(replacement);
548

  
549
    if (Object.isString(pattern))
550
      pattern = RegExp.escape(pattern);
551

  
552
    if (!(pattern.length || pattern.source)) {
553
      replacement = replacement('');
554
      return replacement + source.split('').join(replacement) + replacement;
555
    }
556

  
557
    while (source.length > 0) {
558
      if (match = source.match(pattern)) {
559
        result += source.slice(0, match.index);
560
        result += String.interpret(replacement(match));
561
        source  = source.slice(match.index + match[0].length);
562
      } else {
563
        result += source, source = '';
564
      }
565
    }
566
    return result;
567
  }
568

  
569
  function sub(pattern, replacement, count) {
570
    replacement = prepareReplacement(replacement);
571
    count = Object.isUndefined(count) ? 1 : count;
572

  
573
    return this.gsub(pattern, function(match) {
574
      if (--count < 0) return match[0];
575
      return replacement(match);
576
    });
577
  }
578

  
579
  function scan(pattern, iterator) {
580
    this.gsub(pattern, iterator);
581
    return String(this);
582
  }
583

  
584
  function truncate(length, truncation) {
585
    length = length || 30;
586
    truncation = Object.isUndefined(truncation) ? '...' : truncation;
587
    return this.length > length ?
588
      this.slice(0, length - truncation.length) + truncation : String(this);
589
  }
590

  
591
  function strip() {
592
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
593
  }
594

  
595
  function stripTags() {
596
    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
597
  }
598

  
599
  function stripScripts() {
600
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
601
  }
602

  
603
  function extractScripts() {
604
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
605
        matchOne = new RegExp(Prototype.ScriptFragment, 'im');
606
    return (this.match(matchAll) || []).map(function(scriptTag) {
607
      return (scriptTag.match(matchOne) || ['', ''])[1];
608
    });
609
  }
610

  
611
  function evalScripts() {
612
    return this.extractScripts().map(function(script) { return eval(script) });
613
  }
614

  
615
  function escapeHTML() {
616
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
617
  }
618

  
619
  function unescapeHTML() {
620
    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
621
  }
622

  
623

  
624
  function toQueryParams(separator) {
625
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
626
    if (!match) return { };
627

  
628
    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
629
      if ((pair = pair.split('='))[0]) {
630
        var key = decodeURIComponent(pair.shift()),
631
            value = pair.length > 1 ? pair.join('=') : pair[0];
632

  
633
        if (value != undefined) value = decodeURIComponent(value);
634

  
635
        if (key in hash) {
636
          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
637
          hash[key].push(value);
638
        }
639
        else hash[key] = value;
640
      }
641
      return hash;
642
    });
643
  }
644

  
645
  function toArray() {
646
    return this.split('');
647
  }
648

  
649
  function succ() {
650
    return this.slice(0, this.length - 1) +
651
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
652
  }
653

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

  
658
  function camelize() {
659
    return this.replace(/-+(.)?/g, function(match, chr) {
660
      return chr ? chr.toUpperCase() : '';
661
    });
662
  }
663

  
664
  function capitalize() {
665
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
666
  }
667

  
668
  function underscore() {
669
    return this.replace(/::/g, '/')
670
               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
671
               .replace(/([a-z\d])([A-Z])/g, '$1_$2')
672
               .replace(/-/g, '_')
673
               .toLowerCase();
674
  }
675

  
676
  function dasherize() {
677
    return this.replace(/_/g, '-');
678
  }
679

  
680
  function inspect(useDoubleQuotes) {
681
    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
682
      if (character in String.specialChar) {
683
        return String.specialChar[character];
684
      }
685
      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
686
    });
687
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
688
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
689
  }
690

  
691
  function unfilterJSON(filter) {
692
    return this.replace(filter || Prototype.JSONFilter, '$1');
693
  }
694

  
695
  function isJSON() {
696
    var str = this;
697
    if (str.blank()) return false;
698
    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
699
    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
700
    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
701
    return (/^[\],:{}\s]*$/).test(str);
702
  }
703

  
704
  function evalJSON(sanitize) {
705
    var json = this.unfilterJSON(),
706
        cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
707
    if (cx.test(json)) {
708
      json = json.replace(cx, function (a) {
709
        return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
710
      });
711
    }
712
    try {
713
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
714
    } catch (e) { }
715
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
716
  }
717

  
718
  function parseJSON() {
719
    var json = this.unfilterJSON();
720
    return JSON.parse(json);
721
  }
722

  
723
  function include(pattern) {
724
    return this.indexOf(pattern) > -1;
725
  }
726

  
727
  function startsWith(pattern) {
728
    return this.lastIndexOf(pattern, 0) === 0;
729
  }
730

  
731
  function endsWith(pattern) {
732
    var d = this.length - pattern.length;
733
    return d >= 0 && this.indexOf(pattern, d) === d;
734
  }
735

  
736
  function empty() {
737
    return this == '';
738
  }
739

  
740
  function blank() {
741
    return /^\s*$/.test(this);
742
  }
743

  
744
  function interpolate(object, pattern) {
745
    return new Template(this, pattern).evaluate(object);
746
  }
747

  
748
  return {
749
    gsub:           gsub,
750
    sub:            sub,
751
    scan:           scan,
752
    truncate:       truncate,
753
    strip:          String.prototype.trim || strip,
754
    stripTags:      stripTags,
755
    stripScripts:   stripScripts,
756
    extractScripts: extractScripts,
757
    evalScripts:    evalScripts,
758
    escapeHTML:     escapeHTML,
759
    unescapeHTML:   unescapeHTML,
760
    toQueryParams:  toQueryParams,
761
    parseQuery:     toQueryParams,
762
    toArray:        toArray,
763
    succ:           succ,
764
    times:          times,
765
    camelize:       camelize,
766
    capitalize:     capitalize,
767
    underscore:     underscore,
768
    dasherize:      dasherize,
769
    inspect:        inspect,
770
    unfilterJSON:   unfilterJSON,
771
    isJSON:         isJSON,
772
    evalJSON:       NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
773
    include:        include,
774
    startsWith:     startsWith,
775
    endsWith:       endsWith,
776
    empty:          empty,
777
    blank:          blank,
778
    interpolate:    interpolate
779
  };
780
})());
781

  
782
var Template = Class.create({
783
  initialize: function(template, pattern) {
784
    this.template = template.toString();
785
    this.pattern = pattern || Template.Pattern;
786
  },
787

  
788
  evaluate: function(object) {
789
    if (object && Object.isFunction(object.toTemplateReplacements))
790
      object = object.toTemplateReplacements();
791

  
792
    return this.template.gsub(this.pattern, function(match) {
793
      if (object == null) return (match[1] + '');
794

  
795
      var before = match[1] || '';
796
      if (before == '\\') return match[2];
797

  
798
      var ctx = object, expr = match[3],
799
          pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
800

  
801
      match = pattern.exec(expr);
802
      if (match == null) return before;
803

  
804
      while (match != null) {
805
        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
806
        ctx = ctx[comp];
807
        if (null == ctx || '' == match[3]) break;
808
        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
809
        match = pattern.exec(expr);
810
      }
811

  
812
      return before + String.interpret(ctx);
813
    });
814
  }
815
});
816
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
817

  
818
var $break = { };
819

  
820
var Enumerable = (function() {
821
  function each(iterator, context) {
822
    var index = 0;
823
    try {
824
      this._each(function(value) {
825
        iterator.call(context, value, index++);
826
      });
827
    } catch (e) {
828
      if (e != $break) throw e;
829
    }
830
    return this;
831
  }
832

  
833
  function eachSlice(number, iterator, context) {
834
    var index = -number, slices = [], array = this.toArray();
835
    if (number < 1) return array;
836
    while ((index += number) < array.length)
837
      slices.push(array.slice(index, index+number));
838
    return slices.collect(iterator, context);
839
  }
840

  
841
  function all(iterator, context) {
842
    iterator = iterator || Prototype.K;
843
    var result = true;
844
    this.each(function(value, index) {
845
      result = result && !!iterator.call(context, value, index);
846
      if (!result) throw $break;
847
    });
848
    return result;
849
  }
850

  
851
  function any(iterator, context) {
852
    iterator = iterator || Prototype.K;
853
    var result = false;
854
    this.each(function(value, index) {
855
      if (result = !!iterator.call(context, value, index))
856
        throw $break;
857
    });
858
    return result;
859
  }
860

  
861
  function collect(iterator, context) {
862
    iterator = iterator || Prototype.K;
863
    var results = [];
864
    this.each(function(value, index) {
865
      results.push(iterator.call(context, value, index));
866
    });
867
    return results;
868
  }
869

  
870
  function detect(iterator, context) {
871
    var result;
872
    this.each(function(value, index) {
873
      if (iterator.call(context, value, index)) {
874
        result = value;
875
        throw $break;
876
      }
877
    });
878
    return result;
879
  }
880

  
881
  function findAll(iterator, context) {
882
    var results = [];
883
    this.each(function(value, index) {
884
      if (iterator.call(context, value, index))
885
        results.push(value);
886
    });
887
    return results;
888
  }
889

  
890
  function grep(filter, iterator, context) {
891
    iterator = iterator || Prototype.K;
892
    var results = [];
893

  
894
    if (Object.isString(filter))
895
      filter = new RegExp(RegExp.escape(filter));
896

  
897
    this.each(function(value, index) {
898
      if (filter.match(value))
899
        results.push(iterator.call(context, value, index));
900
    });
901
    return results;
902
  }
903

  
904
  function include(object) {
905
    if (Object.isFunction(this.indexOf))
906
      if (this.indexOf(object) != -1) return true;
907

  
908
    var found = false;
909
    this.each(function(value) {
910
      if (value == object) {
911
        found = true;
912
        throw $break;
913
      }
914
    });
915
    return found;
916
  }
917

  
918
  function inGroupsOf(number, fillWith) {
919
    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
920
    return this.eachSlice(number, function(slice) {
921
      while(slice.length < number) slice.push(fillWith);
922
      return slice;
923
    });
924
  }
925

  
926
  function inject(memo, iterator, context) {
927
    this.each(function(value, index) {
928
      memo = iterator.call(context, memo, value, index);
929
    });
930
    return memo;
931
  }
932

  
933
  function invoke(method) {
934
    var args = $A(arguments).slice(1);
935
    return this.map(function(value) {
936
      return value[method].apply(value, args);
937
    });
938
  }
939

  
940
  function max(iterator, context) {
941
    iterator = iterator || Prototype.K;
942
    var result;
943
    this.each(function(value, index) {
944
      value = iterator.call(context, value, index);
945
      if (result == null || value >= result)
946
        result = value;
947
    });
948
    return result;
949
  }
950

  
951
  function min(iterator, context) {
952
    iterator = iterator || Prototype.K;
953
    var result;
954
    this.each(function(value, index) {
955
      value = iterator.call(context, value, index);
956
      if (result == null || value < result)
957
        result = value;
958
    });
959
    return result;
960
  }
961

  
962
  function partition(iterator, context) {
963
    iterator = iterator || Prototype.K;
964
    var trues = [], falses = [];
965
    this.each(function(value, index) {
966
      (iterator.call(context, value, index) ?
967
        trues : falses).push(value);
968
    });
969
    return [trues, falses];
970
  }
971

  
972
  function pluck(property) {
973
    var results = [];
974
    this.each(function(value) {
975
      results.push(value[property]);
976
    });
977
    return results;
978
  }
979

  
980
  function reject(iterator, context) {
981
    var results = [];
982
    this.each(function(value, index) {
983
      if (!iterator.call(context, value, index))
984
        results.push(value);
985
    });
986
    return results;
987
  }
988

  
989
  function sortBy(iterator, context) {
990
    return this.map(function(value, index) {
991
      return {
992
        value: value,
993
        criteria: iterator.call(context, value, index)
994
      };
995
    }).sort(function(left, right) {
996
      var a = left.criteria, b = right.criteria;
997
      return a < b ? -1 : a > b ? 1 : 0;
998
    }).pluck('value');
999
  }
1000

  
1001
  function toArray() {
1002
    return this.map();
1003
  }
1004

  
1005
  function zip() {
1006
    var iterator = Prototype.K, args = $A(arguments);
1007
    if (Object.isFunction(args.last()))
1008
      iterator = args.pop();
1009

  
1010
    var collections = [this].concat(args).map($A);
1011
    return this.map(function(value, index) {
1012
      return iterator(collections.pluck(index));
1013
    });
1014
  }
1015

  
1016
  function size() {
1017
    return this.toArray().length;
1018
  }
1019

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

  
1024

  
1025

  
1026

  
1027

  
1028

  
1029

  
1030

  
1031

  
1032
  return {
1033
    each:       each,
1034
    eachSlice:  eachSlice,
1035
    all:        all,
1036
    every:      all,
1037
    any:        any,
1038
    some:       any,
1039
    collect:    collect,
1040
    map:        collect,
1041
    detect:     detect,
1042
    findAll:    findAll,
1043
    select:     findAll,
1044
    filter:     findAll,
1045
    grep:       grep,
1046
    include:    include,
1047
    member:     include,
1048
    inGroupsOf: inGroupsOf,
1049
    inject:     inject,
1050
    invoke:     invoke,
1051
    max:        max,
1052
    min:        min,
1053
    partition:  partition,
1054
    pluck:      pluck,
1055
    reject:     reject,
1056
    sortBy:     sortBy,
1057
    toArray:    toArray,
1058
    entries:    toArray,
1059
    zip:        zip,
1060
    size:       size,
1061
    inspect:    inspect,
1062
    find:       detect
1063
  };
1064
})();
1065

  
1066
function $A(iterable) {
1067
  if (!iterable) return [];
1068
  if ('toArray' in Object(iterable)) return iterable.toArray();
1069
  var length = iterable.length || 0, results = new Array(length);
1070
  while (length--) results[length] = iterable[length];
1071
  return results;
1072
}
1073

  
1074

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

  
1081
Array.from = $A;
1082

  
1083

  
1084
(function() {
1085
  var arrayProto = Array.prototype,
1086
      slice = arrayProto.slice,
1087
      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
1088

  
1089
  function each(iterator, context) {
1090
    for (var i = 0, length = this.length >>> 0; i < length; i++) {
1091
      if (i in this) iterator.call(context, this[i], i, this);
1092
    }
1093
  }
1094
  if (!_each) _each = each;
1095

  
1096
  function clear() {
1097
    this.length = 0;
1098
    return this;
1099
  }
1100

  
1101
  function first() {
1102
    return this[0];
1103
  }
1104

  
1105
  function last() {
1106
    return this[this.length - 1];
1107
  }
1108

  
1109
  function compact() {
1110
    return this.select(function(value) {
1111
      return value != null;
1112
    });
1113
  }
1114

  
1115
  function flatten() {
1116
    return this.inject([], function(array, value) {
1117
      if (Object.isArray(value))
1118
        return array.concat(value.flatten());
1119
      array.push(value);
1120
      return array;
1121
    });
1122
  }
1123

  
1124
  function without() {
1125
    var values = slice.call(arguments, 0);
1126
    return this.select(function(value) {
1127
      return !values.include(value);
1128
    });
1129
  }
1130

  
1131
  function reverse(inline) {
1132
    return (inline === false ? this.toArray() : this)._reverse();
1133
  }
1134

  
1135
  function uniq(sorted) {
1136
    return this.inject([], function(array, value, index) {
1137
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
1138
        array.push(value);
1139
      return array;
1140
    });
1141
  }
1142

  
1143
  function intersect(array) {
1144
    return this.uniq().findAll(function(item) {
1145
      return array.detect(function(value) { return item === value });
1146
    });
1147
  }
1148

  
1149

  
1150
  function clone() {
1151
    return slice.call(this, 0);
1152
  }
1153

  
1154
  function size() {
1155
    return this.length;
1156
  }
1157

  
1158
  function inspect() {
1159
    return '[' + this.map(Object.inspect).join(', ') + ']';
1160
  }
1161

  
1162
  function indexOf(item, i) {
1163
    i || (i = 0);
1164
    var length = this.length;
1165
    if (i < 0) i = length + i;
1166
    for (; i < length; i++)
1167
      if (this[i] === item) return i;
1168
    return -1;
1169
  }
1170

  
1171
  function lastIndexOf(item, i) {
1172
    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
1173
    var n = this.slice(0, i).reverse().indexOf(item);
1174
    return (n < 0) ? n : i - n - 1;
1175
  }
1176

  
1177
  function concat() {
1178
    var array = slice.call(this, 0), item;
1179
    for (var i = 0, length = arguments.length; i < length; i++) {
1180
      item = arguments[i];
1181
      if (Object.isArray(item) && !('callee' in item)) {
1182
        for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
1183
          array.push(item[j]);
1184
      } else {
1185
        array.push(item);
1186
      }
1187
    }
1188
    return array;
1189
  }
1190

  
1191
  Object.extend(arrayProto, Enumerable);
1192

  
1193
  if (!arrayProto._reverse)
1194
    arrayProto._reverse = arrayProto.reverse;
1195

  
1196
  Object.extend(arrayProto, {
1197
    _each:     _each,
1198
    clear:     clear,
1199
    first:     first,
1200
    last:      last,
1201
    compact:   compact,
1202
    flatten:   flatten,
1203
    without:   without,
1204
    reverse:   reverse,
1205
    uniq:      uniq,
1206
    intersect: intersect,
1207
    clone:     clone,
1208
    toArray:   clone,
1209
    size:      size,
1210
    inspect:   inspect
1211
  });
1212

  
1213
  var CONCAT_ARGUMENTS_BUGGY = (function() {
1214
    return [].concat(arguments)[0][0] !== 1;
1215
  })(1,2)
1216

  
1217
  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
1218

  
1219
  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
1220
  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
1221
})();
1222
function $H(object) {
1223
  return new Hash(object);
1224
};
1225

  
1226
var Hash = Class.create(Enumerable, (function() {
1227
  function initialize(object) {
1228
    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
1229
  }
1230

  
1231

  
1232
  function _each(iterator) {
1233
    for (var key in this._object) {
1234
      var value = this._object[key], pair = [key, value];
1235
      pair.key = key;
1236
      pair.value = value;
1237
      iterator(pair);
1238
    }
1239
  }
1240

  
1241
  function set(key, value) {
1242
    return this._object[key] = value;
1243
  }
1244

  
1245
  function get(key) {
1246
    if (this._object[key] !== Object.prototype[key])
1247
      return this._object[key];
1248
  }
1249

  
1250
  function unset(key) {
1251
    var value = this._object[key];
1252
    delete this._object[key];
1253
    return value;
1254
  }
1255

  
1256
  function toObject() {
1257
    return Object.clone(this._object);
1258
  }
1259

  
1260

  
1261

  
1262
  function keys() {
1263
    return this.pluck('key');
1264
  }
1265

  
1266
  function values() {
1267
    return this.pluck('value');
1268
  }
1269

  
1270
  function index(value) {
1271
    var match = this.detect(function(pair) {
1272
      return pair.value === value;
1273
    });
1274
    return match && match.key;
1275
  }
1276

  
1277
  function merge(object) {
1278
    return this.clone().update(object);
1279
  }
1280

  
1281
  function update(object) {
1282
    return new Hash(object).inject(this, function(result, pair) {
1283
      result.set(pair.key, pair.value);
1284
      return result;
1285
    });
1286
  }
1287

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

  
1293
  function toQueryString() {
1294
    return this.inject([], function(results, pair) {
1295
      var key = encodeURIComponent(pair.key), values = pair.value;
1296

  
1297
      if (values && typeof values == 'object') {
1298
        if (Object.isArray(values)) {
1299
          var queryValues = [];
1300
          for (var i = 0, len = values.length, value; i < len; i++) {
1301
            value = values[i];
1302
            queryValues.push(toQueryPair(key, value));
1303
          }
1304
          return results.concat(queryValues);
1305
        }
1306
      } else results.push(toQueryPair(key, values));
1307
      return results;
1308
    }).join('&');
1309
  }
1310

  
1311
  function inspect() {
1312
    return '#<Hash:{' + this.map(function(pair) {
1313
      return pair.map(Object.inspect).join(': ');
1314
    }).join(', ') + '}>';
1315
  }
1316

  
1317
  function clone() {
1318
    return new Hash(this);
1319
  }
1320

  
1321
  return {
1322
    initialize:             initialize,
1323
    _each:                  _each,
1324
    set:                    set,
1325
    get:                    get,
1326
    unset:                  unset,
1327
    toObject:               toObject,
1328
    toTemplateReplacements: toObject,
1329
    keys:                   keys,
1330
    values:                 values,
1331
    index:                  index,
1332
    merge:                  merge,
1333
    update:                 update,
1334
    toQueryString:          toQueryString,
1335
    inspect:                inspect,
1336
    toJSON:                 toObject,
1337
    clone:                  clone
1338
  };
1339
})());
1340

  
1341
Hash.from = $H;
1342
Object.extend(Number.prototype, (function() {
1343
  function toColorPart() {
1344
    return this.toPaddedString(2, 16);
1345
  }
1346

  
1347
  function succ() {
1348
    return this + 1;
1349
  }
1350

  
1351
  function times(iterator, context) {
1352
    $R(0, this, true).each(iterator, context);
1353
    return this;
1354
  }
1355

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

  
1361
  function abs() {
1362
    return Math.abs(this);
1363
  }
1364

  
1365
  function round() {
1366
    return Math.round(this);
1367
  }
1368

  
1369
  function ceil() {
1370
    return Math.ceil(this);
1371
  }
1372

  
1373
  function floor() {
1374
    return Math.floor(this);
1375
  }
1376

  
1377
  return {
1378
    toColorPart:    toColorPart,
1379
    succ:           succ,
1380
    times:          times,
1381
    toPaddedString: toPaddedString,
1382
    abs:            abs,
1383
    round:          round,
1384
    ceil:           ceil,
1385
    floor:          floor
1386
  };
1387
})());
1388

  
1389
function $R(start, end, exclusive) {
1390
  return new ObjectRange(start, end, exclusive);
1391
}
1392

  
1393
var ObjectRange = Class.create(Enumerable, (function() {
1394
  function initialize(start, end, exclusive) {
1395
    this.start = start;
1396
    this.end = end;
1397
    this.exclusive = exclusive;
1398
  }
1399

  
1400
  function _each(iterator) {
1401
    var value = this.start;
1402
    while (this.include(value)) {
1403
      iterator(value);
1404
      value = value.succ();
1405
    }
1406
  }
1407

  
1408
  function include(value) {
1409
    if (value < this.start)
1410
      return false;
1411
    if (this.exclusive)
1412
      return value < this.end;
1413
    return value <= this.end;
1414
  }
1415

  
1416
  return {
1417
    initialize: initialize,
1418
    _each:      _each,
1419
    include:    include
1420
  };
1421
})());
1422

  
1423

  
1424

  
1425
var Ajax = {
1426
  getTransport: function() {
1427
    return Try.these(
1428
      function() {return new XMLHttpRequest()},
1429
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
1430
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
1431
    ) || false;
1432
  },
1433

  
1434
  activeRequestCount: 0
1435
};
1436

  
1437
Ajax.Responders = {
1438
  responders: [],
1439

  
1440
  _each: function(iterator) {
1441
    this.responders._each(iterator);
1442
  },
1443

  
1444
  register: function(responder) {
1445
    if (!this.include(responder))
1446
      this.responders.push(responder);
1447
  },
1448

  
1449
  unregister: function(responder) {
1450
    this.responders = this.responders.without(responder);
1451
  },
1452

  
1453
  dispatch: function(callback, request, transport, json) {
1454
    this.each(function(responder) {
1455
      if (Object.isFunction(responder[callback])) {
1456
        try {
1457
          responder[callback].apply(responder, [request, transport, json]);
1458
        } catch (e) { }
1459
      }
1460
    });
1461
  }
1462
};
1463

  
1464
Object.extend(Ajax.Responders, Enumerable);
1465

  
1466
Ajax.Responders.register({
1467
  onCreate:   function() { Ajax.activeRequestCount++ },
1468
  onComplete: function() { Ajax.activeRequestCount-- }
1469
});
1470
Ajax.Base = Class.create({
1471
  initialize: function(options) {
1472
    this.options = {
1473
      method:       'post',
1474
      asynchronous: true,
1475
      contentType:  'application/x-www-form-urlencoded',
1476
      encoding:     'UTF-8',
1477
      parameters:   '',
1478
      evalJSON:     true,
1479
      evalJS:       true
1480
    };
1481
    Object.extend(this.options, options || { });
1482

  
1483
    this.options.method = this.options.method.toLowerCase();
1484

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff