Changeset 6651


Ignore:
Timestamp:
07/02/10 06:53:40 (10 years ago)
Author:
rvelices
Message:

rv_gmaps - start using google.maps JS namespace + upgrade prototype.js

Location:
extensions/rv_gmaps/trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • extensions/rv_gmaps/trunk/changelog.txt

    r6472 r6651  
    112.1.b 
    22- fixed admin navigation bar 
     3- compatible with extended description 
     4- upgrade prototype 
    35 
    462.1.a 
  • extensions/rv_gmaps/trunk/template/data_handler.js

    r6245 r6651  
    1010                , opts || {} ); 
    1111 
    12         GEvent.addListener( map, "infowindowclose", function() {map.getInfoWindow().pwgMarker=null;} ); 
     12        google.maps.Event.addListener( map, "infowindowclose", function() {map.getInfoWindow().pwgMarker=null;} ); 
    1313} 
    1414 
     
    8383                        { 
    8484                                this._map.removeOverlay( marker ); 
    85                                 GEvent.clearListeners(marker, "click" ); 
    86                                 GEvent.clearListeners(marker, "dblclick" ); 
     85                                google.maps.Event.clearListeners(marker, "click" ); 
     86                                google.maps.Event.clearListeners(marker, "dblclick" ); 
    8787                                this._map.getInfoWindow().pwgMarker = infoWindowMarker = null; 
    88                                 if (document.is_debug) GLog.write('removed marker with infoWindow'); 
     88                                if (document.is_debug) google.maps.Log.write('removed marker with infoWindow'); 
    8989                                marker = this._markers.pop(); 
    9090                        } 
     
    9292                        if (!marker) 
    9393                        { 
    94                                 marker = new GMarker( cluster.position, {title:  theTitle, icon: this.options.icon } ); 
    95                                 GEvent.addListener( marker, "click", this._onMarkerClick.bind(this, marker) ); 
    96                                 GEvent.addListener( marker, "dblclick", this._onMarkerDblClick.bind(this, marker) ); 
     94                                marker = new google.maps.Marker( cluster.position, {title:  theTitle, icon: this.options.icon } ); 
     95                                google.maps.Event.addListener( marker, "click", this._onMarkerClick.bind(this, marker) ); 
     96                                google.maps.Event.addListener( marker, "dblclick", this._onMarkerDblClick.bind(this, marker) ); 
    9797                                this._map.addOverlay( marker ); 
    9898                        } 
     
    144144                { 
    145145                        this._map.removeOverlay( this._markers[i] ); 
    146                         GEvent.clearListeners(this._markers[i], "click" ); 
    147                         GEvent.clearListeners(this._markers[i], "dblclick" ); 
     146                        google.maps.Event.clearListeners(this._markers[i], "click" ); 
     147                        google.maps.Event.clearListeners(this._markers[i], "dblclick" ); 
    148148                } 
    149149 
     
    160160        if (this._map.getInfoWindow().pwgMarker == marker ) 
    161161                return; // already open 
    162   var content = ""; 
    163   if ( !marker.currentImageIndex ) 
    164     marker.currentImageIndex = 0; 
    165   content += '<div class="gmiw_header" style="' + (marker.pwg.images.length>1 ? '': 'display:none')+ '">'; 
    166   content += '<span id="pwgImageCounters">'+this.buildCurrentPictureCounterHtml(marker)+'</span> '; 
    167   content += '<a href="javascript:void(0);" id="'+this._navHtmlIds[0]+'">'; 
    168   content +=    '<span>'+ "&laquo; " + Localization.get('Prev') + '</span>'; 
    169   content += '</a>'; 
    170   content += " "; 
    171   content += '<a href="javascript:void(0);" id="'+this._navHtmlIds[1]+'">'; 
    172   content +=    '<span>'+Localization.get('Next') + " &raquo;"+'</span>'; 
    173   content += '</a>'; 
    174   content += " "; 
    175   var imgShowAll = ''; 
    176   if (this.options.show_all_img_src) 
    177     imgShowAll = '<img src="'+this.options.show_all_img_src+'" alt="" style="border:0" /> '; 
    178   content += '<a id="pwgImageBlowup" href="'+marker.pwg.blowup_url+'" onclick="return PwgDataHandler.blowupUrl(this.href);" title='+Localization.getQ('show all pictures around this location')+'>'+ 
    179             imgShowAll+ '<span>'+Localization.get('Show all')+'</span>'+ 
    180           '</a>'; 
    181   content += '</div>'; 
    182   content += '<div id="pwgImageDetail">' + this.buildCurrentPictureHtml( marker ) + '</div>'; 
    183  
    184   marker.openInfoWindowHtml( content ); 
    185  
    186   // bind to next / prev a little later because sometimes the nodes are not immediately created 
    187   if (this._timerBindPictureNavigation) clearTimeout(this._timerBindPictureNavigation); 
    188   this._timerBindPictureNavigation = null; 
    189   if (marker.pwg.images.length>1) 
    190     this._timerBindPictureNavigation = setTimeout( this._onTimeoutBindPictureNavigation.bind(this, marker), 250 ); 
     162        var content = ""; 
     163        if ( !marker.currentImageIndex ) 
     164                marker.currentImageIndex = 0; 
     165        content += '<div class="gmiw_header" style="' + (marker.pwg.images.length>1 ? '': 'display:none')+ '">'; 
     166        content += '<span id="pwgImageCounters">'+this.buildCurrentPictureCounterHtml(marker)+'</span> '; 
     167        content += '<a href="javascript:void(0);" id="'+this._navHtmlIds[0]+'">'; 
     168        content +=    '<span>'+ "&laquo; " + Localization.get('Prev') + '</span>'; 
     169        content += '</a>'; 
     170        content += " "; 
     171        content += '<a href="javascript:void(0);" id="'+this._navHtmlIds[1]+'">'; 
     172        content +=    '<span>'+Localization.get('Next') + " &raquo;"+'</span>'; 
     173        content += '</a>'; 
     174        content += " "; 
     175        var imgShowAll = ''; 
     176        if (this.options.show_all_img_src) 
     177                imgShowAll = '<img src="'+this.options.show_all_img_src+'" alt="" style="border:0" /> '; 
     178        content += '<a id="pwgImageBlowup" href="'+marker.pwg.blowup_url+'" onclick="return PwgDataHandler.blowupUrl(this.href);" title='+Localization.getQ('show all pictures around this location')+'>'+ 
     179                                                imgShowAll+ '<span>'+Localization.get('Show all')+'</span>'+ 
     180                                        '</a>'; 
     181        content += '</div>'; 
     182        content += '<div id="pwgImageDetail">' + this.buildCurrentPictureHtml( marker ) + '</div>'; 
     183 
     184        marker.openInfoWindowHtml( content ); 
     185 
     186        // bind to next / prev a little later because sometimes the nodes are not immediately created 
     187        if (this._timerBindPictureNavigation) clearTimeout(this._timerBindPictureNavigation); 
     188        this._timerBindPictureNavigation = null; 
     189        if (marker.pwg.images.length>1) 
     190                this._timerBindPictureNavigation = setTimeout( this._onTimeoutBindPictureNavigation.bind(this, marker), 250 ); 
    191191}, 
    192192 
    193193_onMarkerDblClick: function( marker ) 
    194194{ 
    195   this._map.setCenter( marker.pwg.bounds.getCenter(), this._map.getBoundsZoomLevel( marker.pwg.bounds ) ); 
     195        this._map.setCenter( marker.pwg.bounds.getCenter(), this._map.getBoundsZoomLevel( marker.pwg.bounds ) ); 
    196196}, 
    197197 
    198198buildCurrentPictureHtml: function( marker ) 
    199199{ 
    200   var imageDetail = marker.pwg.images[marker.currentImageIndex]; 
    201   var res = ""; 
    202   res += '<div class="gmiw_imageTitle">' + imageDetail.name + "</div>"; 
    203   res += 
     200        var imageDetail = marker.pwg.images[marker.currentImageIndex]; 
     201        var res = ""; 
     202        res += '<div class="gmiw_imageTitle">' + imageDetail.name + "</div>"; 
     203        res += 
    204204'<div class="gmiw_imageContent">' + 
    205205'<div class="gmiw_imageWrap">'+ 
     
    209209'<div class="gmiw_imageComment">' + imageDetail.comment + '</div>' + 
    210210'</div>'; 
    211   return res; 
     211        return res; 
    212212}, 
    213213 
    214214buildCurrentPictureCounterHtml: function( marker ) 
    215215{ 
    216   var res = 
    217     '<b>'+(marker.currentImageIndex+1)+'</b>'+ 
    218     '/' + 
    219     '<b>'+marker.pwg.images.length+'</b>'; 
    220   if (marker.pwg.nb_items>marker.pwg.images.length) 
    221     res+= " "+Localization.fmt1("out of %d", marker.pwg.nb_items ); 
    222   return res; 
     216        var res = 
     217                '<b>'+(marker.currentImageIndex+1)+'</b>'+ 
     218                '/' + 
     219                '<b>'+marker.pwg.images.length+'</b>'; 
     220        if (marker.pwg.nb_items>marker.pwg.images.length) 
     221                res+= " "+Localization.fmt1("out of %d", marker.pwg.nb_items ); 
     222        return res; 
    223223}, 
    224224 
     
    226226_onTimeoutBindPictureNavigation: function( marker ) 
    227227{ 
    228   clearTimeout(this._timerBindPictureNavigation); 
    229   this._timerBindPictureNavigation = null; 
    230   this._map.getInfoWindow().pwgMarker = marker; 
    231   for (var i=0; i< this._navHtmlIds.length; i++) 
    232   { 
    233     var elt = document.getElementById( this._navHtmlIds[i] ); 
    234     if (elt) 
    235       GEvent.addDomListener(elt, "click", this._onPictureNavigate.bind(this, marker, i) ); 
    236   } 
     228        clearTimeout(this._timerBindPictureNavigation); 
     229        this._timerBindPictureNavigation = null; 
     230        this._map.getInfoWindow().pwgMarker = marker; 
     231        for (var i=0; i< this._navHtmlIds.length; i++) 
     232        { 
     233                var elt = document.getElementById( this._navHtmlIds[i] ); 
     234                if (elt) 
     235                        google.maps.Event.addDomListener(elt, "click", this._onPictureNavigate.bind(this, marker, i) ); 
     236        } 
    237237}, 
    238238 
    239239_onPictureNavigate: function(marker, dir ) 
    240240{ 
    241   if (dir==0) dir=-1; 
    242   marker.currentImageIndex += dir; 
    243   if (marker.currentImageIndex<0) 
    244     marker.currentImageIndex = marker.pwg.images.length-1; 
    245   else if (marker.currentImageIndex >= marker.pwg.images.length) 
    246     marker.currentImageIndex = 0; 
    247  
    248   try { 
    249     var elt = document.getElementById( "pwgImageDetail" ); 
    250     elt.innerHTML = this.buildCurrentPictureHtml( marker ); 
    251   } 
    252   catch (e) 
    253   { 
    254     alert (e.message); 
    255   } 
    256  
    257   try { 
    258     var elt = document.getElementById( "pwgImageCounters" ); 
    259     elt.innerHTML = this.buildCurrentPictureCounterHtml( marker ); 
    260   } 
    261   catch (e) 
    262   { 
    263     alert (e.message); 
    264   } 
    265   return false; 
     241        if (dir==0) dir=-1; 
     242        marker.currentImageIndex += dir; 
     243        if (marker.currentImageIndex<0) 
     244                marker.currentImageIndex = marker.pwg.images.length-1; 
     245        else if (marker.currentImageIndex >= marker.pwg.images.length) 
     246                marker.currentImageIndex = 0; 
     247 
     248        try { 
     249                var elt = document.getElementById( "pwgImageDetail" ); 
     250                elt.innerHTML = this.buildCurrentPictureHtml( marker ); 
     251        } 
     252        catch (e) 
     253        { 
     254                alert (e.message); 
     255        } 
     256 
     257        try { 
     258                var elt = document.getElementById( "pwgImageCounters" ); 
     259                elt.innerHTML = this.buildCurrentPictureCounterHtml( marker ); 
     260        } 
     261        catch (e) 
     262        { 
     263                alert (e.message); 
     264        } 
     265        return false; 
    266266} 
    267267 
     
    270270PwgDataHandler.blowupUrl = function(theUrl) 
    271271{ 
    272   var win = new Window({ 
    273     title: document.title, 
    274     url: theUrl, 
    275     classname: "alphacube", 
    276     left: 0, top: 0, 
    277     width:"640", height:"480", 
    278     minimizable: false, 
    279     maximizable: false, 
    280     draggable: false, 
    281     resizable: false, 
    282     destroyOnClose: true, 
    283     hideEffect: Element.hide, 
    284     showEffectOptions: {duration:1.5} 
    285   }); 
    286  
    287   win.setConstraint(true, {top:20, left:20, bottom:30, right:20} ); 
    288   win.maximize(); 
    289   win.showCenter(true, 20, 20); 
    290   return false; 
     272        var win = new Window({ 
     273                title: document.title, 
     274                url: theUrl, 
     275                classname: "alphacube", 
     276                left: 0, top: 0, 
     277                width:"640", height:"480", 
     278                minimizable: false, 
     279                maximizable: false, 
     280                draggable: false, 
     281                resizable: false, 
     282                destroyOnClose: true, 
     283                hideEffect: Element.hide, 
     284                showEffectOptions: {duration:1.5} 
     285        }); 
     286 
     287        win.setConstraint(true, {top:20, left:20, bottom:30, right:20} ); 
     288        win.maximize(); 
     289        win.showCenter(true, 20, 20); 
     290        return false; 
    291291} 
    292292 
     
    294294String.prototype.urlNoHtm = function() 
    295295{ 
    296   return this.replace( "&amp;", "&" ); 
    297 } 
     296        return this.replace( "&amp;", "&" ); 
     297} 
  • extensions/rv_gmaps/trunk/template/data_loader.js

    r6400 r6651  
    88                } 
    99                , opts || {} ); 
    10         this.options.rectangle_of_confusion = new GSize( this.options.rectangle_of_confusion.width, this.options.rectangle_of_confusion.height ); 
     10        this.options.rectangle_of_confusion = new google.maps.Size( this.options.rectangle_of_confusion.width, this.options.rectangle_of_confusion.height ); 
    1111        if (this.options.rectangle_of_confusion.width<16) this.options.rectangle_of_confusion.width=16; 
    1212        if (this.options.rectangle_of_confusion.height<16) this.options.rectangle_of_confusion.height=16; 
     
    3737{ 
    3838        this._urlMapData = urlMapData; 
    39         GEvent.bind( this._map, "movestart", this, this.clearTimerReloadData ); 
    40         GEvent.bind( this._map, "moveend", this, this._onMapMoveEnd ); 
     39        google.maps.Event.bind( this._map, "movestart", this, this.clearTimerReloadData ); 
     40        google.maps.Event.bind( this._map, "moveend", this, this._onMapMoveEnd ); 
    4141        this._loadData(); 
    4242}, 
     
    7777        var bounds = this._map.getBounds(); 
    7878 
    79         // BEGIN BUG in maps api 2.185 up to "today" 2.193 - when map wraps horizontally more than 360 deg - the getBounds is wrong 
    80         /*if ( this._map.getZoom() <= 2 || this._map.getZoom() == 3 && this._map.getSize().width > 1000 ) 
    81         { 
    82                 bounds = new GLatLngBounds( 
    83                                 new GLatLng( bounds.getSouthWest().lat(),  -180 ), 
    84                                 new GLatLng( bounds.getNorthEast().lat(),  180 ) 
    85                         ); 
    86         }*/ 
    87         // END BUG 
    8879        var latRange = bounds.toSpan().lat(); 
    8980        var latPrec = latRange * this.options.rectangle_of_confusion.height / this._map.getSize().height; 
     
    10798                                        ) 
    10899                                { 
    109                                         if (document.is_debug) GLog.write('no load: zoom crt: '+this._map.getZoom()+'; prev: '+this._previousLoadDataReq.zoom+'; target: '+this._map.getBoundsZoomLevel(this._previousLoadDataReq.resultBounds)); 
     100                                        if (document.is_debug) google.maps.Log.write('no load: zoom crt: '+this._map.getZoom()+'; prev: '+this._previousLoadDataReq.zoom+'; target: '+this._map.getBoundsZoomLevel(this._previousLoadDataReq.resultBounds)); 
    110101                                        return; 
    111102                                } 
     
    129120        } 
    130121        var digits = Math.max( getLatLonDigits(latRange,4,2), getLatLonDigits(lonRange,4,2) ); 
    131         var box = new GLatLngBounds( 
    132                         new GLatLng( Math.roundN(bounds.getSouthWest().lat()-sd,digits), Math.roundN( bounds.getSouthWest().lng()-wd,digits ) ), 
    133                         new GLatLng( Math.roundN(bounds.getNorthEast().lat()+nd,digits), Math.roundN( bounds.getNorthEast().lng()+ed,digits) ) 
    134                 ); 
     122        /*var box = new google.maps.LatLngBounds( 
     123                        new google.maps.LatLng( Math.roundN(bounds.getSouthWest().lat()-sd,digits), Math.roundN( bounds.getSouthWest().lng()-wd,digits ) ), 
     124                        new google.maps.LatLng( Math.roundN(bounds.getNorthEast().lat()+nd,digits), Math.roundN( bounds.getNorthEast().lng()+ed,digits) ) 
     125                );*/ 
     126        var box = new google.maps.LatLngBounds( bounds.getSouthWest(), bounds.getNorthEast() ); 
     127        box.extend( new google.maps.LatLng( Math.roundN(bounds.getSouthWest().lat()-sd,digits), Math.roundN( bounds.getSouthWest().lng()-wd,digits ) ) ); 
     128        box.extend( new google.maps.LatLng( Math.roundN(bounds.getNorthEast().lat()+nd,digits), Math.roundN( bounds.getNorthEast().lng()+ed,digits) ) ); 
    135129 
    136130        var url = this._urlMapData; 
     
    140134 
    141135        if (document.is_debug) { 
    142                 GLog.write( "bounds: " + this._map.getBounds().getSouthWest().toUrlValue() + " " + this._map.getBounds().getNorthEast().toUrlValue() +"; zoom: "+this._map.getZoom() +"; size: "+this._map.getSize().toString() +"; c: "+this._map.getCenter().toUrlValue() ); 
    143                 GLog.writeUrl( url ); 
     136                google.maps.Log.write("sd="+sd+" wd="+wd+" nd="+nd+" ed="+ed); 
     137                google.maps.Log.write( "bounds: " + this._map.getBounds().getSouthWest().toUrlValue() + " " + this._map.getBounds().getNorthEast().toUrlValue() +"; zoom: "+this._map.getZoom() +"; size: "+this._map.getSize().toString() +"; c: "+this._map.getCenter().toUrlValue() ); 
     138                google.maps.Log.writeUrl( url ); 
    144139        } 
    145140 
     
    150145 
    151146        try { 
    152                 GEvent.trigger( this, "dataloading" ); 
     147                google.maps.Event.trigger( this, "dataloading" ); 
    153148                GDownloadUrl(url, this._onDataReceived.bind(this) ); 
    154149        } 
     
    156151                this._dataLoading = false; 
    157152                this._previousLoadDataReq.box=null; 
    158                 GEvent.trigger( this, "dataloadfailed", 600, e ); 
     153                google.maps.Event.trigger( this, "dataloadfailed", 600, e ); 
    159154        } 
    160155}, 
     
    168163                { 
    169164                        this._previousLoadDataReq.box=null; 
    170                         GEvent.trigger( this, "dataloadfailed", responseCode, null ); 
     165                        google.maps.Event.trigger( this, "dataloadfailed", responseCode, null ); 
    171166                } 
    172167                else 
     
    178173 
    179174                        this._previousLoadDataReq.resultBounds = resp.bounds; 
    180                         if (document.is_debug && resp.debug) GLog.write( resp.debug ); 
    181                         GEvent.trigger( this, "dataloaded", resp ); 
     175                        if (document.is_debug && resp.debug) google.maps.Log.write( resp.debug ); 
     176                        google.maps.Event.trigger( this, "dataloaded", resp ); 
    182177                } 
    183178                catch (e)       { 
    184179                        this._previousLoadDataReq.box=null; 
    185                         GEvent.trigger( this, "dataloadfailed", responseCode, e ); 
     180                        google.maps.Event.trigger( this, "dataloadfailed", responseCode, e ); 
    186181                        var s = e.message; 
    187182                        s += '\n' + data.substr(0,1000); 
  • extensions/rv_gmaps/trunk/template/map.tpl

    r6609 r6651  
    2424<script src="{$PLUGIN_ROOT_URL}/template/page_linker.js?v={$RVM_PLUGIN_VERSION}" type="text/javascript"></script> 
    2525 
    26 <script src="{$PLUGIN_ROOT_URL}/template/windows_13/javascripts/prototype.js" type="text/javascript"></script> 
     26{* <script src="{$PLUGIN_ROOT_URL}/template/windows_13/javascripts/prototype.js" type="text/javascript"></script> *} 
     27<script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js" type="text/javascript"></script> 
    2728<link href="{$PLUGIN_ROOT_URL}/template/windows_13/themes/default.css" rel="stylesheet" type="text/css" /> 
    2829<link href="{$PLUGIN_ROOT_URL}/template/windows_13/themes/alphacube.css" rel="stylesheet" type="text/css" /> 
  • extensions/rv_gmaps/trunk/template/page_linker.js

    r3447 r6651  
    66  PageLinker.url2Map( map ); 
    77   
    8   GEvent.bind( this._map, "maptypechanged", this, this._regenerateUrl ); 
    9   GEvent.bind( this._map, "moveend", this, this._regenerateUrl ); 
     8  google.maps.Event.bind( this._map, "maptypechanged", this, this._regenerateUrl ); 
     9  google.maps.Event.bind( this._map, "moveend", this, this._regenerateUrl ); 
    1010  if ( this._map.isLoaded() ) 
    1111    this._regenerateUrl(); 
     
    7070    if (ll.length==2) 
    7171    { 
    72       var center = new GLatLng( ll[0], ll[1] ); 
     72      var center = new google.maps.LatLng( ll[0], ll[1] ); 
    7373      map.setCenter( center, zoom, mapType ); 
    7474    } 
  • extensions/rv_gmaps/trunk/template/picture_map_content.tpl

    r6245 r6651  
    11{html_head} 
    22<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key={$GMAPS_API_KEY}&amp;hl={$lang_info.code}" type="text/javascript"></script> 
    3 <script src="{$PLUGIN_ROOT_URL}/template/windows_13/javascripts/prototype.js" type="text/javascript"></script> 
     3{* <script src="{$PLUGIN_ROOT_URL}/template/windows_13/javascripts/prototype.js" type="text/javascript"></script> *} 
     4<script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js" type="text/javascript"></script> 
    45<script src="{$PLUGIN_ROOT_URL}/template/windows_13/javascripts/window.js" type="text/javascript" defer="defer"></script> 
    56<link href="{$PLUGIN_ROOT_URL}/template/windows_13/themes/default.css" rel="stylesheet" type="text/css"> 
     
    4041function onLoad() 
    4142{ 
    42   if (!GBrowserIsCompatible()) 
    43     return; 
     43        if (!GBrowserIsCompatible()) 
     44                return; 
    4445 
    45   var mapElement = document.getElementById("map"); 
    46   var map = new GMap2( mapElement ); 
    47    
    48   map.addControl(new GLargeMapControl()); 
    49   map.addControl(new GMapTypeControl()); 
    50   map.addControl(new GScaleControl()); 
    51 {/literal}{if isset($coordinates)} 
    52   var coord = new GLatLng( {$coordinates.LAT}, {$coordinates.LON} ); 
    53   map.setCenter( coord, 12 ); 
    54   var marker = new GMarker(coord); 
    55   map.addOverlay(marker); 
    56 {/if}{literal} 
    57   if ( !map.isLoaded() ) 
    58     map.setCenter( new GLatLng(0,0), 2); 
    59   try { 
    60     // the overview must be added after setting map center 
    61     var ovcontrol = new GOverviewMapControl(new GSize(165,165)); 
     46        var mapElement = document.getElementById("map"); 
     47        var map = new GMap2( mapElement ); 
     48 
     49        map.addControl(new GLargeMapControl()); 
     50        map.addControl(new GMapTypeControl()); 
     51        map.addControl(new GScaleControl()); 
     52        {/literal}{if isset($coordinates)} 
     53        var coord = new google.maps.LatLng( {$coordinates.LAT}, {$coordinates.LON} ); 
     54        map.setCenter( coord, 12 ); 
     55        var marker = new google.maps.Marker(coord); 
     56        map.addOverlay(marker); 
     57        {/if}{literal} 
     58        if ( !map.isLoaded() ) 
     59                map.setCenter( new google.maps.LatLng(0,0), 2); 
     60        try { 
     61                // the overview must be added after setting map center 
     62                var ovcontrol = new GOverviewMapControl(new GSize(165,165)); 
    6263                map.addControl(ovcontrol); 
    6364                var ov_map = ovcontrol.getOverviewMap(); 
    64                 GEvent.addListener(map, 'maptypechanged', function(){ 
     65                google.maps.Event.addListener(map, 'maptypechanged', function(){ 
    6566                        ov_map.setMapType(G_NORMAL_MAP); 
    6667                }); 
    6768  } 
    68   catch(e){ alert( e.message ); } 
    69    
    70   map.enableDoubleClickZoom(); 
     69        catch(e){ alert( e.message ); } 
     70 
     71        map.enableDoubleClickZoom(); 
    7172} 
    7273 
    7374function blowupUrl(theUrl) 
    7475{ 
    75   var win = new Window({ 
    76     title: document.title, 
    77     url: theUrl, 
    78     classname: "alphacube", 
    79     left: 0, top: 0, 
    80     width:"640", height:"480", 
    81     minimizable: false, 
    82     maximizable: false, 
    83     draggable: false, 
    84     resizable: false, 
    85     destroyOnClose: true, 
    86     hideEffect: Element.hide, 
    87     showEffectOptions: {duration:1.5} 
    88   }); 
     76        var win = new Window({ 
     77                title: document.title, 
     78                url: theUrl, 
     79                classname: "alphacube", 
     80                left: 0, top: 0, 
     81                width:"640", height:"480", 
     82                minimizable: false, 
     83                maximizable: false, 
     84                draggable: false, 
     85                resizable: false, 
     86                destroyOnClose: true, 
     87                hideEffect: Element.hide, 
     88                showEffectOptions: {duration:1.5} 
     89        }); 
    8990 
    90   win.setConstraint(true, {top:20, left:20, bottom:30, right:20} ); 
    91   win.maximize(); 
    92   win.showCenter(true, 20, 20); 
    93   return false; 
     91        win.setConstraint(true, {top:20, left:20, bottom:30, right:20} ); 
     92        win.maximize(); 
     93        win.showCenter(true, 20, 20); 
     94        return false; 
    9495} 
    9596 
  • extensions/rv_gmaps/trunk/template/windows_13/javascripts/prototype.js

    r3447 r6651  
    1 /*  Prototype JavaScript framework, version 1.6.0.2 
    2  *  (c) 2005-2008 Sam Stephenson 
     1/*  Prototype JavaScript framework, version 1.6.1 
     2 *  (c) 2005-2009 Sam Stephenson 
    33 * 
    44 *  Prototype is freely distributable under the terms of an MIT-style license. 
     
    88 
    99var 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   }, 
     10  Version: '1.6.1', 
     11 
     12  Browser: (function(){ 
     13    var ua = navigator.userAgent; 
     14    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; 
     15    return { 
     16      IE:             !!window.attachEvent && !isOpera, 
     17      Opera:          isOpera, 
     18      WebKit:         ua.indexOf('AppleWebKit/') > -1, 
     19      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, 
     20      MobileSafari:   /Apple.*Mobile.*Safari/.test(ua) 
     21    } 
     22  })(), 
    1923 
    2024  BrowserFeatures: { 
    2125    XPath: !!document.evaluate, 
    22     ElementExtensions: !!window.HTMLElement, 
    23     SpecificElementExtensions: 
    24       document.createElement('div').__proto__ && 
    25       document.createElement('div').__proto__ !== 
    26         document.createElement('form').__proto__ 
     26    SelectorsAPI: !!document.querySelector, 
     27    ElementExtensions: (function() { 
     28      var constructor = window.Element || window.HTMLElement; 
     29      return !!(constructor && constructor.prototype); 
     30    })(), 
     31    SpecificElementExtensions: (function() { 
     32      if (typeof window.HTMLDivElement !== 'undefined') 
     33        return true; 
     34 
     35      var div = document.createElement('div'); 
     36      var form = document.createElement('form'); 
     37      var isSupported = false; 
     38 
     39      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { 
     40        isSupported = true; 
     41      } 
     42 
     43      div = form = null; 
     44 
     45      return isSupported; 
     46    })() 
    2747  }, 
    2848 
     
    3858 
    3959 
     60var Abstract = { }; 
     61 
     62 
     63var Try = { 
     64  these: function() { 
     65    var returnValue; 
     66 
     67    for (var i = 0, length = arguments.length; i < length; i++) { 
     68      var lambda = arguments[i]; 
     69      try { 
     70        returnValue = lambda(); 
     71        break; 
     72      } catch (e) { } 
     73    } 
     74 
     75    return returnValue; 
     76  } 
     77}; 
     78 
    4079/* Based on Alex Arnell's inheritance implementation. */ 
    41 var Class = { 
    42   create: function() { 
     80 
     81var Class = (function() { 
     82  function subclass() {}; 
     83  function create() { 
    4384    var parent = null, properties = $A(arguments); 
    4485    if (Object.isFunction(properties[0])) 
     
    5495 
    5596    if (parent) { 
    56       var subclass = function() { }; 
    5797      subclass.prototype = parent.prototype; 
    5898      klass.prototype = new subclass; 
     
    67107 
    68108    klass.prototype.constructor = klass; 
    69  
    70109    return klass; 
    71110  } 
    72 }; 
    73  
    74 Class.Methods = { 
    75   addMethods: function(source) { 
     111 
     112  function addMethods(source) { 
    76113    var ancestor   = this.superclass && this.superclass.prototype; 
    77114    var properties = Object.keys(source); 
    78115 
    79     if (!Object.keys({ toString: true }).length) 
    80       properties.push("toString", "valueOf"); 
     116    if (!Object.keys({ toString: true }).length) { 
     117      if (source.toString != Object.prototype.toString) 
     118        properties.push("toString"); 
     119      if (source.valueOf != Object.prototype.valueOf) 
     120        properties.push("valueOf"); 
     121    } 
    81122 
    82123    for (var i = 0, length = properties.length; i < length; i++) { 
     
    84125      if (ancestor && Object.isFunction(value) && 
    85126          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         }); 
     127        var method = value; 
     128        value = (function(m) { 
     129          return function() { return ancestor[m].apply(this, arguments); }; 
     130        })(property).wrap(method); 
     131 
     132        value.valueOf = method.valueOf.bind(method); 
     133        value.toString = method.toString.bind(method); 
    92134      } 
    93135      this.prototype[property] = value; 
     
    96138    return this; 
    97139  } 
    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) { 
     140 
     141  return { 
     142    create: create, 
     143    Methods: { 
     144      addMethods: addMethods 
     145    } 
     146  }; 
     147})(); 
     148(function() { 
     149 
     150  var _toString = Object.prototype.toString; 
     151 
     152  function extend(destination, source) { 
     153    for (var property in source) 
     154      destination[property] = source[property]; 
     155    return destination; 
     156  } 
     157 
     158  function inspect(object) { 
    110159    try { 
    111       if (Object.isUndefined(object)) return 'undefined'; 
     160      if (isUndefined(object)) return 'undefined'; 
    112161      if (object === null) return 'null'; 
    113162      return object.inspect ? object.inspect() : String(object); 
     
    116165      throw e; 
    117166    } 
    118   }, 
    119  
    120   toJSON: function(object) { 
     167  } 
     168 
     169  function toJSON(object) { 
    121170    var type = typeof object; 
    122171    switch (type) { 
     
    129178    if (object === null) return 'null'; 
    130179    if (object.toJSON) return object.toJSON(); 
    131     if (Object.isElement(object)) return; 
     180    if (isElement(object)) return; 
    132181 
    133182    var results = []; 
    134183    for (var property in object) { 
    135       var value = Object.toJSON(object[property]); 
    136       if (!Object.isUndefined(value)) 
     184      var value = toJSON(object[property]); 
     185      if (!isUndefined(value)) 
    137186        results.push(property.toJSON() + ': ' + value); 
    138187    } 
    139188 
    140189    return '{' + results.join(', ') + '}'; 
    141   }, 
    142  
    143   toQueryString: function(object) { 
     190  } 
     191 
     192  function toQueryString(object) { 
    144193    return $H(object).toQueryString(); 
    145   }, 
    146  
    147   toHTML: function(object) { 
     194  } 
     195 
     196  function toHTML(object) { 
    148197    return object && object.toHTML ? object.toHTML() : String.interpret(object); 
    149   }, 
    150  
    151   keys: function(object) { 
    152     var keys = []; 
     198  } 
     199 
     200  function keys(object) { 
     201    var results = []; 
    153202    for (var property in object) 
    154       keys.push(property); 
    155     return keys; 
    156   }, 
    157  
    158   values: function(object) { 
    159     var values = []; 
     203      results.push(property); 
     204    return results; 
     205  } 
     206 
     207  function values(object) { 
     208    var results = []; 
    160209    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) { 
     210      results.push(object[property]); 
     211    return results; 
     212  } 
     213 
     214  function clone(object) { 
     215    return extend({ }, object); 
     216  } 
     217 
     218  function isElement(object) { 
     219    return !!(object && object.nodeType == 1); 
     220  } 
     221 
     222  function isArray(object) { 
     223    return _toString.call(object) == "[object Array]"; 
     224  } 
     225 
     226 
     227  function isHash(object) { 
    179228    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"); 
     229  } 
     230 
     231  function isFunction(object) { 
     232    return typeof object === "function"; 
     233  } 
     234 
     235  function isString(object) { 
     236    return _toString.call(object) == "[object String]"; 
     237  } 
     238 
     239  function isNumber(object) { 
     240    return _toString.call(object) == "[object Number]"; 
     241  } 
     242 
     243  function isUndefined(object) { 
     244    return typeof object === "undefined"; 
     245  } 
     246 
     247  extend(Object, { 
     248    extend:        extend, 
     249    inspect:       inspect, 
     250    toJSON:        toJSON, 
     251    toQueryString: toQueryString, 
     252    toHTML:        toHTML, 
     253    keys:          keys, 
     254    values:        values, 
     255    clone:         clone, 
     256    isElement:     isElement, 
     257    isArray:       isArray, 
     258    isHash:        isHash, 
     259    isFunction:    isFunction, 
     260    isString:      isString, 
     261    isNumber:      isNumber, 
     262    isUndefined:   isUndefined 
     263  }); 
     264})(); 
     265Object.extend(Function.prototype, (function() { 
     266  var slice = Array.prototype.slice; 
     267 
     268  function update(array, args) { 
     269    var arrayLength = array.length, length = args.length; 
     270    while (length--) array[arrayLength + length] = args[length]; 
     271    return array; 
     272  } 
     273 
     274  function merge(array, args) { 
     275    array = slice.call(array, 0); 
     276    return update(array, args); 
     277  } 
     278 
     279  function argumentNames() { 
     280    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] 
     281      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') 
     282      .replace(/\s+/g, '').split(','); 
    202283    return names.length == 1 && !names[0] ? [] : names; 
    203   }, 
    204  
    205   bind: function() { 
     284  } 
     285 
     286  function bind(context) { 
    206287    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; 
    207     var __method = this, args = $A(arguments), object = args.shift(); 
     288    var __method = this, args = slice.call(arguments, 1); 
    208289    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(); 
     290      var a = merge(args, arguments); 
     291      return __method.apply(context, a); 
     292    } 
     293  } 
     294 
     295  function bindAsEventListener(context) { 
     296    var __method = this, args = slice.call(arguments, 1); 
    215297    return function(event) { 
    216       return __method.apply(object, [event || window.event].concat(args)); 
    217     } 
    218   }, 
    219  
    220   curry: function() { 
     298      var a = update([event || window.event], args); 
     299      return __method.apply(context, a); 
     300    } 
     301  } 
     302 
     303  function curry() { 
    221304    if (!arguments.length) return this; 
    222     var __method = this, args = $A(arguments); 
     305    var __method = this, args = slice.call(arguments, 0); 
    223306    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; 
     307      var a = merge(args, arguments); 
     308      return __method.apply(this, a); 
     309    } 
     310  } 
     311 
     312  function delay(timeout) { 
     313    var __method = this, args = slice.call(arguments, 1); 
     314    timeout = timeout * 1000 
    230315    return window.setTimeout(function() { 
    231316      return __method.apply(__method, args); 
    232317    }, timeout); 
    233   }, 
    234  
    235   wrap: function(wrapper) { 
     318  } 
     319 
     320  function defer() { 
     321    var args = update([0.01], arguments); 
     322    return this.delay.apply(this, args); 
     323  } 
     324 
     325  function wrap(wrapper) { 
    236326    var __method = this; 
    237327    return function() { 
    238       return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); 
    239     } 
    240   }, 
    241  
    242   methodize: function() { 
     328      var a = update([__method.bind(this)], arguments); 
     329      return wrapper.apply(this, a); 
     330    } 
     331  } 
     332 
     333  function methodize() { 
    243334    if (this._methodized) return this._methodized; 
    244335    var __method = this; 
    245336    return this._methodized = function() { 
    246       return __method.apply(null, [this].concat($A(arguments))); 
     337      var a = update([this], arguments); 
     338      return __method.apply(null, a); 
    247339    }; 
    248340  } 
    249 }); 
    250  
    251 Function.prototype.defer = Function.prototype.delay.curry(0.01); 
     341 
     342  return { 
     343    argumentNames:       argumentNames, 
     344    bind:                bind, 
     345    bindAsEventListener: bindAsEventListener, 
     346    curry:               curry, 
     347    delay:               delay, 
     348    defer:               defer, 
     349    wrap:                wrap, 
     350    methodize:           methodize 
     351  } 
     352})()); 
     353 
    252354 
    253355Date.prototype.toJSON = function() { 
     
    260362}; 
    261363 
    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 }; 
    277364 
    278365RegExp.prototype.match = RegExp.prototype.test; 
     
    281368  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); 
    282369}; 
    283  
    284 /*--------------------------------------------------------------------------*/ 
    285  
    286370var PeriodicalExecuter = Class.create({ 
    287371  initialize: function(callback, frequency) { 
     
    312396        this.currentlyExecuting = true; 
    313397        this.execute(); 
    314       } finally { 
    315398        this.currentlyExecuting = false; 
     399      } catch(e) { 
     400        this.currentlyExecuting = false; 
     401        throw e; 
    316402      } 
    317403    } 
     
    332418}); 
    333419 
    334 Object.extend(String.prototype, { 
    335   gsub: function(pattern, replacement) { 
     420Object.extend(String.prototype, (function() { 
     421 
     422  function prepareReplacement(replacement) { 
     423    if (Object.isFunction(replacement)) return replacement; 
     424    var template = new Template(replacement); 
     425    return function(match) { return template.evaluate(match) }; 
     426  } 
     427 
     428  function gsub(pattern, replacement) { 
    336429    var result = '', source = this, match; 
    337     replacement = arguments.callee.prepareReplacement(replacement); 
     430    replacement = prepareReplacement(replacement); 
     431 
     432    if (Object.isString(pattern)) 
     433      pattern = RegExp.escape(pattern); 
     434 
     435    if (!(pattern.length || pattern.source)) { 
     436      replacement = replacement(''); 
     437      return replacement + source.split('').join(replacement) + replacement; 
     438    } 
    338439 
    339440    while (source.length > 0) { 
     
    347448    } 
    348449    return result; 
    349   }, 
    350  
    351   sub: function(pattern, replacement, count) { 
    352     replacement = this.gsub.prepareReplacement(replacement); 
     450  } 
     451 
     452  function sub(pattern, replacement, count) { 
     453    replacement = prepareReplacement(replacement); 
    353454    count = Object.isUndefined(count) ? 1 : count; 
    354455 
     
    357458      return replacement(match); 
    358459    }); 
    359   }, 
    360  
    361   scan: function(pattern, iterator) { 
     460  } 
     461 
     462  function scan(pattern, iterator) { 
    362463    this.gsub(pattern, iterator); 
    363464    return String(this); 
    364   }, 
    365  
    366   truncate: function(length, truncation) { 
     465  } 
     466 
     467  function truncate(length, truncation) { 
    367468    length = length || 30; 
    368469    truncation = Object.isUndefined(truncation) ? '...' : truncation; 
    369470    return this.length > length ? 
    370471      this.slice(0, length - truncation.length) + truncation : String(this); 
    371   }, 
    372  
    373   strip: function() { 
     472  } 
     473 
     474  function strip() { 
    374475    return this.replace(/^\s+/, '').replace(/\s+$/, ''); 
    375   }, 
    376  
    377   stripTags: function() { 
    378     return this.replace(/<\/?[^>]+>/gi, ''); 
    379   }, 
    380  
    381   stripScripts: function() { 
     476  } 
     477 
     478  function stripTags() { 
     479    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); 
     480  } 
     481 
     482  function stripScripts() { 
    382483    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); 
    383   }, 
    384  
    385   extractScripts: function() { 
     484  } 
     485 
     486  function extractScripts() { 
    386487    var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); 
    387488    var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); 
     
    389490      return (scriptTag.match(matchOne) || ['', ''])[1]; 
    390491    }); 
    391   }, 
    392  
    393   evalScripts: function() { 
     492  } 
     493 
     494  function evalScripts() { 
    394495    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) { 
     496  } 
     497 
     498  function escapeHTML() { 
     499    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); 
     500  } 
     501 
     502  function unescapeHTML() { 
     503    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&'); 
     504  } 
     505 
     506 
     507  function toQueryParams(separator) { 
    412508    var match = this.strip().match(/([^?#]*)(#.*)?$/); 
    413509    if (!match) return { }; 
     
    427523      return hash; 
    428524    }); 
    429   }, 
    430  
    431   toArray: function() { 
     525  } 
     526 
     527  function toArray() { 
    432528    return this.split(''); 
    433   }, 
    434  
    435   succ: function() { 
     529  } 
     530 
     531  function succ() { 
    436532    return this.slice(0, this.length - 1) + 
    437533      String.fromCharCode(this.charCodeAt(this.length - 1) + 1); 
    438   }, 
    439  
    440   times: function(count) { 
     534  } 
     535 
     536  function times(count) { 
    441537    return count < 1 ? '' : new Array(count + 1).join(this); 
    442   }, 
    443  
    444   camelize: function() { 
     538  } 
     539 
     540  function camelize() { 
    445541    var parts = this.split('-'), len = parts.length; 
    446542    if (len == 1) return parts[0]; 
     
    454550 
    455551    return camelized; 
    456   }, 
    457  
    458   capitalize: function() { 
     552  } 
     553 
     554  function capitalize() { 
    459555    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); 
     556  } 
     557 
     558  function underscore() { 
     559    return this.replace(/::/g, '/') 
     560               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') 
     561               .replace(/([a-z\d])([A-Z])/g, '$1_$2') 
     562               .replace(/-/g, '_') 
     563               .toLowerCase(); 
     564  } 
     565 
     566  function dasherize() { 
     567    return this.replace(/_/g, '-'); 
     568  } 
     569 
     570  function inspect(useDoubleQuotes) { 
     571    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { 
     572      if (character in String.specialChar) { 
     573        return String.specialChar[character]; 
     574      } 
     575      return '\\u00' + character.charCodeAt().toPaddedString(2, 16); 
    474576    }); 
    475577    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; 
    476578    return "'" + escapedString.replace(/'/g, '\\\'') + "'"; 
    477   }, 
    478  
    479   toJSON: function() { 
     579  } 
     580 
     581  function toJSON() { 
    480582    return this.inspect(true); 
    481   }, 
    482  
    483   unfilterJSON: function(filter) { 
    484     return this.sub(filter || Prototype.JSONFilter, '#{1}'); 
    485   }, 
    486  
    487   isJSON: function() { 
     583  } 
     584 
     585  function unfilterJSON(filter) { 
     586    return this.replace(filter || Prototype.JSONFilter, '$1'); 
     587  } 
     588 
     589  function isJSON() { 
    488590    var str = this; 
    489591    if (str.blank()) return false; 
    490592    str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); 
    491593    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); 
    492   }, 
    493  
    494   evalJSON: function(sanitize) { 
     594  } 
     595 
     596  function evalJSON(sanitize) { 
    495597    var json = this.unfilterJSON(); 
    496598    try { 
     
    498600    } catch (e) { } 
    499601    throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); 
    500   }, 
    501  
    502   include: function(pattern) { 
     602  } 
     603 
     604  function include(pattern) { 
    503605    return this.indexOf(pattern) > -1; 
    504   }, 
    505  
    506   startsWith: function(pattern) { 
     606  } 
     607 
     608  function startsWith(pattern) { 
    507609    return this.indexOf(pattern) === 0; 
    508   }, 
    509  
    510   endsWith: function(pattern) { 
     610  } 
     611 
     612  function endsWith(pattern) { 
    511613    var d = this.length - pattern.length; 
    512614    return d >= 0 && this.lastIndexOf(pattern) === d; 
    513   }, 
    514  
    515   empty: function() { 
     615  } 
     616 
     617  function empty() { 
    516618    return this == ''; 
    517   }, 
    518  
    519   blank: function() { 
     619  } 
     620 
     621  function blank() { 
    520622    return /^\s*$/.test(this); 
    521   }, 
    522  
    523   interpolate: function(object, pattern) { 
     623  } 
     624 
     625  function interpolate(object, pattern) { 
    524626    return new Template(this, pattern).evaluate(object); 
    525627  } 
    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); 
     628 
     629  return { 
     630    gsub:           gsub, 
     631    sub:            sub, 
     632    scan:           scan, 
     633    truncate:       truncate, 
     634    strip:          String.prototype.trim ? String.prototype.trim : strip, 
     635    stripTags:      stripTags, 
     636    stripScripts:   stripScripts, 
     637    extractScripts: extractScripts, 
     638    evalScripts:    evalScripts, 
     639    escapeHTML:     escapeHTML, 
     640    unescapeHTML:   unescapeHTML, 
     641    toQueryParams:  toQueryParams, 
     642    parseQuery:     toQueryParams, 
     643    toArray:        toArray, 
     644    succ:           succ, 
     645    times:          times, 
     646    camelize:       camelize, 
     647    capitalize:     capitalize, 
     648    underscore:     underscore, 
     649    dasherize:      dasherize, 
     650    inspect:        inspect, 
     651    toJSON:         toJSON, 
     652    unfilterJSON:   unfilterJSON, 
     653    isJSON:         isJSON, 
     654    evalJSON:       evalJSON, 
     655    include:        include, 
     656    startsWith:     startsWith, 
     657    endsWith:       endsWith, 
     658    empty:          empty, 
     659    blank:          blank, 
     660    interpolate:    interpolate 
     661  }; 
     662})()); 
    551663 
    552664var Template = Class.create({ 
     
    557669 
    558670  evaluate: function(object) { 
    559     if (Object.isFunction(object.toTemplateReplacements)) 
     671    if (object && Object.isFunction(object.toTemplateReplacements)) 
    560672      object = object.toTemplateReplacements(); 
    561673 
    562674    return this.template.gsub(this.pattern, function(match) { 
    563       if (object == null) return ''; 
     675      if (object == null) return (match[1] + ''); 
    564676 
    565677      var before = match[1] || ''; 
     
    572684 
    573685      while (match != null) { 
    574         var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; 
     686        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1]; 
    575687        ctx = ctx[comp]; 
    576688        if (null == ctx || '' == match[3]) break; 
     
    587699var $break = { }; 
    588700 
    589 var Enumerable = { 
    590   each: function(iterator, context) { 
     701var Enumerable = (function() { 
     702  function each(iterator, context) { 
    591703    var index = 0; 
    592     iterator = iterator.bind(context); 
    593704    try { 
    594705      this._each(function(value) { 
    595         iterator(value, index++); 
     706        iterator.call(context, value, index++); 
    596707      }); 
    597708    } catch (e) { 
     
    599710    } 
    600711    return this; 
    601   }, 
    602  
    603   eachSlice: function(number, iterator, context) { 
    604     iterator = iterator ? iterator.bind(context) : Prototype.K; 
     712  } 
     713 
     714  function eachSlice(number, iterator, context) { 
    605715    var index = -number, slices = [], array = this.toArray(); 
     716    if (number < 1) return array; 
    606717    while ((index += number) < array.length) 
    607718      slices.push(array.slice(index, index+number)); 
    608719    return slices.collect(iterator, context); 
    609   }, 
    610  
    611   all: function(iterator, context) { 
    612     iterator = iterator ? iterator.bind(context) : Prototype.K; 
     720  } 
     721 
     722  function all(iterator, context) { 
     723    iterator = iterator || Prototype.K; 
    613724    var result = true; 
    614725    this.each(function(value, index) { 
    615       result = result && !!iterator(value, index); 
     726      result = result && !!iterator.call(context, value, index); 
    616727      if (!result) throw $break; 
    617728    }); 
    618729    return result; 
    619   }, 
    620  
    621   any: function(iterator, context) { 
    622     iterator = iterator ? iterator.bind(context) : Prototype.K; 
     730  } 
     731 
     732  function any(iterator, context) { 
     733    iterator = iterator || Prototype.K; 
    623734    var result = false; 
    624735    this.each(function(value, index) { 
    625       if (result = !!iterator(value, index)) 
     736      if (result = !!iterator.call(context, value, index)) 
    626737        throw $break; 
    627738    }); 
    628739    return result; 
    629   }, 
    630  
    631   collect: function(iterator, context) { 
    632     iterator = iterator ? iterator.bind(context) : Prototype.K; 
     740  } 
     741 
     742  function collect(iterator, context) { 
     743    iterator = iterator || Prototype.K; 
    633744    var results = []; 
    634745    this.each(function(value, index) { 
    635       results.push(iterator(value, index)); 
     746      results.push(iterator.call(context, value, index)); 
    636747    }); 
    637748    return results; 
    638   }, 
    639  
    640   detect: function(iterator, context) { 
    641     iterator = iterator.bind(context); 
     749  } 
     750 
     751  function detect(iterator, context) { 
    642752    var result; 
    643753    this.each(function(value, index) { 
    644       if (iterator(value, index)) { 
     754      if (iterator.call(context, value, index)) { 
    645755        result = value; 
    646756        throw $break; 
     
    648758    }); 
    649759    return result; 
    650   }, 
    651  
    652   findAll: function(iterator, context) { 
    653     iterator = iterator.bind(context); 
     760  } 
     761 
     762  function findAll(iterator, context) { 
    654763    var results = []; 
    655764    this.each(function(value, index) { 
    656       if (iterator(value, index)) 
     765      if (iterator.call(context, value, index)) 
    657766        results.push(value); 
    658767    }); 
    659768    return results; 
    660   }, 
    661  
    662   grep: function(filter, iterator, context) { 
    663     iterator = iterator ? iterator.bind(context) : Prototype.K; 
     769  } 
     770 
     771  function grep(filter, iterator, context) { 
     772    iterator = iterator || Prototype.K; 
    664773    var results = []; 
    665774 
    666775    if (Object.isString(filter)) 
    667       filter = new RegExp(filter); 
     776      filter = new RegExp(RegExp.escape(filter)); 
    668777 
    669778    this.each(function(value, index) { 
    670779      if (filter.match(value)) 
    671         results.push(iterator(value, index)); 
     780        results.push(iterator.call(context, value, index)); 
    672781    }); 
    673782    return results; 
    674   }, 
    675  
    676   include: function(object) { 
     783  } 
     784 
     785  function include(object) { 
    677786    if (Object.isFunction(this.indexOf)) 
    678787      if (this.indexOf(object) != -1) return true; 
     
    686795    }); 
    687796    return found; 
    688   }, 
    689  
    690   inGroupsOf: function(number, fillWith) { 
     797  } 
     798 
     799  function inGroupsOf(number, fillWith) { 
    691800    fillWith = Object.isUndefined(fillWith) ? null : fillWith; 
    692801    return this.eachSlice(number, function(slice) { 
     
    694803      return slice; 
    695804    }); 
    696   }, 
    697  
    698   inject: function(memo, iterator, context) { 
    699     iterator = iterator.bind(context); 
     805  } 
     806 
     807  function inject(memo, iterator, context) { 
    700808    this.each(function(value, index) { 
    701       memo = iterator(memo, value, index); 
     809      memo = iterator.call(context, memo, value, index); 
    702810    }); 
    703811    return memo; 
    704   }, 
    705  
    706   invoke: function(method) { 
     812  } 
     813 
     814  function invoke(method) { 
    707815    var args = $A(arguments).slice(1); 
    708816    return this.map(function(value) { 
    709817      return value[method].apply(value, args); 
    710818    }); 
    711   }, 
    712  
    713   max: function(iterator, context) { 
    714     iterator = iterator ? iterator.bind(context) : Prototype.K; 
     819  } 
     820 
     821  function max(iterator, context) { 
     822    iterator = iterator || Prototype.K; 
    715823    var result; 
    716824    this.each(function(value, index) { 
    717       value = iterator(value, index); 
     825      value = iterator.call(context, value, index); 
    718826      if (result == null || value >= result) 
    719827        result = value; 
    720828    }); 
    721829    return result; 
    722   }, 
    723  
    724   min: function(iterator, context) { 
    725     iterator = iterator ? iterator.bind(context) : Prototype.K; 
     830  } 
     831 
     832  function min(iterator, context) { 
     833    iterator = iterator || Prototype.K; 
    726834    var result; 
    727835    this.each(function(value, index) { 
    728       value = iterator(value, index); 
     836      value = iterator.call(context, value, index); 
    729837      if (result == null || value < result) 
    730838        result = value; 
    731839    }); 
    732840    return result; 
    733   }, 
    734  
    735   partition: function(iterator, context) { 
    736     iterator = iterator ? iterator.bind(context) : Prototype.K; 
     841  } 
     842 
     843  function partition(iterator, context) { 
     844    iterator = iterator || Prototype.K; 
    737845    var trues = [], falses = []; 
    738846    this.each(function(value, index) { 
    739       (iterator(value, index) ? 
     847      (iterator.call(context, value, index) ? 
    740848        trues : falses).push(value); 
    741849    }); 
    742850    return [trues, falses]; 
    743   }, 
    744  
    745   pluck: function(property) { 
     851  } 
     852 
     853  function pluck(property) { 
    746854    var results = []; 
    747855    this.each(function(value) { 
     
    749857    }); 
    750858    return results; 
    751   }, 
    752  
    753   reject: function(iterator, context) { 
    754     iterator = iterator.bind(context); 
     859  } 
     860 
     861  function reject(iterator, context) { 
    755862    var results = []; 
    756863    this.each(function(value, index) { 
    757       if (!iterator(value, index)) 
     864      if (!iterator.call(context, value, index)) 
    758865        results.push(value); 
    759866    }); 
    760867    return results; 
    761   }, 
    762  
    763   sortBy: function(iterator, context) { 
    764     iterator = iterator.bind(context); 
     868  } 
     869 
     870  function sortBy(iterator, context) { 
    765871    return this.map(function(value, index) { 
    766       return {value: value, criteria: iterator(value, index)}; 
     872      return { 
     873        value: value, 
     874        criteria: iterator.call(context, value, index) 
     875      }; 
    767876    }).sort(function(left, right) { 
    768877      var a = left.criteria, b = right.criteria; 
    769878      return a < b ? -1 : a > b ? 1 : 0; 
    770879    }).pluck('value'); 
    771   }, 
    772  
    773   toArray: function() { 
     880  } 
     881 
     882  function toArray() { 
    774883    return this.map(); 
    775   }, 
    776  
    777   zip: function() { 
     884  } 
     885 
     886  function zip() { 
    778887    var iterator = Prototype.K, args = $A(arguments); 
    779888    if (Object.isFunction(args.last())) 
     
    784893      return iterator(collections.pluck(index)); 
    785894    }); 
    786   }, 
    787  
    788   size: function() { 
     895  } 
     896 
     897  function size() { 
    789898    return this.toArray().length; 
    790   }, 
    791  
    792   inspect: function() { 
     899  } 
     900 
     901  function inspect() { 
    793902    return '#<Enumerable:' + this.toArray().inspect() + '>'; 
    794903  } 
    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 }); 
     904 
     905 
     906 
     907 
     908 
     909 
     910 
     911 
     912 
     913  return { 
     914    each:       each, 
     915    eachSlice:  eachSlice, 
     916    all:        all, 
     917    every:      all, 
     918    any:        any, 
     919    some:       any, 
     920    collect:    collect, 
     921    map:        collect, 
     922    detect:     detect, 
     923    findAll:    findAll, 
     924    select:     findAll, 
     925    filter:     findAll, 
     926    grep:       grep, 
     927    include:    include, 
     928    member:     include, 
     929    inGroupsOf: inGroupsOf, 
     930    inject:     inject, 
     931    invoke:     invoke, 
     932    max:        max, 
     933    min:        min, 
     934    partition:  partition, 
     935    pluck:      pluck, 
     936    reject:     reject, 
     937    sortBy:     sortBy, 
     938    toArray:    toArray, 
     939    entries:    toArray, 
     940    zip:        zip, 
     941    size:       size, 
     942    inspect:    inspect, 
     943    find:       detect 
     944  }; 
     945})(); 
    807946function $A(iterable) { 
    808947  if (!iterable) return []; 
    809   if (iterable.toArray) return iterable.toArray(); 
     948  if ('toArray' in Object(iterable)) return iterable.toArray(); 
    810949  var length = iterable.length || 0, results = new Array(length); 
    811950  while (length--) results[length] = iterable[length]; 
     
    813952} 
    814953 
    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   }; 
     954function $w(string) { 
     955  if (!Object.isString(string)) return []; 
     956  string = string.strip(); 
     957  return string ? string.split(/\s+/) : []; 
    824958} 
    825959 
    826960Array.from = $A; 
    827961 
    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) { 
     962 
     963(function() { 
     964  var arrayProto = Array.prototype, 
     965      slice = arrayProto.slice, 
     966      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available 
     967 
     968  function each(iterator) { 
    834969    for (var i = 0, length = this.length; i < length; i++) 
    835970      iterator(this[i]); 
    836   }, 
    837  
    838   clear: function() { 
     971  } 
     972  if (!_each) _each = each; 
     973 
     974  function clear() { 
    839975    this.length = 0; 
    840976    return this; 
    841   }, 
    842  
    843   first: function() { 
     977  } 
     978 
     979  function first() { 
    844980    return this[0]; 
    845   }, 
    846  
    847   last: function() { 
     981  } 
     982 
     983  function last() { 
    848984    return this[this.length - 1]; 
    849   }, 
    850  
    851   compact: function() { 
     985  } 
     986 
     987  function compact() { 
    852988    return this.select(function(value) { 
    853989      return value != null; 
    854990    }); 
    855   }, 
    856  
    857   flatten: function() { 
     991  } 
     992 
     993  function flatten() { 
    858994    return this.inject([], function(array, value) { 
    859       return array.concat(Object.isArray(value) ? 
    860         value.flatten() : [value]); 
     995      if (Object.isArray(value)) 
     996        return array.concat(value.flatten()); 
     997      array.push(value); 
     998      return array; 
    861999    }); 
    862   }, 
    863  
    864   without: function() { 
    865     var values = $A(arguments); 
     1000  } 
     1001 
     1002  function without() { 
     1003    var values = slice.call(arguments, 0); 
    8661004    return this.select(function(value) { 
    8671005      return !values.include(value); 
    8681006    }); 
    869   }, 
    870  
    871   reverse: function(inline) { 
     1007  } 
     1008 
     1009  function reverse(inline) { 
    8721010    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) { 
     1011  } 
     1012 
     1013  function uniq(sorted) { 
    8801014    return this.inject([], function(array, value, index) { 
    8811015      if (0 == index || (sorted ? array.last() != value : !array.include(value))) 
     
    8831017      return array; 
    8841018    }); 
    885   }, 
    886  
    887   intersect: function(array) { 
     1019  } 
     1020 
     1021  function intersect(array) { 
    8881022    return this.uniq().findAll(function(item) { 
    8891023      return array.detect(function(value) { return item === value }); 
    8901024    }); 
    891   }, 
    892  
    893   clone: function() { 
    894     return [].concat(this); 
    895   }, 
    896  
    897   size: function() { 
     1025  } 
     1026 
     1027 
     1028  function clone() { 
     1029    return slice.call(this, 0); 
     1030  } 
     1031 
     1032  function size() { 
    8981033    return this.length; 
    899   }, 
    900  
    901   inspect: function() { 
     1034  } 
     1035 
     1036  function inspect() { 
    9021037    return '[' + this.map(Object.inspect).join(', ') + ']'; 
    903   }, 
    904  
    905   toJSON: function() { 
     1038  } 
     1039 
     1040  function toJSON() { 
    9061041    var results = []; 
    9071042    this.each(function(object) { 
     
    9111046    return '[' + results.join(', ') + ']'; 
    9121047  } 
    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]); 
     1048 
     1049  function indexOf(item, i) { 
     1050    i || (i = 0); 
     1051    var length = this.length; 
     1052    if (i < 0) i = length + i; 
     1053    for (; i < length; i++) 
     1054      if (this[i] === item) return i; 
     1055    return -1; 
     1056  } 
     1057 
     1058  function lastIndexOf(item, i) { 
     1059    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; 
     1060    var n = this.slice(0, i).reverse().indexOf(item); 
     1061    return (n < 0) ? n : i - n - 1; 
     1062  } 
     1063 
     1064  function concat() { 
     1065    var array = slice.call(this, 0), item; 
    9461066    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]); 
     1067      item = arguments[i]; 
     1068      if (Object.isArray(item) && !('callee' in item)) { 
     1069        for (var j = 0, arrayLength = item.length; j < arrayLength; j++) 
     1070          array.push(item[j]); 
    9501071      } else { 
    951         array.push(arguments[i]); 
     1072        array.push(item); 
    9521073      } 
    9531074    } 
    9541075    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 }); 
     1076  } 
     1077 
     1078  Object.extend(arrayProto, Enumerable); 
     1079 
     1080  if (!arrayProto._reverse) 
     1081    arrayProto._reverse = arrayProto.reverse; 
     1082 
     1083  Object.extend(arrayProto, { 
     1084    _each:     _each, 
     1085    clear:     clear, 
     1086    first:     first, 
     1087    last:      last, 
     1088    compact:   compact, 
     1089    flatten:   flatten, 
     1090    without:   without, 
     1091    reverse:   reverse, 
     1092    uniq:      uniq, 
     1093    intersect: intersect, 
     1094    clone:     clone, 
     1095    toArray:   clone, 
     1096    size:      size, 
     1097    inspect:   inspect, 
     1098    toJSON:    toJSON 
     1099  }); 
     1100 
     1101  var CONCAT_ARGUMENTS_BUGGY = (function() { 
     1102    return [].concat(arguments)[0][0] !== 1; 
     1103  })(1,2) 
     1104 
     1105  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; 
     1106 
     1107  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; 
     1108  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; 
     1109})(); 
    9841110function $H(object) { 
    9851111  return new Hash(object); 
     
    9871113 
    9881114var Hash = Class.create(Enumerable, (function() { 
     1115  function initialize(object) { 
     1116    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); 
     1117  } 
     1118 
     1119  function _each(iterator) { 
     1120    for (var key in this._object) { 
     1121      var value = this._object[key], pair = [key, value]; 
     1122      pair.key = key; 
     1123      pair.value = value; 
     1124      iterator(pair); 
     1125    } 
     1126  } 
     1127 
     1128  function set(key, value) { 
     1129    return this._object[key] = value; 
     1130  } 
     1131 
     1132  function get(key) { 
     1133    if (this._object[key] !== Object.prototype[key]) 
     1134      return this._object[key]; 
     1135  } 
     1136 
     1137  function unset(key) { 
     1138    var value = this._object[key]; 
     1139    delete this._object[key]; 
     1140    return value; 
     1141  } 
     1142 
     1143  function toObject() { 
     1144    return Object.clone(this._object); 
     1145  } 
     1146 
     1147  function keys() { 
     1148    return this.pluck('key'); 
     1149  } 
     1150 
     1151  function values() { 
     1152    return this.pluck('value'); 
     1153  } 
     1154 
     1155  function index(value) { 
     1156    var match = this.detect(function(pair) { 
     1157      return pair.value === value; 
     1158    }); 
     1159    return match && match.key; 
     1160  } 
     1161 
     1162  function merge(object) { 
     1163    return this.clone().update(object); 
     1164  } 
     1165 
     1166  function update(object) { 
     1167    return new Hash(object).inject(this, function(result, pair) { 
     1168      result.set(pair.key, pair.value); 
     1169      return result; 
     1170    }); 
     1171  } 
    9891172 
    9901173  function toQueryPair(key, value) { 
     
    9931176  } 
    9941177 
     1178  function toQueryString() { 
     1179    return this.inject([], function(results, pair) { 
     1180      var key = encodeURIComponent(pair.key), values = pair.value; 
     1181 
     1182      if (values && typeof values == 'object') { 
     1183        if (Object.isArray(values)) 
     1184          return results.concat(values.map(toQueryPair.curry(key))); 
     1185      } else results.push(toQueryPair(key, values)); 
     1186      return results; 
     1187    }).join('&'); 
     1188  } 
     1189 
     1190  function inspect() { 
     1191    return '#<Hash:{' + this.map(function(pair) { 
     1192      return pair.map(Object.inspect).join(': '); 
     1193    }).join(', ') + '}>'; 
     1194  } 
     1195 
     1196  function toJSON() { 
     1197    return Object.toJSON(this.toObject()); 
     1198  } 
     1199 
     1200  function clone() { 
     1201    return new Hash(this); 
     1202  } 
     1203 
    9951204  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   } 
     1205    initialize:             initialize, 
     1206    _each:                  _each, 
     1207    set:                    set, 
     1208    get:                    get, 
     1209    unset:                  unset, 
     1210    toObject:               toObject, 
     1211    toTemplateReplacements: toObject, 
     1212    keys:                   keys, 
     1213    values:                 values, 
     1214    index:                  index, 
     1215    merge:                  merge, 
     1216    update:                 update, 
     1217    toQueryString:          toQueryString, 
     1218    inspect:                inspect, 
     1219    toJSON:                 toJSON, 
     1220    clone:                  clone 
     1221  }; 
    10791222})()); 
    10801223 
    1081 Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; 
    10821224Hash.from = $H; 
    1083 var ObjectRange = Class.create(Enumerable, { 
    1084   initialize: function(start, end, exclusive) { 
     1225Object.extend(Number.prototype, (function() { 
     1226  function toColorPart() { 
     1227    return this.toPaddedString(2, 16); 
     1228  } 
     1229 
     1230  function succ() { 
     1231    return this + 1; 
     1232  } 
     1233 
     1234  function times(iterator, context) { 
     1235    $R(0, this, true).each(iterator, context); 
     1236    return this; 
     1237  } 
     1238 
     1239  function toPaddedString(length, radix) { 
     1240    var string = this.toString(radix || 10); 
     1241    return '0'.times(length - string.length) + string; 
     1242  } 
     1243 
     1244  function toJSON() { 
     1245    return isFinite(this) ? this.toString() : 'null'; 
     1246  } 
     1247 
     1248  function abs() { 
     1249    return Math.abs(this); 
     1250  } 
     1251 
     1252  function round() { 
     1253    return Math.round(this); 
     1254  } 
     1255 
     1256  function ceil() { 
     1257    return Math.ceil(this); 
     1258  } 
     1259 
     1260  function floor() { 
     1261    return Math.floor(this); 
     1262  } 
     1263 
     1264  return { 
     1265    toColorPart:    toColorPart, 
     1266    succ:           succ, 
     1267    times:          times, 
     1268    toPaddedString: toPaddedString, 
     1269    toJSON:         toJSON, 
     1270    abs:            abs, 
     1271    round:          round, 
     1272    ceil:           ceil, 
     1273    floor:          floor 
     1274  }; 
     1275})()); 
     1276 
     1277function $R(start, end, exclusive) { 
     1278  return new ObjectRange(start, end, exclusive); 
     1279} 
     1280 
     1281var ObjectRange = Class.create(Enumerable, (function() { 
     1282  function initialize(start, end, exclusive) { 
    10851283    this.start = start; 
    10861284    this.end = end; 
    10871285    this.exclusive = exclusive; 
    1088   }, 
    1089  
    1090   _each: function(iterator) { 
     1286  } 
     1287 
     1288  function _each(iterator) { 
    10911289    var value = this.start; 
    10921290    while (this.include(value)) { 
     
    10941292      value = value.succ(); 
    10951293    } 
    1096   }, 
    1097  
    1098   include: function(value) { 
     1294  } 
     1295 
     1296  function include(value) { 
    10991297    if (value < this.start) 
    11001298      return false; 
     
    11031301    return value <= this.end; 
    11041302  } 
    1105 }); 
    1106  
    1107 var $R = function(start, end, exclusive) { 
    1108   return new ObjectRange(start, end, exclusive); 
    1109 }; 
     1303 
     1304  return { 
     1305    initialize: initialize, 
     1306    _each:      _each, 
     1307    include:    include 
     1308  }; 
     1309})()); 
     1310 
     1311 
    11101312 
    11111313var Ajax = { 
     
    11541356  onComplete: function() { Ajax.activeRequestCount-- } 
    11551357}); 
    1156  
    11571358Ajax.Base = Class.create({ 
    11581359  initialize: function(options) { 
     
    11761377  } 
    11771378}); 
    1178  
    11791379Ajax.Request = Class.create(Ajax.Base, { 
    11801380  _complete: false, 
     
    11921392 
    11931393    if (!['get', 'post'].include(this.method)) { 
    1194       // simulate other verbs over post 
    11951394      params['_method'] = this.method; 
    11961395      this.method = 'post'; 
     
    12001399 
    12011400    if (params = Object.toQueryString(params)) { 
    1202       // when GET, append parameters to URL 
    12031401      if (this.method == 'get') 
    12041402        this.url += (this.url.include('?') ? '&' : '?') + params; 
     
    12591457    } 
    12601458 
    1261     // user-defined headers 
    12621459    if (typeof this.options.requestHeaders == 'object') { 
    12631460      var extras = this.options.requestHeaders; 
     
    13131510 
    13141511    if (state == 'Complete') { 
    1315       // avoid memory leak in MSIE: clean up 
    13161512      this.transport.onreadystatechange = Prototype.emptyFunction; 
    13171513    } 
     
    13301526    try { 
    13311527      return this.transport.getResponseHeader(name) || null; 
    1332     } catch (e) { return null } 
     1528    } catch (e) { return null; } 
    13331529  }, 
    13341530 
     
    13501546  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; 
    13511547 
     1548 
     1549 
     1550 
     1551 
     1552 
     1553 
     1554 
    13521555Ajax.Response = Class.create({ 
    13531556  initialize: function(request){ 
     
    13711574 
    13721575  status:      0, 
     1576 
    13731577  statusText: '', 
    13741578 
     
    15001704  } 
    15011705}); 
     1706 
     1707 
     1708 
    15021709function $(element) { 
    15031710  if (arguments.length > 1) { 
     
    15271734 
    15281735if (!Node.ELEMENT_NODE) { 
    1529   // DOM level 2 ECMAScript Language Binding 
    15301736  Object.extend(Node, { 
    15311737    ELEMENT_NODE: 1, 
     
    15441750} 
    15451751 
    1546 (function() { 
    1547   var element = this.Element; 
    1548   this.Element = function(tagName, attributes) { 
     1752 
     1753(function(global) { 
     1754 
     1755  var SETATTRIBUTE_IGNORES_NAME = (function(){ 
     1756    var elForm = document.createElement("form"); 
     1757    var elInput = document.createElement("input"); 
     1758    var root = document.documentElement; 
     1759    elInput.setAttribute("name", "test"); 
     1760    elForm.appendChild(elInput); 
     1761    root.appendChild(elForm); 
     1762    var isBuggy = elForm.elements 
     1763      ? (typeof elForm.elements.test == "undefined") 
     1764      : null; 
     1765    root.removeChild(elForm); 
     1766    elForm = elInput = null; 
     1767    return isBuggy; 
     1768  })(); 
     1769 
     1770  var element = global.Element; 
     1771  global.Element = function(tagName, attributes) { 
    15491772    attributes = attributes || { }; 
    15501773    tagName = tagName.toLowerCase(); 
    15511774    var cache = Element.cache; 
    1552     if (Prototype.Browser.IE && attributes.name) { 
     1775    if (SETATTRIBUTE_IGNORES_NAME && attributes.name) { 
    15531776      tagName = '<' + tagName + ' name="' + attributes.name + '">'; 
    15541777      delete attributes.name; 
     
    15581781    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); 
    15591782  }; 
    1560   Object.extend(this.Element, element || { }); 
    1561 }).call(window); 
     1783  Object.extend(global.Element, element || { }); 
     1784  if (element) global.Element.prototype = element.prototype; 
     1785})(this); 
    15621786 
    15631787Element.cache = { }; 
     1788Element.idCounter = 1; 
    15641789 
    15651790Element.Methods = { 
     
    15741799  }, 
    15751800 
     1801 
    15761802  hide: function(element) { 
    1577     $(element).style.display = 'none'; 
     1803    element = $(element); 
     1804    element.style.display = 'none'; 
    15781805    return element; 
    15791806  }, 
    15801807 
    15811808  show: function(element) { 
    1582     $(element).style.display = ''; 
     1809    element = $(element); 
     1810    element.style.display = ''; 
    15831811    return element; 
    15841812  }, 
     
    15901818  }, 
    15911819 
    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   }, 
     1820  update: (function(){ 
     1821 
     1822    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ 
     1823      var el = document.createElement("select"), 
     1824          isBuggy = true; 
     1825      el.innerHTML = "<option value=\"test\">test</option>"; 
     1826      if (el.options && el.options[0]) { 
     1827        isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; 
     1828      } 
     1829      el = null; 
     1830      return isBuggy; 
     1831    })(); 
     1832 
     1833    var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ 
     1834      try { 
     1835        var el = document.createElement("table"); 
     1836        if (el && el.tBodies) { 
     1837          el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>"; 
     1838          var isBuggy = typeof el.tBodies[0] == "undefined"; 
     1839          el = null; 
     1840          return isBuggy; 
     1841        } 
     1842      } catch (e) { 
     1843        return true; 
     1844      } 
     1845    })(); 
     1846 
     1847    var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { 
     1848      var s = document.createElement("script"), 
     1849          isBuggy = false; 
     1850      try { 
     1851        s.appendChild(document.createTextNode("")); 
     1852        isBuggy = !s.firstChild || 
     1853          s.firstChild && s.firstChild.nodeType !== 3; 
     1854      } catch (e) { 
     1855        isBuggy = true; 
     1856      } 
     1857      s = null; 
     1858      return isBuggy; 
     1859    })(); 
     1860 
     1861    function update(element, content) { 
     1862      element = $(element); 
     1863 
     1864      if (content && content.toElement) 
     1865        content = content.toElement(); 
     1866 
     1867      if (Object.isElement(content)) 
     1868        return element.update().insert(content); 
     1869 
     1870      content = Object.toHTML(content); 
     1871 
     1872      var tagName = element.tagName.toUpperCase(); 
     1873 
     1874      if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { 
     1875        element.text = content; 
     1876        return element; 
     1877      } 
     1878 
     1879      if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) { 
     1880        if (tagName in Element._insertionTranslations.tags) { 
     1881          while (element.firstChild) { 
     1882            element.removeChild(element.firstChild); 
     1883          } 
     1884          Element._getContentFromAnonymousElement(tagName, content.stripScripts()) 
     1885            .each(function(node) { 
     1886              element.appendChild(node) 
     1887            }); 
     1888        } 
     1889        else { 
     1890          element.innerHTML = content.stripScripts(); 
     1891        } 
     1892      } 
     1893      else { 
     1894        element.innerHTML = content.stripScripts(); 
     1895      } 
     1896 
     1897      content.evalScripts.bind(content).defer(); 
     1898      return element; 
     1899    } 
     1900 
     1901    return update; 
     1902  })(), 
    16011903 
    16021904  replace: function(element, content) { 
     
    16831985 
    16841986  ancestors: function(element) { 
    1685     return $(element).recursivelyCollect('parentNode'); 
     1987    return Element.recursivelyCollect(element, 'parentNode'); 
    16861988  }, 
    16871989 
    16881990  descendants: function(element) { 
    1689     return $(element).select("*"); 
     1991    return Element.select(element, "*"); 
    16901992  }, 
    16911993 
     
    17042006 
    17052007  previousSiblings: function(element) { 
    1706     return $(element).recursivelyCollect('previousSibling'); 
     2008    return Element.recursivelyCollect(element, 'previousSibling'); 
    17072009  }, 
    17082010 
    17092011  nextSiblings: function(element) { 
    1710     return $(element).recursivelyCollect('nextSibling'); 
     2012    return Element.recursivelyCollect(element, 'nextSibling'); 
    17112013  }, 
    17122014 
    17132015  siblings: function(element) { 
    17142016    element = $(element); 
    1715     return element.previousSiblings().reverse().concat(element.nextSiblings()); 
     2017    return Element.previousSiblings(element).reverse() 
     2018      .concat(Element.nextSiblings(element)); 
    17162019  }, 
    17172020 
     
    17252028    element = $(element); 
    17262029    if (arguments.length == 1) return $(element.parentNode); 
    1727     var ancestors = element.ancestors(); 
     2030    var ancestors = Element.ancestors(element); 
    17282031    return Object.isNumber(expression) ? ancestors[expression] : 
    17292032      Selector.findElement(ancestors, expression, index); 
     
    17322035  down: function(element, expression, index) { 
    17332036    element = $(element); 
    1734     if (arguments.length == 1) return element.firstDescendant(); 
    1735     return Object.isNumber(expression) ? element.descendants()[expression] : 
    1736       element.select(expression)[index || 0]; 
     2037    if (arguments.length == 1) return Element.firstDescendant(element); 
     2038    return Object.isNumber(expression) ? Element.descendants(element)[expression] : 
     2039      Element.select(element, expression)[index || 0]; 
    17372040  }, 
    17382041 
     
    17402043    element = $(element); 
    17412044    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); 
    1742     var previousSiblings = element.previousSiblings(); 
     2045    var previousSiblings = Element.previousSiblings(element); 
    17432046    return Object.isNumber(expression) ? previousSiblings[expression] : 
    17442047      Selector.findElement(previousSiblings, expression, index); 
     
    17482051    element = $(element); 
    17492052    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); 
    1750     var nextSiblings = element.nextSiblings(); 
     2053    var nextSiblings = Element.nextSiblings(element); 
    17512054    return Object.isNumber(expression) ? nextSiblings[expression] : 
    17522055      Selector.findElement(nextSiblings, expression, index); 
    17532056  }, 
    17542057 
    1755   select: function() { 
    1756     var args = $A(arguments), element = $(args.shift()); 
     2058 
     2059  select: function(element) { 
     2060    var args = Array.prototype.slice.call(arguments, 1); 
    17572061    return Selector.findChildElements(element, args); 
    17582062  }, 
    17592063 
    1760   adjacent: function() { 
    1761     var args = $A(arguments), element = $(args.shift()); 
     2064  adjacent: function(element) { 
     2065    var args = Array.prototype.slice.call(arguments, 1); 
    17622066    return Selector.findChildElements(element.parentNode, args).without(element); 
    17632067  }, 
     
    17652069  identify: function(element) { 
    17662070    element = $(element); 
    1767     var id = element.readAttribute('id'), self = arguments.callee; 
     2071    var id = Element.readAttribute(element, 'id'); 
    17682072    if (id) return id; 
    1769     do { id = 'anonymous_element_' + self.counter++ } while ($(id)); 
    1770     element.writeAttribute('id', id); 
     2073    do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id)); 
     2074    Element.writeAttribute(element, 'id', id); 
    17712075    return id; 
    17722076  }, 
     
    18072111 
    18082112  getHeight: function(element) { 
    1809     return $(element).getDimensions().height; 
     2113    return Element.getDimensions(element).height; 
    18102114  }, 
    18112115 
    18122116  getWidth: function(element) { 
    1813     return $(element).getDimensions().width; 
     2117    return Element.getDimensions(element).width; 
    18142118  }, 
    18152119 
     
    18272131  addClassName: function(element, className) { 
    18282132    if (!(element = $(element))) return; 
    1829     if (!element.hasClassName(className)) 
     2133    if (!Element.hasClassName(element, className)) 
    18302134      element.className += (element.className ? ' ' : '') + className; 
    18312135    return element; 
     
    18412145  toggleClassName: function(element, className) { 
    18422146    if (!(element = $(element))) return; 
    1843     return element[element.hasClassName(className) ? 
    1844       'removeClassName' : 'addClassName'](className); 
    1845   }, 
    1846  
    1847   // removes whitespace-only text node children 
     2147    return Element[Element.hasClassName(element, className) ? 
     2148      'removeClassName' : 'addClassName'](element, className); 
     2149  }, 
     2150 
    18482151  cleanWhitespace: function(element) { 
    18492152    element = $(element); 
     
    18642167  descendantOf: function(element, ancestor) { 
    18652168    element = $(element), ancestor = $(ancestor); 
    1866     var originalAncestor = ancestor; 
    18672169 
    18682170    if (element.compareDocumentPosition) 
    18692171      return (element.compareDocumentPosition(ancestor) & 8) === 8; 
    18702172 
    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     } 
     2173    if (ancestor.contains) 
     2174      return ancestor.contains(element) && ancestor !== element; 
    18812175 
    18822176    while (element = element.parentNode) 
    1883       if (element == originalAncestor) return true; 
     2177      if (element == ancestor) return true; 
     2178 
    18842179    return false; 
    18852180  }, 
     
    18872182  scrollTo: function(element) { 
    18882183    element = $(element); 
    1889     var pos = element.cumulativeOffset(); 
     2184    var pos = Element.cumulativeOffset(element); 
    18902185    window.scrollTo(pos[0], pos[1]); 
    18912186    return element; 
     
    18962191    style = style == 'float' ? 'cssFloat' : style.camelize(); 
    18972192    var value = element.style[style]; 
    1898     if (!value) { 
     2193    if (!value || value == 'auto') { 
    18992194      var css = document.defaultView.getComputedStyle(element, null); 
    19002195      value = css ? css[style] : null; 
     
    19352230  getDimensions: function(element) { 
    19362231    element = $(element); 
    1937     var display = $(element).getStyle('display'); 
     2232    var display = Element.getStyle(element, 'display'); 
    19382233    if (display != 'none' && display != null) // Safari bug 
    19392234      return {width: element.offsetWidth, height: element.offsetHeight}; 
    19402235 
    1941     // All *Width and *Height properties give 0 on elements with display none, 
    1942     // so enable the element temporarily 
    19432236    var els = element.style; 
    19442237    var originalVisibility = els.visibility; 
     
    19462239    var originalDisplay = els.display; 
    19472240    els.visibility = 'hidden'; 
    1948     els.position = 'absolute'; 
     2241    if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari 
     2242      els.position = 'absolute'; 
    19492243    els.display = 'block'; 
    19502244    var originalWidth = element.clientWidth; 
     
    19622256      element._madePositioned = true; 
    19632257      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) { 
     2258      if (Prototype.Browser.Opera) { 
    19672259        element.style.top = 0; 
    19682260        element.style.left = 0; 
     
    20192311      element = element.offsetParent; 
    20202312      if (element) { 
    2021         if (element.tagName == 'BODY') break; 
     2313        if (element.tagName.toUpperCase() == 'BODY') break; 
    20222314        var p = Element.getStyle(element, 'position'); 
    20232315        if (p !== 'static') break; 
     
    20292321  absolutize: function(element) { 
    20302322    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(); 
     2323    if (Element.getStyle(element, 'position') == 'absolute') return element; 
     2324 
     2325    var offsets = Element.positionedOffset(element); 
    20352326    var top     = offsets[1]; 
    20362327    var left    = offsets[0]; 
     
    20532344  relativize: function(element) { 
    20542345    element = $(element); 
    2055     if (element.getStyle('position') == 'relative') return; 
    2056     // Position.prepare(); // To be done manually by Scripty when it needs it. 
     2346    if (Element.getStyle(element, 'position') == 'relative') return element; 
    20572347 
    20582348    element.style.position = 'relative'; 
     
    20962386      valueL += element.offsetLeft || 0; 
    20972387 
    2098       // Safari fix 
    20992388      if (element.offsetParent == document.body && 
    21002389        Element.getStyle(element, 'position') == 'absolute') break; 
     
    21042393    element = forElement; 
    21052394    do { 
    2106       if (!Prototype.Browser.Opera || element.tagName == 'BODY') { 
     2395      if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) { 
    21072396        valueT -= element.scrollTop  || 0; 
    21082397        valueL -= element.scrollLeft || 0; 
     
    21232412    }, arguments[2] || { }); 
    21242413 
    2125     // find page position of source 
    21262414    source = $(source); 
    2127     var p = source.viewportOffset(); 
    2128  
    2129     // find coordinate system to use 
     2415    var p = Element.viewportOffset(source); 
     2416 
    21302417    element = $(element); 
    21312418    var delta = [0, 0]; 
    21322419    var parent = null; 
    2133     // delta [0,0] will do fine with position: fixed elements, 
    2134     // position:absolute needs offsetParent deltas 
    21352420    if (Element.getStyle(element, 'position') == 'absolute') { 
    2136       parent = element.getOffsetParent(); 
    2137       delta = parent.viewportOffset(); 
    2138     } 
    2139  
    2140     // correct by body offsets (fixes Safari) 
     2421      parent = Element.getOffsetParent(element); 
     2422      delta = Element.viewportOffset(parent); 
     2423    } 
     2424 
    21412425    if (parent == document.body) { 
    21422426      delta[0] -= document.body.offsetLeft; 
     
    21442428    } 
    21452429 
    2146     // set position 
    21472430    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px'; 
    21482431    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px'; 
     
    21532436}; 
    21542437 
    2155 Element.Methods.identify.counter = 1; 
    2156  
    21572438Object.extend(Element.Methods, { 
    21582439  getElementsBySelector: Element.Methods.select, 
     2440 
    21592441  childElements: Element.Methods.immediateDescendants 
    21602442}); 
     
    21772459          if (proceed(element, 'position') === 'static') return null; 
    21782460        case 'height': case 'width': 
    2179           // returns '0px' for hidden elements; we want it to return null 
    21802461          if (!Element.visible(element)) return null; 
    21812462 
    2182           // returns the border-box dimensions rather than the content-box 
    2183           // dimensions, so we subtract padding and borders from the value 
    21842463          var dim = parseInt(proceed(element, style), 10); 
    21852464 
     
    22142493 
    22152494else 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. 
    22182495  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( 
    22192496    function(proceed, element) { 
    22202497      element = $(element); 
     2498      try { element.offsetParent } 
     2499      catch(e) { return $(document.body) } 
    22212500      var position = element.getStyle('position'); 
    22222501      if (position !== 'static') return proceed(element); 
     
    22322511      function(proceed, element) { 
    22332512        element = $(element); 
     2513        try { element.offsetParent } 
     2514        catch(e) { return Element._returnOffset(0,0) } 
    22342515        var position = element.getStyle('position'); 
    22352516        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. 
    22382517        var offsetParent = element.getOffsetParent(); 
    22392518        if (offsetParent && offsetParent.getStyle('position') === 'fixed') 
     
    22462525    ); 
    22472526  }); 
     2527 
     2528  Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap( 
     2529    function(proceed, element) { 
     2530      try { element.offsetParent } 
     2531      catch(e) { return Element._returnOffset(0,0) } 
     2532      return proceed(element); 
     2533    } 
     2534  ); 
    22482535 
    22492536  Element.Methods.getStyle = function(element, style) { 
     
    22882575  }; 
    22892576 
    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); 
     2577  Element._attributeTranslations = (function(){ 
     2578 
     2579    var classProp = 'className'; 
     2580    var forProp = 'for'; 
     2581 
     2582    var el = document.createElement('div'); 
     2583 
     2584    el.setAttribute(classProp, 'x'); 
     2585 
     2586    if (el.className !== 'x') { 
     2587      el.setAttribute('class', 'x'); 
     2588      if (el.className === 'x') { 
     2589        classProp = 'class'; 
     2590      } 
     2591    } 
     2592    el = null; 
     2593 
     2594    el = document.createElement('label'); 
     2595    el.setAttribute(forProp, 'x'); 
     2596    if (el.htmlFor !== 'x') { 
     2597      el.setAttribute('htmlFor', 'x'); 
     2598      if (el.htmlFor === 'x') { 
     2599        forProp = 'htmlFor'; 
     2600      } 
     2601    } 
     2602    el = null; 
     2603 
     2604    return { 
     2605      read: { 
     2606        names: { 
     2607          'class':      classProp, 
     2608          'className':  classProp, 
     2609          'for':        forProp, 
     2610          'htmlFor':    forProp 
    22992611        }, 
    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; 
     2612        values: { 
     2613          _getAttr: function(element, attribute) { 
     2614            return element.getAttribute(attribute); 
     2615          }, 
     2616          _getAttr2: function(element, attribute) { 
     2617            return element.getAttribute(attribute, 2); 
     2618          }, 
     2619          _getAttrNode: function(element, attribute) { 
     2620            var node = element.getAttributeNode(attribute); 
     2621            return node ? node.value : ""; 
     2622          }, 
     2623          _getEv: (function(){ 
     2624 
     2625            var el = document.createElement('div'); 
     2626            el.onclick = Prototype.emptyFunction; 
     2627            var value = el.getAttribute('onclick'); 
     2628            var f; 
     2629 
     2630            if (String(value).indexOf('{') > -1) { 
     2631              f = function(element, attribute) { 
     2632                attribute = element.getAttribute(attribute); 
     2633                if (!attribute) return null; 
     2634                attribute = attribute.toString(); 
     2635                attribute = attribute.split('{')[1]; 
     2636                attribute = attribute.split('}')[0]; 
     2637                return attribute.strip(); 
     2638              }; 
     2639            } 
     2640            else if (value === '') { 
     2641              f = function(element, attribute) { 
     2642                attribute = element.getAttribute(attribute); 
     2643                if (!attribute) return null; 
     2644                return attribute.strip(); 
     2645              }; 
     2646            } 
     2647            el = null; 
     2648            return f; 
     2649          })(), 
     2650          _flag: function(element, attribute) { 
     2651            return $(element).hasAttribute(attribute) ? attribute : null; 
     2652          }, 
     2653          style: function(element) { 
     2654            return element.style.cssText.toLowerCase(); 
     2655          }, 
     2656          title: function(element) { 
     2657            return element.title; 
     2658          } 
    23162659        } 
    23172660      } 
    23182661    } 
    2319   }; 
     2662  })(); 
    23202663 
    23212664  Element._attributeTranslations.write = { 
     
    23382681 
    23392682  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + 
    2340       'encType maxLength readOnly longDesc').each(function(attr) { 
     2683      'encType maxLength readOnly longDesc frameBorder').each(function(attr) { 
    23412684    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; 
    23422685    Element._attributeTranslations.has[attr.toLowerCase()] = attr; 
     
    23452688  (function(v) { 
    23462689    Object.extend(v, { 
    2347       href:        v._getAttr, 
    2348       src:         v._getAttr, 
     2690      href:        v._getAttr2, 
     2691      src:         v._getAttr2, 
    23492692      type:        v._getAttr, 
    23502693      action:      v._getAttrNode, 
     
    23732716    }); 
    23742717  })(Element._attributeTranslations.read.values); 
     2718 
     2719  if (Prototype.BrowserFeatures.ElementExtensions) { 
     2720    (function() { 
     2721      function _descendants(element) { 
     2722        var nodes = element.getElementsByTagName('*'), results = []; 
     2723        for (var i = 0, node; node = nodes[i]; i++) 
     2724          if (node.tagName !== "!") // Filter out comment nodes. 
     2725            results.push(node); 
     2726        return results; 
     2727      } 
     2728 
     2729      Element.Methods.down = function(element, expression, index) { 
     2730        element = $(element); 
     2731        if (arguments.length == 1) return element.firstDescendant(); 
     2732        return Object.isNumber(expression) ? _descendants(element)[expression] : 
     2733          Element.select(element, expression)[index || 0]; 
     2734      } 
     2735    })(); 
     2736  } 
     2737 
    23752738} 
    23762739 
     
    23912754 
    23922755    if (value == 1) 
    2393       if(element.tagName == 'IMG' && element.width) { 
     2756      if(element.tagName.toUpperCase() == 'IMG' && element.width) { 
    23942757        element.width++; element.width--; 
    23952758      } else try { 
     
    24022765  }; 
    24032766 
    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. 
    24072767  Element.Methods.cumulativeOffset = function(element) { 
    24082768    var valueT = 0, valueL = 0; 
     
    24202780} 
    24212781 
    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')) { 
     2782if ('outerHTML' in document.documentElement) { 
    24462783  Element.Methods.replace = function(element, content) { 
    24472784    element = $(element); 
     
    25112848 
    25122849(function() { 
    2513   Object.extend(this.tags, { 
    2514     THEAD: this.tags.TBODY, 
    2515     TFOOT: this.tags.TBODY, 
    2516     TH:    this.tags.TD 
     2850  var tags = Element._insertionTranslations.tags; 
     2851  Object.extend(tags, { 
     2852    THEAD: tags.TBODY, 
     2853    TFOOT: tags.TBODY, 
     2854    TH:    tags.TD 
    25172855  }); 
    2518 }).call(Element._insertionTranslations); 
     2856})(); 
    25192857 
    25202858Element.Methods.Simulated = { 
     
    25222860    attribute = Element._attributeTranslations.has[attribute] || attribute; 
    25232861    var node = $(element).getAttributeNode(attribute); 
    2524     return node && node.specified; 
     2862    return !!(node && node.specified); 
    25252863  } 
    25262864}; 
     
    25302868Object.extend(Element, Element.Methods); 
    25312869 
    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 } 
     2870(function(div) { 
     2871 
     2872  if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) { 
     2873    window.HTMLElement = { }; 
     2874    window.HTMLElement.prototype = div['__proto__']; 
     2875    Prototype.BrowserFeatures.ElementExtensions = true; 
     2876  } 
     2877 
     2878  div = null; 
     2879 
     2880})(document.createElement('div')) 
    25382881 
    25392882Element.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]; 
     2883 
     2884  function checkDeficiency(tagName) { 
     2885    if (typeof window.Element != 'undefined') { 
     2886      var proto = window.Element.prototype; 
     2887      if (proto) { 
     2888        var id = '_' + (Math.random()+'').slice(2); 
     2889        var el = document.createElement(tagName); 
     2890        proto[id] = 'x'; 
     2891        var isBuggy = (el[id] !== 'x'); 
     2892        delete proto[id]; 
     2893        el = null; 
     2894        return isBuggy; 
     2895      } 
     2896    } 
     2897    return false; 
     2898  } 
     2899 
     2900  function extendElementWith(element, methods) { 
     2901    for (var property in methods) { 
     2902      var value = methods[property]; 
    25572903      if (Object.isFunction(value) && !(property in element)) 
    25582904        element[property] = value.methodize(); 
    25592905    } 
     2906  } 
     2907 
     2908  var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object'); 
     2909 
     2910  if (Prototype.BrowserFeatures.SpecificElementExtensions) { 
     2911    if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) { 
     2912      return function(element) { 
     2913        if (element && typeof element._extendedByPrototype == 'undefined') { 
     2914          var t = element.tagName; 
     2915          if (t && (/^(?:object|applet|embed)$/i.test(t))) { 
     2916            extendElementWith(element, Element.Methods); 
     2917            extendElementWith(element, Element.Methods.Simulated); 
     2918            extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); 
     2919          } 
     2920        } 
     2921        return element; 
     2922      } 
     2923    } 
     2924    return Prototype.K; 
     2925  } 
     2926 
     2927  var Methods = { }, ByTag = Element.Methods.ByTag; 
     2928 
     2929  var extend = Object.extend(function(element) { 
     2930    if (!element || typeof element._extendedByPrototype != 'undefined' || 
     2931        element.nodeType != 1 || element == window) return element; 
     2932 
     2933    var methods = Object.clone(Methods), 
     2934        tagName = element.tagName.toUpperCase(); 
     2935 
     2936    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); 
     2937 
     2938    extendElementWith(element, methods); 
    25602939 
    25612940    element._extendedByPrototype = Prototype.emptyFunction; 
     
    25642943  }, { 
    25652944    refresh: function() { 
    2566       // extend methods for all tags (Safari doesn't need this) 
    25672945      if (!Prototype.BrowserFeatures.ElementExtensions) { 
    25682946        Object.extend(Methods, Element.Methods); 
     
    26433021    if (window[klass]) return window[klass]; 
    26443022 
    2645     window[klass] = { }; 
    2646     window[klass].prototype = document.createElement(tagName).__proto__; 
    2647     return window[klass]; 
    2648   } 
     3023    var element = document.createElement(tagName); 
     3024    var proto = element['__proto__'] || element.constructor.prototype; 
     3025    element = null; 
     3026    return proto; 
     3027  } 
     3028 
     3029  var elementPrototype = window.HTMLElement ? HTMLElement.prototype : 
     3030   Element.prototype; 
    26493031 
    26503032  if (F.ElementExtensions) { 
    2651     copy(Element.Methods, HTMLElement.prototype); 
    2652     copy(Element.Methods.Simulated, HTMLElement.prototype, true); 
     3033    copy(Element.Methods, elementPrototype); 
     3034    copy(Element.Methods.Simulated, elementPrototype, true); 
    26533035  } 
    26543036 
     
    26683050}; 
    26693051 
     3052 
    26703053document.viewport = { 
     3054 
    26713055  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; 
     3056    return { width: this.getWidth(), height: this.getHeight() }; 
    26883057  }, 
    26893058 
     
    26913060    return Element._returnOffset( 
    26923061      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, 
    2693       window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 
     3062      window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop); 
    26943063  } 
    26953064}; 
    2696 /* Portions of the Selector class are derived from Jack Slocum’s DomQuery, 
     3065 
     3066(function(viewport) { 
     3067  var B = Prototype.Browser, doc = document, element, property = {}; 
     3068 
     3069  function getRootElement() { 
     3070    if (B.WebKit && !doc.evaluate) 
     3071      return document; 
     3072 
     3073    if (B.Opera && window.parseFloat(window.opera.version()) < 9.5) 
     3074      return document.body; 
     3075 
     3076    return document.documentElement; 
     3077  } 
     3078 
     3079  function define(D) { 
     3080    if (!element) element = getRootElement(); 
     3081 
     3082    property[D] = 'client' + D; 
     3083 
     3084    viewport['get' + D] = function() { return element[property[D]] }; 
     3085    return viewport['get' + D](); 
     3086  } 
     3087 
     3088  viewport.getWidth  = define.curry('Width'); 
     3089 
     3090  viewport.getHeight = define.curry('Height'); 
     3091})(document.viewport); 
     3092 
     3093 
     3094Element.Storage = { 
     3095  UID: 1 
     3096}; 
     3097 
     3098Element.addMethods({ 
     3099  getStorage: function(element) { 
     3100    if (!(element = $(element))) return; 
     3101 
     3102    var uid; 
     3103    if (element === window) { 
     3104      uid = 0; 
     3105    } else { 
     3106      if (typeof element._prototypeUID === "undefined") 
     3107        element._prototypeUID = [Element.Storage.UID++]; 
     3108      uid = element._prototypeUID[0]; 
     3109    } 
     3110 
     3111    if (!Element.Storage[uid]) 
     3112      Element.Storage[uid] = $H(); 
     3113 
     3114    return Element.Storage[uid]; 
     3115  }, 
     3116 
     3117  store: function(element, key, value) { 
     3118    if (!(element = $(element))) return; 
     3119 
     3120    if (arguments.length === 2) { 
     3121      Element.getStorage(element).update(key); 
     3122    } else { 
     3123      Element.getStorage(element).set(key, value); 
     3124    } 
     3125 
     3126    return element; 
     3127  }, 
     3128 
     3129  retrieve: function(element, key, defaultValue) { 
     3130    if (!(element = $(element))) return; 
     3131    var hash = Element.getStorage(element), value = hash.get(key); 
     3132 
     3133    if (Object.isUndefined(value)) { 
     3134      hash.set(key, defaultValue); 
     3135      value = defaultValue; 
     3136    } 
     3137 
     3138    return value; 
     3139  }, 
     3140 
     3141  clone: function(element, deep) { 
     3142    if (!(element = $(element))) return; 
     3143    var clone = element.cloneNode(deep); 
     3144    clone._prototypeUID = void 0; 
     3145    if (deep) { 
     3146      var descendants = Element.select(clone, '*'), 
     3147          i = descendants.length; 
     3148      while (i--) { 
     3149        descendants[i]._prototypeUID = void 0; 
     3150      } 
     3151    } 
     3152    return Element.extend(clone); 
     3153  } 
     3154}); 
     3155/* Portions of the Selector class are derived from Jack Slocum's DomQuery, 
    26973156 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style 
    26983157 * license.  Please see http://www.yui-ext.com/ for more information. */ 
     
    27013160  initialize: function(expression) { 
    27023161    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"))) 
     3162 
     3163    if (this.shouldUseSelectorsAPI()) { 
     3164      this.mode = 'selectorsAPI'; 
     3165    } else if (this.shouldUseXPath()) { 
     3166      this.mode = 'xpath'; 
     3167      this.compileXPathMatcher(); 
     3168    } else { 
     3169      this.mode = "normal"; 
     3170      this.compileMatcher(); 
     3171    } 
     3172 
     3173  }, 
     3174 
     3175  shouldUseXPath: (function() { 
     3176 
     3177    var IS_DESCENDANT_SELECTOR_BUGGY = (function(){ 
     3178      var isBuggy = false; 
     3179      if (document.evaluate && window.XPathResult) { 
     3180        var el = document.createElement('div'); 
     3181        el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>'; 
     3182 
     3183        var xpath = ".//*[local-name()='ul' or local-name()='UL']" + 
     3184          "//*[local-name()='li' or local-name()='LI']"; 
     3185 
     3186        var result = document.evaluate(xpath, el, null, 
     3187          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 
     3188 
     3189        isBuggy = (result.snapshotLength !== 2); 
     3190        el = null; 
     3191      } 
     3192      return isBuggy; 
     3193    })(); 
     3194 
     3195    return function() { 
     3196      if (!Prototype.BrowserFeatures.XPath) return false; 
     3197 
     3198      var e = this.expression; 
     3199 
     3200      if (Prototype.Browser.WebKit && 
     3201       (e.include("-of-type") || e.include(":empty"))) 
     3202        return false; 
     3203 
     3204      if ((/(\[[\w-]*?:|:checked)/).test(e)) 
     3205        return false; 
     3206 
     3207      if (IS_DESCENDANT_SELECTOR_BUGGY) return false; 
     3208 
     3209      return true; 
     3210    } 
     3211 
     3212  })(), 
     3213 
     3214  shouldUseSelectorsAPI: function() { 
     3215    if (!Prototype.BrowserFeatures.SelectorsAPI) return false; 
     3216 
     3217    if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false; 
     3218 
     3219    if (!Selector._div) Selector._div = new Element('div'); 
     3220 
     3221    try { 
     3222      Selector._div.querySelector(this.expression); 
     3223    } catch(e) { 
    27143224      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; 
     3225    } 
    27203226 
    27213227    return true; 
     
    27233229 
    27243230  compileMatcher: function() { 
    2725     if (this.shouldUseXPath()) 
    2726       return this.compileXPathMatcher(); 
    2727  
    27283231    var e = this.expression, ps = Selector.patterns, h = Selector.handlers, 
    2729         c = Selector.criteria, le, p, m; 
     3232        c = Selector.criteria, le, p, m, len = ps.length, name; 
    27303233 
    27313234    if (Selector._cache[e]) { 
     
    27393242    while (e && le != e && (/\S/).test(e)) { 
    27403243      le = e; 
    2741       for (var i in ps) { 
    2742         p = ps[i]; 
     3244      for (var i = 0; i<len; i++) { 
     3245        p = ps[i].re; 
     3246        name = ps[i].name; 
    27433247        if (m = e.match(p)) { 
    2744           this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : 
    2745               new Template(c[i]).evaluate(m)); 
     3248          this.matcher.push(Object.isFunction(c[name]) ? c[name](m) : 
     3249            new Template(c[name]).evaluate(m)); 
    27463250          e = e.replace(m[0], ''); 
    27473251          break; 
     
    27573261  compileXPathMatcher: function() { 
    27583262    var e = this.expression, ps = Selector.patterns, 
    2759         x = Selector.xpath, le, m; 
     3263        x = Selector.xpath, le, m, len = ps.length, name; 
    27603264 
    27613265    if (Selector._cache[e]) { 
     
    27663270    while (e && le != e && (/\S/).test(e)) { 
    27673271      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)); 
     3272      for (var i = 0; i<len; i++) { 
     3273        name = ps[i].name; 
     3274        if (m = e.match(ps[i].re)) { 
     3275          this.matcher.push(Object.isFunction(x[name]) ? x[name](m) : 
     3276            new Template(x[name]).evaluate(m)); 
    27723277          e = e.replace(m[0], ''); 
    27733278          break; 
     
    27823287  findElements: function(root) { 
    27833288    root = root || document; 
    2784     if (this.xpath) return document._getElementsByXPath(this.xpath, root); 
    2785     return this.matcher(root); 
     3289    var e = this.expression, results; 
     3290 
     3291    switch (this.mode) { 
     3292      case 'selectorsAPI': 
     3293        if (root !== document) { 
     3294          var oldId = root.id, id = $(root).identify(); 
     3295          id = id.replace(/([\.:])/g, "\\$1"); 
     3296          e = "#" + id + " " + e; 
     3297        } 
     3298 
     3299        results = $A(root.querySelectorAll(e)).map(Element.extend); 
     3300        root.id = oldId; 
     3301 
     3302        return results; 
     3303      case 'xpath': 
     3304        return document._getElementsByXPath(this.xpath, root); 
     3305      default: 
     3306       return this.matcher(root); 
     3307    } 
    27863308  }, 
    27873309 
     
    27903312 
    27913313    var e = this.expression, ps = Selector.patterns, as = Selector.assertions; 
    2792     var le, p, m; 
     3314    var le, p, m, len = ps.length, name; 
    27933315 
    27943316    while (e && le !== e && (/\S/).test(e)) { 
    27953317      le = e; 
    2796       for (var i in ps) { 
    2797         p = ps[i]; 
     3318      for (var i = 0; i<len; i++) { 
     3319        p = ps[i].re; 
     3320        name = ps[i].name; 
    27983321        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)]); 
     3322          if (as[name]) { 
     3323            this.tokens.push([name, Object.clone(m)]); 
    28033324            e = e.replace(m[0], ''); 
    28043325          } else { 
    2805             // reluctantly do a document-wide search 
    2806             // and look for a match in the array 
    28073326            return this.findElements(document).include(element); 
    28083327          } 
     
    28303349  } 
    28313350}); 
     3351 
     3352if (Prototype.BrowserFeatures.SelectorsAPI && 
     3353 document.compatMode === 'BackCompat') { 
     3354  Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){ 
     3355    var div = document.createElement('div'), 
     3356     span = document.createElement('span'); 
     3357 
     3358    div.id = "prototype_test_id"; 
     3359    span.className = 'Test'; 
     3360    div.appendChild(span); 
     3361    var isIgnored = (div.querySelector('#prototype_test_id .test') !== null); 
     3362    div = span = null; 
     3363    return isIgnored; 
     3364  })(); 
     3365} 
    28323366 
    28333367Object.extend(Selector, { 
     
    28743408      'last-child':  '[not(following-sibling::*)]', 
    28753409      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]', 
    2876       'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", 
     3410      'empty':       "[count(*) = 0 and (count(text()) = 0)]", 
    28773411      'checked':     "[@checked]", 
    2878       'disabled':    "[@disabled]", 
    2879       'enabled':     "[not(@disabled)]", 
     3412      'disabled':    "[(@disabled) and (@type!='hidden')]", 
     3413      'enabled':     "[not(@disabled) and (@type!='hidden')]", 
    28803414      'not': function(m) { 
    28813415        var e = m[6], p = Selector.patterns, 
    2882             x = Selector.xpath, le, v; 
     3416            x = Selector.xpath, le, v, len = p.length, name; 
    28833417 
    28843418        var exclusion = []; 
    28853419        while (e && le != e && (/\S/).test(e)) { 
    28863420          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); 
     3421          for (var i = 0; i<len; i++) { 
     3422            name = p[i].name 
     3423            if (m = e.match(p[i].re)) { 
     3424              v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m); 
    28903425              exclusion.push("(" + v.substring(1, v.length - 1) + ")"); 
    28913426              e = e.replace(m[0], ''); 
     
    29553490  }, 
    29563491 
    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 
     3492  patterns: [ 
     3493    { name: 'laterSibling', re: /^\s*~\s*/ }, 
     3494    { name: 'child',        re: /^\s*>\s*/ }, 
     3495    { name: 'adjacent',     re: /^\s*\+\s*/ }, 
     3496    { name: 'descendant',   re: /^\s/ }, 
     3497 
     3498    { name: 'tagName',      re: /^\s*(\*|[\w\-]+)(\b|$)?/ }, 
     3499    { name: 'id',           re: /^#([\w\-\*]+)(\b|$)/ }, 
     3500    { name: 'className',    re: /^\.([\w\-\*]+)(\b|$)/ }, 
     3501    { name: 'pseudo',       re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ }, 
     3502    { name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ }, 
     3503    { name: 'attr',         re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ } 
     3504  ], 
     3505 
    29763506  assertions: { 
    29773507    tagName: function(element, matches) { 
     
    29983528 
    29993529  handlers: { 
    3000     // UTILITY FUNCTIONS 
    3001     // joins two collections 
    30023530    concat: function(a, b) { 
    30033531      for (var i = 0, node; node = b[i]; i++) 
     
    30063534    }, 
    30073535 
    3008     // marks an array of nodes for counting 
    30093536    mark: function(nodes) { 
    30103537      var _true = Prototype.emptyFunction; 
     
    30143541    }, 
    30153542 
    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 
     3543    unmark: (function(){ 
     3544 
     3545      var PROPERTIES_ATTRIBUTES_MAP = (function(){ 
     3546        var el = document.createElement('div'), 
     3547            isBuggy = false, 
     3548            propName = '_countedByPrototype', 
     3549            value = 'x' 
     3550        el[propName] = value; 
     3551        isBuggy = (el.getAttribute(propName) === value); 
     3552        el = null; 
     3553        return isBuggy; 
     3554      })(); 
     3555 
     3556      return PROPERTIES_ATTRIBUTES_MAP ? 
     3557        function(nodes) { 
     3558          for (var i = 0, node; node = nodes[i]; i++) 
     3559            node.removeAttribute('_countedByPrototype'); 
     3560          return nodes; 
     3561        } : 
     3562        function(nodes) { 
     3563          for (var i = 0, node; node = nodes[i]; i++) 
     3564            node._countedByPrototype = void 0; 
     3565          return nodes; 
     3566        } 
     3567    })(), 
     3568 
    30253569    index: function(parentNode, reverse, ofType) { 
    30263570      parentNode._countedByPrototype = Prototype.emptyFunction; 
     
    30363580    }, 
    30373581 
    3038     // filters out duplicates and extends all nodes 
    30393582    unique: function(nodes) { 
    30403583      if (nodes.length == 0) return nodes; 
    30413584      var results = [], n; 
    30423585      for (var i = 0, l = nodes.length; i < l; i++) 
    3043         if (!(n = nodes[i])._countedByPrototype) { 
     3586        if (typeof (n = nodes[i])._countedByPrototype == 'undefined') { 
    30443587          n._countedByPrototype = Prototype.emptyFunction; 
    30453588          results.push(Element.extend(n)); 
     
    30483591    }, 
    30493592 
    3050     // COMBINATOR FUNCTIONS 
    30513593    descendant: function(nodes) { 
    30523594      var h = Selector.handlers; 
     
    30823624    nextElementSibling: function(node) { 
    30833625      while (node = node.nextSibling) 
    3084               if (node.nodeType == 1) return node; 
     3626        if (node.nodeType == 1) return node; 
    30853627      return null; 
    30863628    }, 
     
    30923634    }, 
    30933635 
    3094     // TOKEN FUNCTIONS 
    30953636    tagName: function(nodes, root, tagName, combinator) { 
    30963637      var uTagName = tagName.toUpperCase(); 
     
    30983639      if (nodes) { 
    30993640        if (combinator) { 
    3100           // fastlane for ordinary descendant combinators 
    31013641          if (combinator == "descendant") { 
    31023642            for (var i = 0, node; node = nodes[i]; i++) 
     
    31143654    id: function(nodes, root, id, combinator) { 
    31153655      var targetNode = $(id), h = Selector.handlers; 
    3116       if (!targetNode) return []; 
    3117       if (!nodes && root == document) return [targetNode]; 
     3656 
     3657      if (root == document) { 
     3658        if (!targetNode) return []; 
     3659        if (!nodes) return [targetNode]; 
     3660      } else { 
     3661        if (!root.sourceIndex || root.sourceIndex < 1) { 
     3662          var nodes = root.getElementsByTagName('*'); 
     3663          for (var j = 0, node; node = nodes[j]; j++) { 
     3664            if (node.id === id) return [node]; 
     3665          } 
     3666        } 
     3667      } 
     3668 
    31183669      if (nodes) { 
    31193670        if (combinator) { 
     
    32273778    }, 
    32283779 
    3229     // handles the an+b logic 
    32303780    getIndices: function(a, b, total) { 
    32313781      if (a == 0) return b > 0 ? [b] : []; 
     
    32363786    }, 
    32373787 
    3238     // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type 
    32393788    nth: function(nodes, formula, root, reverse, ofType) { 
    32403789      if (nodes.length == 0) return []; 
     
    32703819    'empty': function(nodes, value, root) { 
    32713820      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; 
     3821        if (node.tagName == '!' || node.firstChild) continue; 
    32743822        results.push(node); 
    32753823      } 
     
    32893837    'enabled': function(nodes, value, root) { 
    32903838      for (var i = 0, results = [], node; node = nodes[i]; i++) 
    3291         if (!node.disabled) results.push(node); 
     3839        if (!node.disabled && (!node.type || node.type !== 'hidden')) 
     3840          results.push(node); 
    32923841      return results; 
    32933842    }, 
     
    33093858    '=':  function(nv, v) { return nv == v; }, 
    33103859    '!=': 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); }, 
     3860    '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); }, 
     3861    '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); }, 
     3862    '*=': function(nv, v) { return nv == v || nv && nv.include(v); }, 
    33143863    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, 
    3315     '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } 
     3864    '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() + 
     3865     '-').include('-' + (v || "").toUpperCase() + '-'); } 
    33163866  }, 
    33173867 
     
    33533903if (Prototype.Browser.IE) { 
    33543904  Object.extend(Selector.handlers, { 
    3355     // IE returns comment nodes on getElementsByTagName("*"). 
    3356     // Filter them out. 
    33573905    concat: function(a, b) { 
    33583906      for (var i = 0, node; node = b[i]; i++) 
    33593907        if (node.tagName !== "!") a.push(node); 
    33603908      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; 
    33683909    } 
    33693910  }); 
     
    33733914  return Selector.findChildElements(document, $A(arguments)); 
    33743915} 
     3916 
    33753917var Form = { 
    33763918  reset: function(form) { 
    3377     $(form).reset(); 
     3919    form = $(form); 
     3920    form.reset(); 
    33783921    return form; 
    33793922  }, 
     
    33873930      if (!element.disabled && element.name) { 
    33883931        key = element.name; value = $(element).getValue(); 
    3389         if (value != null && (element.type != 'submit' || (!submitted && 
     3932        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted && 
    33903933            submit !== false && (!submit || key == submit) && (submitted = true)))) { 
    33913934          if (key in result) { 
    3392             // a key is already present; construct an array of values 
    33933935            if (!Object.isArray(result[key])) result[key] = [result[key]]; 
    33943936            result[key].push(value); 
     
    34103952 
    34113953  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     ); 
     3954    var elements = $(form).getElementsByTagName('*'), 
     3955        element, 
     3956        arr = [ ], 
     3957        serializers = Form.Element.Serializers; 
     3958    for (var i = 0; element = elements[i]; i++) { 
     3959      arr.push(element); 
     3960    } 
     3961    return arr.inject([], function(elements, child) { 
     3962      if (serializers[child.tagName.toLowerCase()]) 
     3963        elements.push(Element.extend(child)); 
     3964      return elements; 
     3965    }) 
    34193966  }, 
    34203967 
     
    34564003 
    34574004    return firstByIndex ? firstByIndex : elements.find(function(element) { 
    3458       return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); 
     4005      return /^(?:input|select|textarea)$/i.test(element.tagName); 
    34594006    }); 
    34604007  }, 
     
    34874034/*--------------------------------------------------------------------------*/ 
    34884035 
     4036 
    34894037Form.Element = { 
    34904038  focus: function(element) { 
     
    35004048 
    35014049Form.Element.Methods = { 
     4050 
    35024051  serialize: function(element) { 
    35034052    element = $(element); 
     
    35404089      element.focus(); 
    35414090      if (element.select && (element.tagName.toLowerCase() != 'input' || 
    3542           !['button', 'reset', 'submit'].include(element.type))) 
     4091          !(/^(?:button|reset|submit)$/i.test(element.type)))) 
    35434092        element.select(); 
    35444093    } catch (e) { } 
     
    35484097  disable: function(element) { 
    35494098    element = $(element); 
    3550     element.blur(); 
    35514099    element.disabled = true; 
    35524100    return element; 
     
    35634111 
    35644112var Field = Form.Element; 
     4113 
    35654114var $F = Form.Element.Methods.getValue; 
    35664115 
     
    35884137  }, 
    35894138 
    3590   select: function(element, index) { 
    3591     if (Object.isUndefined(index)) 
     4139  select: function(element, value) { 
     4140    if (Object.isUndefined(value)) 
    35924141      return this[element.type == 'select-one' ? 
    35934142        'selectOne' : 'selectMany'](element); 
    35944143    else { 
    3595       var opt, value, single = !Object.isArray(index); 
     4144      var opt, currentValue, single = !Object.isArray(value); 
    35964145      for (var i = 0, length = element.length; i < length; i++) { 
    35974146        opt = element.options[i]; 
    3598         value = this.optionValue(opt); 
     4147        currentValue = this.optionValue(opt); 
    35994148        if (single) { 
    3600           if (value == index) { 
     4149          if (currentValue == value) { 
    36014150            opt.selected = true; 
    36024151            return; 
    36034152          } 
    36044153        } 
    3605         else opt.selected = index.include(value); 
     4154        else opt.selected = value.include(currentValue); 
    36064155      } 
    36074156    } 
     
    36254174 
    36264175  optionValue: function(opt) { 
    3627     // extend element because hasAttribute may not be native 
    36284176    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; 
    36294177  } 
     
    36314179 
    36324180/*--------------------------------------------------------------------------*/ 
     4181 
    36334182 
    36344183Abstract.TimedObserver = Class.create(PeriodicalExecuter, { 
     
    37134262  } 
    37144263}); 
    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  
     4264(function() { 
     4265 
     4266  var Event = { 
     4267    KEY_BACKSPACE: 8, 
     4268    KEY_TAB:       9, 
     4269    KEY_RETURN:   13, 
     4270    KEY_ESC:      27, 
     4271    KEY_LEFT:     37, 
     4272    KEY_UP:       38, 
     4273    KEY_RIGHT:    39, 
     4274    KEY_DOWN:     40, 
     4275    KEY_DELETE:   46, 
     4276    KEY_HOME:     36, 
     4277    KEY_END:      35, 
     4278    KEY_PAGEUP:   33, 
     4279    KEY_PAGEDOWN: 34, 
     4280    KEY_INSERT:   45, 
     4281 
     4282    cache: {} 
     4283  }; 
     4284 
     4285  var docEl = document.documentElement; 
     4286  var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl 
     4287    && 'onmouseleave' in docEl; 
     4288 
     4289  var _isButton; 
    37494290  if (Prototype.Browser.IE) { 
    37504291    var buttonMap = { 0: 1, 1: 4, 2: 2 }; 
    3751     isButton = function(event, code) { 
    3752       return event.button == buttonMap[code]; 
     4292    _isButton = function(event, code) { 
     4293      return event.button === buttonMap[code]; 
    37534294    }; 
    3754  
    37554295  } else if (Prototype.Browser.WebKit) { 
    3756     isButton = function(event, code) { 
     4296    _isButton = function(event, code) { 
    37574297      switch (code) { 
    37584298        case 0: return event.which == 1 && !event.metaKey; 
     
    37614301      } 
    37624302    }; 
    3763  
    37644303  } else { 
    3765     isButton = function(event, code) { 
     4304    _isButton = function(event, code) { 
    37664305      return event.which ? (event.which === code + 1) : (event.button === code); 
    37674306    }; 
    37684307  } 
    37694308 
    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     } 
     4309  function isLeftClick(event)   { return _isButton(event, 0) } 
     4310 
     4311  function isMiddleClick(event) { return _isButton(event, 1) } 
     4312 
     4313  function isRightClick(event)  { return _isButton(event, 2) } 
     4314 
     4315  function element(event) { 
     4316    event = Event.extend(event); 
     4317 
     4318    var node = event.target, type = event.type, 
     4319     currentTarget = event.currentTarget; 
     4320 
     4321    if (currentTarget && currentTarget.tagName) { 
     4322      if (type === 'load' || type === 'error' || 
     4323        (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' 
     4324          && currentTarget.type === 'radio')) 
     4325            node = currentTarget; 
     4326    } 
     4327 
     4328    if (node.nodeType == Node.TEXT_NODE) 
     4329      node = node.parentNode; 
     4330 
     4331    return Element.extend(node); 
     4332  } 
     4333 
     4334  function findElement(event, expression) { 
     4335    var element = Event.element(event); 
     4336    if (!expression) return element; 
     4337    var elements = [element].concat(element.ancestors()); 
     4338    return Selector.findElement(elements, expression, 0); 
     4339  } 
     4340 
     4341  function pointer(event) { 
     4342    return { x: pointerX(event), y: pointerY(event) }; 
     4343  } 
     4344 
     4345  function pointerX(event) { 
     4346    var docElement = document.documentElement, 
     4347     body = document.body || { scrollLeft: 0 }; 
     4348 
     4349    return event.pageX || (event.clientX + 
     4350      (docElement.scrollLeft || body.scrollLeft) - 
     4351      (docElement.clientLeft || 0)); 
     4352  } 
     4353 
     4354  function pointerY(event) { 
     4355    var docElement = document.documentElement, 
     4356     body = document.body || { scrollTop: 0 }; 
     4357 
     4358    return  event.pageY || (event.clientY + 
     4359       (docElement.scrollTop || body.scrollTop) - 
     4360       (docElement.clientTop || 0)); 
     4361  } 
     4362 
     4363 
     4364  function stop(event) { 
     4365    Event.extend(event); 
     4366    event.preventDefault(); 
     4367    event.stopPropagation(); 
     4368 
     4369    event.stopped = true; 
     4370  } 
     4371 
     4372  Event.Methods = { 
     4373    isLeftClick: isLeftClick, 
     4374    isMiddleClick: isMiddleClick, 
     4375    isRightClick: isRightClick, 
     4376 
     4377    element: element, 
     4378    findElement: findElement, 
     4379 
     4380    pointer: pointer, 
     4381    pointerX: pointerX, 
     4382    pointerY: pointerY, 
     4383 
     4384    stop: stop 
    38054385  }; 
    3806 })(); 
    3807  
    3808 Event.extend = (function() { 
     4386 
     4387 
    38094388  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { 
    38104389    m[name] = Event.Methods[name].methodize(); 
     
    38134392 
    38144393  if (Prototype.Browser.IE) { 
     4394    function _relatedTarget(event) { 
     4395      var element; 
     4396      switch (event.type) { 
     4397        case 'mouseover': element = event.fromElement; break; 
     4398        case 'mouseout':  element = event.toElement;   break; 
     4399        default: return null; 
     4400      } 
     4401      return Element.extend(element); 
     4402    } 
     4403 
    38154404    Object.extend(methods, { 
    38164405      stopPropagation: function() { this.cancelBubble = true }, 
    38174406      preventDefault:  function() { this.returnValue = false }, 
    3818       inspect: function() { return "[object Event]" } 
     4407      inspect: function() { return '[object Event]' } 
    38194408    }); 
    38204409 
    3821     return function(event) { 
     4410    Event.extend = function(event, element) { 
    38224411      if (!event) return false; 
    38234412      if (event._extendedByPrototype) return event; 
     
    38254414      event._extendedByPrototype = Prototype.emptyFunction; 
    38264415      var pointer = Event.pointer(event); 
     4416 
    38274417      Object.extend(event, { 
    3828         target: event.srcElement, 
    3829         relatedTarget: Event.relatedTarget(event), 
     4418        target: event.srcElement || element, 
     4419        relatedTarget: _relatedTarget(event), 
    38304420        pageX:  pointer.x, 
    38314421        pageY:  pointer.y 
    38324422      }); 
     4423 
    38334424      return Object.extend(event, methods); 
    38344425    }; 
    3835  
    38364426  } else { 
    3837     Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__; 
     4427    Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__; 
    38384428    Object.extend(Event.prototype, methods); 
    3839     return Prototype.K; 
    3840   } 
     4429    Event.extend = Prototype.K; 
     4430  } 
     4431 
     4432  function _createResponder(element, eventName, handler) { 
     4433    var registry = Element.retrieve(element, 'prototype_event_registry'); 
     4434 
     4435    if (Object.isUndefined(registry)) { 
     4436      CACHE.push(element); 
     4437      registry = Element.retrieve(element, 'prototype_event_registry', $H()); 
     4438    } 
     4439 
     4440    var respondersForEvent = registry.get(eventName); 
     4441    if (Object.isUndefined(respondersForEvent)) { 
     4442      respondersForEvent = []; 
     4443      registry.set(eventName, respondersForEvent); 
     4444    } 
     4445 
     4446    if (respondersForEvent.pluck('handler').include(handler)) return false; 
     4447 
     4448    var responder; 
     4449    if (eventName.include(":")) { 
     4450      responder = function(event) { 
     4451        if (Object.isUndefined(event.eventName)) 
     4452          return false; 
     4453 
     4454        if (event.eventName !== eventName) 
     4455          return false; 
     4456 
     4457        Event.extend(event, element); 
     4458        handler.call(element, event); 
     4459      }; 
     4460    } else { 
     4461      if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && 
     4462       (eventName === "mouseenter" || eventName === "mouseleave")) { 
     4463        if (eventName === "mouseenter" || eventName === "mouseleave") { 
     4464          responder = function(event) { 
     4465            Event.extend(event, element); 
     4466 
     4467            var parent = event.relatedTarget; 
     4468            while (parent && parent !== element) { 
     4469              try { parent = parent.parentNode; } 
     4470              catch(e) { parent = element; } 
     4471            } 
     4472 
     4473            if (parent === element) return; 
     4474 
     4475            handler.call(element, event); 
     4476          }; 
     4477        } 
     4478      } else { 
     4479        responder = function(event) { 
     4480          Event.extend(event, element); 
     4481          handler.call(element, event); 
     4482        }; 
     4483      } 
     4484    } 
     4485 
     4486    responder.handler = handler; 
     4487    respondersForEvent.push(responder); 
     4488    return responder; 
     4489  } 
     4490 
     4491  function _destroyCache() { 
     4492    for (var i = 0, length = CACHE.length; i < length; i++) { 
     4493      Event.stopObserving(CACHE[i]); 
     4494      CACHE[i] = null; 
     4495    } 
     4496  } 
     4497 
     4498  var CACHE = []; 
     4499 
     4500  if (Prototype.Browser.IE) 
     4501    window.attachEvent('onunload', _destroyCache); 
     4502 
     4503  if (Prototype.Browser.WebKit) 
     4504    window.addEventListener('unload', Prototype.emptyFunction, false); 
     4505 
     4506 
     4507  var _getDOMEventName = Prototype.K; 
     4508 
     4509  if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { 
     4510    _getDOMEventName = function(eventName) { 
     4511      var translations = { mouseenter: "mouseover", mouseleave: "mouseout" }; 
     4512      return eventName in translations ? translations[eventName] : eventName; 
     4513    }; 
     4514  } 
     4515 
     4516  function observe(element, eventName, handler) { 
     4517    element = $(element); 
     4518 
     4519    var responder = _createResponder(element, eventName, handler); 
     4520 
     4521    if (!responder) return element; 
     4522 
     4523    if (eventName.include(':')) { 
     4524      if (element.addEventListener) 
     4525        element.addEventListener("dataavailable", responder, false); 
     4526      else { 
     4527        element.attachEvent("ondataavailable", responder); 
     4528        element.attachEvent("onfilterchange", responder); 
     4529      } 
     4530    } else { 
     4531      var actualEventName = _getDOMEventName(eventName); 
     4532 
     4533      if (element.addEventListener) 
     4534        element.addEventListener(actualEventName, responder, false); 
     4535      else 
     4536        element.attachEvent("on" + actualEventName, responder); 
     4537    } 
     4538 
     4539    return element; 
     4540  } 
     4541 
     4542  function stopObserving(element, eventName, handler) { 
     4543    element = $(element); 
     4544 
     4545    var registry = Element.retrieve(element, 'prototype_event_registry'); 
     4546 
     4547    if (Object.isUndefined(registry)) return element; 
     4548 
     4549    if (eventName && !handler) { 
     4550      var responders = registry.get(eventName); 
     4551 
     4552      if (Object.isUndefined(responders)) return element; 
     4553 
     4554      responders.each( function(r) { 
     4555        Element.stopObserving(element, eventName, r.handler); 
     4556      }); 
     4557      return element; 
     4558    } else if (!eventName) { 
     4559      registry.each( function(pair) { 
     4560        var eventName = pair.key, responders = pair.value; 
     4561 
     4562        responders.each( function(r) { 
     4563          Element.stopObserving(element, eventName, r.handler); 
     4564        }); 
     4565      }); 
     4566      return element; 
     4567    } 
     4568 
     4569    var responders = registry.get(eventName); 
     4570 
     4571    if (!responders) return; 
     4572 
     4573    var responder = responders.find( function(r) { return r.handler === handler; }); 
     4574    if (!responder) return element; 
     4575 
     4576    var actualEventName = _getDOMEventName(eventName); 
     4577 
     4578    if (eventName.include(':')) { 
     4579      if (element.removeEventListener) 
     4580        element.removeEventListener("dataavailable", responder, false); 
     4581      else { 
     4582        element.detachEvent("ondataavailable", responder); 
     4583        element.detachEvent("onfilterchange",  responder); 
     4584      } 
     4585    } else { 
     4586      if (element.removeEventListener) 
     4587        element.removeEventListener(actualEventName, responder, false); 
     4588      else 
     4589        element.detachEvent('on' + actualEventName, responder); 
     4590    } 
     4591 
     4592    registry.set(eventName, responders.without(responder)); 
     4593 
     4594    return element; 
     4595  } 
     4596 
     4597  function fire(element, eventName, memo, bubble) { 
     4598    element = $(element); 
     4599 
     4600    if (Object.isUndefined(bubble)) 
     4601      bubble = true; 
     4602 
     4603    if (element == document && document.createEvent && !element.dispatchEvent) 
     4604      element = document.documentElement; 
     4605 
     4606    var event; 
     4607    if (document.createEvent) { 
     4608      event = document.createEvent('HTMLEvents'); 
     4609      event.initEvent('dataavailable', true, true); 
     4610    } else { 
     4611      event = document.createEventObject(); 
     4612      event.eventType = bubble ? 'ondataavailable' : 'onfilterchange'; 
     4613    } 
     4614 
     4615    event.eventName = eventName; 
     4616    event.memo = memo || { }; 
     4617 
     4618    if (document.createEvent) 
     4619      element.dispatchEvent(event); 
     4620    else 
     4621      element.fireEvent(event.eventType, event); 
     4622 
     4623    return Event.extend(event); 
     4624  } 
     4625 
     4626 
     4627  Object.extend(Event, Event.Methods); 
     4628 
     4629  Object.extend(Event, { 
     4630    fire:          fire, 
     4631    observe:       observe, 
     4632    stopObserving: stopObserving 
     4633  }); 
     4634 
     4635  Element.addMethods({ 
     4636    fire:          fire, 
     4637 
     4638    observe:       observe, 
     4639 
     4640    stopObserving: stopObserving 
     4641  }); 
     4642 
     4643  Object.extend(document, { 
     4644    fire:          fire.methodize(), 
     4645 
     4646    observe:       observe.methodize(), 
     4647 
     4648    stopObserving: stopObserving.methodize(), 
     4649 
     4650    loaded:        false 
     4651  }); 
     4652 
     4653  if (window.Event) Object.extend(window.Event, Event); 
     4654  else window.Event = Event; 
    38414655})(); 
    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 }); 
    39964656 
    39974657(function() { 
    39984658  /* Support for the DOMContentLoaded event is based on work by Dan Webb, 
    3999      Matthias Miller, Dean Edwards and John Resig. */ 
     4659     Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ 
    40004660 
    40014661  var timer; 
     
    40034663  function fireContentLoadedEvent() { 
    40044664    if (document.loaded) return; 
    4005     if (timer) window.clearInterval(timer); 
    4006     document.fire("dom:loaded"); 
     4665    if (timer) window.clearTimeout(timer); 
    40074666    document.loaded = true; 
     4667    document.fire('dom:loaded'); 
     4668  } 
     4669 
     4670  function checkReadyState() { 
     4671    if (document.readyState === 'complete') { 
     4672      document.stopObserving('readystatechange', checkReadyState); 
     4673      fireContentLoadedEvent(); 
     4674    } 
     4675  } 
     4676 
     4677  function pollDoScroll() { 
     4678    try { document.documentElement.doScroll('left'); } 
     4679    catch(e) { 
     4680      timer = pollDoScroll.defer(); 
     4681      return; 
     4682    } 
     4683    fireContentLoadedEvent(); 
    40084684  } 
    40094685 
    40104686  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  
     4687    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); 
    40244688  } 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   } 
     4689    document.observe('readystatechange', checkReadyState); 
     4690    if (window == top) 
     4691      timer = pollDoScroll.defer(); 
     4692  } 
     4693 
     4694  Event.observe(window, 'load', fireContentLoadedEvent); 
    40334695})(); 
     4696 
     4697Element.addMethods(); 
     4698 
    40344699/*------------------------------- DEPRECATED -------------------------------*/ 
    40354700 
     
    40604725var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); 
    40614726 
    4062 // This should be moved to script.aculo.us; notice the deprecated methods 
    4063 // further below, that map to the newer Element methods. 
    40644727var 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 
    40684728  includeScrollOffsets: false, 
    40694729 
    4070   // must be called before calling withinIncludingScrolloffset, every time the 
    4071   // page is scrolled 
    40724730  prepare: function() { 
    40734731    this.deltaX =  window.pageXOffset 
     
    40814739  }, 
    40824740 
    4083   // caches x/y coordinate pair to use with overlap 
    40844741  within: function(element, x, y) { 
    40854742    if (this.includeScrollOffsets) 
     
    41084765  }, 
    41094766 
    4110   // within must be called directly before 
    41114767  overlap: function(mode, element) { 
    41124768    if (!mode) return 0; 
     
    41194775  }, 
    41204776 
    4121   // Deprecation layer -- use newer Element methods now (1.5.2). 
    41224777 
    41234778  cumulativeOffset: Element.Methods.cumulativeOffset, 
     
    42184873 
    42194874/*--------------------------------------------------------------------------*/ 
    4220  
    4221 Element.addMethods(); 
Note: See TracChangeset for help on using the changeset viewer.