<commit_before>$(document).on('click', '#chat_button', function() {
    var screen_top = $(window).scrollTop();
    $('#chat_menu').css('top', screen_top);
    $('html').toggleClass('chat_menu_open');
});

$(document).on('click', '.chat_header, .chat_option', function() {
    $('.chat_box').toggleClass('active');
});
$(document).on('submit', '#create_messge_form', function(){
    $('#create_messge_form input').val('');
    $('#message').attr('disabled','disabled');
	var user = $('#message').data('user');
    $theForm = $(this);
    // send xhr request
    $.ajax({
        type: "post",
        url: "/chat_msg/new",
        beforeSend: function(xhr){
            xhr.setRequestHeader('X-CSRF-Token', $('meta[name="_csrf"]').attr('content'))
        },
        data: {
			channelId: '0',
			username: user,
            data: $('#message').val()
        },
        success: function (data) {
            $('#chat_conversation').scrollTop($('#chat_conversation')[0].scrollHeight);
            $('#message').removeAttr('disabled');
        }
    });

    // prevent submitting again
    return false;
});

$(function(){
    $('#chat_conversation').scrollTop($('#chat_conversation')[0].scrollHeight);
});

setInterval(function() {
    var mid = $('.chat_msg').length ? $('.chat_msg:last').data('message-id') : 0;
    $.ajax({
        type: "POST",
        url: "/chat_msg/read",
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-CSRF-Token', $('meta[name="_csrf"]').attr('content'))
        },
        data: {
            mid: mid,
        },
        success: function (data) {
            $('#chat_conversation').append(data);
        }
    });
}, 1000);<commit_msg>message ids<commit_after>$(document).on('click', '#chat_button', function() {
    var screen_top = $(window).scrollTop();
    $('#chat_menu').css('top', screen_top);
    $('html').toggleClass('chat_menu_open');
});

$(document).on('click', '.chat_header, .chat_option', function() {
    $('.chat_box').toggleClass('active');
});
$(document).on('submit', '#create_messge_form', function(){
    var data = $('#message').val();
    $('#message').val('');
    $('#message').attr('disabled','disabled');
	var user = $('#message').data('user');
    $theForm = $(this);
    // send xhr request
    $.ajax({
        type: "post",
        url: "/chat_msg/new",
        beforeSend: function(xhr){
            xhr.setRequestHeader('X-CSRF-Token', $('meta[name="_csrf"]').attr('content'))
        },
        data: {
			channelId: '0',
			username: user,
            data: data
        },
        success: function (data) {
            $('#chat_conversation').scrollTop($('#chat_conversation')[0].scrollHeight);
            $('#message').removeAttr('disabled');
        }
    });

    // prevent submitting again
    return false;
});

$(function(){
    console.log($('#chat_conversation')[0].scrollHeight);
    $('#chat_conversation').scrollTop($('#chat_conversation')[0].scrollHeight);
});

setInterval(function() {
    var mid = $('.chat_msg').length ? $('.chat_msg:last').data('message-id') : 0;
    $.ajax({
        type: "POST",
        url: "/chat_msg/read",
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-CSRF-Token', $('meta[name="_csrf"]').attr('content'))
        },
        data: {
            mid: mid,
        },
        success: function (data) {
            $('#chat_conversation').append(data);
        }
    });
}, 1000);<|endoftext|>


<commit_before>export class InputTracker {
  constructor(element, notifier) {
    this.element = element
    this.notifier = notifier
    this.element.data("initial-value", this.element.val())
    this.element.data("tracker", this)
    this.element.change(this.value_changed)
  }

  reset() {
    this.element.data("initial-value", this.element.val())
    this.notifier.mark_unchanged(this.element)
  }

  get value_changed() {
    return () => {
      if(this.element.val() == this.element.data("initial-value")) {
        this.notifier.mark_unchanged(this.element)
      } else {
        this.notifier.push_changed(this.element)
      }
    }
  }
}
export class FileManagerMember {
  constructor(element, save_manager) {
    this.element = element
    this.save_manager = save_manager
    this.elements = []
    this.track_label()
  }

  push_changed(element) {
    this.elements.push(element)
    this.elements = $.unique(this.elements)
    this.save_manager.push_changed(this)
  }

  mark_unchanged(element) {
    this.elements = jQuery.grep(this.elements, (value) => {
      return value != element
    })
    if(!this.is_changed) {
      this.save_manager.mark_unchanged(this)
    }
  }

  get is_changed() {
    return this.elements.length > 0
  }

  track_label() {
    new InputTracker(this.element.find("input[type='text']"), this)
  }

  persist() {
    if(this.is_changed) {
      let form = this.element.find("form")
      let deferred = $.Deferred()
      this.element.addClass("pending")
      this.element.removeClass("success")
      this.element.removeClass("failure")
      form.on("ajax:success", () => {
        this.elements.forEach((element) => {
          element.data("tracker").reset()
        })
        deferred.resolve()
        this.element.addClass("success")
        this.element.removeClass("failure")
        this.element.removeClass("pending")
      })
      form.on("ajax:error", () => {
        deferred.reject()
        this.element.addClass("failure")
        this.element.removeClass("success")
        this.element.removeClass("pending")
      })
      // unset the callbacks after they've run so they don't build up
      // and consume memory
      deferred.always(function() {
        form.off('ajax:success')
        form.off('ajax:error')
      })
      form.submit()
      return deferred
    } else {
      return $.Deferred().resolve()
    }
  }
}

<commit_msg>Add documentation to a method<commit_after>export class InputTracker {
  /*
   * @param element {jQuery} The field to bind to. Typically instantiated for
   *                         the titles of each member (file_set) object as well
   *                         the hidden work thumbnail_id and representative_id
   * @param notifier {FileManagerMember}
   */
  constructor(element, notifier) {
    this.element = element
    this.notifier = notifier
    this.element.data("initial-value", this.element.val())
    this.element.data("tracker", this)
    this.element.change(this.value_changed)
  }

  reset() {
    this.element.data("initial-value", this.element.val())
    this.notifier.mark_unchanged(this.element)
  }

  get value_changed() {
    return () => {
      if(this.element.val() == this.element.data("initial-value")) {
        this.notifier.mark_unchanged(this.element)
      } else {
        this.notifier.push_changed(this.element)
      }
    }
  }
}
export class FileManagerMember {
  constructor(element, save_manager) {
    this.element = element
    this.save_manager = save_manager
    this.elements = []
    this.track_label()
  }

  push_changed(element) {
    this.elements.push(element)
    this.elements = $.unique(this.elements)
    this.save_manager.push_changed(this)
  }

  mark_unchanged(element) {
    this.elements = jQuery.grep(this.elements, (value) => {
      return value != element
    })
    if(!this.is_changed) {
      this.save_manager.mark_unchanged(this)
    }
  }

  get is_changed() {
    return this.elements.length > 0
  }

  track_label() {
    new InputTracker(this.element.find("input[type='text']"), this)
  }

  persist() {
    if(this.is_changed) {
      let form = this.element.find("form")
      let deferred = $.Deferred()
      this.element.addClass("pending")
      this.element.removeClass("success")
      this.element.removeClass("failure")
      form.on("ajax:success", () => {
        this.elements.forEach((element) => {
          element.data("tracker").reset()
        })
        deferred.resolve()
        this.element.addClass("success")
        this.element.removeClass("failure")
        this.element.removeClass("pending")
      })
      form.on("ajax:error", () => {
        deferred.reject()
        this.element.addClass("failure")
        this.element.removeClass("success")
        this.element.removeClass("pending")
      })
      // unset the callbacks after they've run so they don't build up
      // and consume memory
      deferred.always(function() {
        form.off('ajax:success')
        form.off('ajax:error')
      })
      form.submit()
      return deferred
    } else {
      return $.Deferred().resolve()
    }
  }
}

<|endoftext|>


<commit_before>var eventThrottler = function(eventHandler) {
  var eventHandlerTimeout;
  return function(event) {
    // ignore events as long as an eventHandler execution is in the queue
    if ( !eventHandlerTimeout ) {
      eventHandlerTimeout = setTimeout(function() {
        eventHandlerTimeout = null;
        eventHandler(event);
        // The eventHandler will execute at a rate of 15fps
      }, 66);
    }
  };
};

var scrollSpy = {

  spyCallbacks: [],
  spySetState: [],
  scrollSpyContainers: [],

  mount: function (scrollSpyContainer) {
    var t = this;
    if (scrollSpyContainer) {
      var eventHandler = eventThrottler(function(event) {
  			t.scrollHandler(scrollSpyContainer);
  		});
      this.scrollSpyContainers.push(scrollSpyContainer);
      scrollSpyContainer.addEventListener('scroll', eventHandler);
    }
  },

  isMounted: function (scrollSpyContainer) {
    return this.scrollSpyContainers.indexOf(scrollSpyContainer) !== -1;
  },

  currentPositionY: function (scrollSpyContainer) {
    if(scrollSpyContainer === document) {
      var supportPageOffset = window.pageXOffset !== undefined;
      var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat");
      return supportPageOffset ? window.pageYOffset : isCSS1Compat ?
      document.documentElement.scrollTop : document.body.scrollTop;
    } else {
      return scrollSpyContainer.scrollTop;
    }
  },

  scrollHandler: function (scrollSpyContainer) {
    var callbacks = this.scrollSpyContainers[this.scrollSpyContainers.indexOf(scrollSpyContainer)].spyCallbacks;
    for(var i = 0; i < callbacks.length; i++) {
      var position =this.currentPositionY(scrollSpyContainer);
      callbacks[i](this.currentPositionY(scrollSpyContainer));
    }
  },

  addStateHandler: function(handler){
    this.spySetState.push(handler);
  },

  addSpyHandler: function(handler, scrollSpyContainer) {
    var container = this.scrollSpyContainers[this.scrollSpyContainers.indexOf(scrollSpyContainer)];
    if(!container.spyCallbacks) {
      container.spyCallbacks = [];
    }
    container.spyCallbacks.push(handler);
  },

  updateStates: function(){
    var length = this.spySetState.length;

    for(var i = 0; i < length; i++) {
      this.spySetState[i]();
    }
  },

  unmount: function () {
    for (var i = 0; i < this.scrollSpyContainers.length; i++) {
      this.scrollSpyContainers[i].spyCallbacks = [];
    }
    this.spySetState = [];

    document.removeEventListener('scroll', this.scrollHandler);
  },

  update: function() {
    for (var i = 0; i < this.scrollSpyContainers.length; i++) {
      this.scrollHandler(this.scrollSpyContainers[i]);
    }
  }
}

module.exports = scrollSpy;
<commit_msg>Handle length of undefined when scrollSpyContainer is missing spyCallbacks (#118)<commit_after>var eventThrottler = function(eventHandler) {
  var eventHandlerTimeout;
  return function(event) {
    // ignore events as long as an eventHandler execution is in the queue
    if ( !eventHandlerTimeout ) {
      eventHandlerTimeout = setTimeout(function() {
        eventHandlerTimeout = null;
        eventHandler(event);
        // The eventHandler will execute at a rate of 15fps
      }, 66);
    }
  };
};

var scrollSpy = {

  spyCallbacks: [],
  spySetState: [],
  scrollSpyContainers: [],

  mount: function (scrollSpyContainer) {
    var t = this;
    if (scrollSpyContainer) {
      var eventHandler = eventThrottler(function(event) {
        t.scrollHandler(scrollSpyContainer);
      });
      this.scrollSpyContainers.push(scrollSpyContainer);
      scrollSpyContainer.addEventListener('scroll', eventHandler);
    }
  },

  isMounted: function (scrollSpyContainer) {
    return this.scrollSpyContainers.indexOf(scrollSpyContainer) !== -1;
  },

  currentPositionY: function (scrollSpyContainer) {
    if(scrollSpyContainer === document) {
      var supportPageOffset = window.pageXOffset !== undefined;
      var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat");
      return supportPageOffset ? window.pageYOffset : isCSS1Compat ?
      document.documentElement.scrollTop : document.body.scrollTop;
    } else {
      return scrollSpyContainer.scrollTop;
    }
  },

  scrollHandler: function (scrollSpyContainer) {
    var callbacks = this.scrollSpyContainers[this.scrollSpyContainers.indexOf(scrollSpyContainer)].spyCallbacks;
    if (callbacks) {
      for(var i = 0; i < callbacks.length; i++) {
        var position =this.currentPositionY(scrollSpyContainer);
        callbacks[i](this.currentPositionY(scrollSpyContainer));
      }
    }
  },

  addStateHandler: function(handler){
    this.spySetState.push(handler);
  },

  addSpyHandler: function(handler, scrollSpyContainer) {
    var container = this.scrollSpyContainers[this.scrollSpyContainers.indexOf(scrollSpyContainer)];
    if(!container.spyCallbacks) {
      container.spyCallbacks = [];
    }
    container.spyCallbacks.push(handler);
  },

  updateStates: function(){
    var length = this.spySetState.length;

    for(var i = 0; i < length; i++) {
      this.spySetState[i]();
    }
  },

  unmount: function () {
    for (var i = 0; i < this.scrollSpyContainers.length; i++) {
      this.scrollSpyContainers[i].spyCallbacks = [];
    }
    this.spySetState = [];

    document.removeEventListener('scroll', this.scrollHandler);
  },

  update: function() {
    for (var i = 0; i < this.scrollSpyContainers.length; i++) {
      this.scrollHandler(this.scrollSpyContainers[i]);
    }
  }
}

module.exports = scrollSpy;
<|endoftext|>


<commit_before>import Ember from 'ember';
import Strings from '../utils/mappings/strings';
import Health from '../utils/mappings/health';
import healthToString from '../utils/convert/health-to-string';
import healthToIconClass from '../utils/convert/health-to-icon-class';
import operationalToString from '../utils/convert/operational-to-string';
import operationalToIconClass from '../utils/convert/operational-to-icon-class';
import slaToString from '../utils/convert/sla-to-string';
import slaToIconClass from '../utils/convert/sla-to-icon-class';
import trustToString from '../utils/convert/trust-to-string';
import trustToIconClass from '../utils/convert/trust-to-icon-class';
import stripFloat from '../utils/strip-float';

export default Ember.Mixin.create({
  healthMessage: function() {
    return 'Health: ' + healthToString(this.get('status.health'), 'good').capitalize();
  }.property('status.health'),
  healthIconClass: function() {
    return healthToIconClass(this.get('status.health'));
  }.property('status.health'),
  operationalMessage: function() {
    return 'Operational State: ' + operationalToString(this.get('status.operational')).capitalize();
  }.property('status.operational'),
  operationalIconClass: function() {
    return operationalToIconClass(this.get('status.operational'));
  }.property('status.operational'),
  slaMessage: function() {
    return 'SLA Status: ' + slaToString(this.get('status.sla_status')).capitalize();
  }.property('status.sla_status'),
  slaIconClass: function() {
    return slaToIconClass(this.get('status.sla_status'));
  }.property('status.sla_status'),
  trustMessage: function() {
    return 'Trust Status: ' + trustToString(this.get('status.trust')).capitalize();
  }.property('status.trust'),
  trustIconClass: function() {
    return trustToIconClass(this.get('status.trust'));
  }.property('status.trust'),
  memoryCurrent: function() {
    var memoryCurrent = parseInt(this.get('utilization.memory'));
    if (typeof memoryCurrent !== 'number') return null;
    return (memoryCurrent / Math.pow(1024, 2));  // To GiB, assuming KiB
  }.property('utilization.memory'),
  memoryMax: function() {
    var memoryMax = parseInt(this.get('capabilities.memory_size'));
    if (typeof memoryMax !== 'number') return null;
    return (memoryMax / Math.pow(1024, 2));  // To GiB, assuming KiB
  }.property('capabilities.memory_size'),
  memoryPercent: function() {
    if (Ember.isEmpty(this.get('memoryCurrent')) || Ember.isEmpty(this.get('memoryMax'))) return null;
    return ((this.get('memoryCurrent') / this.get('memoryMax')) * 100).toFixed(0) + '%';
  }.property('memoryCurrent', 'memoryMax'),
  memoryStyle: function() {
    return 'width:' + this.get('memoryPercent');
  }.property('memoryPercent'),
  contentionCurrent: function() {
    var contention = this.get('contention.system.llc.value');
    if (Ember.isEmpty(contention) || !(contention >= 0)) return null;
    return contention;
  }.property('contention.system.llc.value'),
  contentionPercent: function() {
    var contentionMax = 50;
    if (Ember.isEmpty(this.get('contentionCurrent'))) return null;
    var percent = (this.get('contentionCurrent') / contentionMax) * 100;
    if (percent > 0 && percent < 2) percent = 2;  // If any contention exists, show at least a small bar
    return percent.toFixed(0) + '%';
  }.property('contentionCurrent'),
  contentionStyle: function() {
    return 'width:' + this.get('contentionPercent');
  }.property('contentionPercent'),
  cpuFrequency: function() {
    var cpuFrequency = parseInt(this.get('node.capabilities.cpu_frequency')) / 1000;
    if (isNaN(cpuFrequency)) return Strings.NA;
    return stripFloat(cpuFrequency) + ' GHz';
  }.property('node.capabilities.cpu_frequency'),
  hasCores: Ember.computed.notEmpty('capabilities.cores'),
  cores: function() {
    var cores = this.get('capabilities.cores');
    if (Ember.isEmpty(cores)) return Strings.NA;
    return cores + ((cores === 1) ? ' core' : ' cores');
  }.property('capabilities.cores'),
  hasVcpus: Ember.computed.notEmpty('capabilities.vcpus'),
  vcpus: function() {
    var vcpus = this.get('capabilities.vcpus');
    if (Ember.isEmpty(vcpus)) return Strings.NA;
    return vcpus + ((vcpus === 1) ? ' vCPU' : ' vCPUs');
  }.property('capabilities.vcpus'),
  isAggressor: Ember.computed.gte('status.aggressor', Health.INFO),
  isVictim: Ember.computed.gte('status.victim', Health.INFO),

  // Compute SCU allocation floor/ceiling computed properties
  hasCompute: function() {
    return !Ember.isEmpty(this.get('utilizationTotal')) && !Ember.isEmpty(this.get('suFloor'));
  }.property('utilizationTotal', 'suFloor'),
  suFloor: Ember.computed.alias('capabilities.scu_allocated_min'),
  suCeiling: Ember.computed.alias('capabilities.scu_allocated_max'),
  isRange: function() {
    if (Ember.isEmpty(this.get('suFloor'))) return false;
    if (this.get('suFloor') > this.get('suCeiling')) return false;
    return this.get('suFloor') !== this.get('suCeiling');
  }.property('suFloor', 'suCeiling'),
  allocationMin: function() {
    if (Ember.isEmpty(this.get('capabilities.scu_allocated_min'))) return 0;
    if (!this.get('isRange')) return 100;
    return 100 * parseFloat(this.get('capabilities.scu_allocated_min')) / parseFloat(this.get('capabilities.scu_allocated_max'));
  }.property('isRange', 'capabilities.scu_allocated_min', 'capabilities.scu_allocated_max'),
  allocationMinWidth: function() {
    return 'width:' + this.get('allocationMin') + 'px;';
  }.property('allocationMin'),
  allocationMessage: function() {
    var message = '';
    if (this.get('isRange')) {
      message += 'Utilization: ' + stripFloat(this.get('utilizationTotal')) + '\n';
      if (this.get('utilizationBurst')) {
        message += 'Non-bursting: ' + stripFloat(this.get('utilizationCurrent')) + '\n';
        message += 'Bursting: ' + this.get('utilizationBurst').toFixed(2) + '\n';
      }
      message += 'Min Allocated: ' + stripFloat(this.get('capabilities.scu_allocated_min')) + '\n';
      message += 'Burst Allocated: ' + stripFloat(this.get('capabilities.scu_allocated_max'));
    } else {
      message += 'Utilization: ' + stripFloat(this.get('utilizationTotal')) + '\n';
      if (this.get('utilizationBurst')) {
        message += 'Non-bursting: ' + stripFloat(this.get('utilizationCurrent')) + '\n';
        message += 'Bursting: ' + stripFloat(this.get('utilizationBurst')) + '\n';
      }
      message += 'Allocated: ' + stripFloat(this.get('capabilities.scu_allocated_min'));
    }
    return message;
  }.property('isRange', 'utilizationTotal', 'utilizationCurrent', 'utilizationBurst', 'capabilities.scu_allocated_min', 'capabilities.scu_allocated_max'),
  utilizationBurst: function() {
    var burst =  this.get('capabilities.scu_allocated_min') - this.get('scuTotal');
    if (Ember.isEmpty(burst)) burst = 0;
    return stripFloat(burst);
  }.property('capabilities.scu_allocated_min', 'scuTotal'),
  utilizationTotal: function() {
    var utilization = this.get('scuTotal');
    if (Ember.isEmpty(utilization)) utilization = this.get('utilization.scu_max');
    if (Ember.isEmpty(utilization) || !(utilization >= 0)) return null;
    return utilization;
  }.property('scuTotal', 'utilization.scu_max'),
  utilizationCurrent: function() {
    var total = this.get('utilizationTotal');
    if (Ember.isEmpty(total)) total = 0;
    return Math.max(0, total - this.get('utilizationBurst'));
  }.property('utilizationTotal', 'utilizationBurst'),
  utilizationBurstWidth: function() {
    if (Ember.isEmpty(this.get('capabilities.scu_allocated_max'))) return null;
    var percent = 100 * parseFloat(this.get('utilizationBurst')) / parseFloat(this.get('capabilities.scu_allocated_max'));
    return 'width:' + percent.toFixed(0) + 'px;';
  }.property('utilizationBurst', 'capabilities.scu_allocated_max'),
  utilizationCurrentWidth: function() {
    if (Ember.isEmpty(this.get('capabilities.scu_allocated_max'))) return null;
    var percent = 100 * parseFloat(this.get('utilizationCurrent')) / parseFloat(this.get('capabilities.scu_allocated_max'));
    return 'width:' + percent.toFixed(0) + 'px;';
  }.property('utilizationCurrent', 'capabilities.scu_allocated_max'),
  utilizationBurstLeft: function() {
    var percent;
    if (Ember.isEmpty(this.get('capabilities.scu_allocated_max'))) return null;
    if (!this.get('isRange')) {
      // Current
      percent = 100 * parseFloat(this.get('utilizationCurrent')) / parseFloat(this.get('capabilities.scu_allocated_max'));
      return 'left:' + percent.toFixed(0) + 'px;';
    } else {
      // Max of current and scu_allocated_min
      var left = Math.max(this.get('utilizationCurrent'), this.get('capabilities.scu_allocated_min'));
      percent = (100 * left / parseFloat(this.get('capabilities.scu_allocated_max'))) + 1;
      return 'left:' + percent.toFixed(0) + 'px;';
    }
  }.property('isRange', 'capabilities.scu_allocated_max', 'utilizationCurrent'),
  utilizationBurstStyle: function() {
    return this.get('utilizationBurstWidth') + this.get('utilizationBurstLeft');
  }.property('utilizationBurstWidth', 'utilizationBurstLeft')
});
<commit_msg>Format cache contention to be 2 digits<commit_after>import Ember from 'ember';
import Strings from '../utils/mappings/strings';
import Health from '../utils/mappings/health';
import healthToString from '../utils/convert/health-to-string';
import healthToIconClass from '../utils/convert/health-to-icon-class';
import operationalToString from '../utils/convert/operational-to-string';
import operationalToIconClass from '../utils/convert/operational-to-icon-class';
import slaToString from '../utils/convert/sla-to-string';
import slaToIconClass from '../utils/convert/sla-to-icon-class';
import trustToString from '../utils/convert/trust-to-string';
import trustToIconClass from '../utils/convert/trust-to-icon-class';
import stripFloat from '../utils/strip-float';

export default Ember.Mixin.create({
  healthMessage: function() {
    return 'Health: ' + healthToString(this.get('status.health'), 'good').capitalize();
  }.property('status.health'),
  healthIconClass: function() {
    return healthToIconClass(this.get('status.health'));
  }.property('status.health'),
  operationalMessage: function() {
    return 'Operational State: ' + operationalToString(this.get('status.operational')).capitalize();
  }.property('status.operational'),
  operationalIconClass: function() {
    return operationalToIconClass(this.get('status.operational'));
  }.property('status.operational'),
  slaMessage: function() {
    return 'SLA Status: ' + slaToString(this.get('status.sla_status')).capitalize();
  }.property('status.sla_status'),
  slaIconClass: function() {
    return slaToIconClass(this.get('status.sla_status'));
  }.property('status.sla_status'),
  trustMessage: function() {
    return 'Trust Status: ' + trustToString(this.get('status.trust')).capitalize();
  }.property('status.trust'),
  trustIconClass: function() {
    return trustToIconClass(this.get('status.trust'));
  }.property('status.trust'),
  memoryCurrent: function() {
    var memoryCurrent = parseInt(this.get('utilization.memory'));
    if (typeof memoryCurrent !== 'number') return null;
    return (memoryCurrent / Math.pow(1024, 2));  // To GiB, assuming KiB
  }.property('utilization.memory'),
  memoryMax: function() {
    var memoryMax = parseInt(this.get('capabilities.memory_size'));
    if (typeof memoryMax !== 'number') return null;
    return (memoryMax / Math.pow(1024, 2));  // To GiB, assuming KiB
  }.property('capabilities.memory_size'),
  memoryPercent: function() {
    if (Ember.isEmpty(this.get('memoryCurrent')) || Ember.isEmpty(this.get('memoryMax'))) return null;
    return ((this.get('memoryCurrent') / this.get('memoryMax')) * 100).toFixed(0) + '%';
  }.property('memoryCurrent', 'memoryMax'),
  memoryStyle: function() {
    return 'width:' + this.get('memoryPercent');
  }.property('memoryPercent'),
  contentionCurrent: function() {
    var contention = this.get('contention.system.llc.value');
    if (Ember.isEmpty(contention) || !(contention >= 0)) return null;
    return contention.toFixed(2);
  }.property('contention.system.llc.value'),
  contentionPercent: function() {
    var contentionMax = 50;
    if (Ember.isEmpty(this.get('contentionCurrent'))) return null;
    var percent = (this.get('contentionCurrent') / contentionMax) * 100;
    if (percent > 0 && percent < 2) percent = 2;  // If any contention exists, show at least a small bar
    return percent.toFixed(0) + '%';
  }.property('contentionCurrent'),
  contentionStyle: function() {
    return 'width:' + this.get('contentionPercent');
  }.property('contentionPercent'),
  cpuFrequency: function() {
    var cpuFrequency = parseInt(this.get('node.capabilities.cpu_frequency')) / 1000;
    if (isNaN(cpuFrequency)) return Strings.NA;
    return stripFloat(cpuFrequency) + ' GHz';
  }.property('node.capabilities.cpu_frequency'),
  hasCores: Ember.computed.notEmpty('capabilities.cores'),
  cores: function() {
    var cores = this.get('capabilities.cores');
    if (Ember.isEmpty(cores)) return Strings.NA;
    return cores + ((cores === 1) ? ' core' : ' cores');
  }.property('capabilities.cores'),
  hasVcpus: Ember.computed.notEmpty('capabilities.vcpus'),
  vcpus: function() {
    var vcpus = this.get('capabilities.vcpus');
    if (Ember.isEmpty(vcpus)) return Strings.NA;
    return vcpus + ((vcpus === 1) ? ' vCPU' : ' vCPUs');
  }.property('capabilities.vcpus'),
  isAggressor: Ember.computed.gte('status.aggressor', Health.INFO),
  isVictim: Ember.computed.gte('status.victim', Health.INFO),

  // Compute SCU allocation floor/ceiling computed properties
  hasCompute: function() {
    return !Ember.isEmpty(this.get('utilizationTotal')) && !Ember.isEmpty(this.get('suFloor'));
  }.property('utilizationTotal', 'suFloor'),
  suFloor: Ember.computed.alias('capabilities.scu_allocated_min'),
  suCeiling: Ember.computed.alias('capabilities.scu_allocated_max'),
  isRange: function() {
    if (Ember.isEmpty(this.get('suFloor'))) return false;
    if (this.get('suFloor') > this.get('suCeiling')) return false;
    return this.get('suFloor') !== this.get('suCeiling');
  }.property('suFloor', 'suCeiling'),
  allocationMin: function() {
    if (Ember.isEmpty(this.get('capabilities.scu_allocated_min'))) return 0;
    if (!this.get('isRange')) return 100;
    return 100 * parseFloat(this.get('capabilities.scu_allocated_min')) / parseFloat(this.get('capabilities.scu_allocated_max'));
  }.property('isRange', 'capabilities.scu_allocated_min', 'capabilities.scu_allocated_max'),
  allocationMinWidth: function() {
    return 'width:' + this.get('allocationMin') + 'px;';
  }.property('allocationMin'),
  allocationMessage: function() {
    var message = '';
    if (this.get('isRange')) {
      message += 'Utilization: ' + stripFloat(this.get('utilizationTotal')) + '\n';
      if (this.get('utilizationBurst')) {
        message += 'Non-bursting: ' + stripFloat(this.get('utilizationCurrent')) + '\n';
        message += 'Bursting: ' + this.get('utilizationBurst').toFixed(2) + '\n';
      }
      message += 'Min Allocated: ' + stripFloat(this.get('capabilities.scu_allocated_min')) + '\n';
      message += 'Burst Allocated: ' + stripFloat(this.get('capabilities.scu_allocated_max'));
    } else {
      message += 'Utilization: ' + stripFloat(this.get('utilizationTotal')) + '\n';
      if (this.get('utilizationBurst')) {
        message += 'Non-bursting: ' + stripFloat(this.get('utilizationCurrent')) + '\n';
        message += 'Bursting: ' + stripFloat(this.get('utilizationBurst')) + '\n';
      }
      message += 'Allocated: ' + stripFloat(this.get('capabilities.scu_allocated_min'));
    }
    return message;
  }.property('isRange', 'utilizationTotal', 'utilizationCurrent', 'utilizationBurst', 'capabilities.scu_allocated_min', 'capabilities.scu_allocated_max'),
  utilizationBurst: function() {
    var burst =  this.get('capabilities.scu_allocated_min') - this.get('scuTotal');
    if (Ember.isEmpty(burst)) burst = 0;
    return stripFloat(burst);
  }.property('capabilities.scu_allocated_min', 'scuTotal'),
  utilizationTotal: function() {
    var utilization = this.get('scuTotal');
    if (Ember.isEmpty(utilization)) utilization = this.get('utilization.scu_max');
    if (Ember.isEmpty(utilization) || !(utilization >= 0)) return null;
    return utilization;
  }.property('scuTotal', 'utilization.scu_max'),
  utilizationCurrent: function() {
    var total = this.get('utilizationTotal');
    if (Ember.isEmpty(total)) total = 0;
    return Math.max(0, total - this.get('utilizationBurst'));
  }.property('utilizationTotal', 'utilizationBurst'),
  utilizationBurstWidth: function() {
    if (Ember.isEmpty(this.get('capabilities.scu_allocated_max'))) return null;
    var percent = 100 * parseFloat(this.get('utilizationBurst')) / parseFloat(this.get('capabilities.scu_allocated_max'));
    return 'width:' + percent.toFixed(0) + 'px;';
  }.property('utilizationBurst', 'capabilities.scu_allocated_max'),
  utilizationCurrentWidth: function() {
    if (Ember.isEmpty(this.get('capabilities.scu_allocated_max'))) return null;
    var percent = 100 * parseFloat(this.get('utilizationCurrent')) / parseFloat(this.get('capabilities.scu_allocated_max'));
    return 'width:' + percent.toFixed(0) + 'px;';
  }.property('utilizationCurrent', 'capabilities.scu_allocated_max'),
  utilizationBurstLeft: function() {
    var percent;
    if (Ember.isEmpty(this.get('capabilities.scu_allocated_max'))) return null;
    if (!this.get('isRange')) {
      // Current
      percent = 100 * parseFloat(this.get('utilizationCurrent')) / parseFloat(this.get('capabilities.scu_allocated_max'));
      return 'left:' + percent.toFixed(0) + 'px;';
    } else {
      // Max of current and scu_allocated_min
      var left = Math.max(this.get('utilizationCurrent'), this.get('capabilities.scu_allocated_min'));
      percent = (100 * left / parseFloat(this.get('capabilities.scu_allocated_max'))) + 1;
      return 'left:' + percent.toFixed(0) + 'px;';
    }
  }.property('isRange', 'capabilities.scu_allocated_max', 'utilizationCurrent'),
  utilizationBurstStyle: function() {
    return this.get('utilizationBurstWidth') + this.get('utilizationBurstLeft');
  }.property('utilizationBurstWidth', 'utilizationBurstLeft')
});
<|endoftext|>


<commit_before>define([
  'extensions/views/table/table'
],
  function (Table) {

    var HelpUsageTable = Table.extend({

      capitalizeFirstWord: function(string) {
        return string.replace(/(?:^|\s)\S/, function(letter) { return letter.toUpperCase(); });
      },

      capitalizeSpecialWords: function(string) {
        return string.replace(/(\s|^)lpa(\s|$)/g, " LPA ")
                     .replace(/(\s|^)bacs(\s|$)/g, " BACS ")
                     .replace(/(\s|^)i(\s|$)/g, " I ");
      },

      sanitizeDescription: function (rawDescription) {
        var spaceSeparatedDescription = rawDescription.replace(/-/g, " "),
            lowercaseDescription = this.capitalizeSpecialWords(spaceSeparatedDescription);
        return this.capitalizeFirstWord(lowercaseDescription);
      },

      columns: [
        {
          id: 'description',
          title: 'Description',
          sortable: true,
          getValue: function (model) {
            return this.sanitizeDescription(model.get('description'));
          }
        },
        {
          id: 'count',
          className: 'count numeric',
          title: 'Usage last week',
          sortable: true,
          defaultDescending: true,
          getValue: function (model) {
            return this.formatNumericLabel(model.get('count'));
          }
        }
      ],

      defaultSortColumn: 1
    });

    return HelpUsageTable;
  });
<commit_msg>Refactor method to have an explicit list of special words<commit_after>define([
  'extensions/views/table/table'
],
  function (Table) {

    var HelpUsageTable = Table.extend({

      capitalizeFirstWord: function(string) {
        return string.replace(/(?:^|\s)\S/, function(letter) { return letter.toUpperCase(); });
      },

      capitalizeSpecialWords: function(string) {
        var specialWords = ["LPA", "BACS", "I"];

        return _.reduce(specialWords, function (newString, word) {
          var lowerCaseExpression = new RegExp("(\\s|^)" + word.toLowerCase() + "(\\s|$)", "g"),
              upperCaseReplacement = " " + word + " ";
          return newString.replace(lowerCaseExpression, upperCaseReplacement);
        }, string);
      },

      sanitizeDescription: function (rawDescription) {
        var spaceSeparatedDescription = rawDescription.replace(/-/g, " "),
            lowercaseDescription = this.capitalizeSpecialWords(spaceSeparatedDescription);
        return this.capitalizeFirstWord(lowercaseDescription);
      },

      columns: [
        {
          id: 'description',
          title: 'Description',
          sortable: true,
          getValue: function (model) {
            return this.sanitizeDescription(model.get('description'));
          }
        },
        {
          id: 'count',
          className: 'count numeric',
          title: 'Usage last week',
          sortable: true,
          defaultDescending: true,
          getValue: function (model) {
            return this.formatNumericLabel(model.get('count'));
          }
        }
      ],

      defaultSortColumn: 1
    });

    return HelpUsageTable;
  });
<|endoftext|>


<commit_before>const amqp = require('amqplib');
// const amqpSugar = require('amqplib-sugar');
const superagent = require('superagent-promise')(require('superagent'), Promise);
const GitHubProfile = require('./../modules/github/github.profile');
const gitHubProfileBL = require('./../modules/profile/profile.bl');
const logger = require('./../config/context').instance().logger;
const moment = require('moment');

const uri = process.env.SAMMLER_RABBITMQ_URI;
const SAMMLER_JOBS_SERVICE = process.env.SAMMLER_JOBS_SERVICE__URI;

// Todo: Remove, just a prototype
class MqWorker {
  constructor() {
    this.init();
    this.gitHubProfile = new GitHubProfile();
  }

  init() {
    this.listenProfileSyncRequested();
  }

  listenProfileSyncRequested() {
    const ex = 'github.profile-sync';
    const exchangeType = 'topic';
    const queueProfileSync = 'queue.github.profile-sync';

    amqp.connect(uri)
      .then(conn => {
        return conn.createChannel();
      })
      .then(channel => {
        return Promise.all([
          channel.assertExchange(ex, exchangeType),
          channel.assertQueue(queueProfileSync, {exclusive: false}),
          channel.bindQueue(queueProfileSync, ex, 'sync.requested'),
          channel.consume(queueProfileSync, msg => {

            const msgContent = JSON.parse(msg.content.toString());
            // eslint-disable-next-line quotes
            logger.silly(" [x] %s - %s:'%s'", '#', msg.fields.routingKey, msg.content.toString());

            // Mark job as running
            const jobId = msgContent.job_id;
            return superagent
              .patch(SAMMLER_JOBS_SERVICE + `/v1/jobs/${jobId}/status`)
              .send({status: 'running'})
              .then(() => {
                return this.gitHubProfile.getProfile()
                  .then(result => {
                    logger.silly('GitHub meta: ', result.meta);
                    // Todo: Something is wrong, the x-ratelimit-reset is always in the past
                    // https://developer.github.com/v3/#rate-limiting
                    logger.silly('Time to next reset: ', moment.utc(result.meta['x-ratelimit-reset'], 'X').format("DD-MM-YYYY HH:mm:ss"));
                    logger.silly('Time to next reset: ', new Date(result.meta['x-ratelimit-reset'] * 1000));
                    logger.silly('Time to next reset: ', new Date(result.meta['x-ratelimit-reset'] * 1000).toLocaleString());
                    return result;
                  })
                  .then(result => gitHubProfileBL.save(result))
                  .then(() => {
                    logger.silly('Complete job', jobId);
                    return superagent
                      .patch(SAMMLER_JOBS_SERVICE + `/v1/jobs/${jobId}/status`)
                      .send({status: 'completed'})
                  })
                  .then(() => {
                    superagent
                      .get(SAMMLER_JOBS_SERVICE + `/v1/jobs/${jobId}`)
                      .then(result => {
                        logger.silly('response.body', result.body);
                        return Promise.resolve();
                      })
                  })
                  .then(() => {
                    logger.silly('OK, ack');
                    channel.ack(msg);
                    return Promise.resolve();
                  })
              })
              .catch(err => {
                logger.error('err', err);
              });

          }, {noAck: false})
        ]);
      });
  }
}

module.exports = MqWorker;
<commit_msg>style: linting<commit_after>const amqp = require('amqplib');
// const amqpSugar = require('amqplib-sugar');
const superagent = require('superagent-promise')(require('superagent'), Promise);
const GitHubProfile = require('./../modules/github/github.profile');
const gitHubProfileBL = require('./../modules/profile/profile.bl');
const logger = require('./../config/context').instance().logger;
const moment = require('moment');

const uri = process.env.SAMMLER_RABBITMQ_URI;
const SAMMLER_JOBS_SERVICE = process.env.SAMMLER_JOBS_SERVICE__URI;

// Todo: Remove, just a prototype
class MqWorker {
  constructor() {
    this.init();
    this.gitHubProfile = new GitHubProfile();
  }

  init() {
    this.listenProfileSyncRequested();
  }

  listenProfileSyncRequested() {
    const ex = 'github.profile-sync';
    const exchangeType = 'topic';
    const queueProfileSync = 'queue.github.profile-sync';

    amqp.connect(uri)
      .then(conn => {
        return conn.createChannel();
      })
      .then(channel => {
        return Promise.all([
          channel.assertExchange(ex, exchangeType),
          channel.assertQueue(queueProfileSync, {exclusive: false}),
          channel.bindQueue(queueProfileSync, ex, 'sync.requested'),
          channel.consume(queueProfileSync, msg => {

            const msgContent = JSON.parse(msg.content.toString());
            // eslint-disable-next-line quotes
            logger.silly(" [x] %s - %s:'%s'", '#', msg.fields.routingKey, msg.content.toString());

            // Mark job as running
            const jobId = msgContent.job_id;
            return superagent
              .patch(SAMMLER_JOBS_SERVICE + `/v1/jobs/${jobId}/status`)
              .send({status: 'running'})
              .then(() => {
                return this.gitHubProfile.getProfile()
                  .then(result => {
                    logger.silly('GitHub meta: ', result.meta);
                    // Todo: Something is wrong, the x-ratelimit-reset is always in the past
                    // https://developer.github.com/v3/#rate-limiting
                    logger.silly('Time to next reset: ', moment.utc(result.meta['x-ratelimit-reset'], 'X').format("DD-MM-YYYY HH:mm:ss"));
                    logger.silly('Time to next reset: ', new Date(result.meta['x-ratelimit-reset'] * 1000));
                    logger.silly('Time to next reset: ', new Date(result.meta['x-ratelimit-reset'] * 1000).toLocaleString());
                    return result;
                  })
                  .then(result => gitHubProfileBL.save(result))
                  .then(() => {
                    logger.silly('Complete job', jobId);
                    return superagent
                      .patch(SAMMLER_JOBS_SERVICE + `/v1/jobs/${jobId}/status`)
                      .send({status: 'completed'});
                  })
                  // Todo: Delete, just for debugging purposes
                  .then(() => {
                    superagent
                      .get(SAMMLER_JOBS_SERVICE + `/v1/jobs/${jobId}`)
                      .then(result => {
                        logger.silly('response.body', result.body);
                        return Promise.resolve();
                      });
                  })
                  .then(() => {
                    logger.silly('OK, ack');
                    channel.ack(msg);
                    return Promise.resolve();
                  });
              })
              .catch(err => {
                logger.error('err', err);
              });

          }, {noAck: false})
        ]);
      });
  }
}

module.exports = MqWorker;
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');

const name = 'react-native-debugger-patch';
const startFlag = `/* ${name} start */`;
const endFlag = `/* ${name} end */`;
const keyFunc = 'launchChromeDevTools';
const funcFlag = `function ${keyFunc}(port) {`;
const replaceFuncFlag = `function ${keyFunc}(port, skipRNDebugger) {`;

exports.dir = 'local-cli/server/middleware';
exports.file = 'getDevToolsMiddleware.js';
exports.fullPath = path.join(exports.dir, exports.file);

exports.inject = modulePath => {
  const filePath = path.join(modulePath, exports.fullPath);
  if (!fs.existsSync(filePath)) return false;

  const code = [
    startFlag,
    'var _rndebuggerIsOpening = false;',
    replaceFuncFlag,
    '  if (process.platform === "darwin" && !skipRNDebugger) {',
    '    if (_rndebuggerIsOpening) return;',
    '    _rndebuggerIsOpening = true;',
    '    opn("rndebugger://set-debugger-loc?host=localhost&port=" + port, { wait: false }, err => {',
    '      if (err) {',
    '        console.log(',
    '          "\\nCannot open React Native Debugger, maybe not install?\\n" +',
    '          "(Please visit https://github.com/jhen0409/react-native-debugger#usage)\\n" +',
    '          "Or it\'s never started. (Not registered URI Scheme)\\n"',
    '        );',
    `        ${keyFunc}(port, true);`,
    '      }',
    '      _rndebuggerIsOpening = false;',
    '    });',
    '    return;',
    '  }',
    endFlag,
  ].join('\n');

  const middlewareCode = fs.readFileSync(filePath, 'utf-8');
  let start = middlewareCode.indexOf(startFlag);  // already injected ?
  let end = middlewareCode.indexOf(endFlag) + endFlag.length;
  if (start === -1) {
    start = middlewareCode.indexOf(funcFlag);
    end = start + funcFlag.length;
  }
  fs.writeFileSync(
    filePath,
    middlewareCode.substr(0, start) + code + middlewareCode.substr(end, middlewareCode.length)
  );
  return true;
};

exports.revert = modulePath => {
  const filePath = path.join(modulePath, exports.fullPath);
  if (!fs.existsSync(filePath)) return false;

  const middlewareCode = fs.readFileSync(filePath, 'utf-8');
  const start = middlewareCode.indexOf(startFlag); // already injected ?
  const end = middlewareCode.indexOf(endFlag) + endFlag.length;
  if (start !== -1) {
    fs.writeFileSync(
      filePath,
      middlewareCode.substr(0, start) + funcFlag + middlewareCode.substr(end, middlewareCode.length)
    );
  }
  return true;
};
<commit_msg>[Patch] Fix injectDevToolsMiddleware.path<commit_after>'use strict';

const fs = require('fs');
const path = require('path');

const name = 'react-native-debugger-patch';
const startFlag = `/* ${name} start */`;
const endFlag = `/* ${name} end */`;
const keyFunc = 'launchChromeDevTools';
const funcFlag = `function ${keyFunc}(port) {`;
const replaceFuncFlag = `function ${keyFunc}(port, skipRNDebugger) {`;

exports.dir = 'local-cli/server/middleware';
exports.file = 'getDevToolsMiddleware.js';
exports.path = path.join(exports.dir, exports.file);

exports.inject = modulePath => {
  const filePath = path.join(modulePath, exports.fullPath);
  if (!fs.existsSync(filePath)) return false;

  const code = [
    startFlag,
    'var _rndebuggerIsOpening = false;',
    replaceFuncFlag,
    '  if (process.platform === "darwin" && !skipRNDebugger) {',
    '    if (_rndebuggerIsOpening) return;',
    '    _rndebuggerIsOpening = true;',
    '    opn("rndebugger://set-debugger-loc?host=localhost&port=" + port, { wait: false }, err => {',
    '      if (err) {',
    '        console.log(',
    '          "\\nCannot open React Native Debugger, maybe not install?\\n" +',
    '          "(Please visit https://github.com/jhen0409/react-native-debugger#usage)\\n" +',
    '          "Or it\'s never started. (Not registered URI Scheme)\\n"',
    '        );',
    `        ${keyFunc}(port, true);`,
    '      }',
    '      _rndebuggerIsOpening = false;',
    '    });',
    '    return;',
    '  }',
    endFlag,
  ].join('\n');

  const middlewareCode = fs.readFileSync(filePath, 'utf-8');
  let start = middlewareCode.indexOf(startFlag);  // already injected ?
  let end = middlewareCode.indexOf(endFlag) + endFlag.length;
  if (start === -1) {
    start = middlewareCode.indexOf(funcFlag);
    end = start + funcFlag.length;
  }
  fs.writeFileSync(
    filePath,
    middlewareCode.substr(0, start) + code + middlewareCode.substr(end, middlewareCode.length)
  );
  return true;
};

exports.revert = modulePath => {
  const filePath = path.join(modulePath, exports.fullPath);
  if (!fs.existsSync(filePath)) return false;

  const middlewareCode = fs.readFileSync(filePath, 'utf-8');
  const start = middlewareCode.indexOf(startFlag); // already injected ?
  const end = middlewareCode.indexOf(endFlag) + endFlag.length;
  if (start !== -1) {
    fs.writeFileSync(
      filePath,
      middlewareCode.substr(0, start) + funcFlag + middlewareCode.substr(end, middlewareCode.length)
    );
  }
  return true;
};
<|endoftext|>


<commit_before>steal.then(function(){
	//adds open selector support to closest, but only on 1 element
	var oldClosest = jQuery.fn.closest;
	jQuery.fn.closest = function(selectors, context){
		var rooted = {}, res, result, thing, i, j, selector, rootedIsEmpty = true, selector;

		$.each(selectors, function(i, selector){
		    if(selector.indexOf(">") == 0 ){
				if(selector.indexOf(" ") != -1){
					throw " closest does not work with > followed by spaces!"
				}
				rooted[( selectors[i] = selector.substr(1)  )] = selector;
				rootedIsEmpty = false;
			}
		})

		res = oldClosest.call(this, selectors, context);

		if(rootedIsEmpty) return res;
		i =0;
		while(i < res.length){
			result = res[i], selector = result.selector;
			if (rooted[selector] !== undefined) {
				result.selector = rooted[selector];
				rooted[selector] = false;
				if(typeof result.selector !== "string"  || result.elem.parentNode !== context ){
					res.splice(i,1);
						continue;
				}
			}
			i++;
		}
		return res;
	}
})<commit_msg>changes to closest to allow selectors like >ul>li<commit_after>steal.then(function(){
	//adds open selector support to closest, but only on 1 element
	var oldClosest = jQuery.fn.closest;
	jQuery.fn.closest = function(selectors, context){
		var rooted = {}, res, result, thing, i, j, selector, matchEl,
			rootedIsEmpty = true, selector, nbrParents;

		$.each(selectors, function(i, selector){
		    if(selector.indexOf(">") == 0 ){
				if(selector.indexOf(" ") != -1){
					throw " closest does not work with > followed by spaces!"
				}
				rooted[( selectors[i] = selector.substr(1)  )] = selector;
				rootedIsEmpty = false;
			}
		})

		res = oldClosest.call(this, selectors, context);

		if(rootedIsEmpty) return res;
		i =0;
		while(i < res.length){
			result = res[i], selector = result.selector;
			if (rooted[selector] !== undefined) {
				result.selector = rooted[selector];
				rooted[selector] = false;
				if(typeof result.selector !== "string"){
				  nbrParents = selector.match(/>/g).length;
				  matchEl = result.elem;
				  for(j = 0; j<nbrParents.length; j++)
				  	matchEl = result.elem
				  if (matchEl !== context) {
				  	res.splice(i, 1);
				  	continue;
				  }
				}
			}
			i++;
		}
		return res;
	}
})<|endoftext|>


<commit_before>(function(debugParams) {

	var view = {
		map: L.map("map"),
		marker: null,
		bitsControl: {
			input: $("#bitsInput"),
			label: $("#bitsOutput")
		},
		debugLine: {
			pointLabel: $("#pointLabel"),
			hashLabel: $("#hashLabel")
		}
	};

	var controller = {
		onLocationChange: function(ev) {
			var point = ev.latlng;
			debugParams.lat = point.lat;
			debugParams.lng = point.lng;

			controller.updateMarker(point);
			controller.updatePointLabel(point);
			controller.requestHashData();
		},

		onBitsChanged: function() {
			debugParams.bits = view.bitsControl.input.val();
			view.bitsControl.label.text(debugParams.bits);
			controller.requestHashData();
		},

		requestHashData: function() {
			$.getJSON("/hashes/point?" + $.param(debugParams), controller.whenHashReceived);
		},

		whenHashReceived: function(hashData) {
			view.debugLine.hashLabel.text(hashData.binary);
		},

		setMarker: function(point) {
			view.marker = L.marker(point).addTo(view.map);
		},

		updateMarker: function(point) {
			view.marker.setLatLng(point).update();
		},

		updatePointLabel: function(point) {
			view.debugLine.pointLabel.text("(" + point.lat + ", " + point.lng + ")");
		},

		initMap: function(center) {
			view.map.setView(center, 12);
			L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
				attribution: '© OpenStreetMap contributors'
				}).addTo(view.map);
			view.map.on('click', controller.onLocationChange);
		},

		initBitsControl: function() {
			view.bitsControl.label.text(debugParams.bits);
			view.bitsControl.input.val(debugParams.bits);
			view.bitsControl.input.on('change', controller.onBitsChanged);
		},

		initView: function() {
			var mapCenter = [debugParams.lat, debugParams.lng];

			controller.initMap(mapCenter);
			controller.setMarker(mapCenter);
			controller.initBitsControl();

			controller.onLocationChange({latlng: debugParams});
		}
	};

	controller.initView();

})({lat:49.977, lng: 20.027, bits: 32});
<commit_msg>drawing bounding box of geohash, fit map to show it entirely<commit_after>(function(debugParams) {

	var view = {
		map: L.map("map"),
		marker: null,
		hashBounds: null,
		bitsControl: {
			input: $("#bitsInput"),
			label: $("#bitsOutput")
		},
		debugLine: {
			pointLabel: $("#pointLabel"),
			hashLabel: $("#hashLabel")
		}
	};

	var controller = {
		onLocationChange: function(ev) {
			var point = ev.latlng;
			debugParams.lat = point.lat;
			debugParams.lng = point.lng;

			controller.updateMarker(point);
			controller.updatePointLabel(point);
			controller.requestHashData();
		},

		onBitsChanged: function() {
			debugParams.bits = view.bitsControl.input.val();
			view.bitsControl.label.text(debugParams.bits);
			controller.requestHashData();
		},

		requestHashData: function() {
			$.getJSON("/hashes/point?" + $.param(debugParams), controller.whenHashReceived);
		},

		whenHashReceived: function(hashData) {
			view.debugLine.hashLabel.text(hashData.binary);
			controller.setHashBounds(hashData.bbox)
		},

		setHashBounds: function(bbox) {
			var bounds = [[bbox.minLat, bbox.minLng], [bbox.maxLat, bbox.maxLng]];
			if (null == view.hashBounds) {
				view.hashBounds = L.rectangle(bounds, {color: "#D8C358", fillOpacity: 0.75, weight: 1});
				view.hashBounds.addTo(view.map);
			} else {
				view.hashBounds.setBounds(bounds);
			}
			view.map.fitBounds(bounds);
		},

		setMarker: function(point) {
			view.marker = L.marker(point).addTo(view.map);
		},

		updateMarker: function(point) {
			view.marker.setLatLng(point).update();
		},

		updatePointLabel: function(point) {
			view.debugLine.pointLabel.text("(" + point.lat + ", " + point.lng + ")");
		},

		initMap: function(center) {
			view.map.setView(center, 12);
			L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
				attribution: '© OpenStreetMap contributors'
				}).addTo(view.map);
			view.map.on('click', controller.onLocationChange);
		},

		initBitsControl: function() {
			view.bitsControl.label.text(debugParams.bits);
			view.bitsControl.input.val(debugParams.bits);
			view.bitsControl.input.on('change', controller.onBitsChanged);
		},

		initView: function() {
			var mapCenter = [debugParams.lat, debugParams.lng];

			controller.initMap(mapCenter);
			controller.setMarker(mapCenter);
			controller.initBitsControl();

			controller.onLocationChange({latlng: debugParams});
		}
	};

	controller.initView();

})({lat:49.977, lng: 20.027, bits: 32});
<|endoftext|>


<commit_before>// Cancels out the automatic creation of isolate scope for the directive,
// because Angular 1.x allows only one isolate scope directive per element.
// This is useful when actually creating directives, which add behaviour
// to an existing element, as opposed to components which are stand alone
// bits of html and behaviour.
// The other way to do this is to pass "scope: undefined" to @Component.
export function ScopeShared (target) {
    target.scope = undefined;
    return target
}
<commit_msg>style(ScopeShared)<commit_after>// Cancels out the automatic creation of isolate scope for the directive,
// because Angular 1.x allows only one isolate scope directive per element.
// This is useful when actually creating directives, which add behaviour
// to an existing element, as opposed to components which are stand alone
// bits of html and behaviour.
// The other way to do this is to pass "scope: undefined" to @Component.
export function ScopeShared(target) {
  target.scope = undefined;
  return target
}
<|endoftext|>


<commit_before>// Copyright 2010 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview HTML5 based history implementation, compatible with
 * goog.History.
 *
 * TODO(user): There should really be a history interface and multiple
 * implementations.
 *
 *
 */

goog.provide('goog.history.Html5History');

goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventType');
goog.require('goog.history.Event');
goog.require('goog.history.EventType');

/**
 * An implementation compatible with goog.History that uses the HTML5
 * history APIs.
 *
 * @param {Window=} opt_win The window to listen/dispatch history events on.
 * @constructor
 * @extends {goog.events.EventTarget}
 */
goog.history.Html5History = function(opt_win) {
  goog.events.EventTarget.call(this);
  goog.asserts.assert(goog.history.Html5History.isSupported(opt_win),
      'HTML5 history is not supported.');

  /**
   * The window object to use for history tokens.  Typically the top window.
   * @type {Window}
   * @private
   */
  this.window_ = opt_win || window;

  goog.events.listen(this.window_, goog.events.EventType.POPSTATE,
      this.onHistoryEvent_, false, this);
  goog.events.listen(this.window_, goog.events.EventType.HASHCHANGE,
      this.onHistoryEvent_, false, this);
};
goog.inherits(goog.history.Html5History, goog.events.EventTarget);

/**
 * Returns whether Html5History is supported.
 * @param {Window=} opt_win Optional window to check.
 * @return {boolean} Whether html5 history is supported.
 */
goog.history.Html5History.isSupported = function(opt_win) {
  var win = opt_win || window;
  return !!(win.history && win.history.pushState);
};

/**
 * Status of when the object is active and dispatching events.
 * @type {boolean}
 * @private
 */
goog.history.Html5History.prototype.enabled_ = false;

/**
 * Whether to use the fragment to store the token, defaults to true.
 * @type {boolean}
 * @private
 */
goog.history.Html5History.prototype.useFragment_ = true;

/**
 * If useFragment is false the path will be used, the path prefix will be
 * prepended to all tokens.
 * @type {string}
 * @private
 */
goog.history.Html5History.prototype.pathPrefix_ = '';

/**
 * Starts or stops the History.  When enabled, the History object
 * will immediately fire an event for the current location. The caller can set
 * up event listeners between the call to the constructor and the call to
 * setEnabled.
 *
 * @param {boolean} enable Whether to enable history.
 */
goog.history.Html5History.prototype.setEnabled = function(enable) {
  if (enable == this.enabled_) {
    return;
  }

  this.enabled_ = enable;

  if (enable) {
    this.dispatchEvent(new goog.history.Event(this.getToken(), false));
  }
};

/**
 * Returns the current token.
 * @return {string} The current token.
 */
goog.history.Html5History.prototype.getToken = function() {
  if (this.useFragment_) {
    var loc = this.window_.location.href;
    var index = loc.indexOf('#');
    return index < 0 ? '' : loc.substring(index + 1);
  } else {
    return this.window_.location.pathname.substring(this.pathPrefix_.length);
  }
};

/**
 * Sets the history state.
 * @param {string} token The history state identifier.
 * @param {string=} opt_title Optional title to associate with history entry.
 */
goog.history.Html5History.prototype.setToken = function(token, opt_title) {
  // Per externs/gecko_dom.js document.title can be null.
  this.window_.history.pushState(null,
      opt_title || this.window_.document.title || '', this.getUrl_(token));
  this.dispatchEvent(new goog.history.Event(token, false));
};

/**
 * Replaces the current history state without affecting the rest of the history
 * stack.
 * @param {string} token The history state identifier.
 * @param {string=} opt_title Optional title to associate with history entry.
 */
goog.history.Html5History.prototype.replaceToken = function(token, opt_title) {
  // Per externs/gecko_dom.js document.title can be null.
  this.window_.history.replaceState(null,
      opt_title || this.window_.document.title || '', this.getUrl_(token));
  this.dispatchEvent(new goog.history.Event(token, false));
};

/** @inheritDoc */
goog.history.Html5History.prototype.disposeInternal = function() {
  goog.events.unlisten(this.window_, goog.events.EventType.POPSTATE,
      this.onHistoryEvent_, false, this);
  if (this.useFragment_) {
    goog.events.unlisten(this.window_, goog.events.EventType.HASHCHANGE,
        this.onHistoryEvent_, false, this);
  }
};

/**
 * Sets whether to use the fragment to store tokens.
 * @param {boolean} useFragment Whether to use the fragment.
 */
goog.history.Html5History.prototype.setUseFragment = function(useFragment) {
  if (this.useFragment_ != useFragment) {
    if (useFragment) {
      goog.events.listen(this.window_, goog.events.EventType.HASHCHANGE,
          this.onHistoryEvent_, false, this);
    } else {
      goog.events.unlisten(this.window_, goog.events.EventType.HASHCHANGE,
          this.onHistoryEvent_, false, this);
    }
    this.useFragment_ = useFragment;
  }
};

/**
 * Sets the path prefix to use if storing tokens in the path.
 * @param {string} pathPrefix Sets the path prefix.
 */
goog.history.Html5History.prototype.setPathPrefix = function(pathPrefix) {
  this.pathPrefix_ = pathPrefix;
};

/**
 * Gets the path prefix.
 * @return {string} The path prefix.
 */
goog.history.Html5History.prototype.getPathPrefix = function() {
  return this.pathPrefix_;
};

/**
 * Gets the URL to set when calling history.pushState
 * @param {string} token The history token.
 * @return {string} The URL.
 * @private
 */
goog.history.Html5History.prototype.getUrl_ = function(token) {
  if (this.useFragment_) {
    return '#' + token;
  } else {
    // Paths need to be absolute to maintain correct nesting, so we prepend the
    // known path prefix.  We also preserve the query string, since this is
    // usually what is intended.
    return this.pathPrefix_ + token + this.window_.location.search;
  }
};

/**
 * Handles history events dispatched by the browser.
 * @param {goog.events.BrowserEvent} e The browser event object.
 * @private
 */
goog.history.Html5History.prototype.onHistoryEvent_ = function(e) {
  if (this.enabled_) {
    this.dispatchEvent(new goog.history.Event(this.getToken(), true));
  }
};
<commit_msg><commit_after>// Copyright 2010 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview HTML5 based history implementation, compatible with
 * goog.History.
 *
 * TODO(user): There should really be a history interface and multiple
 * implementations.
 *
 *
 */

goog.provide('goog.history.Html5History');

goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventType');
goog.require('goog.history.Event');
goog.require('goog.history.EventType');

/**
 * An implementation compatible with goog.History that uses the HTML5
 * history APIs.
 *
 * @param {Window=} opt_win The window to listen/dispatch history events on.
 * @constructor
 * @extends {goog.events.EventTarget}
 */
goog.history.Html5History = function(opt_win) {
  goog.events.EventTarget.call(this);
  goog.asserts.assert(goog.history.Html5History.isSupported(opt_win),
      'HTML5 history is not supported.');

  /**
   * The window object to use for history tokens.  Typically the top window.
   * @type {Window}
   * @private
   */
  this.window_ = opt_win || window;

  goog.events.listen(this.window_, goog.events.EventType.POPSTATE,
      this.onHistoryEvent_, false, this);
  goog.events.listen(this.window_, goog.events.EventType.HASHCHANGE,
      this.onHistoryEvent_, false, this);
};
goog.inherits(goog.history.Html5History, goog.events.EventTarget);

/**
 * Returns whether Html5History is supported.
 * @param {Window=} opt_win Optional window to check.
 * @return {boolean} Whether html5 history is supported.
 */
goog.history.Html5History.isSupported = function(opt_win) {
  var win = opt_win || window;
  return !!(win.history && win.history.pushState);
};

/**
 * Status of when the object is active and dispatching events.
 * @type {boolean}
 * @private
 */
goog.history.Html5History.prototype.enabled_ = false;

/**
 * Whether to use the fragment to store the token, defaults to true.
 * @type {boolean}
 * @private
 */
goog.history.Html5History.prototype.useFragment_ = true;

/**
 * If useFragment is false the path will be used, the path prefix will be
 * prepended to all tokens.
 * @type {string}
 * @private
 */
goog.history.Html5History.prototype.pathPrefix_ = '';

/**
 * Starts or stops the History.  When enabled, the History object
 * will immediately fire an event for the current location. The caller can set
 * up event listeners between the call to the constructor and the call to
 * setEnabled.
 *
 * @param {boolean} enable Whether to enable history.
 */
goog.history.Html5History.prototype.setEnabled = function(enable) {
  if (enable == this.enabled_) {
    return;
  }

  this.enabled_ = enable;

  if (enable) {
    this.dispatchEvent(new goog.history.Event(this.getToken(), false));
  }
};

/**
 * Returns the current token.
 * @return {string} The current token.
 */
goog.history.Html5History.prototype.getToken = function() {
  if (this.useFragment_) {
    var loc = this.window_.location.href;
    var index = loc.indexOf('#');
    return index < 0 ? '' : loc.substring(index + 1);
  } else {
    return this.window_.location.pathname.substring(this.pathPrefix_.length);
  }
};

/**
 * Sets the history state.
 * @param {string} token The history state identifier.
 * @param {string=} opt_title Optional title to associate with history entry.
 */
goog.history.Html5History.prototype.setToken = function(token, opt_title) {
  if (token == this.getToken()) {
    return;
  }

  // Per externs/gecko_dom.js document.title can be null.
  this.window_.history.pushState(null,
      opt_title || this.window_.document.title || '', this.getUrl_(token));
  this.dispatchEvent(new goog.history.Event(token, false));
};

/**
 * Replaces the current history state without affecting the rest of the history
 * stack.
 * @param {string} token The history state identifier.
 * @param {string=} opt_title Optional title to associate with history entry.
 */
goog.history.Html5History.prototype.replaceToken = function(token, opt_title) {
  // Per externs/gecko_dom.js document.title can be null.
  this.window_.history.replaceState(null,
      opt_title || this.window_.document.title || '', this.getUrl_(token));
  this.dispatchEvent(new goog.history.Event(token, false));
};

/** @inheritDoc */
goog.history.Html5History.prototype.disposeInternal = function() {
  goog.events.unlisten(this.window_, goog.events.EventType.POPSTATE,
      this.onHistoryEvent_, false, this);
  if (this.useFragment_) {
    goog.events.unlisten(this.window_, goog.events.EventType.HASHCHANGE,
        this.onHistoryEvent_, false, this);
  }
};

/**
 * Sets whether to use the fragment to store tokens.
 * @param {boolean} useFragment Whether to use the fragment.
 */
goog.history.Html5History.prototype.setUseFragment = function(useFragment) {
  if (this.useFragment_ != useFragment) {
    if (useFragment) {
      goog.events.listen(this.window_, goog.events.EventType.HASHCHANGE,
          this.onHistoryEvent_, false, this);
    } else {
      goog.events.unlisten(this.window_, goog.events.EventType.HASHCHANGE,
          this.onHistoryEvent_, false, this);
    }
    this.useFragment_ = useFragment;
  }
};

/**
 * Sets the path prefix to use if storing tokens in the path.
 * @param {string} pathPrefix Sets the path prefix.
 */
goog.history.Html5History.prototype.setPathPrefix = function(pathPrefix) {
  this.pathPrefix_ = pathPrefix;
};

/**
 * Gets the path prefix.
 * @return {string} The path prefix.
 */
goog.history.Html5History.prototype.getPathPrefix = function() {
  return this.pathPrefix_;
};

/**
 * Gets the URL to set when calling history.pushState
 * @param {string} token The history token.
 * @return {string} The URL.
 * @private
 */
goog.history.Html5History.prototype.getUrl_ = function(token) {
  if (this.useFragment_) {
    return '#' + token;
  } else {
    // Paths need to be absolute to maintain correct nesting, so we prepend the
    // known path prefix.  We also preserve the query string, since this is
    // usually what is intended.
    return this.pathPrefix_ + token + this.window_.location.search;
  }
};

/**
 * Handles history events dispatched by the browser.
 * @param {goog.events.BrowserEvent} e The browser event object.
 * @private
 */
goog.history.Html5History.prototype.onHistoryEvent_ = function(e) {
  if (this.enabled_) {
    this.dispatchEvent(new goog.history.Event(this.getToken(), true));
  }
};
<|endoftext|>


<commit_before>
var teamSelector = function teamSelector(isPerson, obj){
  this.isPerson = isPerson;
  this.selector = $(obj);
  this.orgBrowser = this.selector.find('.org-browser');
  this.editButton = this.selector.find('a.show-editable-fields');
  this.newTeam = this.selector.find('.new-team');
  this.newTeamInput = this.newTeam.find('.new-team-name');

  /* Listen for events */
  this.initEvents = function(){
    var self = this;
    /* Clicking the 'Edit' link to show the team selector */
    this.selector.on('click', '.show-editable-fields, .editable-summary .title', function (e){
      self.onClick(e);
      self.editButton.hide();
      self.selector.find('.editable-fields').show();
      self.init();
    });
    /* Clicking the 'Done' button to hide the team selector */
    this.selector.on('click', '.hide-editable-fields', function (e){
      self.onClick(e);
      self.editButton.show();
      self.selector.find('.editable-fields').hide();
    });
    /* Clicking on the 'Back' link */
    this.orgBrowser.on('click', '.team-back', function (e){
      self.onClick(e);
      self.currentTarget = $(e.currentTarget);
      self.back();
    });
    /* Clicking on a team with subteams */
    this.orgBrowser.on('click', 'li:not(.disabled) .subteam-link', function (e){
      self.onClick(e);
      self.currentTarget = $(e.currentTarget);
      self.forward();
    });
    /* Clicking on a team with no subteams */
    this.orgBrowser.on('click', '.team-link', function (e){
      self.onClick(e);
      self.currentTarget = $(e.currentTarget);
      // if it's a form
      if( self.orgBrowser.hasClass('has-form') ){
        e.preventDefault();
        e.stopPropagation();
        self.currentTarget.closest('h3').children('input').prop('checked', 'checked').trigger('change');
      }
    });
    /* Clicking directly on a radio button */
    this.orgBrowser.on('change', 'input[type=radio]', function(e){
      self.currentTarget = $(e.currentTarget);
      self.currentTarget.focus();
      self.setTeamName(self.getTeamName(self.currentTarget));
      var isSubTeam = self.currentTarget.next('a').hasClass('subteam-link')? true : false;
      self.getBreadcrumb(isSubTeam);
    });

    this.orgBrowser.on('keypress, keydown', function(e){
      var keyCode = e.keyCode || e.which,
        target = $(e.target),
        top = target.parent().prev().hasClass('team-back');

      switch(keyCode) {
        case 9: //Tab
        case 13: // Enter
          self.selector.find('.hide-editable-fields').focus();
          break;
        case 37: //Left
        case 38: // Up
          if(top){
            self.currentTarget = target.parent().prev();
            self.back();
            return false;
          } else {
            var li = target.closest('li').prev('li');
            if(li.hasClass('has-subteams')){
              li.find('> p > .subteam-link').focus();
              return false;
            } else {
              li.find('>p>input').prop('checked', 'checked').trigger('change').focus();

            }
          }
          break;
        case 40: // Down
          if(top){
            var subTeam = target.parent().next('ul');
            if(subTeam.length > 0){
              var li = subTeam.find('li').first();
              if(li.hasClass('leaf-node')){
                li.find('>p>input').prop('checked', 'checked').trigger('change').focus();
                return;
              } else {
                li.find('> p > .subteam-link').focus();
              }
              return false;
            }
          } else {
            var li = target.closest('li').next('li');
            if(li.hasClass('leaf-node')){
              li.find('>p>input').prop('checked', 'checked').trigger('change').focus();
            } else {
              li.find('.subteam-link').focus();
              return false;
            }
          }
          break;
        case 39: // Right
          if(target.hasClass('subteam-link')){
            self.currentTarget = target;
            self.forward();
          }
          return false;
          break;
        default:
          null;
      }
    });

    /* Add New Team */
    this.selector.on('click', '.button-add-team', function(e){
      self.onClick(e);
      self.toggleTeamInput(true);
    });
    this.newTeam.on('click', '.button', function (e){
      self.onClick(e);
      self.createNewTeam();
    });
    this.newTeamInput.on('keypress', function(e){
      var keyCode = e.keyCode || e.which;
      if(keyCode === 13){
        self.onClick(e);
        self.createNewTeam();
      }
    });
  };

  /* Handle clicks and preventDefault and stopPropagation */
  this.onClick = function(e){
    e.preventDefault();
    e.stopPropagation();
  };

  /* Set the 'selected' class on the last visible team */
  this.init = function(){
    var self = this;
    this.orgBrowser.find('.team-back').first().remove();
    if( this.orgBrowser.hasClass('has-form') ){
      var $checked = this.orgBrowser.find('input:checked');
      if( $checked.length > 0 ){
        $checked.parents('.team').addClass('visible');
        $checked.focus();
      }
    }
    this.setExpanded();
    // Hide all team headings (for testing purposes)
    this.orgBrowser.find('h3 > a').hide();
    this.removeSelected();
    var visible = this.getLastVisible().addClass('selected').find('> h3 > a').show();
    setTimeout(function (){ self.animateScroll(); }, 0);
  };

  /*
  Remove the 'expanded' class from current subteams
  Scroll backwards and wait before removing the 'visible' class
  */
  this.back = function(){
    var self = this,
      team = this.currentTarget.parent('.team');
    this.currentTarget.children('li').removeClass('expanded');
    this.animateScroll('left');
    // Wait for the scroll back to complete
    setTimeout(function (){
      self.orgBrowser.find('.visible > h3 > a').hide();
      team.removeClass('visible');
      self.selectCurrent();
    }, 400);
  };

  /* If the team has subteams, find the next team */
  this.forward = function(){
    if( this.currentTarget.closest('li').hasClass('has-subteams') === false ){
      if( this.orgBrowser.hasClass('has-form') ){
        var input = this.currentTarget.closest('p').children('input').prop('checked', 'checked').trigger('change');
        this.setTeamName(this.getTeamName(input));
      }
      // if this is a leaf-node, we let the link work as it normally would
      return;
    }
    var team = this.currentTarget.closest('p').siblings('.team');
    this.revealSubteam(team);
    this.selectCurrent();
    this.animateScroll('right');
  };

  this.getBreadcrumb = function(isSubTeam){
    var arr = [],
      selector = isSubTeam? '.team.visible' : '.team.visible:not(.selected)';
    this.orgBrowser.find(selector).each(function(i,obj){
      var text = $(obj).find('>h3>a').text();
      arr.push(text);
    });
    arr.push(this.getTeamName(this.currentTarget));
    this.orgBrowser.closest('.editable-container').find('.editable-summary .title').html(this.createBreadcrumb(arr));
  };

  this.createBreadcrumb = function(arr){
    var ol = $('
');
    $(arr).each(function(i, crumb){
      var li = $('
').addClass('breadcrumb-'+i).text($.trim(crumb));
      ol.append(li);
    });
    return $(ol);
  };

  /* Return the text of the given input element */
  this.getTeamName = function(input){
    return input.next('a').text();
  };

  /* Set the Team leader heading and hint spans with the given team name */
  this.setTeamName = function(teamName){
    if(this.isPerson){
      this.selector.find('.team-led').text(teamName + ' team');
    }
  };

  /* Remove the 'selected' class from all teams */
  this.removeSelected = function(){
    this.orgBrowser.find('.team').removeClass('selected');
  };

  /* Return the last 'visible' team element */
  this.getLastVisible = function(){
    return this.orgBrowser.find('.visible').last();
  };

  /* Set the last 'visible' elements parent li to have the 'expanded' class */
  this.setExpanded = function(){
    this.orgBrowser.find('.visible').parents('li').addClass('expanded');
  };

  /* When moving forward down the subteams */
  this.revealSubteam = function (team){
    this.setExpanded();
    // Remove the 'visible' class from all teams
    this.orgBrowser.find('.team').removeClass('visible');
    team.children().parents('.team').addClass('visible');
  };

  /* Set the last 'visible' element to be 'selected' and check the radio button, then set the team name */
  this.selectCurrent = function(){
    var teamText, $current;
    this.removeSelected();
    var visible = this.getLastVisible();
    visible.addClass('selected').find('> h3 > input').prop('checked', 'checked').trigger('change');
    visible.find('> h3 > a').show();
  };

  /* Animate the team selector to scroll left or right */
  this.animateScroll = function(direction){
    var visible = this.orgBrowser.find('.visible');
    var offset = direction === 'left'? (visible.length - 2) * visible.width() : visible.length * visible.width();
    this.orgBrowser.animate({ scrollLeft: offset }, 400);
  };

  this.toggleTeamInput = function(focus){
    this.newTeam.toggle();
    if(focus)
      this.newTeamInput.val('').focus();
  };

  this.createNewTeam = function(){
    var self = this,
    input = this.orgBrowser.find('input:checked'),
      teamId = input.val(),
      teamName = input.next('a').text(),
      newTeamName = this.newTeamInput.val();
    if(teamId && newTeamName){
      $.ajax({
        type: 'POST',
        dataType: 'json',
        url: '/teams',
        data: { group: { parent_id: teamId, name: newTeamName } },
        success: function(data){
          data = { id: data.id, name: data.name, parentId: data.parent_id, parentName: teamName };
          self.addTeamToList(data);
        },
        error: function(){
          self.orgBrowser.before('

There was an error adding the team. Please try again later.

');
        }
      });
    }
  };

  this.createInput = function(i, id){
    return '<input type="radio" value="'+id+'" name="person[memberships_attributes]['+i+'][group_id]" id="person_memberships_attributes_'+i+'_group_id_'+id+'">';
  };

  this.createTeamName = function(data){
    return ' \
      '+data.name+' \
    ';
  };

  this.createTeamList = function(i, data){
    return '
 \
      Back \

'+
        this.createInput(i, data.parentId)
        + ''+data.parentName+' \

 \

 \

 \

 \
            <input type="radio" value="'+data.id+'" name="person[memberships_attributes]['+i+'][group_id]" id="person_memberships_attributes_'+i+'_group_id_'+data.id+'">'+
            this.createTeamName(data)
          + '
 \

 \

 \

';
  };

  this.addTeamToList = function(data){
    var self = this,
      isSubteam = this.orgBrowser.find('input:checked').next().hasClass('subteam-link')? true : false,
      input = isSubteam? $('input[value="'+data.parentId+'"]').closest('li') : $('input[value="'+data.parentId+'"]').parent('h3').next('ul');

    $.each(input, function(i, obj){
      if(isSubteam){
        self.currentTarget = self.orgBrowser.find('input:checked').next('.subteam-link');
        var el = self.createTeamList(i, data);
        $(obj).find('.subteam-link').append('1 sub-team');
        $(obj).attr('class', 'has-subteams').append(el);
        self.forward();
      } else {
        var el = '
' +
          self.createInput(i, data.id)
          + self.createTeamName(data)
        + '
';
        var li = $('
').addClass('leaf-node').html(el);
        $(obj).append(li);
      }
    });
    this.toggleTeamInput();
  };

};

$(function (){
  // Is this the person profile page?
  var isPerson = $('#memberships').length === 1? true : false;
  // Which element should we be targeting?
  var selector = isPerson? '#memberships .membership' : '.editable-container';
  // For each element, set the team name on team leader text and create a new teamSelector
  $(selector).each(function (i, obj){
    $(obj).addClass('index'+i);
    if(isPerson){
      teamName = $(obj).find('.editable-summary ol li:last-child').text();
      $(obj).find('.team-led').text(teamName + ' team');
    }
    var team = new teamSelector(isPerson, obj);
    team.initEvents();
  });
});
<commit_msg>Fix keypress for Firefox and IE<commit_after>
var teamSelector = function teamSelector(isPerson, obj){
  this.isPerson = isPerson;
  this.selector = $(obj);
  this.orgBrowser = this.selector.find('.org-browser');
  this.editButton = this.selector.find('a.show-editable-fields');
  this.newTeam = this.selector.find('.new-team');
  this.newTeamInput = this.newTeam.find('.new-team-name');

  /* Listen for events */
  this.initEvents = function(){
    var self = this;
    /* Clicking the 'Edit' link to show the team selector */
    this.selector.on('click', '.show-editable-fields, .editable-summary .title', function (e){
      self.onClick(e);
      self.editButton.hide();
      self.selector.find('.editable-fields').show();
      self.init();
    });
    /* Clicking the 'Done' button to hide the team selector */
    this.selector.on('click', '.hide-editable-fields', function (e){
      self.onClick(e);
      self.editButton.show();
      self.selector.find('.editable-fields').hide();
    });
    /* Clicking on the 'Back' link */
    this.orgBrowser.on('click', '.team-back', function (e){
      self.onClick(e);
      self.currentTarget = $(e.currentTarget);
      self.back();
    });
    /* Clicking on a team with subteams */
    this.orgBrowser.on('click', 'li:not(.disabled) .subteam-link', function (e){
      self.onClick(e);
      self.currentTarget = $(e.currentTarget);
      self.forward();
    });
    /* Clicking on a team with no subteams */
    this.orgBrowser.on('click', '.team-link', function (e){
      self.onClick(e);
      self.currentTarget = $(e.currentTarget);
      // if it's a form
      if( self.orgBrowser.hasClass('has-form') ){
        e.preventDefault();
        e.stopPropagation();
        self.currentTarget.closest('h3').children('input').prop('checked', 'checked').trigger('change');
      }
    });
    /* Clicking directly on a radio button */
    this.orgBrowser.on('change', 'input[type=radio]', function(e){
      self.currentTarget = $(e.currentTarget);
      self.currentTarget.focus();
      self.setTeamName(self.getTeamName(self.currentTarget));
      var isSubTeam = self.currentTarget.next('a').hasClass('subteam-link')? true : false;
      self.getBreadcrumb(isSubTeam);
    });

    this.orgBrowser.on('keypress, keydown', function(e){
      var keyCode = e.keyCode || e.which || e.charCode,
        target = $(e.target),
        top = target.parent().prev().hasClass('team-back');
      switch(keyCode) {
        case 9: //Tab
        case 13: // Enter
          self.selector.find('.hide-editable-fields').focus();
          break;
        case 37: //Left
        case 38: // Up
          if(top){
            self.currentTarget = target.parent().prev();
            self.back();
            return false;
          } else {
            var li = target.closest('li').prev('li');
            if(li.hasClass('has-subteams')){
              li.find('> p > .subteam-link').focus();
              return false;
            } else if(li.hasClass('leaf-node')) {
              li.find('>p>input').prop('checked', 'checked').trigger('change').focus();
              return false;
            }
          }
          break;
        case 40: // Down
          if(top){
            var subTeam = target.parent().next('ul');
            if(subTeam.length > 0){
              var li = subTeam.find('li').first();
              if(li.hasClass('leaf-node')){
                li.find('>p>input').prop('checked', 'checked').trigger('change').focus();
                return false;
              } else {
                li.find('> p > .subteam-link').focus();
              }
              return false;
            }
          } else {
            var li = target.closest('li').next('li');
            if(li.hasClass('leaf-node')){
              li.find('>p>input').prop('checked', 'checked').trigger('change').focus();
              return false;
            } else {
              li.find('.subteam-link').focus();
              return false;
            }
          }
          break;
        case 39: // Right
          if(target.hasClass('subteam-link')){
            self.currentTarget = target;
            self.forward();
          }
          return false;
          break;
        default:
          null;
      }
    });

    /* Add New Team */
    this.selector.on('click', '.button-add-team', function(e){
      self.onClick(e);
      self.toggleTeamInput(true);
    });
    this.newTeam.on('click', '.button', function (e){
      self.onClick(e);
      self.createNewTeam();
    });
    this.newTeamInput.on('keypress', function(e){
      var keyCode = e.keyCode || e.which;
      if(keyCode === 13){
        self.onClick(e);
        self.createNewTeam();
      }
    });
  };

  /* Handle clicks and preventDefault and stopPropagation */
  this.onClick = function(e){
    e.preventDefault();
    e.stopPropagation();
  };

  /* Set the 'selected' class on the last visible team */
  this.init = function(){
    var self = this;
    this.orgBrowser.find('.team-back').first().remove();
    if( this.orgBrowser.hasClass('has-form') ){
      var $checked = this.orgBrowser.find('input:checked');
      if( $checked.length > 0 ){
        $checked.parents('.team').addClass('visible');
        $checked.focus();
      }
    }
    this.setExpanded();
    // Hide all team headings (for testing purposes)
    this.orgBrowser.find('h3 > a').hide();
    this.removeSelected();
    var visible = this.getLastVisible().addClass('selected').find('> h3 > a').show();
    setTimeout(function (){ self.animateScroll(); }, 0);
  };

  /*
  Remove the 'expanded' class from current subteams
  Scroll backwards and wait before removing the 'visible' class
  */
  this.back = function(){
    var self = this,
      team = this.currentTarget.parent('.team');
    this.currentTarget.children('li').removeClass('expanded');
    this.animateScroll('left');
    // Wait for the scroll back to complete
    setTimeout(function (){
      self.orgBrowser.find('.visible > h3 > a').hide();
      team.removeClass('visible');
      self.selectCurrent();
    }, 400);
  };

  /* If the team has subteams, find the next team */
  this.forward = function(){
    if( this.currentTarget.closest('li').hasClass('has-subteams') === false ){
      if( this.orgBrowser.hasClass('has-form') ){
        var input = this.currentTarget.closest('p').children('input').prop('checked', 'checked').trigger('change');
        this.setTeamName(this.getTeamName(input));
      }
      // if this is a leaf-node, we let the link work as it normally would
      return;
    }
    var team = this.currentTarget.closest('p').siblings('.team');
    this.revealSubteam(team);
    this.selectCurrent();
    this.animateScroll('right');
  };

  this.getBreadcrumb = function(isSubTeam){
    var arr = [],
      selector = isSubTeam? '.team.visible' : '.team.visible:not(.selected)';
    this.orgBrowser.find(selector).each(function(i,obj){
      var text = $(obj).find('>h3>a').text();
      arr.push(text);
    });
    arr.push(this.getTeamName(this.currentTarget));
    this.orgBrowser.closest('.editable-container').find('.editable-summary .title').html(this.createBreadcrumb(arr));
  };

  this.createBreadcrumb = function(arr){
    var ol = $('
');
    $(arr).each(function(i, crumb){
      var li = $('
').addClass('breadcrumb-'+i).text($.trim(crumb));
      ol.append(li);
    });
    return $(ol);
  };

  /* Return the text of the given input element */
  this.getTeamName = function(input){
    return input.next('a').text();
  };

  /* Set the Team leader heading and hint spans with the given team name */
  this.setTeamName = function(teamName){
    if(this.isPerson){
      this.selector.find('.team-led').text(teamName + ' team');
    }
  };

  /* Remove the 'selected' class from all teams */
  this.removeSelected = function(){
    this.orgBrowser.find('.team').removeClass('selected');
  };

  /* Return the last 'visible' team element */
  this.getLastVisible = function(){
    return this.orgBrowser.find('.visible').last();
  };

  /* Set the last 'visible' elements parent li to have the 'expanded' class */
  this.setExpanded = function(){
    this.orgBrowser.find('.visible').parents('li').addClass('expanded');
  };

  /* When moving forward down the subteams */
  this.revealSubteam = function (team){
    this.setExpanded();
    // Remove the 'visible' class from all teams
    this.orgBrowser.find('.team').removeClass('visible');
    team.children().parents('.team').addClass('visible');
  };

  /* Set the last 'visible' element to be 'selected' and check the radio button, then set the team name */
  this.selectCurrent = function(){
    var teamText, $current;
    this.removeSelected();
    var visible = this.getLastVisible();
    visible.addClass('selected').find('> h3 > input').prop('checked', 'checked').trigger('change');
    visible.find('> h3 > a').show();
  };

  /* Animate the team selector to scroll left or right */
  this.animateScroll = function(direction){
    var visible = this.orgBrowser.find('.visible');
    var offset = direction === 'left'? (visible.length - 2) * visible.width() : visible.length * visible.width();
    this.orgBrowser.animate({ scrollLeft: offset }, 400);
  };

  this.toggleTeamInput = function(focus){
    this.newTeam.toggle();
    if(focus)
      this.newTeamInput.val('').focus();
  };

  this.createNewTeam = function(){
    var self = this,
    input = this.orgBrowser.find('input:checked'),
      teamId = input.val(),
      teamName = input.next('a').text(),
      newTeamName = this.newTeamInput.val();
    if(teamId && newTeamName){
      $.ajax({
        type: 'POST',
        dataType: 'json',
        url: '/teams',
        data: { group: { parent_id: teamId, name: newTeamName } },
        success: function(data){
          data = { id: data.id, name: data.name, parentId: data.parent_id, parentName: teamName };
          self.addTeamToList(data);
        },
        error: function(){
          self.orgBrowser.before('

There was an error adding the team. Please try again later.

');
        }
      });
    }
  };

  this.createInput = function(i, id){
    return '<input type="radio" value="'+id+'" name="person[memberships_attributes]['+i+'][group_id]" id="person_memberships_attributes_'+i+'_group_id_'+id+'">';
  };

  this.createTeamName = function(data){
    return ' \
      '+data.name+' \
    ';
  };

  this.createTeamList = function(i, data){
    return '
 \
      Back \

'+
        this.createInput(i, data.parentId)
        + ''+data.parentName+' \

 \

 \

 \

 \
            <input type="radio" value="'+data.id+'" name="person[memberships_attributes]['+i+'][group_id]" id="person_memberships_attributes_'+i+'_group_id_'+data.id+'">'+
            this.createTeamName(data)
          + '
 \

 \

 \

';
  };

  this.addTeamToList = function(data){
    var self = this,
      isSubteam = this.orgBrowser.find('input:checked').next().hasClass('subteam-link')? true : false,
      input = isSubteam? $('input[value="'+data.parentId+'"]').closest('li') : $('input[value="'+data.parentId+'"]').parent('h3').next('ul');

    $.each(input, function(i, obj){
      if(isSubteam){
        self.currentTarget = self.orgBrowser.find('input:checked').next('.subteam-link');
        var el = self.createTeamList(i, data);
        $(obj).find('.subteam-link').append('1 sub-team');
        $(obj).attr('class', 'has-subteams').append(el);
        self.forward();
      } else {
        var el = '
' +
          self.createInput(i, data.id)
          + self.createTeamName(data)
        + '
';
        var li = $('
').addClass('leaf-node').html(el);
        $(obj).append(li);
      }
    });
    this.toggleTeamInput();
  };

};

$(function (){
  // Is this the person profile page?
  var isPerson = $('#memberships').length === 1? true : false;
  // Which element should we be targeting?
  var selector = isPerson? '#memberships .membership' : '.editable-container';
  // For each element, set the team name on team leader text and create a new teamSelector
  $(selector).each(function (i, obj){
    $(obj).addClass('index'+i);
    if(isPerson){
      teamName = $(obj).find('.editable-summary ol li:last-child').text();
      $(obj).find('.team-led').text(teamName + ' team');
    }
    var team = new teamSelector(isPerson, obj);
    team.initEvents();
  });
});
<|endoftext|>


<commit_before>#! /usr/bin/env node

var FeedParser = require('feedparser'); // to parse feeds
// var Feed = require('feed'); // to write feeds (but not necessary to require here because we should get a Feed object from app.js -- which seems wrong)
var async = require('async');
var request = require('request'); // TODO let's abstract this so that we can switch it out (e.g., to fs.readFile )

exports.feedmerger = function (feedsArray, feedObject, mergedCallback) {
  // TODO some error handling; checking the arguments etc.

  var getFeed = function (feed, callback) {
    var req = request(feed);
    var feedparser = new FeedParser();
    req.on('error', function (error) {
      console.log(error);
    });
    req.on('response', function (res) {
      var stream = this;
      if (res.statusCode != 200) {
        return this.emit('error', new Error('Bad status code'));
      }
      //    stream.pipe(process.stdout); //works
      stream.pipe(feedparser);
    });
    feedparser.on('error', function (error) {
      console.log(error);
    });
    feedparser.on('readable', function () {
      // This is where the action is!
      var stream = this;
      //    var meta = this.meta; // **NOTE** the "meta" is always available in the context of the feedparser instance
      var item;
      while (item = stream.read()) {
        var itemTitle = item['rss:title']['#']; // how to make it "or use item['atom:title']['#']" ??
        var itemLink = item.link;
        var itemDescription = item.description;
        var itemDate = item.date;
        var itemAuthor = item.author.name;
        feedObject.addItem({
          title: itemTitle,
          link: itemLink,
          description: itemDescription,
          date: itemDate,
          author: itemAuthor
        });
      }
    });
    feedparser.on('finish', function () {
      callback();
    });
  };

  console.log(feedsArray);
  async.each(feedsArray, getFeed, function (err) {
    if (err) {
      throw err;
    }
    feedObject.items.sort(function (a, b) { //sort by date for creating pages later
      return b.date - a.date;
    });
   console.log("feedmerger completed!");
//     console.log(feedObject.render('atom-1.0'));
   return mergedCallback(null,feedObject);
  });
};

//    exports.feedmerger = new feedmerger();<commit_msg>fix #7 replace item.author.name with item.author; remove logging<commit_after>#! /usr/bin/env node

var FeedParser = require('feedparser'); // to parse feeds
// var Feed = require('feed'); // to write feeds (but not necessary to require here because we should get a Feed object from app.js -- which seems wrong)
var async = require('async');
var request = require('request'); // TODO let's abstract this so that we can switch it out (e.g., to fs.readFile )

exports.feedmerger = function (feedsArray, feedObject, mergedCallback) {
  // TODO some error handling; checking the arguments etc.

  var getFeed = function (feed, callback) {
    var req = request(feed);
    var feedparser = new FeedParser();
    req.on('error', function (error) {
      console.error(error);
    });
    req.on('response', function (res) {
      var stream = this;
      if (res.statusCode != 200) {
        return this.emit('error', new Error('Bad status code'));
      }
      //    stream.pipe(process.stdout); //works
      stream.pipe(feedparser);
    });
    feedparser.on('error', function (error) {
      console.error(error);
    });
    feedparser.on('readable', function () {
      // This is where the action is!
      var stream = this;
      //    var meta = this.meta; // **NOTE** the "meta" is always available in the context of the feedparser instance
      var item;
      while (item = stream.read()) {
        var itemTitle = item['rss:title']['#']; // how to make it "or use item['atom:title']['#']" ??
        var itemLink = item.link;
        var itemDescription = item.description;
        var itemDate = item.date;
        var itemAuthor = item.author;
//        console.error(typeof itemAuthor);
        feedObject.addItem({
          title: itemTitle,
          link: itemLink,
          description: itemDescription,
          date: itemDate,
          author: itemAuthor
        });
      }
    });
    feedparser.on('finish', function () {
      callback();
    });
  };

//  console.log(feedsArray);
  async.each(feedsArray, getFeed, function (err) {
    if (err) {
      throw err;
    }
    feedObject.items.sort(function (a, b) { //sort by date for creating pages later
      return b.date - a.date;
    });
//   console.log("feedmerger completed!");
//     console.log(feedObject.render('atom-1.0'));
   return mergedCallback(null,feedObject);
  });
};

//    exports.feedmerger = new feedmerger();<|endoftext|>