<commit_before>/**
 * Slider
 */
var PIASlider = (function(){

  /**
   * Opciones por defecto.
   * @type {Object}
   */
  var defaultOptions = {
    // Selector de controles
    controlSelector: '.slider-controls',

    // Generar controles
    buildControls : true,

    // Tiempo de transición
    animTime: 500,

    // Slide activo inicial
    activeIndex: 0,

    // Función de animación para transiciones
    easing: "swing",

    // Tiempo de espera entre slides (ms)
    slideTime: 1500,

    // Iniciar slider automáticamente
    autoPlay: true,

    // Pausar slider al pasar el mouse
    pauseOnHover: true,

    // Tipo de animación para transiciones
    animType: "horizontal"
  };

  // registro interno sliders
  var sliders = {};
  // contador sliders creados para generar IDs
  var sliderCount = 0;

  // Genera ID para cada slider creado
  var sliderID = function(){
    return 's'+(++sliderCount);
  };

  // Registrar nuevo slider
  var sliderRegister = function(id, api){
    sliders[id] = api;
  };

  // Recupera slider creado
  var sliderGet = function(id){
    return sliders[id] || null;
  };

  // Elimina slider del registro
  var sliderRemove = function(id){
    delete sliders[id];
  };

  // tipos de animación disponibles para los sliders.
  var animTypes = {

    // Sin animación
    "none": function(opts, $prev, $next, dir, size){
      $prev.stop(true, true);
      $next.stop(true, true);
      $prev.removeClass('inactive');
      $next.removeClass('inactive');
      $prev.css({
        "opacity": 1,
        "top": 0,
        "left": 0,
        "z-index": 1
      });
      $next.css({
        "opacity": 1,
        "z-index": 2,
        "left": 0,
        "top": 0
      });
      $prev.addClass("inactive");
    },

    // Animación: Movimiento horizontal
    "horizontal": function(opts, $prev, $next, dir, size){
      $prev.stop(true, true);
      $next.stop(true, true);
      $prev.removeClass('inactive');
      $next.removeClass('inactive');

      $prev.css({
        "opacity": 1,
        "top" : 0,
        "left" : 0,
        "z-index": 1
      });

      $next.css({
        "opacity": 1,
        "z-index" : 2,
        "left": (-dir*size.width)+'px',
        "top" : 0
      });

      $prev.animate({
        'left' : (dir*size.width)+'px'
      }, opts.animTime, opts.easing, function(){
        $prev.addClass('inactive');
      });

      $next.animate({
        'left': 0
      }, opts.animTime, opts.easing);
    },

    // Animación: movimiento vertical
    "vertical": function(opts, $prev, $next, dir, size){
      $prev.css({
        "opacity": 1,
        "z-index": 1,
        "left": 0,
        "top": 0
      });
      $next.css({
        "opacity": 1,
        "left": 0,
        "z-index": 2,
        "top": (-dir*size.height)+'px'
      });

      $next.addClass('active');
      $prev.animate({
        'top': (dir*size.height)+'px'
      }, opts.animTime, opts.easing, function(){
        $prev.addClass('inactive');
      });

      $next.animate({
        'top': 0
      }, opts.animTime, opts.easing);
    },

    // Animación: desvanecer
    "fade": function(opts, $prev, $next, dir, size) {

      $next.addClass('active');
      $prev.css({
        "z-index": 1,
        "top": 0,
        "left": 0,
        "opacity": 1
      });

      $next.css({
        "z-index": 2,
        "opacity": 0,
        "top": 0,
        "left": 0
      });

      $next.fadeTo(opts.animTime, 1, function(){
        $prev.addClass('inactive');
      });
    },

    // Animación: aleatoria (incluye todas excepto 'none')
    "random": function(opts, $prev, $next, dir, size) {
      var animKeys = $.map(animTypes, function(elem,index){ return index; });
      animKeys = $.grep(animKeys, function(elem,index){ return elem != 'none' && elem != 'random'; });
      var randKey = Math.floor(Math.random()*animKeys.length);
      animTypes[animKeys[randKey]].apply(this, [opts, $prev, $next, dir, size]);
    }
  };

  /**
   * Permite extender la funcionalidad de PIASlider.
   *
   * La función llamada recibe la API General de PIASlider
   * - plugin
   * - getSlider
   * - removeSlider
   * - getSliders
   * - create
   */
  var plugin = function(pluginFunc){
    pluginFunc({
      defaultOptions: defaultOptions,
      animTypes: animTypes,
      api: generalAPI
    });
  };

  /**
   * Crea un slider
   *
   * @param string selector Indica el elemento en el que crear el slider.
   * @param object options Opciones a pasar al slider
   */
  var sliderCreate = function(selector, options)
  {
    var id = sliderID();
    var opts = $.extend({}, defaultOptions, options);
    var $container = (selector instanceof jQuery ? selector : $(selector));
    var $slider = $container.find('.slider');
    var $controls = $container.find(opts.controlSelector);
    var slideTm = 0;
    var playing = false;

    var getAnimFunc = function(){
      if($.isFunction(opts.animType)){
        return opts.animType;
      } else {
        return animTypes[opts.animType];
      }
    };

    var getID = function()
    {
      return id;
    };

    var play = function()
    {
      stop();
      slideTm = setTimeout(playNext, opts.slideTime);
    };

    var pause = function()
    {
      if(playing){
        stop();
      } else {
        play();
      }
    };

    /**
     * Parar slider
     */
    var stop = function(){
      clearTimeout(slideTm);
      playing = false;
    };

    /**
     * Ir a siguiente slide (temporizador)
     */
    var playNext = function(){
      stop();
      playing = true;
      nextSlide();
      slideTm = setTimeout(playNext, opts.slideTime);
    };

    /**
     * Devuelve un número entre 0 y el máximo,
     * utilizando el módulo de n y máximo.
     */
    var getCyclic = function(n, maxN){
      return (maxN + (n % maxN)) % maxN;
    };

    /**
     * Recupera los slides actuales.
     */
    var getSlides = function(){
      return $slider.find('.slide');
    };

    /**
     * número de slides.
     */
    var getSlideCount = function(){
      return getSlides().length;
    };

    /**
     * Slide activo (indice)
     */
    var getActiveIndex = function(){
      return getSlides().filter('.active').index();
    };

    /**
     * Medidas del slider.
     */
    var getSize = function(){
      return {
        width: $slider.width(),
        height: $slider.height()
      };
    };

    /**
     * Handler para pulsación en control de slider.
     */
    var controlClick = function(ev){
      var index = $(this).data('index');
      gotoSlide(index);
     };

    /**
     * Genera los controles.
     */
    var buildControls = function(){
      if($controls.length === 0){
        $controls = $('

');
        $controls.appendTo($container);
      }
      var slideCount = getSlideCount();
      for(var i = 0; i < slideCount; i++){
         var $control = $('');
         $control.addClass('slider-control-item');
         $control.html('');
         $control.attr('data-index', i);
         $control.data('index', i);
         $control.on('click', controlClick);
         $control.appendTo($controls);
      }
    };

    /**
     * Iniciar los slides ( ocultar, etc)
     */
    var initSlides = function()
    {
        $container.hover(function(){
          if(opts.autoPlay && opts.pauseOnHover){
            stop();
          }
        }, function(){
          if(opts.autoPlay && opts.pauseOnHover){
            play();
          }
        });

      var $slides = getSlides();
      $slides.addClass('inactive');
      var $activeSlide = $slides.eq(opts.activeIndex);
      $activeSlide.removeClass('inactive');
      $activeSlide.addClass('active');
      updateControls();
    };

    /**
     * Actualizar controles para reflejar estado actual de slider.
     */
    var updateControls = function()
    {
      var activeIndex = getActiveIndex();
      var $controlItems = $controls.find('.slider-control-item');
      var $cControl = $controlItems.eq(activeIndex);
      $controlItems.not(':eq('+activeIndex+')').removeClass('active');
      $cControl.addClass('active');
    };

    /**
     * Ir a slide, calcula número dentro del total de slides,
     * de modo que -1 = num slides - 1
     */
    var gotoSlide = function(n){
      stop();
      var activeIndex = getActiveIndex();
      var $slides = getSlides();
      var slideCount = getSlideCount();
      var dir = 0;

      n = getCyclic(n, slideCount);
      if(activeIndex != n){
        dir = -(n - activeIndex);
        dir = dir / Math.abs(dir);
        if(activeIndex === slideCount - 1 && n === 0) dir = -1;
      } else {
        return;
      }

      var $cSlide = $slides.eq(activeIndex);
      var $nSlide = $slides.eq(n);
      var size = getSize();

      var animFunc = getAnimFunc();
      $nSlide.stop();
      $cSlide.stop();
      $nSlide.addClass('active');
      $cSlide.removeClass('active');
      $nSlide.removeClass('inactive');
      $cSlide.removeClass('inactive');
      animFunc(opts, $cSlide, $nSlide, dir, size);
      updateControls();
      $container.trigger('pia.slider.slide', [{
        slider: sliderAPI,
        index: n,
        prevIndex: activeIndex,
        $prev: $cSlide,
        $next : $nSlide}]);
    };

    /**
     * Siguiente Slide.
     */
    var nextSlide = function(){
      gotoSlide(getActiveIndex() + 1);
    };

    /**
     * Slide Anterior.
     */
    var prevSlide = function(){
      gotoSlide(getActiveIndex() - 1);
    };

    // Generar botones de control
    if(opts.buildControls){
      buildControls();
    }

    // Inicializar slides
    initSlides();

    // Iniciar slider
    if(opts.autoPlay){
      play();
    }

    /**
     * Especificar opción
     *
     * @param {string} optKey   Nombre de la opción
     * @param {object} optValue Valor de la opción
     */
    var setOption = function(optKey, optValue){
      opts[optKey] = optValue;
    };

    /**
     * Recuperar opción
     *
     * @param  {string} optKey     Nombre de la opción
     * @param  {object} defaultVal Valor por defecto
     * @return {object}
     */
    var getOption = function(optKey, defaultVal){
      return opts[optKey] || defaultVal;
    };

    /**
     * Funciones disponibles externamente (por cada slider)
     * @type {Object}
     */
    var sliderAPI = {
      $element: $container,
      gotoSlide : gotoSlide,
      nextSlide: nextSlide,
      prevSlide: prevSlide,
      slideCount: getSlideCount,
      play: play,
      pause: pause,
      stop: stop,
      setOption: setOption,
      getOption: getOption,
      getID: getID,
      getSize: getSize
    };

    sliderRegister(id, sliderAPI);
    return sliderAPI;
  };

  /**
   * Recuperar sliders registrados.
   *
   * @return {array} Array de sliders registrados.
   */
  var slidersGet = function(){
    return sliders;
  };

  /**
   * Funciones disponibles externamente. (Global de PIASlider)
   * @type {Object}
   */
  var generalAPI = {
      plugin: plugin,
      getSlider: sliderGet,
      getSliders: slidersGet,
      removeSlider: sliderRemove,
      create: sliderCreate
  };
  return generalAPI;
})();
<commit_msg>corrección evento click en control slider<commit_after>/**
 * Slider
 */
var PIASlider = (function(){

  /**
   * Opciones por defecto.
   * @type {Object}
   */
  var defaultOptions = {
    // Selector de controles
    controlSelector: '.slider-controls',

    // Generar controles
    buildControls : true,

    // Tiempo de transición
    animTime: 500,

    // Slide activo inicial
    activeIndex: 0,

    // Función de animación para transiciones
    easing: "swing",

    // Tiempo de espera entre slides (ms)
    slideTime: 1500,

    // Iniciar slider automáticamente
    autoPlay: true,

    // Pausar slider al pasar el mouse
    pauseOnHover: true,

    // Tipo de animación para transiciones
    animType: "horizontal"
  };

  // registro interno sliders
  var sliders = {};
  // contador sliders creados para generar IDs
  var sliderCount = 0;

  // Genera ID para cada slider creado
  var sliderID = function(){
    return 's'+(++sliderCount);
  };

  // Registrar nuevo slider
  var sliderRegister = function(id, api){
    sliders[id] = api;
  };

  // Recupera slider creado
  var sliderGet = function(id){
    return sliders[id] || null;
  };

  // Elimina slider del registro
  var sliderRemove = function(id){
    delete sliders[id];
  };

  // tipos de animación disponibles para los sliders.
  var animTypes = {

    // Sin animación
    "none": function(opts, $prev, $next, dir, size){
      $prev.stop(true, true);
      $next.stop(true, true);
      $prev.removeClass('inactive');
      $next.removeClass('inactive');
      $prev.css({
        "opacity": 1,
        "top": 0,
        "left": 0,
        "z-index": 1
      });
      $next.css({
        "opacity": 1,
        "z-index": 2,
        "left": 0,
        "top": 0
      });
      $prev.addClass("inactive");
    },

    // Animación: Movimiento horizontal
    "horizontal": function(opts, $prev, $next, dir, size){
      $prev.stop(true, true);
      $next.stop(true, true);
      $prev.removeClass('inactive');
      $next.removeClass('inactive');

      $prev.css({
        "opacity": 1,
        "top" : 0,
        "left" : 0,
        "z-index": 1
      });

      $next.css({
        "opacity": 1,
        "z-index" : 2,
        "left": (-dir*size.width)+'px',
        "top" : 0
      });

      $prev.animate({
        'left' : (dir*size.width)+'px'
      }, opts.animTime, opts.easing, function(){
        $prev.addClass('inactive');
      });

      $next.animate({
        'left': 0
      }, opts.animTime, opts.easing);
    },

    // Animación: movimiento vertical
    "vertical": function(opts, $prev, $next, dir, size){
      $prev.css({
        "opacity": 1,
        "z-index": 1,
        "left": 0,
        "top": 0
      });
      $next.css({
        "opacity": 1,
        "left": 0,
        "z-index": 2,
        "top": (-dir*size.height)+'px'
      });

      $next.addClass('active');
      $prev.animate({
        'top': (dir*size.height)+'px'
      }, opts.animTime, opts.easing, function(){
        $prev.addClass('inactive');
      });

      $next.animate({
        'top': 0
      }, opts.animTime, opts.easing);
    },

    // Animación: desvanecer
    "fade": function(opts, $prev, $next, dir, size) {

      $next.addClass('active');
      $prev.css({
        "z-index": 1,
        "top": 0,
        "left": 0,
        "opacity": 1
      });

      $next.css({
        "z-index": 2,
        "opacity": 0,
        "top": 0,
        "left": 0
      });

      $next.fadeTo(opts.animTime, 1, function(){
        $prev.addClass('inactive');
      });
    },

    // Animación: aleatoria (incluye todas excepto 'none')
    "random": function(opts, $prev, $next, dir, size) {
      var animKeys = $.map(animTypes, function(elem,index){ return index; });
      animKeys = $.grep(animKeys, function(elem,index){ return elem != 'none' && elem != 'random'; });
      var randKey = Math.floor(Math.random()*animKeys.length);
      animTypes[animKeys[randKey]].apply(this, [opts, $prev, $next, dir, size]);
    }
  };

  /**
   * Permite extender la funcionalidad de PIASlider.
   *
   * La función llamada recibe la API General de PIASlider
   * - plugin
   * - getSlider
   * - removeSlider
   * - getSliders
   * - create
   */
  var plugin = function(pluginFunc){
    pluginFunc({
      defaultOptions: defaultOptions,
      animTypes: animTypes,
      api: generalAPI
    });
  };

  /**
   * Crea un slider
   *
   * @param string selector Indica el elemento en el que crear el slider.
   * @param object options Opciones a pasar al slider
   */
  var sliderCreate = function(selector, options)
  {
    var id = sliderID();
    var opts = $.extend({}, defaultOptions, options);
    var $container = (selector instanceof jQuery ? selector : $(selector));
    var $slider = $container.find('.slider');
    var $controls = $container.find(opts.controlSelector);
    var slideTm = 0;
    var playing = false;

    var getAnimFunc = function(){
      if($.isFunction(opts.animType)){
        return opts.animType;
      } else {
        return animTypes[opts.animType];
      }
    };

    var getID = function()
    {
      return id;
    };

    var play = function()
    {
      stop();
      slideTm = setTimeout(playNext, opts.slideTime);
    };

    var pause = function()
    {
      if(playing){
        stop();
      } else {
        play();
      }
    };

    /**
     * Parar slider
     */
    var stop = function(){
      clearTimeout(slideTm);
      playing = false;
    };

    /**
     * Ir a siguiente slide (temporizador)
     */
    var playNext = function(){
      stop();
      playing = true;
      nextSlide();
      slideTm = setTimeout(playNext, opts.slideTime);
    };

    /**
     * Devuelve un número entre 0 y el máximo,
     * utilizando el módulo de n y máximo.
     */
    var getCyclic = function(n, maxN){
      return (maxN + (n % maxN)) % maxN;
    };

    /**
     * Recupera los slides actuales.
     */
    var getSlides = function(){
      return $slider.find('.slide');
    };

    /**
     * número de slides.
     */
    var getSlideCount = function(){
      return getSlides().length;
    };

    /**
     * Slide activo (indice)
     */
    var getActiveIndex = function(){
      return getSlides().filter('.active').index();
    };

    /**
     * Medidas del slider.
     */
    var getSize = function(){
      return {
        width: $slider.width(),
        height: $slider.height()
      };
    };

    /**
     * Handler para pulsación en control de slider.
     */
    var controlClick = function(ev){
      ev.preventDefault();
      var index = $(this).data('index');
      gotoSlide(index);
      return false;
     };

    /**
     * Genera los controles.
     */
    var buildControls = function(){
      if($controls.length === 0){
        $controls = $('

');
        $controls.appendTo($container);
      }
      var slideCount = getSlideCount();
      for(var i = 0; i < slideCount; i++){
         var $control = $('');
         $control.addClass('slider-control-item');
         $control.html('');
         $control.attr('data-index', i);
         $control.data('index', i);
         $control.on('click', controlClick);
         $control.appendTo($controls);
      }
    };

    /**
     * Iniciar los slides ( ocultar, etc)
     */
    var initSlides = function()
    {
        $container.hover(function(){
          if(opts.autoPlay && opts.pauseOnHover){
            stop();
          }
        }, function(){
          if(opts.autoPlay && opts.pauseOnHover){
            play();
          }
        });

      var $slides = getSlides();
      $slides.addClass('inactive');
      var $activeSlide = $slides.eq(opts.activeIndex);
      $activeSlide.removeClass('inactive');
      $activeSlide.addClass('active');
      updateControls();
    };

    /**
     * Actualizar controles para reflejar estado actual de slider.
     */
    var updateControls = function()
    {
      var activeIndex = getActiveIndex();
      var $controlItems = $controls.find('.slider-control-item');
      var $cControl = $controlItems.eq(activeIndex);
      $controlItems.not(':eq('+activeIndex+')').removeClass('active');
      $cControl.addClass('active');
    };

    /**
     * Ir a slide, calcula número dentro del total de slides,
     * de modo que -1 = num slides - 1
     */
    var gotoSlide = function(n){
      stop();
      var activeIndex = getActiveIndex();
      var $slides = getSlides();
      var slideCount = getSlideCount();
      var dir = 0;

      n = getCyclic(n, slideCount);
      if(activeIndex != n){
        dir = -(n - activeIndex);
        dir = dir / Math.abs(dir);
        if(activeIndex === slideCount - 1 && n === 0) dir = -1;
      } else {
        return;
      }

      var $cSlide = $slides.eq(activeIndex);
      var $nSlide = $slides.eq(n);
      var size = getSize();

      var animFunc = getAnimFunc();
      $nSlide.stop();
      $cSlide.stop();
      $nSlide.addClass('active');
      $cSlide.removeClass('active');
      $nSlide.removeClass('inactive');
      $cSlide.removeClass('inactive');
      animFunc(opts, $cSlide, $nSlide, dir, size);
      updateControls();
      $container.trigger('pia.slider.slide', [{
        slider: sliderAPI,
        index: n,
        prevIndex: activeIndex,
        $prev: $cSlide,
        $next : $nSlide}]);
    };

    /**
     * Siguiente Slide.
     */
    var nextSlide = function(){
      gotoSlide(getActiveIndex() + 1);
    };

    /**
     * Slide Anterior.
     */
    var prevSlide = function(){
      gotoSlide(getActiveIndex() - 1);
    };

    // Generar botones de control
    if(opts.buildControls){
      buildControls();
    }

    // Inicializar slides
    initSlides();

    // Iniciar slider
    if(opts.autoPlay){
      play();
    }

    /**
     * Especificar opción
     *
     * @param {string} optKey   Nombre de la opción
     * @param {object} optValue Valor de la opción
     */
    var setOption = function(optKey, optValue){
      opts[optKey] = optValue;
    };

    /**
     * Recuperar opción
     *
     * @param  {string} optKey     Nombre de la opción
     * @param  {object} defaultVal Valor por defecto
     * @return {object}
     */
    var getOption = function(optKey, defaultVal){
      return opts[optKey] || defaultVal;
    };

    /**
     * Funciones disponibles externamente (por cada slider)
     * @type {Object}
     */
    var sliderAPI = {
      $element: $container,
      gotoSlide : gotoSlide,
      nextSlide: nextSlide,
      prevSlide: prevSlide,
      slideCount: getSlideCount,
      play: play,
      pause: pause,
      stop: stop,
      setOption: setOption,
      getOption: getOption,
      getID: getID,
      getSize: getSize
    };

    sliderRegister(id, sliderAPI);
    return sliderAPI;
  };

  /**
   * Recuperar sliders registrados.
   *
   * @return {array} Array de sliders registrados.
   */
  var slidersGet = function(){
    return sliders;
  };

  /**
   * Funciones disponibles externamente. (Global de PIASlider)
   * @type {Object}
   */
  var generalAPI = {
      plugin: plugin,
      getSlider: sliderGet,
      getSliders: slidersGet,
      removeSlider: sliderRemove,
      create: sliderCreate
  };
  return generalAPI;
})();
<|endoftext|>


<commit_before>#!/usr/bin/env node --expose-gc
/*
Copyright by Oleg Efimov and node-mysql-libmysqlclient contributors
See contributors list in README

See license text in LICENSE file
*/

var
// Require modules
  mysql = require("../"),
  async = require("async"),
  helper = require("./memory-helper"),
// Load configuration
  cfg = require("../tests/config"),
// Parameters
  timeLimitInSec = 10*60*60,
  forceGc = false,
  pauseBetweenOperationsInMs = 1,
  logMemoryUsageIntervalInMs = 400,
  logMemoryUsageInterval = null,
  // Start time
  startHrTime = [0, 0];

function logMemoryUsage() {
  var
    currentHrTime = process.hrtime(),
    timeDelta = '',
    memoryUsage = process.memoryUsage(),
    Mb = 1024*1024;

  if (currentHrTime[1] >= startHrTime[1]) {
    timeDelta = (currentHrTime[0] - startHrTime[0]) + (currentHrTime[1] - startHrTime[1])/1e9;
  } else {
    timeDelta = (currentHrTime[0] - startHrTime[0] - 1) + (currentHrTime[1] - startHrTime[1] + 1e9)/1e9;
  }

  console.log(timeDelta + '\t' + memoryUsage.rss/Mb + '\t' + memoryUsage.heapUsed/Mb + '\t' + memoryUsage.heapTotal/Mb);
}

function performOperation(callback) {
  var connection = mysql.createConnectionSync(cfg.host, cfg.user, cfg.password, cfg.database);

  if (!connection.connectedSync()) {
    setTimeout(callback, pauseBetweenOperationsInMs);
    return;
  }

  connection.query("SELECT 'some string' AS `str`;", function (error, result) {
    if (error) throw error;

    result.fetchAll(function (error, rows) {
      if (error) throw error;

      rows = null;

      process.nextTick(callback);
    });
  });
}

// Main program
console.log("time\tRSS\theapUsed\theapTotal");

startHrTime = process.hrtime();
logMemoryUsage();

if (logMemoryUsageIntervalInMs > 0) {
  logMemoryUsageInterval = setInterval(logMemoryUsage, logMemoryUsageIntervalInMs);
}

async.whilst(
  function () {
    var currentHrTime = process.hrtime();

    return (currentHrTime[0] - startHrTime[0]) < timeLimitInSec;
  },
  function (callback) {
    performOperation(function () {
      if (forceGc) {
        helper.heavyGc();
      }

      if (logMemoryUsageIntervalInMs == 0) {
        logMemoryUsage();
      }

      if (pauseBetweenOperationsInMs > 0) {
        setTimeout(callback, pauseBetweenOperationsInMs);
      } else {
        process.nextTick(callback);
      }
    });
  },
  function (error) {
    if (error) throw error;

    // All ok
    if (logMemoryUsageInterval) {
      clearInterval(logMemoryUsageInterval);
    }

    process.exit(0);
  }
);
<commit_msg>Improve memory usage dumper<commit_after>#!/usr/bin/env node --expose-gc
/*
Copyright by Oleg Efimov and node-mysql-libmysqlclient contributors
See contributors list in README

See license text in LICENSE file
*/

var
// Require modules
  fs = require("fs"),
  mysql = require("../"),
  async = require("async"),
  helper = require("./memory-helper"),
// Load configuration
  cfg = require("../tests/config"),
// Parameters
  timeLimitInSec = 10 * 60,
  gcLevel = 0,
  pauseBetweenOperationsInMs = 1,
  dumpMemoryUsageIntervalInMs = 200,
  dumpMemoryUsageInterval = null,
  drawMemoryUsageGraphIntervalInMs = 60*1000,
  drawMemoryUsageGraphInterval = null,
// Start time
  startHrTime = [0, 0],
// Other
  filenameResult = '',
  filenameData = '',
  dataFd = null;

function dumpMemoryUsage() {
  var
    currentHrTime = process.hrtime(),
    timeDelta = '',
    memoryUsage = process.memoryUsage(),
    Mb = 1024*1024;

  if (currentHrTime[1] >= startHrTime[1]) {
    timeDelta = (currentHrTime[0] - startHrTime[0]) + (currentHrTime[1] - startHrTime[1])/1e9;
  } else {
    timeDelta = (currentHrTime[0] - startHrTime[0] - 1) + (currentHrTime[1] - startHrTime[1] + 1e9)/1e9;
  }

  fs.writeSync(dataFd, timeDelta + '\t' + memoryUsage.rss/Mb + '\t' + memoryUsage.heapUsed/Mb + '\t' + memoryUsage.heapTotal/Mb + "\n");
}

function performOperation(callback) {
  var connection = mysql.createConnectionSync(cfg.host, cfg.user, cfg.password, cfg.database);

  if (!connection.connectedSync()) {
    setTimeout(callback, pauseBetweenOperationsInMs);
    return;
  }

  connection.query("SELECT 'some string' AS `str`;", function (error, result) {
    if (error) throw error;

    result.fetchAll(function (error, rows) {
      if (error) throw error;

      rows = null;

      process.nextTick(callback);
    });
  });
}

// Parse program arguments
params = process.argv.splice(2);

var gcLevelFound = false;
params.forEach(function (param) {
  if (param.slice(0, 5) === "--gc=") {
    gcLevel = param.slice(5);
  } else if (param === '--gc') {
    gcLevelFound = true;
  } else if (gcLevelFound) {
    gcLevel = param;
    gcLevelFound = false;
  }
});

gcLevel = parseInt(gcLevel, 10);

var myGc = function () {};
if (gcLevel > 0) {
  myGc = gc;
}
if (gcLevel > 1) {
  myGc = helper.heavyGc;
}

filenameData = "memory-usage-dump.dat";
filenameResult = "memory-usage-gc-" + gcLevel + ".png";

// Main program
openDataFile();

function openDataFile() {
  console.log("Opening data file for writing...");

  fs.open(__dirname + "/" + filenameData, "w", function (error, fd) {
    if (error) throw error;

    dataFd = fd;

    process.nextTick(dumpMemoryUsageProfile);
  });
}

function dumpMemoryUsageProfile() {
  console.log("Start writing...");

  // Write data table header to file
  fs.writeSync(dataFd, "time\tRSS\theapUsed\theapTotal\n");

  // Start timer, save initial memory usage
  startHrTime = process.hrtime();
  if (dumpMemoryUsageIntervalInMs > 0) {
    dumpMemoryUsageInterval = setInterval(dumpMemoryUsage, dumpMemoryUsageIntervalInMs);
  }
  dumpMemoryUsage();
  if (drawMemoryUsageGraphIntervalInMs > 0) {
    drawMemoryUsageGraphInterval = setInterval(drawMemoryUsageGraph, drawMemoryUsageGraphIntervalInMs);
  }

  // Start async operations
  async.whilst(
    function () {
      var currentHrTime = process.hrtime();

      return (currentHrTime[0] - startHrTime[0]) < timeLimitInSec;
    },
    function (callback) {
      performOperation(function () {
        myGc();

        if (dumpMemoryUsageIntervalInMs === 0) {
          dumpMemoryUsage();
        }

        if (pauseBetweenOperationsInMs > 0) {
          setTimeout(callback, pauseBetweenOperationsInMs);
        } else {
          process.nextTick(callback);
        }
      });
    },
    function (error) {
      if (error) throw error;

      // All ok
      if (dumpMemoryUsageInterval) {
        clearInterval(dumpMemoryUsageInterval);
      }
      if (drawMemoryUsageGraphInterval) {
        clearInterval(drawMemoryUsageGraphInterval);
      }

      fs.close(dataFd, function (error) {
        if (error) throw error;

        console.log("Draw graph...");
        drawMemoryUsageGraph(function () {
          console.log("Done.");
        });
      });
    }
  );
}

function drawMemoryUsageGraph(callback) {
  require("child_process").exec(
    "gle -output " + __dirname + "/" + filenameResult +  " " + __dirname + "/memory-usage-dump.gle",
    function (error) {
      if (error) throw error;

      if (typeof callback === "function") {
        process.nextTick(callback);
      }
    }
  );
}
<|endoftext|>


<commit_before>var util          = require("util")
  , EventEmitter = require("events").EventEmitter

module.exports = (function() {
  var CustomEventEmitter = function(fct) {
    this.fct = fct
  }
  util.inherits(CustomEventEmitter, EventEmitter)

  CustomEventEmitter.prototype.run = function() {
    var self = this

    // delay the function call and return the emitter
    setTimeout(function(){
      self.fct.call(self, self)
    }, 1)

    return this
  }

  CustomEventEmitter.prototype.success =
  CustomEventEmitter.prototype.ok =
  function(fct) {
    this.on('success', fct)
    return this
  }

  CustomEventEmitter.prototype.failure =
  CustomEventEmitter.prototype.fail =
  CustomEventEmitter.prototype.error =
  function(fct) {
    this.on('failure', fct)
    return this
  }

  return CustomEventEmitter
})()
<commit_msg>fixes #156 Single Error/Success function? - add "done" and "complete"<commit_after>var util          = require("util")
  , EventEmitter = require("events").EventEmitter

module.exports = (function() {
  var CustomEventEmitter = function(fct) {
    this.fct = fct
  }
  util.inherits(CustomEventEmitter, EventEmitter)

  CustomEventEmitter.prototype.run = function() {
    var self = this

    // delay the function call and return the emitter
    setTimeout(function(){
      self.fct.call(self, self)
    }, 1)

    return this
  }

  CustomEventEmitter.prototype.success =
  CustomEventEmitter.prototype.ok =
  function(fct) {
    this.on('success', fct)
    return this
  }

  CustomEventEmitter.prototype.failure =
  CustomEventEmitter.prototype.fail =
  CustomEventEmitter.prototype.error =
  function(fct) {
    this.on('failure', fct)
    return this
  }

  CustomEventEmitter.prototype.done =
  CustomEventEmitter.prototype.complete =
  function(fct) {
    this.on('failure', function(d){ fct(d, null) })
        .on('success', function(d){ fct(null, d) })
    return this
  }

  return CustomEventEmitter
})()
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var package = require('../package');
var encode = require('websafe-base64').encode;
var slug = require('slug');
var map = require('map');

/**
 * Initialize our regular expression for url construction/deconstruction
 */

var regexp = /:([\w-]+)/g;

/**
 * Register it with angular
 */

package.directive('hyperLink', [
  function() {
    return {
      link: function($scope, elem, attrs) {
        elem.addClass('ng-hyper-loading');

        var keys = parse(attrs.hyperLink);

        var exp = '[' + keys.toString() + ']';

        $scope.$watch(exp, function() {
          var loaded = true;

          var href = attrs.hyperLink.replace(regexp, function(full, key) {
            if ($scope[key] || $scope[key] === 0) return fmt($scope[key]);
            loaded = false;
            return '-';
          });

          // we're still waiting for properties to come in
          if (!loaded) return;

          // If we're in a browser that doesn't support push state
          if (!window.history.pushState) href = '/#!' + href;

          elem.attr('href', href);
          elem.removeClass('ng-hyper-loading');
          elem.addClass('ng-hyper-loaded');
        }, true);
      }
    };
  }
]);

/**
 * Parse the link
 */

exports.parse = parse;
function parse(link) {
  return map(link.match(regexp), function(key) {
    return key.substr(1);
  });
}

/**
 * Format a value for the url
 */

exports.fmt = fmt;
function fmt(v) {
  if (v && v.href) return encode(v.href);
  return slug(v);
}
<commit_msg>add support for normal links in hyper-link<commit_after>/**
 * Module dependencies
 */

var package = require('../package');
var encode = require('websafe-base64').encode;
var slug = require('slug');
var map = require('map');

/**
 * Initialize our regular expression for url construction/deconstruction
 */

var regexp = /:([\w-]+)/g;

/**
 * Register it with angular
 */

package.directive('hyperLink', [
  function() {
    return {
      link: function($scope, elem, attrs) {
        elem.addClass('ng-hyper-loading');

        var href = attrs.hyperLink;
        var keys = parse(href);

        // If it doesn't have any templated properties just render it
        if (!keys) return loadLink(href);

        var exp = '[' + keys.toString() + ']';

        $scope.$watch(exp, function() {
          var loaded = true;

          var href = attrs.hyperLink.replace(regexp, function(full, key) {
            if ($scope[key] || $scope[key] === 0) return fmt($scope[key]);
            loaded = false;
            return '-';
          });

          // we're still waiting for properties to come in
          if (!loaded) return;

          loadLink(href);
        }, true);

        function loadLink(href) {
          elem.attr('href', href);
          elem.removeClass('ng-hyper-loading');
          elem.addClass('ng-hyper-loaded');
        };
      }
    };
  }
]);

/**
 * Parse the link
 */

exports.parse = parse;
function parse(link) {
  var matches = link.match(regexp);
  if (!matches) return;
  return map(matches, function(key) {
    return key.substr(1);
  });
}

/**
 * Format a value for the url
 */

exports.fmt = fmt;
function fmt(v) {
  if (v && v.href) return encode(v.href);
  return slug(v);
}
<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _from = require('babel-runtime/core-js/array/from');

var _from2 = _interopRequireDefault(_from);

var _map = require('babel-runtime/core-js/map');

var _map2 = _interopRequireDefault(_map);

var _assign = require('babel-runtime/core-js/object/assign');

var _assign2 = _interopRequireDefault(_assign);

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');

var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

var _defineProperty2 = require('babel-runtime/helpers/defineProperty');

var _defineProperty3 = _interopRequireDefault(_defineProperty2);

var _extends2 = require('babel-runtime/helpers/extends');

var _extends3 = _interopRequireDefault(_extends2);

var _stylesheet;

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _markdownToReactComponents = require('markdown-to-react-components');

var _markdownToReactComponents2 = _interopRequireDefault(_markdownToReactComponents);

var _PropTable = require('./PropTable');

var _PropTable2 = _interopRequireDefault(_PropTable);

var _Node = require('./Node');

var _Node2 = _interopRequireDefault(_Node);

var _markdown = require('./markdown');

var _theme = require('./theme');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

_markdownToReactComponents2.default.configure({
  h1: _markdown.H1,
  h2: _markdown.H2,
  h3: _markdown.H3,
  h4: _markdown.H4,
  h5: _markdown.H5,
  h6: _markdown.H6,
  code: _markdown.Code,
  // pre: Pre,
  p: _markdown.P,
  a: _markdown.A,
  li: _markdown.LI,
  ul: _markdown.UL
});

var stylesheet = (_stylesheet = {
  link: {
    base: {
      fontFamily: 'sans-serif',
      fontSize: 12,
      display: 'block',
      position: 'fixed',
      textDecoration: 'none',
      background: '#28c',
      color: '#fff',
      padding: '5px 15px',
      cursor: 'pointer'
    },
    topRight: {
      top: 0,
      right: 0,
      borderRadius: '0 0 0 5px'
    }
  },
  info: {
    position: 'absolute',
    background: 'white',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    padding: '0 40px',
    overflow: 'auto'
  },
  infoBody: {
    fontSize: "16px"
  }
}, (0, _defineProperty3.default)(_stylesheet, 'infoBody', (0, _extends3.default)({}, _theme.baseFonts, {
  fontWeight: 300,
  lineHeight: 1.45,
  fontSize: 15
})), (0, _defineProperty3.default)(_stylesheet, 'infoContent', {
  marginBottom: 0
}), (0, _defineProperty3.default)(_stylesheet, 'header', {
  h1: {
    margin: '20px 0 0 0',
    padding: 0,
    fontSize: 35
  },
  h2: {
    margin: '0 0 10px 0',
    padding: 0,
    fontWeight: 400,
    fontSize: 22
  },
  body: {
    borderBottom: '1px solid #eee',
    marginBottom: 10
  }
}), (0, _defineProperty3.default)(_stylesheet, 'source', {
  h1: {
    margin: '20px 0 0 0',
    padding: '0 0 5px 0',
    fontSize: 25,
    borderBottom: '1px solid #EEE'
  }
}), (0, _defineProperty3.default)(_stylesheet, 'propTableHead', {
  margin: '20px 0 0 0'
}), _stylesheet);

var Story = function (_React$Component) {
  (0, _inherits3.default)(Story, _React$Component);

  function Story() {
    var _Object$getPrototypeO;

    (0, _classCallCheck3.default)(this, Story);

    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    var _this = (0, _possibleConstructorReturn3.default)(this, (_Object$getPrototypeO = (0, _getPrototypeOf2.default)(Story)).call.apply(_Object$getPrototypeO, [this].concat(args)));

    _this.state = { open: false };
    return _this;
  }

  (0, _createClass3.default)(Story, [{
    key: 'render',
    value: function render() {
      if (this.props.showInline) {
        return this._renderInline();
      }
      return this._renderOverlay();
    }
  }, {
    key: '_renderStory',
    value: function _renderStory() {
      return _react2.default.createElement(
        'div',
        null,
        this.props.children
      );
    }
  }, {
    key: '_renderInline',
    value: function _renderInline() {
      return _react2.default.createElement(
        'div',
        null,
        _react2.default.createElement(
          'div',
          { style: stylesheet.infoPage },
          _react2.default.createElement(
            'div',
            { style: stylesheet.infoBody },
            this._getInfoHeader(),
            this._renderStory(),
            this._getInfoContent(),
            this._getSourceCode(),
            this._getPropTables()
          )
        )
      );
    }
  }, {
    key: '_renderOverlay',
    value: function _renderOverlay() {
      var _this2 = this;

      var linkStyle = (0, _extends3.default)({}, stylesheet.link.base, stylesheet.link.topRight);
      var infoStyle = (0, _assign2.default)({}, stylesheet.info);
      if (!this.state.open) {
        infoStyle.display = 'none';
      }

      var openOverlay = function openOverlay() {
        _this2.setState({ open: true });
        return false;
      };

      var closeOverlay = function closeOverlay() {
        _this2.setState({ open: false });
        return false;
      };

      return _react2.default.createElement(
        'div',
        null,
        this.props.children,
        _react2.default.createElement(
          'a',
          { style: linkStyle, onClick: openOverlay },
          '?'
        ),
        _react2.default.createElement(
          'div',
          { style: infoStyle },
          _react2.default.createElement(
            'a',
            { style: linkStyle, onClick: closeOverlay },
            '×'
          ),
          _react2.default.createElement(
            'div',
            { style: stylesheet.infoPage },
            _react2.default.createElement(
              'div',
              { style: stylesheet.infoBody },
              this._getInfoHeader(),
              this._getInfoContent(),
              this._getSourceCode(),
              this._getPropTables()
            )
          )
        )
      );
    }
  }, {
    key: '_getInfoHeader',
    value: function _getInfoHeader() {
      if (!this.props.context || !this.props.showHeader) {
        return null;
      }

      return _react2.default.createElement(
        'div',
        { style: stylesheet.header.body },
        _react2.default.createElement(
          'h1',
          { style: stylesheet.header.h1 },
          this.props.context.kind
        ),
        _react2.default.createElement(
          'h2',
          { style: stylesheet.header.h2 },
          this.props.context.story
        )
      );
    }
  }, {
    key: '_getInfoContent',
    value: function _getInfoContent() {
      if (!this.props.info) {
        return '';
      }
      var lines = this.props.info.split('\n');
      while (lines[0].trim() === '') {
        lines.shift();
      }
      var padding = 0;
      var matches = lines[0].match(/^ */);
      if (matches) {
        padding = matches[0].length;
      }
      var source = lines.map(function (s) {
        return s.slice(padding);
      }).join('\n');
      return _react2.default.createElement(
        'div',
        { style: stylesheet.infoContent },
        (0, _markdownToReactComponents2.default)(source).tree
      );
    }
  }, {
    key: '_getSourceCode',
    value: function _getSourceCode() {
      if (!this.props.showSource) {
        return null;
      }

      return _react2.default.createElement(
        'div',
        null,
        _react2.default.createElement(
          'h1',
          { style: stylesheet.source.h1 },
          'Story Source'
        ),
        _react2.default.createElement(
          _markdown.Pre,
          null,
          _react2.default.Children.map(this.props.children, function (root, idx) {
            return _react2.default.createElement(_Node2.default, { key: idx, depth: 0, node: root });
          })
        )
      );
    }
  }, {
    key: '_getPropTables',
    value: function _getPropTables() {
      if (this.props.propTables === false) {
        return null;
      }

      if (!this.props.children) {
        return null;
      }

      var types = new _map2.default();

      if (this.props.propTables) {
        this.props.propTables.forEach(function (type) {
          types.set(type, true);
        });
      }

      function extract(children) {
        if (Array.isArray(children)) {
          children.forEach(extract);
          return;
        }
        if (typeof children === 'string' || typeof children.type === 'string') {
          return;
        }

        var type = children.type;
        var name = type.displayName || type.name;
        if (!types.has(type)) {
          types.set(type, true);
        }
        if (children.props.children) {
          extract(children.props.children);
        }
      }

      // extract components from children
      extract(this.props.children);

      var array = (0, _from2.default)(types.keys());
      array.sort(function (a, b) {
        return (a.displayName || a.name) > (b.displayName || b.name);
      });

      var propTables = array.map(function (type, idx) {
        return _react2.default.createElement(
          'div',
          { key: idx },
          _react2.default.createElement(
            'h2',
            { style: stylesheet.propTableHead },
            '"',
            type.displayName || type.name,
            '" Component'
          ),
          _react2.default.createElement(_PropTable2.default, { type: type })
        );
      });

      if (!propTables || propTables.length === 0) {
        return null;
      }

      return _react2.default.createElement(
        'div',
        null,
        _react2.default.createElement(
          'h1',
          { style: stylesheet.source.h1 },
          'Prop Types'
        ),
        propTables
      );
      return;
    }
  }]);
  return Story;
}(_react2.default.Component);

exports.default = Story;

Story.displayName = 'Story';
Story.propTypes = {
  context: _react2.default.PropTypes.object,
  info: _react2.default.PropTypes.string,
  propTables: _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.func),
  showInline: _react2.default.PropTypes.bool,
  showHeader: _react2.default.PropTypes.bool,
  showSource: _react2.default.PropTypes.bool
};
Story.defaultProps = {
  showInline: false,
  showHeader: true,
  showSource: true
};<commit_msg>Build dist<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _from = require('babel-runtime/core-js/array/from');

var _from2 = _interopRequireDefault(_from);

var _map = require('babel-runtime/core-js/map');

var _map2 = _interopRequireDefault(_map);

var _assign = require('babel-runtime/core-js/object/assign');

var _assign2 = _interopRequireDefault(_assign);

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');

var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

var _defineProperty2 = require('babel-runtime/helpers/defineProperty');

var _defineProperty3 = _interopRequireDefault(_defineProperty2);

var _extends2 = require('babel-runtime/helpers/extends');

var _extends3 = _interopRequireDefault(_extends2);

var _stylesheet;

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _markdownToReactComponents = require('markdown-to-react-components');

var _markdownToReactComponents2 = _interopRequireDefault(_markdownToReactComponents);

var _PropTable = require('./PropTable');

var _PropTable2 = _interopRequireDefault(_PropTable);

var _Node = require('./Node');

var _Node2 = _interopRequireDefault(_Node);

var _markdown = require('./markdown');

var _theme = require('./theme');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

_markdownToReactComponents2.default.configure({
  h1: _markdown.H1,
  h2: _markdown.H2,
  h3: _markdown.H3,
  h4: _markdown.H4,
  h5: _markdown.H5,
  h6: _markdown.H6,
  code: _markdown.Code,
  // pre: Pre,
  p: _markdown.P,
  a: _markdown.A,
  li: _markdown.LI,
  ul: _markdown.UL
});

var stylesheet = (_stylesheet = {
  link: {
    base: {
      fontFamily: 'sans-serif',
      fontSize: 12,
      display: 'block',
      position: 'fixed',
      textDecoration: 'none',
      background: '#28c',
      color: '#fff',
      padding: '5px 15px',
      cursor: 'pointer'
    },
    topRight: {
      top: 0,
      right: 0,
      borderRadius: '0 0 0 5px'
    }
  },
  info: {
    position: 'absolute',
    background: 'white',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    padding: '0 40px',
    overflow: 'auto'
  },
  infoBody: {
    fontSize: "16px"
  }
}, (0, _defineProperty3.default)(_stylesheet, 'infoBody', (0, _extends3.default)({}, _theme.baseFonts, {
  fontWeight: 300,
  lineHeight: 1.45,
  fontSize: 15
})), (0, _defineProperty3.default)(_stylesheet, 'infoContent', {
  marginBottom: 0
}), (0, _defineProperty3.default)(_stylesheet, 'header', {
  h1: {
    margin: '20px 0 0 0',
    padding: 0,
    fontSize: 35
  },
  h2: {
    margin: '0 0 10px 0',
    padding: 0,
    fontWeight: 400,
    fontSize: 22
  },
  body: {
    borderBottom: '1px solid #eee',
    marginBottom: 10
  }
}), (0, _defineProperty3.default)(_stylesheet, 'source', {
  h1: {
    margin: '20px 0 0 0',
    padding: '0 0 5px 0',
    fontSize: 25,
    borderBottom: '1px solid #EEE'
  }
}), (0, _defineProperty3.default)(_stylesheet, 'propTableHead', {
  margin: '20px 0 0 0'
}), _stylesheet);

var Story = function (_React$Component) {
  (0, _inherits3.default)(Story, _React$Component);

  function Story() {
    var _Object$getPrototypeO;

    (0, _classCallCheck3.default)(this, Story);

    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    var _this = (0, _possibleConstructorReturn3.default)(this, (_Object$getPrototypeO = (0, _getPrototypeOf2.default)(Story)).call.apply(_Object$getPrototypeO, [this].concat(args)));

    _this.state = { open: false };
    return _this;
  }

  (0, _createClass3.default)(Story, [{
    key: 'render',
    value: function render() {
      if (this.props.showInline) {
        return this._renderInline();
      }
      return this._renderOverlay();
    }
  }, {
    key: '_renderStory',
    value: function _renderStory() {
      return _react2.default.createElement(
        'div',
        null,
        this.props.children
      );
    }
  }, {
    key: '_renderInline',
    value: function _renderInline() {
      return _react2.default.createElement(
        'div',
        null,
        _react2.default.createElement(
          'div',
          { style: stylesheet.infoPage },
          _react2.default.createElement(
            'div',
            { style: stylesheet.infoBody },
            this._getInfoHeader()
          )
        ),
        _react2.default.createElement(
          'div',
          null,
          this._renderStory()
        ),
        _react2.default.createElement(
          'div',
          { style: stylesheet.infoPage },
          _react2.default.createElement(
            'div',
            { style: stylesheet.infoBody },
            this._getInfoContent(),
            this._getSourceCode(),
            this._getPropTables()
          )
        )
      );
    }
  }, {
    key: '_renderOverlay',
    value: function _renderOverlay() {
      var _this2 = this;

      var linkStyle = (0, _extends3.default)({}, stylesheet.link.base, stylesheet.link.topRight);
      var infoStyle = (0, _assign2.default)({}, stylesheet.info);
      if (!this.state.open) {
        infoStyle.display = 'none';
      }

      var openOverlay = function openOverlay() {
        _this2.setState({ open: true });
        return false;
      };

      var closeOverlay = function closeOverlay() {
        _this2.setState({ open: false });
        return false;
      };

      return _react2.default.createElement(
        'div',
        null,
        this.props.children,
        _react2.default.createElement(
          'a',
          { style: linkStyle, onClick: openOverlay },
          '?'
        ),
        _react2.default.createElement(
          'div',
          { style: infoStyle },
          _react2.default.createElement(
            'a',
            { style: linkStyle, onClick: closeOverlay },
            '×'
          ),
          _react2.default.createElement(
            'div',
            { style: stylesheet.infoPage },
            _react2.default.createElement(
              'div',
              { style: stylesheet.infoBody },
              this._getInfoHeader(),
              this._getInfoContent(),
              this._getSourceCode(),
              this._getPropTables()
            )
          )
        )
      );
    }
  }, {
    key: '_getInfoHeader',
    value: function _getInfoHeader() {
      if (!this.props.context || !this.props.showHeader) {
        return null;
      }

      return _react2.default.createElement(
        'div',
        { style: stylesheet.header.body },
        _react2.default.createElement(
          'h1',
          { style: stylesheet.header.h1 },
          this.props.context.kind
        ),
        _react2.default.createElement(
          'h2',
          { style: stylesheet.header.h2 },
          this.props.context.story
        )
      );
    }
  }, {
    key: '_getInfoContent',
    value: function _getInfoContent() {
      if (!this.props.info) {
        return '';
      }
      var lines = this.props.info.split('\n');
      while (lines[0].trim() === '') {
        lines.shift();
      }
      var padding = 0;
      var matches = lines[0].match(/^ */);
      if (matches) {
        padding = matches[0].length;
      }
      var source = lines.map(function (s) {
        return s.slice(padding);
      }).join('\n');
      return _react2.default.createElement(
        'div',
        { style: stylesheet.infoContent },
        (0, _markdownToReactComponents2.default)(source).tree
      );
    }
  }, {
    key: '_getSourceCode',
    value: function _getSourceCode() {
      if (!this.props.showSource) {
        return null;
      }

      return _react2.default.createElement(
        'div',
        null,
        _react2.default.createElement(
          'h1',
          { style: stylesheet.source.h1 },
          'Story Source'
        ),
        _react2.default.createElement(
          _markdown.Pre,
          null,
          _react2.default.Children.map(this.props.children, function (root, idx) {
            return _react2.default.createElement(_Node2.default, { key: idx, depth: 0, node: root });
          })
        )
      );
    }
  }, {
    key: '_getPropTables',
    value: function _getPropTables() {
      if (this.props.propTables === false) {
        return null;
      }

      if (!this.props.children) {
        return null;
      }

      var types = new _map2.default();

      if (this.props.propTables) {
        this.props.propTables.forEach(function (type) {
          types.set(type, true);
        });
      }

      function extract(children) {
        if (Array.isArray(children)) {
          children.forEach(extract);
          return;
        }
        if (typeof children === 'string' || typeof children.type === 'string') {
          return;
        }

        var type = children.type;
        var name = type.displayName || type.name;
        if (!types.has(type)) {
          types.set(type, true);
        }
        if (children.props.children) {
          extract(children.props.children);
        }
      }

      // extract components from children
      extract(this.props.children);

      var array = (0, _from2.default)(types.keys());
      array.sort(function (a, b) {
        return (a.displayName || a.name) > (b.displayName || b.name);
      });

      var propTables = array.map(function (type, idx) {
        return _react2.default.createElement(
          'div',
          { key: idx },
          _react2.default.createElement(
            'h2',
            { style: stylesheet.propTableHead },
            '"',
            type.displayName || type.name,
            '" Component'
          ),
          _react2.default.createElement(_PropTable2.default, { type: type })
        );
      });

      if (!propTables || propTables.length === 0) {
        return null;
      }

      return _react2.default.createElement(
        'div',
        null,
        _react2.default.createElement(
          'h1',
          { style: stylesheet.source.h1 },
          'Prop Types'
        ),
        propTables
      );
      return;
    }
  }]);
  return Story;
}(_react2.default.Component);

exports.default = Story;

Story.displayName = 'Story';
Story.propTypes = {
  context: _react2.default.PropTypes.object,
  info: _react2.default.PropTypes.string,
  propTables: _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.func),
  showInline: _react2.default.PropTypes.bool,
  showHeader: _react2.default.PropTypes.bool,
  showSource: _react2.default.PropTypes.bool
};
Story.defaultProps = {
  showInline: false,
  showHeader: true,
  showSource: true
};<|endoftext|>


<commit_before>/**
 * @author Toru Nagashima
 * See LICENSE file in root directory for full license.
 */
"use strict"

const { rules, utils } = require("eslint-plugin-eslint-comments")

utils.patch("mysticatea/eslint-comments/no-unused-disable")

module.exports = Object.keys(rules).reduce((obj, ruleId) => {
    obj[`eslint-comments/${ruleId}`] = rules[ruleId]
    return obj
}, {})
<commit_msg>Fix: make `@mysticatea/eslint-comments/no-unused-disable` working.<commit_after>/**
 * @author Toru Nagashima
 * See LICENSE file in root directory for full license.
 */
"use strict"

const { rules, utils } = require("eslint-plugin-eslint-comments")

utils.patch("@mysticatea/eslint-comments/no-unused-disable")

module.exports = Object.keys(rules).reduce((obj, ruleId) => {
    obj[`eslint-comments/${ruleId}`] = rules[ruleId]
    return obj
}, {})
<|endoftext|>


<commit_before>const consoleLogger = require('../../util/logger.js')
const http = require('http')
const throng = require('throng')
const split = require('split2')
const createStreamThrottle = require('../../util/throttle')
const extractTokenRegEx = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/
const tokenFormatRegEx = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/
const _SYSTEMD_UNIT = '_systemd_unit'
const SYSLOG_IDENTIFIER = 'syslog_identifier'
const TokenBlacklist = require('../../util/token-blacklist.js')

function JournaldUpload (config, eventEmitter) {
  this.config = config
  this.eventEmitter = eventEmitter
  this.removeFields = {}
  this.tokenBlackList = new TokenBlacklist(eventEmitter)
  // limit throughput per client
  this.throughputPerClient = this.config.maxInputRate || 50 * 1024 * 1024
  if (config.useSematextCommonSchema === undefined) {
    config.useSematextCommonSchema = true
  }
  if (config.parseMessageField === undefined) {
    // try to parse logs using patterns.yml
    config.parseMessageField = true
  }
  if (config.removeFields) {
    for (var i = 0; i < config.removeFields.length; i++) {
      this.removeFields[config.removeFields[i].toLowerCase()] = true
    }
  }
  // set default filter
  if (!config.systemdUnitFilter) {
    config.systemdUnitFilter = {
      include: /.*/i,
      exlude: null
    }
  }

  if (config.workers) {
    this.config.workers = config.workers
  } else {
    this.config.workers = 0
  }
  // blacklist invalid tokens
  let self = this
}

JournaldUpload.prototype.start = function () {
  if (this.config.workers && this.config.workers > 0) {
    throng({
      workers: this.config.workers,
      lifetime: Infinity
    }, this.startJournaldUpload.bind(this))
  } else {
    this.startJournaldUpload(1)
  }
}

JournaldUpload.prototype.stop = function (cb) {
  if (cb) {
    cb()
  }
}

JournaldUpload.prototype.emitEvent = function (log, token) {
  let systemdUnit = log[_SYSTEMD_UNIT]
  let config = this.config
  if (systemdUnit) {
    if (config.systemdUnitFilter !== undefined && config.systemdUnitFilter.include && !config.systemdUnitFilter.include.test(log['_SYSTEMD_UNIT'])) {
      return
    }
    if (config.systemdUnitFilter !== undefined && config.systemdUnitFilter.exclude && config.systemdUnitFilter.exclude.test(log['_SYSTEMD_UNIT'])) {
      return
    }
  }
  let context = {
    sourceName: log[_SYSTEMD_UNIT] || log[SYSLOG_IDENTIFIER] || 'journald',
    name: 'journald'
  }
  if (token) {
    // set index, for elasticsearch output plugin
    context.index = token
  }
  if (Object.keys(log).length > 0) {
    this.addTags(log)
    this.eventEmitter.emit('data.object', log, context)
  }
}

JournaldUpload.prototype.addTags = function (log) {
  if (this.config.tags === undefined) {
    return
  }
  let keys = Object.keys(this.config.tags)
  for (let i = 0; i < keys.length; i++) {
    // avoid overwriting _index when passed in URL
    if (log[keys[i]] === undefined) {
      log[keys[i]] = this.config.tags[keys[i]]
    }
  }
}

JournaldUpload.prototype.getHttpServer = function (aport, handler) {
  var _port = aport || process.env.PORT || 9200
  if (aport === true) {
    _port = process.env.PORT
  }
  var server = http.createServer(handler)
  try {
    var bindAddress = this.config.bindAddress || '0.0.0.0'
    server = server.listen(_port, bindAddress)
    consoleLogger.log('Logagent listening (http journald-upload): ' + bindAddress + ':' + _port + ', process id: ' + process.pid)
    return server
  } catch (err) {
    consoleLogger.log('Port in use journald-upload (' + _port + '): ' + err)
  }
}

JournaldUpload.prototype.parseLine = function (log, line) {
  if (!line) {
    return log
  }
  let index = line.indexOf('=')
  let fieldName = line.substr(0, index).toLowerCase()
  if (!this.removeFields[fieldName]) {
    log[fieldName] = line.substr(index + 1, line.length)
  }
  return log
}

JournaldUpload.prototype.parseBody = function (body, token) {
  let lines = body.split('\n')
  let log = null
  if (lines.length > 0) {
    log = {}
  } else {
    return
  }
  // fastest loop is counting down
  for (let i = lines.length; i >= 0 ; --i) {
    this.parseLine(log, lines[i])
  }
  this.emitEvent(log, token)
}

JournaldUpload.prototype.journaldHttpHandler = function (req, res) {
  try {
    this.config.useIndexFromUrlPath = true
    let self = this
    let bodyIn = ''
    let path = req.url.split('/')
    let token = null
    if (self.config.useIndexFromUrlPath === true && path.length > 1) {
      if (path[1] && path[1].length > 31 && tokenFormatRegEx.test(path[1])) {
        let match = path[1].match(extractTokenRegEx)
        if (match && match.length > 1) {
          token = match[1]
        }
      } else if (path[1] === 'health' || path[1] === 'ping') {
        res.statusCode = 200
        res.end('ok\n')
        return
      }
    }

    if ((self.config.useIndexFromUrlPath === true && !token) || self.tokenBlackList.isTokenInvalid(token)) {
      res.statusCode = 401
      res.end(`invalid logs token in url ${req.url}`)
      return
    }

    req.pipe(createStreamThrottle(this.throughputPerClient)).pipe(split()).on('data', function emitLine (data) {
      // logs are spearated by empty lines
      if (data.length == 0 && bodyIn.length > 0) {
        self.parseBody(bodyIn, token)
        bodyIn = ''
        return
      }
      bodyIn += `${data}\n`
    }).on('end', function endHandler () {
      self.parseBody(bodyIn, token)
      // send response to client
      res.writeHead(
        200,
        { 'Content-Type': 'text/plain' }
      )
      res.end('OK\n')
    }).on('error', console.error)
  } catch (err) {
    res.statusCode = 500
    res.end()
    consoleLogger.error('Error in journaldHttpHandler: ' + err)
  }
}

JournaldUpload.prototype.startJournaldUpload = function (id) {
  this.getHttpServer(Number(this.config.port), this.journaldHttpHandler.bind(this))
  let exitInProgress = false
  let terminate = function (reason) {
    return function () {
      if (exitInProgress) {
        return
      }
      exitInProgress = true
      consoleLogger.log('Stop journald-upload http worker: ' + id + ', pid:' + process.pid + ', terminate reason: ' + reason + ' memory rss: ' + (process.memoryUsage().rss / (1024 * 1024)).toFixed(2) + ' MB')
      setTimeout(process.exit, 250)
    }
  }
  process.once('SIGTERM', terminate('SIGTERM'))
  process.once('SIGINT', terminate('SIGINT'))
  process.once('exit', terminate('exit'))
}

module.exports = JournaldUpload
<commit_msg>detect numeric fields in jounrald logs<commit_after>const consoleLogger = require('../../util/logger.js')
const http = require('http')
const throng = require('throng')
const split = require('split2')
const createStreamThrottle = require('../../util/throttle')
const extractTokenRegEx = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/
const tokenFormatRegEx = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/
const _SYSTEMD_UNIT = '_systemd_unit'
const SYSLOG_IDENTIFIER = 'syslog_identifier'
const TokenBlacklist = require('../../util/token-blacklist.js')

function JournaldUpload (config, eventEmitter) {
  this.config = config
  this.eventEmitter = eventEmitter
  this.removeFields = {}
  this.tokenBlackList = new TokenBlacklist(eventEmitter)
  // limit throughput per client
  this.throughputPerClient = this.config.maxInputRate || 10 * 1024 * 1024
  if (config.useSematextCommonSchema === undefined) {
    config.useSematextCommonSchema = true
  }
  if (config.parseMessageField === undefined) {
    // try to parse logs using patterns.yml
    config.parseMessageField = true
  }
  if (config.removeFields) {
    for (var i = 0; i < config.removeFields.length; i++) {
      this.removeFields[config.removeFields[i].toLowerCase()] = true
    }
  }
  // set default filter
  if (!config.systemdUnitFilter) {
    config.systemdUnitFilter = {
      include: /.*/i,
      exlude: null
    }
  }

  if (config.workers) {
    this.config.workers = config.workers
  } else {
    this.config.workers = 0
  }
  // blacklist invalid tokens
  let self = this
}

JournaldUpload.prototype.start = function () {
  if (this.config.workers && this.config.workers > 0) {
    throng({
      workers: this.config.workers,
      lifetime: Infinity
    }, this.startJournaldUpload.bind(this))
  } else {
    this.startJournaldUpload(1)
  }
}

JournaldUpload.prototype.stop = function (cb) {
  if (cb) {
    cb()
  }
}

JournaldUpload.prototype.emitEvent = function (log, token) {
  let systemdUnit = log[_SYSTEMD_UNIT]
  let config = this.config
  if (systemdUnit) {
    if (config.systemdUnitFilter !== undefined && config.systemdUnitFilter.include && !config.systemdUnitFilter.include.test(log['_SYSTEMD_UNIT'])) {
      return
    }
    if (config.systemdUnitFilter !== undefined && config.systemdUnitFilter.exclude && config.systemdUnitFilter.exclude.test(log['_SYSTEMD_UNIT'])) {
      return
    }
  }
  let context = {
    sourceName: log[_SYSTEMD_UNIT] || log[SYSLOG_IDENTIFIER] || 'journald',
    name: 'journald'
  }
  if (token) {
    // set index, for elasticsearch output plugin
    context.index = token
  }
  if (Object.keys(log).length > 0) {
    this.addTags(log)
    this.eventEmitter.emit('data.object', log, context)
  }
}

JournaldUpload.prototype.addTags = function (log) {
  if (this.config.tags === undefined) {
    return
  }
  let keys = Object.keys(this.config.tags)
  for (let i = 0; i < keys.length; i++) {
    // avoid overwriting _index when passed in URL
    if (log[keys[i]] === undefined) {
      log[keys[i]] = this.config.tags[keys[i]]
    }
  }
}

JournaldUpload.prototype.getHttpServer = function (aport, handler) {
  var _port = aport || process.env.PORT || 9200
  if (aport === true) {
    _port = process.env.PORT
  }
  var server = http.createServer(handler)
  try {
    var bindAddress = this.config.bindAddress || '0.0.0.0'
    server = server.listen(_port, bindAddress)
    consoleLogger.log('Logagent listening (http journald-upload): ' + bindAddress + ':' + _port + ', process id: ' + process.pid)
    return server
  } catch (err) {
    consoleLogger.log('Port in use journald-upload (' + _port + '): ' + err)
  }
}

JournaldUpload.prototype.parseLine = function (log, line) {
  if (!line) {
    return log
  }
  let index = line.indexOf('=')
  let fieldName = line.substr(0, index).toLowerCase()
  let value = line.substr(index + 1, line.length)
  if (!isNaN(value)) {
    value = Number(value)
  }
  if (!this.removeFields[fieldName]) {
    log[fieldName] = value
  }
  return log
}

JournaldUpload.prototype.parseBody = function (body, token) {
  let lines = body.split('\n')
  let log = null
  if (lines.length > 0) {
    log = {}
  } else {
    return
  }
  // fastest loop is counting down
  for (let i = lines.length; i >= 0 ; --i) {
    this.parseLine(log, lines[i])
  }
  this.emitEvent(log, token)
}

JournaldUpload.prototype.journaldHttpHandler = function (req, res) {
  try {
    this.config.useIndexFromUrlPath = true
    let self = this
    let bodyIn = ''
    let path = req.url.split('/')
    let token = null
    if (self.config.useIndexFromUrlPath === true && path.length > 1) {
      if (path[1] && path[1].length > 31 && tokenFormatRegEx.test(path[1])) {
        let match = path[1].match(extractTokenRegEx)
        if (match && match.length > 1) {
          token = match[1]
        }
      } else if (path[1] === 'health' || path[1] === 'ping') {
        res.statusCode = 200
        res.end('ok\n')
        return
      }
    }

    if ((self.config.useIndexFromUrlPath === true && !token) || self.tokenBlackList.isTokenInvalid(token)) {
      res.statusCode = 401
      res.end(`invalid logs token in url ${req.url}`)
      return
    }

    req.pipe(createStreamThrottle(this.throughputPerClient)).pipe(split()).on('data', function emitLine (data) {
      // console.log(data, data.indexOf('\n'))
      // logs are spearated by empty lines
      if (data.length == 0 && bodyIn.length > 0) {
        self.parseBody(bodyIn, token)
        bodyIn = ''
        return
      }
      bodyIn += `${data}\n`
    }).on('end', function endHandler () {
      self.parseBody(bodyIn, token)
      // send response to client
      res.writeHead(
        200,
        { 'Content-Type': 'text/plain' }
      )
      res.end('OK\n')
    }).on('error', console.error)
  } catch (err) {
    res.statusCode = 500
    res.end()
    consoleLogger.error('Error in journaldHttpHandler: ' + err)
  }
}

JournaldUpload.prototype.startJournaldUpload = function (id) {
  this.getHttpServer(Number(this.config.port), this.journaldHttpHandler.bind(this))
  let exitInProgress = false
  let terminate = function (reason) {
    return function () {
      if (exitInProgress) {
        return
      }
      exitInProgress = true
      consoleLogger.log('Stop journald-upload http worker: ' + id + ', pid:' + process.pid + ', terminate reason: ' + reason + ' memory rss: ' + (process.memoryUsage().rss / (1024 * 1024)).toFixed(2) + ' MB')
      setTimeout(process.exit, 250)
    }
  }
  process.once('SIGTERM', terminate('SIGTERM'))
  process.once('SIGINT', terminate('SIGINT'))
  process.once('exit', terminate('exit'))
}

module.exports = JournaldUpload
<|endoftext|>


<commit_before>var util = require('util'),
    extendWithGettersAndSetters = require('../util/extendWithGettersAndSetters'),
    JavaScriptAmdRequire = require('./JavaScriptAmdRequire');

function JavaScriptAmdDefine(config) {
    JavaScriptAmdRequire.call(this, config);
}

util.inherits(JavaScriptAmdDefine, JavaScriptAmdRequire);

module.exports = JavaScriptAmdDefine;
<commit_msg>JavaScriptAmdDefine.js<commit_after>var util = require('util'),
    JavaScriptAmdRequire = require('./JavaScriptAmdRequire');

function JavaScriptAmdDefine(config) {
    JavaScriptAmdRequire.call(this, config);
}

util.inherits(JavaScriptAmdDefine, JavaScriptAmdRequire);

module.exports = JavaScriptAmdDefine;
<|endoftext|>


<commit_before>/*
 * Copyright 2016 resin.io
 *
 * 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.
 */

'use strict';

const Bluebird = require('bluebird');
const childProcess = require('child_process');
const isElevated = Bluebird.promisify(require('is-elevated'));
const ipc = require('node-ipc');
const _ = require('lodash');
const os = require('os');
const path = require('path');
const sudoPrompt = Bluebird.promisifyAll(require('sudo-prompt'));
const EXIT_CODES = require('../exit-codes');
const packageJSON = require('../../../package.json');

// This script is in charge of spawning the writer process and
// ensuring it has the necessary privileges. It might look a bit
// complex at first sight, but this is only because elevation
// modules don't work in a spawn/fork fashion.
//
// This script spawns the writer process and redirects its `stdout`
// and `stderr` to the parent process using IPC communication,
// taking care of the writer elevation as needed.

const EXECUTABLE = process.argv[0];
const ETCHER_ARGUMENTS = process.argv.slice(2);

return isElevated().then((elevated) => {

  if (!elevated) {
    console.log('Attempting to elevate');

    if (os.platform() === 'win32') {
      const elevator = Bluebird.promisifyAll(require('elevator'));

      const commandArguments = [
        'set',
        'ELECTRON_RUN_AS_NODE=1',
        '&&',
        'set',
        `IPC_SERVER_ID=${process.env.IPC_SERVER_ID}`,
        '&&',
        'set',
        `IPC_CLIENT_ID=${process.env.IPC_CLIENT_ID}`,
        '&&',

        // This is a trick to make the binary afterwards catch
        // the environment variables set just previously.
        'call'

      ].concat(process.argv);

      // For debugging purposes
      console.log(`Running: ${commandArguments.join(' ')}`);

      return elevator.executeAsync(commandArguments, {
        hidden: true,
        terminating: true,
        doNotPushdCurrentDirectory: true,
        waitForTermination: true
      }).catch({
        code: 'ELEVATE_CANCELLED'
      }, () => {
        process.exit(EXIT_CODES.CANCELLED);
      });
    }

    const commandArguments = _.attempt(() => {
      const commandPrefix = [

        // Some elevation tools, like `pkexec` or `kdesudo`, don't
        // provide a way to preserve the environment, therefore we
        // have to make sure the environment variables we're interested
        // in are manually inherited.
        'env',
        'ELECTRON_RUN_AS_NODE=1',
        `IPC_SERVER_ID=${process.env.IPC_SERVER_ID}`,
        `IPC_CLIENT_ID=${process.env.IPC_CLIENT_ID}`,

        // This environment variable prevents the AppImages
        // desktop integration script from presenting the
        // "installation" dialog.
        'SKIP=1'

      ];

      if (process.env.APPIMAGE && process.env.APPDIR) {

        // Translate the current arguments to point to the AppImage
        // Relative paths are resolved from `/tmp/.mount_XXXXXX/usr`
        const translatedArguments = _.map(_.tail(process.argv), (argv) => {
          return argv.replace(path.join(process.env.APPDIR, 'usr/'), '');
        });

        return commandPrefix
        .concat([ process.env.APPIMAGE ])
        .concat(translatedArguments);
      }

      return commandPrefix.concat(process.argv);
    });

    const command = _.join(_.map(commandArguments, (argument) => {
      return `"${argument.replace(/(")/g, '\\$1')}"`;
    }), ' ');

    // For debugging purposes
    console.log(`Running: ${command}`);

    return sudoPrompt.execAsync(command, {
      name: packageJSON.displayName
    }).then((stdout, stderr) => {
      if (!_.isEmpty(stderr)) {
        throw new Error(stderr);
      }
    }).catch({
      message: 'User did not grant permission.'
    }, () => {
      process.exit(EXIT_CODES.CANCELLED);
    });
  }

  console.log('Re-spawning with elevation');

  return new Bluebird((resolve, reject) => {
    ipc.config.id = process.env.IPC_CLIENT_ID;
    ipc.config.silent = true;

    // > If set to 0, the client will NOT try to reconnect.
    // See https://github.com/RIAEvangelist/node-ipc/
    //
    // The purpose behind this change is for this process
    // to emit a "disconnect" event as soon as the GUI
    // process is closed, so we can kill the CLI as well.
    ipc.config.stopRetrying = 0;

    ipc.connectTo(process.env.IPC_SERVER_ID, () => {
      ipc.of[process.env.IPC_SERVER_ID].on('error', reject);
      ipc.of[process.env.IPC_SERVER_ID].on('connect', () => {
        const child = childProcess.spawn(EXECUTABLE, ETCHER_ARGUMENTS);
        ipc.of[process.env.IPC_SERVER_ID].on('disconnect', _.bind(child.kill, child));
        child.on('error', reject);
        child.on('close', resolve);

        const emitMessage = (data) => {
          ipc.of[process.env.IPC_SERVER_ID].emit('message', data.toString());
        };

        child.stdout.on('data', emitMessage);
        child.stderr.on('data', emitMessage);
      });
    });
  }).then((exitCode) => {
    process.exit(exitCode);
  });
}).catch((error) => {
  console.error(error);
  process.exit(EXIT_CODES.GENERAL_ERROR);
});
<commit_msg>fix(GUI): multiple JSON objects coming up at once from the IPC client (#997)<commit_after>/*
 * Copyright 2016 resin.io
 *
 * 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.
 */

'use strict';

const Bluebird = require('bluebird');
const childProcess = require('child_process');
const isElevated = Bluebird.promisify(require('is-elevated'));
const ipc = require('node-ipc');
const _ = require('lodash');
const os = require('os');
const path = require('path');
const sudoPrompt = Bluebird.promisifyAll(require('sudo-prompt'));
const EXIT_CODES = require('../exit-codes');
const packageJSON = require('../../../package.json');

// This script is in charge of spawning the writer process and
// ensuring it has the necessary privileges. It might look a bit
// complex at first sight, but this is only because elevation
// modules don't work in a spawn/fork fashion.
//
// This script spawns the writer process and redirects its `stdout`
// and `stderr` to the parent process using IPC communication,
// taking care of the writer elevation as needed.

const EXECUTABLE = process.argv[0];
const ETCHER_ARGUMENTS = process.argv.slice(2);

return isElevated().then((elevated) => {

  if (!elevated) {
    console.log('Attempting to elevate');

    if (os.platform() === 'win32') {
      const elevator = Bluebird.promisifyAll(require('elevator'));

      const commandArguments = [
        'set',
        'ELECTRON_RUN_AS_NODE=1',
        '&&',
        'set',
        `IPC_SERVER_ID=${process.env.IPC_SERVER_ID}`,
        '&&',
        'set',
        `IPC_CLIENT_ID=${process.env.IPC_CLIENT_ID}`,
        '&&',

        // This is a trick to make the binary afterwards catch
        // the environment variables set just previously.
        'call'

      ].concat(process.argv);

      // For debugging purposes
      console.log(`Running: ${commandArguments.join(' ')}`);

      return elevator.executeAsync(commandArguments, {
        hidden: true,
        terminating: true,
        doNotPushdCurrentDirectory: true,
        waitForTermination: true
      }).catch({
        code: 'ELEVATE_CANCELLED'
      }, () => {
        process.exit(EXIT_CODES.CANCELLED);
      });
    }

    const commandArguments = _.attempt(() => {
      const commandPrefix = [

        // Some elevation tools, like `pkexec` or `kdesudo`, don't
        // provide a way to preserve the environment, therefore we
        // have to make sure the environment variables we're interested
        // in are manually inherited.
        'env',
        'ELECTRON_RUN_AS_NODE=1',
        `IPC_SERVER_ID=${process.env.IPC_SERVER_ID}`,
        `IPC_CLIENT_ID=${process.env.IPC_CLIENT_ID}`,

        // This environment variable prevents the AppImages
        // desktop integration script from presenting the
        // "installation" dialog.
        'SKIP=1'

      ];

      if (process.env.APPIMAGE && process.env.APPDIR) {

        // Translate the current arguments to point to the AppImage
        // Relative paths are resolved from `/tmp/.mount_XXXXXX/usr`
        const translatedArguments = _.map(_.tail(process.argv), (argv) => {
          return argv.replace(path.join(process.env.APPDIR, 'usr/'), '');
        });

        return commandPrefix
        .concat([ process.env.APPIMAGE ])
        .concat(translatedArguments);
      }

      return commandPrefix.concat(process.argv);
    });

    const command = _.join(_.map(commandArguments, (argument) => {
      return `"${argument.replace(/(")/g, '\\$1')}"`;
    }), ' ');

    // For debugging purposes
    console.log(`Running: ${command}`);

    return sudoPrompt.execAsync(command, {
      name: packageJSON.displayName
    }).then((stdout, stderr) => {
      if (!_.isEmpty(stderr)) {
        throw new Error(stderr);
      }
    }).catch({
      message: 'User did not grant permission.'
    }, () => {
      process.exit(EXIT_CODES.CANCELLED);
    });
  }

  console.log('Re-spawning with elevation');

  return new Bluebird((resolve, reject) => {
    ipc.config.id = process.env.IPC_CLIENT_ID;
    ipc.config.silent = true;

    // > If set to 0, the client will NOT try to reconnect.
    // See https://github.com/RIAEvangelist/node-ipc/
    //
    // The purpose behind this change is for this process
    // to emit a "disconnect" event as soon as the GUI
    // process is closed, so we can kill the CLI as well.
    ipc.config.stopRetrying = 0;

    ipc.connectTo(process.env.IPC_SERVER_ID, () => {
      ipc.of[process.env.IPC_SERVER_ID].on('error', reject);
      ipc.of[process.env.IPC_SERVER_ID].on('connect', () => {
        const child = childProcess.spawn(EXECUTABLE, ETCHER_ARGUMENTS);
        ipc.of[process.env.IPC_SERVER_ID].on('disconnect', _.bind(child.kill, child));
        child.on('error', reject);
        child.on('close', resolve);

        const emitMessage = (data) => {

          // Output from stdout/stderr coming from the CLI might be buffered,
          // causing several progress lines to come up at once as single message.
          // Trying to parse multiple JSON objects separated by new lines will
          // of course make the parser confused, causing errors later on.
          //
          // As a solution, we split the data coming in from the CLI into
          // separate lines, and only emit a "message" event for the last one.
          //
          // Since each line is terminated by a new line, the last string
          // is an empty string, which we don't want to send to the IPC
          // server, so we take the last element of every element but the last.
          const object = _.last(_.initial(_.split(data.toString(), /\r?\n/)));
          ipc.of[process.env.IPC_SERVER_ID].emit('message', object);

        };

        child.stdout.on('data', emitMessage);
        child.stderr.on('data', emitMessage);
      });
    });
  }).then((exitCode) => {
    process.exit(exitCode);
  });
}).catch((error) => {
  console.error(error);
  process.exit(EXIT_CODES.GENERAL_ERROR);
});
<|endoftext|>


<commit_before>const _ = require('lodash');

module.exports = events => _.chain(events).filter('event').map(ev => {
    const event = ev.event;
    const link = ev.link;

    let mappedEvent = {
        data: JSON.parse(event.data.toString()),
        eventStreamId: event.eventStreamId,
        eventNumber: event.eventNumber,
        eventType: event.eventType,
        created: event.created,
        metadata: event.metadata,
        isJson: event.isJson
    };

    if (link) {
        mappedEvent.positionStreamId = link.eventStreamId;
        mappedEvent.positionEventNumber = link.eventNumber;
    }
    return mappedEvent;
}).value();<commit_msg>[Fix] tcp map stream id from eventStreamId to streamId<commit_after>const _ = require('lodash');

module.exports = events => _.chain(events).filter('event').map(ev => {
    const event = ev.event;
    const link = ev.link;

    let mappedEvent = {
        data: JSON.parse(event.data.toString()),
        streamId: event.eventStreamId,
        eventNumber: event.eventNumber,
        eventType: event.eventType,
        created: event.created,
        metadata: event.metadata,
        isJson: event.isJson
    };

    if (link) {
        mappedEvent.positionStreamId = link.eventStreamId;
        mappedEvent.positionEventNumber = link.eventNumber;
    }
    return mappedEvent;
}).value();<|endoftext|>


<commit_before>const _ = require('lodash');
const os = require('os');
const Promise = require('bluebird');
const uglifyJs = require('uglify-js');
const errors = require('../errors');
const compressorByName = {};

compressorByName.uglifyJs = async (assetGraph, javaScript, compressorOptions) => {
    compressorOptions = compressorOptions || {};
    const sourceMaps = compressorOptions.sourceMaps;
    compressorOptions = Object.assign({}, _.omit(compressorOptions, 'sourceMaps'));
    const mangleOptions = compressorOptions.mangleOptions;
    delete compressorOptions.mangleOptions;
    _.defaults(compressorOptions, _.pick(javaScript.serializationOptions, ['side_effects']), _.pick(assetGraph.javaScriptSerializationOptions, ['side_effects']));

    let ie8;
    if (javaScript.serializationOptions && typeof javaScript.serializationOptions.ie8 !== 'undefined') {
        ie8 = !!javaScript.serializationOptions.ie8;
    } else if (javaScript.serializationOptions && typeof javaScript.serializationOptions.screw_ie8 !== 'undefined') {
        ie8 = !javaScript.serializationOptions.screw_ie8;
    } else if (assetGraph.javaScriptSerializationOptions && typeof assetGraph.javaScriptSerializationOptions.ie8 !== 'undefined') {
        ie8 = !!assetGraph.javaScriptSerializationOptions.ie8;
    } else if (assetGraph.javaScriptSerializationOptions && typeof assetGraph.javaScriptSerializationOptions.screw_ie8 !== 'undefined') {
        ie8 = !assetGraph.javaScriptSerializationOptions.screw_ie8;
    }

    let text;
    let sourceMap;
    if (sourceMaps) {
        ({ text, sourceMap } = javaScript.textAndSourceMap);
    } else {
        text = javaScript.text;
    }

    const { error, code, map } = uglifyJs.minify(text, {
        sourceMap: { content: sourceMap },
        compress: compressorOptions,
        mangle: mangleOptions,
        output: { comments: true, source_map: true, ast: true },
        ie8
    });
    if (error) {
        throw new errors.ParseError({
            message: 'Parse error in ' + javaScript.urlOrDescription + '\n' + error.message + ' (line ' + error.line + ', column ' + (error.col + 1) + ')',
            line: error.line,
            column: error.col + 1,
            asset: javaScript
        });
    }
    return assetGraph.addAsset({
        type: 'JavaScript',
        lastKnownByteLength: javaScript.lastKnownByteLength, // I know, I know
        copyrightNoticeComments: javaScript.copyrightNoticeComments,
        text: code,
        isDirty: true,
        _toBeMinified: javaScript._toBeMinified,
        isPretty: javaScript.isPretty,
        sourceMap: map
    });
};

compressorByName.yuicompressor = async (assetGraph, javaScript, compressorOptions) => {
    let yuicompressor;
    try {
        yuicompressor = require('yui-compressor');
    } catch (e) {
        throw new Error('transforms.compressJavaScript: node-yui-compressor not found. Please run \'npm install yui-compressor\' and try again (tested with version 0.1.3).');
    }
    compressorOptions = compressorOptions || {};
    return assetGraph.addAsset({
        type: 'JavaScript',
        copyrightNoticeComments: javaScript.copyrightNoticeComments,
        text: await Promise.fromNode(cb => yuicompressor.compile(javaScript.text, compressorOptions, cb))
    });
};

compressorByName.closurecompiler = async (assetGraph, javaScript, compressorOptions) => {
    let closurecompiler;
    try {
        closurecompiler = require('closure-compiler');
    } catch (e) {
        throw new Error('transforms.compressJavaScript: node-closure-compiler not found. Please run \'npm install closure-compiler\' and try again (tested with version 0.1.1).');
    }
    compressorOptions = compressorOptions || {};
    return assetGraph.addAsset({
        type: 'JavaScript',
        copyrightNoticeComments: javaScript.copyrightNoticeComments,
        text: await Promise.fromNode(cb => closurecompiler.compile(javaScript.text, compressorOptions, cb))
    });
};

module.exports = (queryObj, compressorName, compressorOptions) => {
    if (!compressorName) {
        compressorName = 'uglifyJs';
    }
    if (!compressorByName[compressorName]) {
        throw new Error('transforms.compressJavaScript: Unknown compressor: ' + compressorName);
    }
    return async function compressJavaScript(assetGraph) {
        await Promise.map(assetGraph.findAssets(Object.assign({type: 'JavaScript'}, queryObj)), async javaScript => {
            try {
                const compressedJavaScript = await compressorByName[compressorName](assetGraph, javaScript, compressorOptions);
                javaScript.replaceWith(compressedJavaScript);
                compressedJavaScript.serializationOptions = Object.assign({}, javaScript.serializationOptions);
                compressedJavaScript.initialComments = javaScript.initialComments;
                javaScript.unload();
            } catch (err) {
                assetGraph.warn(err);
            }
        }, {concurrency: os.cpus().length + 1});
    };
};
<commit_msg>Simplify compressJavaScript<commit_after>const _ = require('lodash');
const os = require('os');
const Promise = require('bluebird');
const uglifyJs = require('uglify-js');
const errors = require('../errors');
const compressorByName = {};

compressorByName.uglifyJs = async (assetGraph, javaScript, compressorOptions) => {
    compressorOptions = compressorOptions || {};
    const sourceMaps = compressorOptions.sourceMaps;
    compressorOptions = Object.assign({}, _.omit(compressorOptions, 'sourceMaps'));
    const mangleOptions = compressorOptions.mangleOptions;
    delete compressorOptions.mangleOptions;
    _.defaults(compressorOptions, _.pick(javaScript.serializationOptions, ['side_effects']), _.pick(assetGraph.javaScriptSerializationOptions, ['side_effects']));

    let ie8;
    if (javaScript.serializationOptions && typeof javaScript.serializationOptions.ie8 !== 'undefined') {
        ie8 = !!javaScript.serializationOptions.ie8;
    } else if (javaScript.serializationOptions && typeof javaScript.serializationOptions.screw_ie8 !== 'undefined') {
        ie8 = !javaScript.serializationOptions.screw_ie8;
    } else if (assetGraph.javaScriptSerializationOptions && typeof assetGraph.javaScriptSerializationOptions.ie8 !== 'undefined') {
        ie8 = !!assetGraph.javaScriptSerializationOptions.ie8;
    } else if (assetGraph.javaScriptSerializationOptions && typeof assetGraph.javaScriptSerializationOptions.screw_ie8 !== 'undefined') {
        ie8 = !assetGraph.javaScriptSerializationOptions.screw_ie8;
    }

    let text;
    let sourceMap;
    if (sourceMaps) {
        ({ text, sourceMap } = javaScript.textAndSourceMap);
    } else {
        text = javaScript.text;
    }

    const { error, code, map } = uglifyJs.minify(text, {
        sourceMap: { content: sourceMap },
        compress: compressorOptions,
        mangle: mangleOptions,
        output: { comments: true, source_map: true, ast: true },
        ie8
    });
    if (error) {
        throw new errors.ParseError({
            message: 'Parse error in ' + javaScript.urlOrDescription + '\n' + error.message + ' (line ' + error.line + ', column ' + (error.col + 1) + ')',
            line: error.line,
            column: error.col + 1,
            asset: javaScript
        });
    }
    return {
        type: 'JavaScript',
        lastKnownByteLength: javaScript.lastKnownByteLength, // I know, I know
        copyrightNoticeComments: javaScript.copyrightNoticeComments,
        text: code,
        isDirty: true,
        _toBeMinified: javaScript._toBeMinified,
        isPretty: javaScript.isPretty,
        sourceMap: map
    };
};

compressorByName.yuicompressor = async (assetGraph, javaScript, compressorOptions) => {
    let yuicompressor;
    try {
        yuicompressor = require('yui-compressor');
    } catch (e) {
        throw new Error('transforms.compressJavaScript: node-yui-compressor not found. Please run \'npm install yui-compressor\' and try again (tested with version 0.1.3).');
    }
    compressorOptions = compressorOptions || {};
    return {
        type: 'JavaScript',
        copyrightNoticeComments: javaScript.copyrightNoticeComments,
        text: await Promise.fromNode(cb => yuicompressor.compile(javaScript.text, compressorOptions, cb))
    };
};

compressorByName.closurecompiler = async (assetGraph, javaScript, compressorOptions) => {
    let closurecompiler;
    try {
        closurecompiler = require('closure-compiler');
    } catch (e) {
        throw new Error('transforms.compressJavaScript: node-closure-compiler not found. Please run \'npm install closure-compiler\' and try again (tested with version 0.1.1).');
    }
    compressorOptions = compressorOptions || {};
    return {
        type: 'JavaScript',
        copyrightNoticeComments: javaScript.copyrightNoticeComments,
        text: await Promise.fromNode(cb => closurecompiler.compile(javaScript.text, compressorOptions, cb))
    };
};

module.exports = (queryObj, compressorName, compressorOptions) => {
    if (!compressorName) {
        compressorName = 'uglifyJs';
    }
    if (!compressorByName[compressorName]) {
        throw new Error('transforms.compressJavaScript: Unknown compressor: ' + compressorName);
    }
    return async function compressJavaScript(assetGraph) {
        await Promise.map(assetGraph.findAssets(Object.assign({type: 'JavaScript'}, queryObj)), async javaScript => {
            try {
                const compressedJavaScript = await compressorByName[compressorName](assetGraph, javaScript, compressorOptions);
                javaScript.replaceWith(compressedJavaScript);
                compressedJavaScript.serializationOptions = Object.assign({}, javaScript.serializationOptions);
                compressedJavaScript.initialComments = javaScript.initialComments;
                javaScript.unload();
            } catch (err) {
                assetGraph.warn(err);
            }
        }, {concurrency: os.cpus().length + 1});
    };
};
<|endoftext|>