
(function ($) {

Drupal.Nodejs = Drupal.Nodejs || {'presenceCallbacks': {}, 'callbacks': {}, 'socket': false, 'connectionSetupHandlers': {}};

Drupal.behaviors.nodejs = {
  attach: function (context, settings) {
    if (!Drupal.Nodejs.socket) {
      if (Drupal.Nodejs.connect()) {
        Drupal.Nodejs.sendAuthMessage();
      }
    }
  }
};

Drupal.Nodejs.runCallbacks = function (message) {
  // It's possible that this message originated from an ajax request from the
  // client associated with this socket.
  if (message.clientSocketId == Drupal.Nodejs.socket.socket.sessionid) {
    return;
  }

  if (message.callback && $.isFunction(Drupal.Nodejs.callbacks[message.callback].callback)) {
    try {
      Drupal.Nodejs.callbacks[message.callback].callback(message);
    }
    catch (exception) {}
  }
  else if (message.presenceNotification != undefined) {
    $.each(Drupal.Nodejs.presenceCallbacks, function () {
      if ($.isFunction(this.callback)) {
        try {
          this.callback(message);
        }
        catch (exception) {}
      }
    });
  }
  else {
    $.each(Drupal.Nodejs.callbacks, function () {
      if ($.isFunction(this.callback)) {
        try {
          this.callback(message);
        }
        catch (exception) {}
      }
    });
  }
};

Drupal.Nodejs.runSetupHandlers = function (type) {
  $.each(Drupal.Nodejs.connectionSetupHandlers, function () {
    if ($.isFunction(this[type])) {
      try {
        this[type]();
      }
      catch (exception) {}
    }
  });
};

Drupal.Nodejs.connect = function () {
  var scheme = Drupal.settings.nodejs.secure ? 'https' : 'http',
      url = scheme + '://' + Drupal.settings.nodejs.host + ':' + Drupal.settings.nodejs.port;
  Drupal.settings.nodejs.connectTimeout = Drupal.settings.nodejs.connectTimeout || 5000;
  if (typeof io === 'undefined') {
     return false;
  }
  Drupal.Nodejs.socket = io.connect(url, {'connect timeout': Drupal.settings.nodejs.connectTimeout});
  Drupal.Nodejs.socket.on('connect', function() {
    Drupal.Nodejs.sendAuthMessage();
    Drupal.Nodejs.runSetupHandlers('connect');
    Drupal.Nodejs.socket.on('message', Drupal.Nodejs.runCallbacks);

    // Monkey-patch Drupal.ajax.prototype.beforeSerialize to auto-magically
    // send sessionId for AJAX requests so we can exclude the current browser
    // window from resulting notifications. We do this so that modules can hook
    // in to other modules ajax requests without having to patch them.
    Drupal.Nodejs.originalBeforeSerialize = Drupal.ajax.prototype.beforeSerialize;
    Drupal.ajax.prototype.beforeSerialize = function(element_settings, options) {
      options.data['nodejs_client_socket_id'] = Drupal.Nodejs.socket.socket.sessionid;
      return Drupal.Nodejs.originalBeforeSerialize(element_settings, options);
    };
  });
  Drupal.Nodejs.socket.on('disconnect', function() {
    Drupal.Nodejs.runSetupHandlers('disconnect');
    Drupal.ajax.prototype.beforeSerialize = Drupal.Nodejs.originalBeforeSerialize;
  });
  setTimeout("Drupal.Nodejs.checkConnection()", Drupal.settings.nodejs.connectTimeout + 250);
};

Drupal.Nodejs.checkConnection = function () {
  if (!Drupal.Nodejs.socket.socket.connected) {
    Drupal.Nodejs.runSetupHandlers('connectionFailure');
  }
};

Drupal.Nodejs.sendAuthMessage = function () {
  var authMessage = {
    authToken: Drupal.settings.nodejs.authToken,
    contentTokens: Drupal.settings.nodejs.contentTokens
  };
  Drupal.Nodejs.socket.emit('authenticate', authMessage);
};

})(jQuery);

// vi:ai:expandtab:sw=2 ts=2

;

(function ($) {
  Drupal.Panels = {};

  Drupal.Panels.autoAttach = function() {
    if ($.browser.msie) {
      // If IE, attach a hover event so we can see our admin links.
      $("div.panel-pane").hover(
        function() {
          $('div.panel-hide', this).addClass("panel-hide-hover"); return true;
        },
        function() {
          $('div.panel-hide', this).removeClass("panel-hide-hover"); return true;
        }
      );
      $("div.admin-links").hover(
        function() {
          $(this).addClass("admin-links-hover"); return true;
        },
        function(){
          $(this).removeClass("admin-links-hover"); return true;
        }
      );
    }
  };

  $(Drupal.Panels.autoAttach);
})(jQuery);
;
/*
 * jQuery autoResize (textarea auto-resizer)
 * @copyright James Padolsey http://james.padolsey.com
 * @version 1.04
 */

(function($){
    
    $.fn.autoResize = function(options) {
        
        // Just some abstracted details,
        // to make plugin users happy:
        var settings = $.extend({
            onResize : function(){},
            animate : true,
            animateDuration : 150,
            animateCallback : function(){},
            extraSpace : 20,
            limit: 1000
        }, options);
        
        // Only textarea's auto-resize:
        this.filter('textarea').each(function(){
            
                // Get rid of scrollbars and disable WebKit resizing:
            var textarea = $(this).css({resize:'none','overflow-y':'hidden'}),
            
                // Cache original height, for use later:
                origHeight = textarea.height(),
                
                // Need clone of textarea, hidden off screen:
                clone = (function(){
                    
                    // Properties which may effect space taken up by chracters:
                    var props = ['height','width','lineHeight','textDecoration','letterSpacing'],
                        propOb = {};
                        
                    // Create object of styles to apply:
                    $.each(props, function(i, prop){
                        propOb[prop] = textarea.css(prop);
                    });
                    
                    // Clone the actual textarea removing unique properties
                    // and insert before original textarea:
                    return textarea.clone().removeAttr('id').removeAttr('name').css({
                        position: 'absolute',
                        top: 0,
                        left: -9999
                    }).css(propOb).attr('tabIndex','-1').insertBefore(textarea);
          
                })(),
                lastScrollTop = null,
                updateSize = function() {
          
                    // Prepare the clone:
                    clone.height(0).val($(this).val()).scrollTop(10000);
          
                    // Find the height of text:
                    var scrollTop = Math.max(clone.scrollTop(), origHeight) + settings.extraSpace,
                        toChange = $(this).add(clone);
            
                    // Don't do anything if scrollTip hasen't changed:
                    if (lastScrollTop === scrollTop) { return; }
                    lastScrollTop = scrollTop;
          
                    // Check for limit:
                    if ( scrollTop >= settings.limit ) {
                        $(this).css('overflow-y','');
                        return;
                    }
                    // Fire off callback:
                    settings.onResize.call(this);
          
                    // Either animate or directly apply height:
                    settings.animate && textarea.css('display') === 'block' ?
                        toChange.stop().animate({height:scrollTop}, settings.animateDuration, settings.animateCallback)
                        : toChange.height(scrollTop);
                };
            
            // Bind namespaced handlers to appropriate events:
            textarea
                .unbind('.dynSiz')
                .bind('keyup.dynSiz', updateSize)
                .bind('keydown.dynSiz', updateSize)
                .bind('change.dynSiz', updateSize);
            
        });
        
        // Chain:
        return this;
        
    };
    
    
    
})(jQuery);;
(function($) {

  /**
   * Heartbeat comments object
   */
  Drupal.heartbeat = Drupal.heartbeat || {};
  Drupal.heartbeat.comments = Drupal.heartbeat.comments || {};
  Drupal.heartbeat.comments.button = null;
  Drupal.heartbeat.comments.autoGrowArea = null;
  
  /**
   * Attach behaviours to the message streams
   */
  Drupal.behaviors.heartbeatComments = {
    attach: function (context, settings) {

      // Hook into submit button for comments.      
      Drupal.heartbeatCommentButton(context);

      // Allow the comment textarea's to grow with the comment length.
      $('.heartbeat-comments .autoGrow', context).once('textarea', function () {
        
        $(this).autoResize({
          // On resize:
          onResize : function() {
            $(this).css({opacity:0.8});
          },
          // After resize:
          animateCallback : function() {
            $(this).css({opacity:1});
          },
          // Quite slow animation:
          animateDuration : 300,
          // More extra space:
          extraSpace : 0
        });
        
      });
      
    }
  };
  
  /**
   * Toggle the comment box.
   */
  Drupal.heartbeat.comments.toggleComments = function (element, uaid) {
    $(element).closest('.heartbeat-activity').find('#heartbeat-comments-wrapper-' + uaid).toggle('fast');
  };
  
  /**
   * Ajax method to load comments for an activity message (and its node).
   */
  Drupal.heartbeat.comments.load = function (uaid, node_comment, nid) {
    var url = Drupal.settings.basePath + 'heartbeat/comments/load/js';
    $.post(url, 
      {uaid: uaid, node_comment: node_comment, nid: nid}, 
      Drupal.heartbeat.comments.loaded, 
      'json');
  };
  
  /**
   * After ajax-load comments function.
   */
  Drupal.heartbeat.comments.loaded = function(data) {
  
    if (data.data != undefined) {
      $('#heartbeat-comments-wrapper-' + data.uaid).html(data.data);
    }
    
  };
  
  /**
   * Class heartbeatCommentButton
   * 
   * Heartbeat comment buttons for the page.
   */
  Drupal.heartbeatCommentButton = function(context) {

    /**
     * Submit handler for a comment for a heartbeat message or its node.
     */
    function commentSubmit() {
      
      var element = this;

      // If the button is set to disabled, don't do anything or if 
      // the field is blank, don't do anything.
      Drupal.heartbeat.comments.field = $(element).parents('form').find('.heartbeat-message-comment');
      if ($(element).attr("disabled") || Drupal.heartbeat.comments.field.val() == ''){
        return false;
      }

      // Throw in the throbber
      Drupal.heartbeat.comments.button = $(element);
      Drupal.heartbeat.wait(Drupal.heartbeat.comments.button, '.heartbeat-comments-wrapper');
      Drupal.heartbeat.comments.button.attr("disabled", "disabled");
      
      var formElement = $(element).parents('form');
      
      // Disable form element, uncomment the line below
      formElement.find('.heartbeat-message-comment').attr('disabled', 'disabled');
      
      var url = Drupal.settings.basePath + 'heartbeat/comment/post';
      var nid = formElement.find('.heartbeat-message-nid').val();
      var node_comment = formElement.find('.heartbeat-message-node-comment').val();
      var arr_list = $('#heartbeat-comments-list-' + formElement.find('.heartbeat-message-uaid').val());

      var args = {
        message: formElement.find('.heartbeat-message-comment').val(), 
        uaid: formElement.find('.heartbeat-message-uaid').val(), 
        nid: (nid == undefined ? 0 : nid), 
        node_comment: (node_comment == undefined ? 0 : node_comment),
        path: location.href,
        first_comment: !(arr_list.length)
      };

      // Send POST request
      $.ajax({
        type: 'POST',
        url: url, //element.href,
        data: args,
        dataType: 'json',
        success: commentSubmitted,
        error: function (xmlhttp) {
          alert('An HTTP error '+ xmlhttp.status +' occurred.\n'+ url);
          Drupal.heartbeat.doneWaiting();
          Drupal.heartbeat.comments.button.removeAttr("disabled");
        }
      });
      
      return false;

    }
    
    /**
     * Function callback after comment has been submitted.
     */
    function commentSubmitted(data) {
    
      if (data.id != undefined) {
        
        var oldest_first = Drupal.settings.heartbeat_comments_order == 'oldest_on_top';
        var list_first = Drupal.settings.heartbeat_comments_position == 'up';
        var arr_list = $('#heartbeat-comments-list-' + data.id);
        
        // If no comments have been posted yet for this activity.
        if (!(arr_list.length)) {
          
          // The created ul or div wrapper is created in PHP.
          if (list_first) {
            var new_comment = $('#heartbeat-comments-wrapper-' + data.id + ' .heartbeat-comments').prepend(data.data);
          }
          else {
            var new_comment = $('#heartbeat-comments-wrapper-' + data.id + ' .heartbeat-comments').append(data.data);
          }
          
        }
        // Add the comment to the rest.
        else {
          
          if (oldest_first) {
            // Here there is a change the "heartbeat-comment-more" is present.
            if ($('#heartbeat-comments-list-' + data.id + ' .heartbeat-comment-more').length > 0) {
              var new_comment = $('#heartbeat-comments-list-' + data.id + ' .heartbeat-comment-more').before(data.data);
            }
            else {
              var new_comment = $('#heartbeat-comments-list-' + data.id).append(data.data);
            }
          }
          else {
            var new_comment = $('#heartbeat-comments-list-' + data.id).prepend(data.data);
            
          }
          
        }
        
        $('#heartbeat-comments-wrapper-' + data.id + ' .heartbeat-comments textarea').each(function(){
          $(this).val('');
        });
        
        // Update the count of the comments.
        var button = $(data.newButton);
        $('.heartbeat-attachment-button',  $('.heartbeat-activity-' + data.id)).after(button).remove();
        
        // Reattach the behaviors for the newly added content (or list).
        Drupal.attachBehaviors(new_comment);
        Drupal.attachBehaviors(button);
        
        Drupal.heartbeat.doneWaiting();
        Drupal.heartbeat.comments.button.removeAttr("disabled");
        
        $('#heartbeat-comments-list-' + data.id).parent().parent().find('.heartbeat-message-comment').removeAttr("disabled");
        
      }
    };

    $('input.heartbeat-comment-submit:not(.heartbeat-processed)', context)
      .addClass('heartbeat-processed')
      .click(commentSubmit);
    
  };
  
})(jQuery);;
(function ($) {

$(document).ready(function() {

  // Accepts a string; returns the string with regex metacharacters escaped. The returned string
  // can safely be used at any point within a regex to match the provided literal string. Escaped
  // characters are [ ] { } ( ) * + ? - . , \ ^ $ # and whitespace. The character | is excluded
  // in this function as it's used to separate the domains names.
  RegExp.escapeDomains = function(text) {
    return (text) ? text.replace(/[-[\]{}()*+?.,\\^$#\s]/g, "\\$&") : '';
  }

  // Attach onclick event to document only and catch clicks on all elements.
  $(document.body).click(function(event) {
    // Catch the closest surrounding link of a clicked element.
    $(event.target).closest("a,area").each(function() {

      var ga = Drupal.settings.googleanalytics;
      // Expression to check for absolute internal links.
      var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i");
      // Expression to check for special links like gotwo.module /go/* links.
      var isInternalSpecial = new RegExp("(\/go\/.*)$", "i");
      // Expression to check for download links.
      var isDownload = new RegExp("\\.(" + ga.trackDownloadExtensions + ")$", "i");
      // Expression to check for the sites cross domains.
      var isCrossDomain = new RegExp("^(https?|ftp|news|nntp|telnet|irc|ssh|sftp|webcal):\/\/.*(" + RegExp.escapeDomains(ga.trackCrossDomains) + ")", "i");

      // Is the clicked URL internal?
      if (isInternal.test(this.href)) {
        // Is download tracking activated and the file extension configured for download tracking?
        if (ga.trackDownload && isDownload.test(this.href)) {
          // Download link clicked.
          var extension = isDownload.exec(this.href);
          _gaq.push(["_trackEvent", "Downloads", extension[1].toUpperCase(), this.href.replace(isInternal, '')]);
        }
        else if (isInternalSpecial.test(this.href)) {
          // Keep the internal URL for Google Analytics website overlay intact.
          _gaq.push(["_trackPageview", this.href.replace(isInternal, '')]);
        }
      }
      else {
        if (ga.trackMailto && $(this).is("a[href^=mailto:],area[href^=mailto:]")) {
          // Mailto link clicked.
          _gaq.push(["_trackEvent", "Mails", "Click", this.href.substring(7)]);
        }
        else if (ga.trackOutbound && this.href) {
          if (ga.trackDomainMode == 2 && isCrossDomain.test(this.href)) {
            // Top-level cross domain clicked. document.location is handled by _link internally.
            _gaq.push(["_link", this.href]);
          }
          else if (ga.trackOutboundAsPageview) {
            // Track all external links as page views after URL cleanup.
            // Currently required, if click should be tracked as goal.
            _gaq.push(["_trackPageview", '/outbound/' + this.href.replace(/^(https?|ftp|news|nntp|telnet|irc|ssh|sftp|webcal):\/\//i, '').split('/').join('--')]);
          }
          else {
            // External link clicked.
            _gaq.push(["_trackEvent", "Outbound links", "Click", this.href]);
          }
        }
      }
    });
  });
});

})(jQuery);
;

