text: 
  /**
   * Provides AJAX-like page updating via AHAH (Asynchronous HTML and HTTP).
   *
   * AHAH is a method of making a request via Javascript while viewing an HTML
   * page. The request returns a small chunk of HTML, which is then directly
   * injected into the page.
   *
   * Drupal uses this file to enhance form elements with #ahah[path] and
   * #ahah[wrapper] properties. If set, this file will automatically be included
   * to provide AHAH capabilities.
   */
  
  /**
   * Attaches the ahah behavior to each ahah form element.
   */
  Drupal.behaviors.ahah = function(context) {
    for (var base in Drupal.settings.ahah) {
      if (!$('#'+ base + '.ahah-processed').size()) {
        var element_settings = Drupal.settings.ahah[base];
  
        $(element_settings.selector).each(function() {
          element_settings.element = this;
          var ahah = new Drupal.ahah(base, element_settings);
        });
  
        $('#'+ base).addClass('ahah-processed');
      }
    }
  };
  
  /**
   * AHAH object.
   */
  Drupal.ahah = function(base, element_settings) {
    // Set the properties for this object.
    this.element = element_settings.element;
    this.selector = element_settings.selector;
    this.event = element_settings.event;
    this.keypress = element_settings.keypress;
    this.url = element_settings.url;
    this.wrapper = '#'+ element_settings.wrapper;
    this.effect = element_settings.effect;
    this.method = element_settings.method;
    this.progress = element_settings.progress;
    this.button = element_settings.button || { };
    this.immutable = element_settings.immutable;
    this.buildId = null;
  
    if (this.effect == 'none') {
      this.showEffect = 'show';
      this.hideEffect = 'hide';
      this.showSpeed = '';
    }
    else if (this.effect == 'fade') {
      this.showEffect = 'fadeIn';
      this.hideEffect = 'fadeOut';
      this.showSpeed = 'slow';
    }
    else {
      this.showEffect = this.effect + 'Toggle';
      this.hideEffect = this.effect + 'Toggle';
      this.showSpeed = 'slow';
    }
  
    // Record the form action and target, needed for iFrame file uploads.
    var form = $(this.element).parents('form');
    this.form_action = form.attr('action');
    this.form_target = form.attr('target');
    this.form_encattr = form.attr('encattr');
  
    // Set the options for the ajaxSubmit function.
    // The 'this' variable will not persist inside of the options object.
    var ahah = this;
    var options = {
      url: ahah.url,
      data: ahah.button,
      beforeSubmit: function(form_values, element_settings, options) {
        return ahah.beforeSubmit(form_values, element_settings, options);
      },
      beforeSend: function(request, options) {
        return ahah.beforeSend(request, options);
      },
      success: function(response, status) {
        // Sanity check for browser support (object expected).
        // When using iFrame uploads, responses must be returned as a string.
        if (typeof(response) == 'string') {
          response = Drupal.parseJson(response);
        }
        return ahah.success(response, status);
      },
      complete: function(response, status) {
        ahah.complete(response, status);
        if (status == 'error' || status == 'parsererror') {
          return ahah.error(response, ahah.url);
        }
      },
      dataType: 'json',
      type: 'POST'
    };
  
    // Bind the ajaxSubmit function to the element event.
    $(element_settings.element).bind(element_settings.event, function() {
      $(element_settings.element).parents('form').ajaxSubmit(options);
      return false;
    });
    // If necessary, enable keyboard submission so that AHAH behaviors
    // can be triggered through keyboard input as well as e.g. a mousedown
    // action.
    if (element_settings.keypress) {
      $(element_settings.element).keypress(function(event) {
        // Detect enter key.
        if (event.keyCode == 13) {
          $(element_settings.element).trigger(element_settings.event);
          return false;
        }
      });
    }
  };
  
  /**
   * Handler for the form redirection submission.
   */
  Drupal.ahah.prototype.beforeSubmit = function (form_values, element, options) {
    // Disable the element that received the change.
    $(this.element).addClass('progress-disabled').attr('disabled', true);
  
    // Insert progressbar or throbber.
    if (this.progress.type == 'bar') {
      var progressBar = new Drupal.progressBar('ahah-progress-' + this.element.id, eval(this.progress.update_callback), this.progress.method, eval(this.progress.error_callback));
      if (this.progress.message) {
        progressBar.setProgress(-1, this.progress.message);
      }
      if (this.progress.url) {
        progressBar.startMonitoring(this.progress.url, this.progress.interval || 1500);
      }
      this.progress.element = $(progressBar.element).addClass('ahah-progress ahah-progress-bar');
      this.progress.object = progressBar;
      $(this.element).after(this.progress.element);
    }
    else if (this.progress.type == 'throbber') {
      this.progress.element = $('<div class="ahah-progress ahah-progress-throbber"><div class="throbber">&nbsp;</div></div>');
      if (this.progress.message) {
        $('.throbber', this.progress.element).after('<div class="message">' + this.progress.message + '</div>')
      }
      $(this.element).after(this.progress.element);
    }
  
    // Record the build-id.
    if (this.immutable) {
      var ahah = this;
      $.each(form_values, function () {
        if (this.name == 'form_build_id') {
          ahah.buildId = this.value;
          return false;
        }
      });
    }
  };
  
  /**
   * Modify the request object before it is sent.
   */
  Drupal.ahah.prototype.beforeSend = function (request, options) {
    if (this.immutable) {
      request.setRequestHeader('X-Drupal-Accept-Build-Id', '1');
    }
  }
  
  /**
   * Handler for the form redirection completion.
   */
  Drupal.ahah.prototype.success = function (response, status) {
    var wrapper = $(this.wrapper);
    var form = $(this.element).parents('form');
    // Manually insert HTML into the jQuery object, using $() directly crashes
    // Safari with long string lengths. http://dev.jquery.com/ticket/1152
    var new_content = $('<div></div>').html(response.data);
  
    // Restore the previous action and target to the form.
    form.attr('action', this.form_action);
    this.form_target ? form.attr('target', this.form_target) : form.removeAttr('target');
    this.form_encattr ? form.attr('target', this.form_encattr) : form.removeAttr('encattr');
  
    // Remove the progress element.
    if (this.progress.element) {
      $(this.progress.element).remove();
    }
    if (this.progress.object) {
      this.progress.object.stopMonitoring();
    }
    $(this.element).removeClass('progress-disabled').attr('disabled', false);
  
    // Add the new content to the page.
    Drupal.freezeHeight();
    if (this.method == 'replace') {
      wrapper.empty().append(new_content);
    }
    else {
      wrapper[this.method](new_content);
    }
  
    // Immediately hide the new content if we're using any effects.
    if (this.showEffect != 'show') {
      new_content.hide();
    }
  
    // Determine what effect use and what content will receive the effect, then
    // show the new content. For browser compatibility, Safari is excluded from
    // using effects on table rows.
    if (($.browser.safari && $("tr.ahah-new-content", new_content).size() > 0)) {
      new_content.show();
    }
    else if ($('.ahah-new-content', new_content).size() > 0) {
      $('.ahah-new-content', new_content).hide();
      new_content.show();
      $(".ahah-new-content", new_content)[this.showEffect](this.showSpeed);
    }
    else if (this.showEffect != 'show') {
      new_content[this.showEffect](this.showSpeed);
    }
  
    // Attach all javascript behaviors to the new content, if it was successfully
    // added to the page, this if statement allows #ahah[wrapper] to be optional.
    if (new_content.parents('html').length > 0) {
      Drupal.attachBehaviors(new_content);
    }
  
    Drupal.unfreezeHeight();
  };
  
  /**
   * Handler for the form redirection error.
   */
  Drupal.ahah.prototype.error = function (response, uri) {
    alert(Drupal.ahahError(response, uri));
    // Restore the previous action and target to the form.
    $(this.element).parent('form').attr( { action: this.form_action, target: this.form_target} );
    // Remove the progress element.
    if (this.progress.element) {
      $(this.progress.element).remove();
    }
    if (this.progress.object) {
      this.progress.object.stopMonitoring();
    }
    // Undo hide.
    $(this.wrapper).show();
    // Re-enable the element.
    $(this.element).removeClass('progress-disabled').attr('disabled', false);
  };
  
  /**
   * Handler called when the request finishes, whether in failure or success.
   */
  Drupal.ahah.prototype.complete = function (response, status) {
    // Update form build id if necessary.
    if (this.immutable) {
      var newBuildId = response.getResponseHeader('X-Drupal-Build-Id');
      if (this.buildId && newBuildId && this.buildId != newBuildId) {
        var $element = $('input[name="form_build_id"][value="' + this.buildId + '"]');
        $element.val(newBuildId);
        $element.attr('id', newBuildId);
      }
      this.buildId = null;
    }
  }
  