<commit_before>var Analytics = require('./analytics')();
var App = require('./webgl/App');
var KeyManager = require('./managers/KeyManager');
var settings = require('./settings');

var state = 0;  // State counter.

function getParameterByName (name, url) {
  if (!url) url = window.location.href;
  name = name.replace(/[\[\]]/g, '\\$&');
  var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
    results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

function initApp (bool) {
  if (getParameterByName('mode') !== 'debug') {
    state++;
    var modeTxt = 'normal';
    if (bool) {
      modeTxt = 'spectator';
    }
    var sObj = { 'state': state, 'message': bool },
      title = 'title',
      url = '?mode=' + modeTxt;

    // Push new state.
    history.pushState(sObj, title, url);
  }

  document.getElementById('launch').remove();

  // App.init(bool);

  if (App.isReadyToStart) {
    App.enterVR();
  } else {
    App.modeSelected(bool);
  }
}

global.window.addEventListener('load', function () {
  App.init(false);

  var mode = getParameterByName('mode');

  if (mode === 'debug') {
    settings.debugMode = true;
    initApp(false);
  } else {
    if (navigator.getVRDisplays === undefined) {
      window.location.replace('fallback.html');
      return;
    }

    document.getElementById('launch').style.display = 'block';

    document.getElementById('button-mode-normal').addEventListener('click', function () {
      e.preventDefault();
      initApp(false);
    });

    document.getElementById('button-mode-spectator').addEventListener('click', function () {
      e.preventDefault();
      initApp(true);
    });

    switch (mode) {
      case 'normal':
        initApp(false);
        break;
      case 'spectator':
        initApp(true);
        break;
    }
  }

  KeyManager.init();
});
<commit_msg>disable for Firefox Nightly (until 1.1 and Gamepad support)<commit_after>var Analytics = require('./analytics')();
var App = require('./webgl/App');
var KeyManager = require('./managers/KeyManager');
var settings = require('./settings');

var state = 0;  // State counter.

function getParameterByName (name, url) {
  if (!url) url = window.location.href;
  name = name.replace(/[\[\]]/g, '\\$&');
  var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
    results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

function initApp (bool) {
  if (getParameterByName('mode') !== 'debug') {
    state++;
    var modeTxt = 'normal';
    if (bool) {
      modeTxt = 'spectator';
    }
    var sObj = { 'state': state, 'message': bool },
      title = 'title',
      url = '?mode=' + modeTxt;

    // Push new state.
    history.pushState(sObj, title, url);
  }

  document.getElementById('launch').remove();

  // App.init(bool);

  if (App.isReadyToStart) {
    App.enterVR();
  } else {
    App.modeSelected(bool);
  }
}

global.window.addEventListener('load', function () {
  App.init(false);

  var mode = getParameterByName('mode');

  if (mode === 'debug') {
    settings.debugMode = true;
    initApp(false);
  } else {
    // `navigator.buildId` is our Firefox feature detection.
    // Temporarily disabling until Firefox has motion-controller
    // Gamepad support (for issue #78).
    if (navigator.getVRDisplays === undefined || navigator.buildId) {
      window.location.replace('fallback.html');
      return;
    }

    document.getElementById('launch').style.display = 'block';

    document.getElementById('button-mode-normal').addEventListener('click', function () {
      e.preventDefault();
      initApp(false);
    });

    document.getElementById('button-mode-spectator').addEventListener('click', function () {
      e.preventDefault();
      initApp(true);
    });

    switch (mode) {
      case 'normal':
        initApp(false);
        break;
      case 'spectator':
        initApp(true);
        break;
    }
  }

  KeyManager.init();
});
<|endoftext|>


<commit_before>'use strict'
var util = require('util')
var winston = require('winston')
var Transport = winston.Transport
var common = require('winston/lib/winston/common')
var _dirname = require('path').dirname
var LogseneJS = require('logsene-js')
var flat = require('flat')

var Logsene = function (options) {
  Transport.call(this, options)
  options = options || {}
  if (!options.flushOnExit) {
    options.flushOnExit = true
  }
  this.logsene_debug=options.logsene_debug
  this.handleExceptions = options.handleExceptions
  this.exitOnError = options.exitOnError
  this.flatOptions = options.flatOptions || {safe: true, delimiter: '_'}
  this.json = options.json || false
  this.colorize = options.colorize || false
  this.prettyPrint = options.prettyPrint || false
  this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false
  this.label = options.label || null
  this.source = options.source || (process.mainModule ? null : _dirname(process.mainModule.filename)) || module.filename
  this.rewriter = options.rewriter || null
  if (this.json) {
    this.stringify = options.stringify || function (obj) {
      return JSON.stringify(obj, null, 2)
    }
  }
  this.logger = new LogseneJS(options.token,
    options.type || 'winston_logsene',
    options.url)
  var self = this
  this.logger.on('error', function (err) {
    self.emit('error', err)
  })
  this.logger.on('log', function (data) {
    self.emit('logged', data)
    self.emit('flush', data)
  })
  var logseneExitHandler = function  (code) {
    this.logger.once('log', function () {
      process.exit(code)
    })
    this.logger.once('error', function () {
      process.exit(code)
    })
    this.logger.send()
  }.bind(this)
  if (options.flushOnExit) {
    process.once('SIGTERM', logseneExitHandler)
    process.once('SIGINT',  logseneExitHandler)
    process.once('SIGQUIT', logseneExitHandler)
    process.once('beforeExit', logseneExitHandler)
  }
  // Add toJSON to Error Class
  if (!('toJSON' in Error.prototype)) {
    Object.defineProperty(Error.prototype, 'toJSON', {
      value: function () {
        var alt = {}
        Object.getOwnPropertyNames(this).forEach(function (key) {
          alt[key] = this[key]
        }, this)
        return alt
      },
      configurable: true,
      writable: true
    })
  }
}

//
// Inherit from `winston.Transport`.
//
util.inherits(Logsene, winston.Transport)

//
// Expose the name of this Transport on the prototype
//
Logsene.prototype.name = 'Logsene'

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
Logsene.prototype.log = function (level, msg, meta, callback) {
  var metaData = meta
  if (this.silent) {
    return callback(null, true)
  }
  if (meta && (!meta['source'])) {
    meta.source = this.source
  }
  if (this.rewriter){
    meta = this.rewriter(level, msg, meta)
  }
  if (meta instanceof Error) {
    if (!msg) {
        msg = meta.stack || meta.message
    }
    metaData = {error_stack: meta.stack || meta.message}
  }
  var output = common.log({
    colorize: this.colorize,
    json: this.json,
    level: level,
    message: msg,
    meta: metaData,
    stringify: this.stringify,
    timestamp: new Date(), //this.timestamp,
    prettyPrint: this.prettyPrint,
    raw: this.raw,
    label: this.label
  })
  if (this.logsene_debug) {
    console.log(output)
  }
  this.logger.log(level, msg, flat(metaData, this.flatOptions), callback)
}

Logsene.prototype.clearLogs = function () {
  // not required ?
}

module.exports = Logsene
module.exports.Logsene = Logsene
<commit_msg>add new option setSource: false<commit_after>'use strict'
var util = require('util')
var winston = require('winston')
var Transport = winston.Transport
var common = require('winston/lib/winston/common')
var _dirname = require('path').dirname
var LogseneJS = require('logsene-js')
var flat = require('flat')

var Logsene = function (options) {
  Transport.call(this, options)
  options = options || {}
  if (!options.flushOnExit) {
    options.flushOnExit = true
  }

  this.setSource = options.setLogSource
  if (options.hasOwnProperty('setSource')) {
    this.setSource = options.setSource
  } else {
    this.setSource = true
  }
  this.logsene_debug = options.logsene_debug
  this.handleExceptions = options.handleExceptions
  this.exitOnError = options.exitOnError
  this.flatOptions = options.flatOptions || {safe: true, delimiter: '_'}
  this.json = options.json || false
  this.colorize = options.colorize || false
  this.prettyPrint = options.prettyPrint || false
  this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false
  this.label = options.label || null
  this.source = options.source || (process.mainModule ? null : _dirname(process.mainModule.filename)) || module.filename

  this.rewriter = options.rewriter || null
  if (this.json) {
    this.stringify = options.stringify || function (obj) {
      return JSON.stringify(obj, null, 2)
    }
  }
  this.logger = new LogseneJS(options.token,
    options.type || 'winston_logsene',
    options.url)
  var self = this
  this.logger.on('error', function (err) {
    self.emit('error', err)
  })
  this.logger.on('log', function (data) {
    self.emit('logged', data)
    self.emit('flush', data)
  })
  var logseneExitHandler = function (code) {
    this.logger.once('log', function () {
      process.exit(code)
    })
    this.logger.once('error', function () {
      process.exit(code)
    })
    this.logger.send()
  }.bind(this)
  if (options.flushOnExit) {
    process.once('SIGTERM', logseneExitHandler)
    process.once('SIGINT', logseneExitHandler)
    process.once('SIGQUIT', logseneExitHandler)
    process.once('beforeExit', logseneExitHandler)
  }
  // Add toJSON to Error Class
  if (!('toJSON' in Error.prototype)) {
    Object.defineProperty(Error.prototype, 'toJSON', {
      value: function () {
        var alt = {}
        Object.getOwnPropertyNames(this).forEach(function (key) {
          alt[key] = this[key]
        }, this)
        return alt
      },
      configurable: true,
      writable: true
    })
  }
}

//
// Inherit from `winston.Transport`.
//
util.inherits(Logsene, winston.Transport)

//
// Expose the name of this Transport on the prototype
//
Logsene.prototype.name = 'Logsene'

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
Logsene.prototype.log = function (level, msg, meta, callback) {
  var metaData = meta
  if (this.silent) {
    return callback(null, true)
  }
  if (this.setSource) {
    if (meta && (!meta['source'])) {
      meta.source = this.source
    }
  }

  if (this.rewriter) {
    metaData = this.rewriter(level, msg, meta)
  }
  if (meta instanceof Error) {
    if (!msg) {
      msg = meta.stack || meta.message
    }
    metaData = {error_stack: meta.stack || meta.message}
  }
  if (this.logsene_debug) {
    var output = common.log({
      colorize: this.colorize,
      json: this.json,
      level: level,
      message: msg,
      meta: metaData,
      stringify: this.stringify,
      timestamp: new Date(), // this.timestamp,
      prettyPrint: this.prettyPrint,
      raw: this.raw,
      label: this.label
    })
    console.log(output)
  }
  this.logger.log(level, msg, flat(metaData, this.flatOptions), callback)
}

Logsene.prototype.clearLogs = function () {
  // not required ?
}

module.exports = Logsene
module.exports.Logsene = Logsene
<|endoftext|>


<commit_before>/**
 * Generate ngdoc with markdown format.
 * @module ngdoc-md
 * @version 1.0.2
 */

"use strict"

var nmdDgeni = require('./nmd_dgeni');

module.exports = nmdDgeni;

<commit_msg>correct require parameter to work properly with progammatic use<commit_after>/**
 * Generate ngdoc with markdown format.
 * @module ngdoc-md
 * @version 1.0.2
 */

"use strict"

module.exports = require('./ngdoc_md');
<|endoftext|>


<commit_before>/**
 * ------------------------------------------
 * 播放器控件实现文件
 * @version  1.0
 * @author   genify(caijf@corp.netease.com)
 * ------------------------------------------
 */
var f = function() {
    // variable declaration
    var _  = NEJ.P,
        _e = _('nej.e'),
        _u = _('nej.u'),
        _t = _('nej.ut'),
        _n = _('nej.n'),
        _p = _('nej.cef.ut'),
        _player = _('window.player'),
        _proPlayer;
    /**
     * 播放器控件，单例模式使用
     *
     * @singleton
     * @class   {nej.cef.ut._$$Player}
     * @extends {nej.ut._$$Event}
     * @param   {Object} 配置参数
     *
     * [hr]
     * 播放状态变化触发事件，播放状态值说明
     * [ntb]
     *   状态值  |  说明
     *   ------------------
     *   0    |  缓冲阶段，出loading提示
     *   1    |  播放状态
     *   2    |  暂停状态
     *   3    |  停止状态
     *   4    |  播放至结尾
     *   5    |  播放异常
     * [/ntb]
     * @event  {onstatechange}
     * @param  {Object} 状态信息
     * @config {Number} state 状态值，见说明表
     *
     * [hr]
     * 歌曲文件下载进度
     * @event  {onloading}
     * @param  {Object} 进度信息
     * @config {Number} loaded 已下载，如0.5
     * @config {Number} total  总数，为1
     *
     * [hr]
     * 播放位置变化触发事件
     * @event  {onpositionchange}
     * @param  {Object} 播放信息
     * @config {Float} current  当前位置
     * @config {Float} duration 音乐总时长
     *
     * [hr]
     * 音量变化触发事件
     * @event  {onvolumechange}
     * @param  {Object} 音量信息
     * @config {Float}  volume 当前音量值，0.0-1.0
     *
     * [hr]
     * 静音状态变化触发事件
     * @event  {onmutechange}
     * @param  {Object}  静音状态信息
     * @config {Boolean} mute 静音状态，true-静音，false-非静音
     *
     * [hr]
     * 歌曲变化触发事件
     * @event  {ontrackchange}
     * @param  {Object}  静音状态信息
     * @config {Boolean} flag 变化标识，-1-上一首，1-下一首
     *
     * [hr]
     * 播放模式变化触发事件，模式说明
     * [ntb]
     *   名称                       |  说明
     *   -----------------------
     *   playorder  |  顺序播放
     *   playcycle  |  循环播放
     *   playrandom |  随机播放
     * [/ntb]
     * @event  {onmodechange}
     * @param  {Object}  静音状态信息
     * @config {Boolean} mode 模式，见描述
     *
     * [hr]
     * 歌词更新触发事件
     * @event  {onlrcupdate}
     * @param  {Object}  歌词信息
     * @config {String}  id  歌曲ID
     * @config {String}  lrc 歌词内容
     *
     *
     */
    _p._$$Player = NEJ.C();
      _proPlayer = _p._$$Player._$extend(_t._$$Event);
    /**
     * 控件初始化
     * @return {Void}
     */
    _proPlayer.__init = function(){
        this.__nevt = [
            'volumechange','notify',
            'dataloaded','play','pause','ended',
            'playmode','error','playpre','loading',
            'playnext','timeupdate','lyricsupdate','buffering'
        ];
        this.__supInit();
    };
    /**
     * 控件重置
     * @param  {Object} 配置信息
     * @return {Void}
     */
    _proPlayer.__reset = (function(){
        // add native event
        var _doAddEvent = function(_name){
            _player['on'+_name] = this.
                __onNativeEvent._$bind(this,_name);
        };
        return function(_options){
            this.__supReset(_options);
            _u._$forEach(
                this.__nevt,_doAddEvent,this
            );
            if (!_player.paused){
                this.__onNativeEvent('play');
            }
        };
    })();
    /**
     * 控件销毁
     * @return {Void}
     */
    _proPlayer.__destroy = (function(){
        var _doDelEvent = function(_name){
            delete _player['on'+_name];
        };
        return function(){
            this.__supDestroy();
            _u._$forEach(
                this.__nevt,_doDelEvent
            );
        };
    })();
    /**
     * 播放音乐
     * @param  {Object} 音乐信息
     * @return {Void}
     */
    _proPlayer._$play = function(_options){
        _n._$exec('player.load',_options);
        _n._$exec('player.setInfo',_options);
        this._$dispatchEvent('onstatechange',{
            state:0
        });
    };
    /**
     * 恢复状态
     * @return {Void}
     */
    _proPlayer._$resume = function(){
        _n._$exec('player.play');
    };
    /**
     * 暂停播放
     * @return {Void}
     */
    _proPlayer._$pause = function(){
        _n._$exec('player.pause');
    };
    /**
     * 停止播放
     * @return {Void}
     */
    _proPlayer._$stop = function(){
        _n._$exec('player.stop');
    };
    /**
     * 设置静音
     * @param  {Boolean} 静音，true-静音，false-非静音
     * @return {Void}
     */
    _proPlayer._$setMute = function(_mute){
        _n._$exec('player.mute',!!_mute);
        this._$dispatchEvent('onmutechange',{
            mute:!!_mute
        });
    };
    /**
     * 设置模式
     * @param  {String} 播放模式
     * @return {Void}
     */
    _proPlayer._$setMode = function(_mode){
        _n._$exec('player.setPlayMode',_mode);
        this.__onNativeEvent('playmode',_mode);
    };
    /**
     * 设置音量
     * @param  {Float} 音量，范围：[0.0,1.0]
     * @return {Void}
     */
    _proPlayer._$setVolume = function(_volume){
        _n._$exec('player.setVolume',_volume);
    };
    /**
     * 设置播放位置
     * @param  {Float} 播放位置，百分比
     * @return {Void}
     */
    _proPlayer._$setPosition = function(_ratio){
        _n._$exec('player.setCurrentTime',_ratio*(_player.duration||0));
    };
    /**
     * 设置歌词
     * @param  {String} 歌词内容
     * @return {Void}
     */
    _proPlayer._$setLRC = function(_lrc){
        !_lrc ? _n._$exec('player.setLRCEmpty')
              : _n._$exec('player.setLRC',_lrc||'');
    };
    /**
     * 设置封面
     * @param  {String} 专辑ID
     * @return {Void}
     */
    _proPlayer._$setCover = function(_aid){
        !_aid ? _n._$exec('player.setCoverDefault')
              : _n._$exec('player.setCover',''+_aid,'album');
    };
    /**
     * native事件回调
     * @param  {String} 事件名称
     * @return {Void}
     */
    _proPlayer.__onNativeEvent = function(_name){
        switch(_name){
            case 'dataloaded':
                this._$resume();
            return;
            case 'play':
                this._$dispatchEvent('onstatechange',{
                    state:1
                });
            return;
            case 'pause':
                this._$dispatchEvent('onstatechange',{
                    state:2
                });
            return;
            case 'ended':
                this._$dispatchEvent('onstatechange',{
                    state:4
                });
            return;
            case 'timeupdate':
                this._$dispatchEvent('onpositionchange',{
                    current:_n._$exec('player.getCurrentTime')||0,
                    duration:_player.duration||0
                });
                // lock loading
                var _loading = _n._$exec('player.getDownloadSchedule')||0;
                if (_loading==1&&this.__loading==1) return;
                this.__loading = _loading;
                this._$dispatchEvent('onloading',{
                    loaded:this.__loading,total:1
                });
            return;
            case 'volumechange':
                this._$dispatchEvent('onvolumechange',{
                    volume:_n._$exec('player.getVolume')
                });
            return;
            case 'error':
                this._$dispatchEvent('onstatechange',{
                    state:5
                });
            return;
            case 'notify':

            return;
            case 'playpre':
            case 'playnext':
                this._$dispatchEvent('ontrackchange',{
                    flag:_name=='playpre'?-1:1
                });
            return;
            case 'playmode':
                this._$dispatchEvent('onmodechange',{
                    mode:arguments[1]
                });
            return;
            case 'lyricsupdate':
                this._$dispatchEvent('onlrcupdate',{
                    id:arguments[1],lrc:arguments[2]
                });
            return;
            case 'loading':
            case 'buffering':
                this._$dispatchEvent('onstatechange',{
                    state:0
                });
            return;
        }
    };
};
NEJ.define('{lib}native/cef/util/player.js',
          ['{lib}util/event.js'
          ,'{lib}native/command.js'],f);<commit_msg>cef player<commit_after>/**
 * ------------------------------------------
 * 播放器控件实现文件
 * @version  1.0
 * @author   genify(caijf@corp.netease.com)
 * ------------------------------------------
 */
var f = function() {
    // variable declaration
    var _  = NEJ.P,
        _e = _('nej.e'),
        _u = _('nej.u'),
        _t = _('nej.ut'),
        _n = _('nej.n'),
        _p = _('nej.cef.ut'),
        _player = _('window.player'),
        _proPlayer;
    /**
     * 播放器控件，单例模式使用
     *
     * @singleton
     * @class   {nej.cef.ut._$$Player}
     * @extends {nej.ut._$$Event}
     * @param   {Object} 配置参数
     *
     * [hr]
     * 播放状态变化触发事件，播放状态值说明
     * [ntb]
     *   状态值  |  说明
     *   ------------------
     *   0    |  缓冲阶段，出loading提示
     *   1    |  播放状态
     *   2    |  暂停状态
     *   3    |  停止状态
     *   4    |  播放至结尾
     *   5    |  播放异常
     * [/ntb]
     * @event  {onstatechange}
     * @param  {Object} 状态信息
     * @config {Number} state 状态值，见说明表
     *
     * [hr]
     * 歌曲文件下载进度
     * @event  {onloading}
     * @param  {Object} 进度信息
     * @config {Number} loaded 已下载，如0.5
     * @config {Number} total  总数，为1
     *
     * [hr]
     * 播放位置变化触发事件
     * @event  {onpositionchange}
     * @param  {Object} 播放信息
     * @config {Float} current  当前位置
     * @config {Float} duration 音乐总时长
     *
     * [hr]
     * 音量变化触发事件
     * @event  {onvolumechange}
     * @param  {Object} 音量信息
     * @config {Float}  volume 当前音量值，0.0-1.0
     *
     * [hr]
     * 静音状态变化触发事件
     * @event  {onmutechange}
     * @param  {Object}  静音状态信息
     * @config {Boolean} mute 静音状态，true-静音，false-非静音
     *
     * [hr]
     * 歌曲变化触发事件
     * @event  {ontrackchange}
     * @param  {Object}  静音状态信息
     * @config {Boolean} flag 变化标识，-1-上一首，1-下一首
     *
     * [hr]
     * 播放模式变化触发事件，模式说明
     * [ntb]
     *   名称                       |  说明
     *   -----------------------
     *   playorder  |  顺序播放
     *   playcycle  |  循环播放
     *   playrandom |  随机播放
     * [/ntb]
     * @event  {onmodechange}
     * @param  {Object}  静音状态信息
     * @config {Boolean} mode 模式，见描述
     *
     * [hr]
     * 歌词更新触发事件
     * @event  {onlrcupdate}
     * @param  {Object}  歌词信息
     * @config {String}  id  歌曲ID
     * @config {String}  lrc 歌词内容
     *
     * [hr]
     * 请求切换到下一个模式
     * @event  {onnextmode}
     * @param  {Object} 模式信息
     */
    _p._$$Player = NEJ.C();
      _proPlayer = _p._$$Player._$extend(_t._$$Event);
    /**
     * 控件初始化
     * @return {Void}
     */
    _proPlayer.__init = function(){
        this.__nevt = [
            'volumechange','notify',
            'dataloaded','play','pause','ended',
            'playmode','playmodechange','error','playpre',
            'loading','playnext','timeupdate','lyricsupdate','buffering'
        ];
        this.__supInit();
    };
    /**
     * 控件重置
     * @param  {Object} 配置信息
     * @return {Void}
     */
    _proPlayer.__reset = (function(){
        // add native event
        var _doAddEvent = function(_name){
            _player['on'+_name] = this.
                __onNativeEvent._$bind(this,_name);
        };
        return function(_options){
            this.__supReset(_options);
            _u._$forEach(
                this.__nevt,_doAddEvent,this
            );
            if (!_player.paused){
                this.__onNativeEvent('play');
            }
        };
    })();
    /**
     * 控件销毁
     * @return {Void}
     */
    _proPlayer.__destroy = (function(){
        var _doDelEvent = function(_name){
            delete _player['on'+_name];
        };
        return function(){
            this.__supDestroy();
            _u._$forEach(
                this.__nevt,_doDelEvent
            );
        };
    })();
    /**
     * 播放音乐
     * @param  {Object} 音乐信息
     * @return {Void}
     */
    _proPlayer._$play = function(_options){
        _n._$exec('player.load',_options);
        _n._$exec('player.setInfo',_options);
        this._$dispatchEvent('onstatechange',{
            state:0
        });
    };
    /**
     * 恢复状态
     * @return {Void}
     */
    _proPlayer._$resume = function(){
        _n._$exec('player.play');
    };
    /**
     * 暂停播放
     * @return {Void}
     */
    _proPlayer._$pause = function(){
        _n._$exec('player.pause');
    };
    /**
     * 停止播放
     * @return {Void}
     */
    _proPlayer._$stop = function(){
        _n._$exec('player.stop');
    };
    /**
     * 设置静音
     * @param  {Boolean} 静音，true-静音，false-非静音
     * @return {Void}
     */
    _proPlayer._$setMute = function(_mute){
        _n._$exec('player.mute',!!_mute);
        this._$dispatchEvent('onmutechange',{
            mute:!!_mute
        });
    };
    /**
     * 设置模式
     * @param  {String} 播放模式
     * @return {Void}
     */
    _proPlayer._$setMode = function(_mode){
        _n._$exec('player.setPlayMode',_mode);
        this.__onNativeEvent('playmode',_mode);
    };
    /**
     * 设置音量
     * @param  {Float} 音量，范围：[0.0,1.0]
     * @return {Void}
     */
    _proPlayer._$setVolume = function(_volume){
        _n._$exec('player.setVolume',_volume);
    };
    /**
     * 设置播放位置
     * @param  {Float} 播放位置，百分比
     * @return {Void}
     */
    _proPlayer._$setPosition = function(_ratio){
        _n._$exec('player.setCurrentTime',_ratio*(_player.duration||0));
    };
    /**
     * 设置歌词
     * @param  {String} 歌词内容
     * @return {Void}
     */
    _proPlayer._$setLRC = function(_lrc){
        !_lrc ? _n._$exec('player.setLRCEmpty')
              : _n._$exec('player.setLRC',_lrc||'');
    };
    /**
     * 设置封面
     * @param  {String} 专辑ID
     * @return {Void}
     */
    _proPlayer._$setCover = function(_aid){
        !_aid ? _n._$exec('player.setCoverDefault')
              : _n._$exec('player.setCover',''+_aid,'album');
    };
    /**
     * native事件回调
     * @param  {String} 事件名称
     * @return {Void}
     */
    _proPlayer.__onNativeEvent = function(_name){
        switch(_name){
            case 'dataloaded':
                this._$resume();
            return;
            case 'play':
                this._$dispatchEvent('onstatechange',{
                    state:1
                });
            return;
            case 'pause':
                this._$dispatchEvent('onstatechange',{
                    state:2
                });
            return;
            case 'ended':
                this._$dispatchEvent('onstatechange',{
                    state:4
                });
            return;
            case 'timeupdate':
                this._$dispatchEvent('onpositionchange',{
                    current:_n._$exec('player.getCurrentTime')||0,
                    duration:_player.duration||0
                });
                // lock loading
                var _loading = _n._$exec('player.getDownloadSchedule')||0;
                if (_loading==1&&this.__loading==1) return;
                this.__loading = _loading;
                this._$dispatchEvent('onloading',{
                    loaded:this.__loading,total:1
                });
            return;
            case 'volumechange':
                this._$dispatchEvent('onvolumechange',{
                    volume:_n._$exec('player.getVolume')
                });
            return;
            case 'error':
                this._$dispatchEvent('onstatechange',{
                    state:5
                });
            return;
            case 'notify':

            return;
            case 'playpre':
            case 'playnext':
                this._$dispatchEvent('ontrackchange',{
                    flag:_name=='playpre'?-1:1
                });
            return;
            case 'playmode':
                this._$dispatchEvent('onmodechange',{
                    mode:arguments[1]
                });
            return;
            case 'lyricsupdate':
                this._$dispatchEvent('onlrcupdate',{
                    id:arguments[1],lrc:arguments[2]
                });
            return;
            case 'loading':
            case 'buffering':
                this._$dispatchEvent('onstatechange',{
                    state:0
                });
            return;
            case 'playmodechange':
                this._$dispatchEvent('onnextmode');
            return;
        }
    };
};
NEJ.define('{lib}native/cef/util/player.js',
          ['{lib}util/event.js'
          ,'{lib}native/command.js'],f);<|endoftext|>


<commit_before>"use strict";

module.exports.create = function (options){
	return new Formatter (options);
};

var Formatter = function (options){
	options = options || {};
	this._complete = options.complete || "#";
	this._incomplete = options.incomplete || "·";
	this._length = options.length || 24;
};

Formatter.prototype.format = function (n){
	var bar = "";
	var percentage = n === 1 ? "100" : " " + Math.round (n*100);
	var complete = Math.round (this._length*n);
	for (var i=0, ii=complete; i<ii; i++){
		bar += this._complete;
	}
	for (var i=0, ii=this._length-complete; i<ii; i++){
		bar += this._incomplete;
	}
	return bar;
};<commit_msg>clean up<commit_after>"use strict";

module.exports.create = function (options){
	return new Formatter (options);
};

var Formatter = function (options){
	options = options || {};
	this._complete = options.complete || "#";
	this._incomplete = options.incomplete || "·";
	this._length = options.length || 24;
};

Formatter.prototype.format = function (n){
	var bar = "";
	var complete = Math.round (this._length*n);
	for (var i=0, ii=complete; i<ii; i++){
		bar += this._complete;
	}
	for (var i=0, ii=this._length-complete; i<ii; i++){
		bar += this._incomplete;
	}
	return bar;
};<|endoftext|>


<commit_before>var Options = require('./options');
var Metafile = require('./metafile');

module.exports = metafiles;

// Not needed in Node 4.0+
if (!Object.assign) Object.assign = require('object-assign');

/**
 * Metalsmith plugin to read file metadata from separate files
 *
 * @param {Object} options
 * @param {boolean} [options.deleteMetaFiles=true] - Whether to delete metadata files from the built site
 * @return {Function}
 */

function metafiles(options) {
  options = new Options(options);

  return function(files, metalsmith) {
    for (var path in files) {
      var metafile = new Metafile(path, files[path], options);

      if (!metafile.isMetafile) continue;
      if (!files[metafile.mainFile]) continue;

      Object.assign(files[metafile.mainFile], metafile.metadata);
      if (options.deleteMetaFiles) delete files[metafile.path];
    }
  };
}
<commit_msg>Update inline docs for the main function<commit_after>var Options = require('./options');
var Metafile = require('./metafile');

module.exports = metafiles;

// Not needed in Node 4.0+
if (!Object.assign) Object.assign = require('object-assign');

/**
 * Metalsmith plugin to read file metadata from separate files
 *
 * @param {Object} options
 * @param {String} [options.postfix=".metadata"] - The postfix added to filenames to indicate they are metadata files
 * @param {String} [options.prefix=""] - The prefix added to filenames to indicate they are metadata files
 * @param {boolean} [options.deleteMetaFiles=true] - Whether to delete metadata files from the built site
 * @return {Function}
 */

function metafiles(options) {
  options = new Options(options);

  return function(files, metalsmith) {
    for (var path in files) {
      var metafile = new Metafile(path, files[path], options);

      if (!metafile.isMetafile) continue;
      if (!files[metafile.mainFile]) continue;

      Object.assign(files[metafile.mainFile], metafile.metadata);
      if (options.deleteMetaFiles) delete files[metafile.path];
    }
  };
}
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var colour = require('colour')
var shell = require('shelljs');
var glob = require('glob');

// Constants
var envProd = 'prod';
var envDev = 'dev';

colour.mode = 'console';

function Dode(cwd) {
    var self = this;

    self.currentDir = process.cwd();

    self.dodeRoot = '';
    self.dodeJson = {};
    self.services = {};

    self._initDodeObject();
    self._initServiceObjects();

    var pkg = require(self.dodeRoot + '/package.json');
    self.name = pkg.name;
    self.version = pkg.version;

    // set env -> todo: wird das noch gebraucht ??
    shell.env['PROJECT_VERSION'] = self.version;
    shell.env['PROJECT_NAME'] = self.name;
    shell.env['DEV_PROJECT_NAME'] = self.name + 'dev';
};

Dode.prototype._initDodeObject = function () {
    var self = this;

    try {
        self.dodeRoot = self.currentDir;
        self.dodeJson = require(self.dodeRoot + '/dode.json');
    } catch (error) {
        try {
            self.dodeRoot = path.resolve(self.dodeRoot, '..')
            self.dodeJson = require(self.dodeRoot + '/dode.json');
        } catch (error) {
            console.error('Error: dode not properly configured, use: dode init');
        }
    };
};

Dode.prototype._initServiceObjects = function () {
    var self = this;
    var pkgs = glob.sync(self.dodeRoot + '/*/package.json');

    pkgs.forEach(function (pkgFile) {
        var dirname = (pkgFile.split('/').reverse()[1]).toUpperCase();
        self.services[dirname] = new Service(dirname, pkgFile);
    }, this);
};

function Service(service, pkgFile) {
    var self = this;
    var pkg = require(pkgFile);

    self.service = service;
    self.name = pkg.name;
    self.version = pkg.version;

    // set env
    shell.env[self.service + '_NAME'] = self.name;
    shell.env[self.service + '_VERSION'] = self.version;
};

module.exports = new Dode()<commit_msg>initial commit<commit_after>'use strict';

var path = require('path');
var colour = require('colour')
var shell = require('shelljs');
var glob = require('glob');

// Constants
var envProd = 'prod';
var envDev = 'dev';

colour.mode = 'console';

function Dode(cwd) {
    var self = this;

    self.currentDir = process.cwd();

    self.dodeRoot = '';
    self.dodeJson = {};
    self.services = {};

    self._initDodeObject();
    self._initServiceObjects();

    var pkg = require(self.dodeRoot + '/package.json');
    self.name = pkg.name;
    self.version = pkg.version;

    // set env -> todo: wird das noch gebraucht ??
    shell.env['PROJECT_VERSION'] = self.version;
    shell.env['PROJECT_NAME'] = self.name;
    shell.env['DEV_PROJECT_NAME'] = self.name + 'dev';
};

Dode.prototype._initDodeObject = function () {
    var self = this;

    try {
        self.dodeRoot = self.currentDir;
        self.dodeJson = require(self.dodeRoot + '/dode.json');
    } catch (error) {
        try {
            self.dodeRoot = path.resolve(self.dodeRoot, '..')
            self.dodeJson = require(self.dodeRoot + '/dode.json');
        } catch (error) {
            console.error('Error: dode not properly configured, use: dode-compose init');
        }
    };
};

Dode.prototype._initServiceObjects = function () {
    var self = this;
    var pkgs = glob.sync(self.dodeRoot + '/*/package.json');

    pkgs.forEach(function (pkgFile) {
        var dirname = (pkgFile.split('/').reverse()[1]).toUpperCase();
        self.services[dirname] = new Service(dirname, pkgFile);
    }, this);
};

function Service(service, pkgFile) {
    var self = this;
    var pkg = require(pkgFile);

    self.service = service;
    self.name = pkg.name;
    self.version = pkg.version;

    // set env
    shell.env[self.service + '_NAME'] = self.name;
    shell.env[self.service + '_VERSION'] = self.version;
};

module.exports = new Dode()<|endoftext|>


<commit_before>(function() {
  'use strict';

  /**
   * Provides implementation of transport-based cross-browser/cross-device
   * bi-directional communication layer for Socket.IO.
   * @constructor
   * @extends {lfr.Transport}
   */
  lfr.WebSocketTransport = function(uri) {
    lfr.WebSocketTransport.base(this, 'constructor', uri);
  };
  lfr.inherits(lfr.WebSocketTransport, lfr.Transport);

  /**
   * Holds the underlying socket mechanism. Default mechanism uses Socket.IO.
   * @type {Socket.IO}
   * @default null
   */
  lfr.WebSocketTransport.prototype.socket = null;

  /**
   * @inheritDoc
   */
  lfr.WebSocketTransport.prototype.close = function() {
    if (this.socket) {
      this.socket.close();
    }
    return this;
  };

  /**
   * Event handle for socket connect event. Fires transport open event.
   * @param {?Object} event
   * @protected
   */
  lfr.WebSocketTransport.prototype.onSocketConnect_ = function() {
    this.emit('open');
  };

  /**
   * Event handle for socket data event. Fires transport data event.
   * @param {*} data
   * @protected
   */
  lfr.WebSocketTransport.prototype.onSocketData_ = function(data) {
    this.emit('data', {
      data: data
    });
  };

  /**
   * Event handle for socket disconnect event. Fires transport close event.
   * @protected
   */
  lfr.WebSocketTransport.prototype.onSocketDisconnect_ = function() {
    this.emit('close');
  };

  /**
   * Event handle for socket error event. Fires transport error event.
   * @param {Object} event
   * @protected
   */
  lfr.WebSocketTransport.prototype.onSocketError_ = function(event) {
    var error = new Error('Transport request error');
    error.socket = this.socket;
    error.message = event;
    this.emit('error', {
      error: error
    });
  };

  /**
   * Event handle for socket message event. Fires transport message event.
   * @protected
   */
  lfr.WebSocketTransport.prototype.onSocketMessage_ = function(message) {
    this.emit('message', {
      data: message
    });
  };

  /**
   * @inheritDoc
   */
  lfr.WebSocketTransport.prototype.open = function() {
    if (this.isOpen()) {
      console.warn('Transport is already open');
      return;
    }

    this.emit('opening');

    /*global io*/
    if (!this.socket) {
      if (!io) {
        throw new Error('Socket.IO client not found');
      }
      this.socket = io(this.getUri());
      this.socket.on('connect', lfr.bind(this.onSocketConnect_, this));
      this.socket.on('disconnect', lfr.bind(this.onSocketDisconnect_, this));
      this.socket.on('error', lfr.bind(this.onSocketError_, this));
      this.socket.on('data', lfr.bind(this.onSocketData_, this));
      this.socket.on('message', lfr.bind(this.onSocketMessage_, this));
    }

    this.socket.open();

    return this;
  };

  /**
   * @inheritDoc
   */
  lfr.WebSocketTransport.prototype.write = function(message) {
    this.socket.send(message);
  };

}());
<commit_msg>Decodes emitted data on WebSocketTransport<commit_after>(function() {
  'use strict';

  /**
   * Provides implementation of transport-based cross-browser/cross-device
   * bi-directional communication layer for Socket.IO.
   * @constructor
   * @extends {lfr.Transport}
   */
  lfr.WebSocketTransport = function(uri) {
    lfr.WebSocketTransport.base(this, 'constructor', uri);
  };
  lfr.inherits(lfr.WebSocketTransport, lfr.Transport);

  /**
   * Holds the underlying socket mechanism. Default mechanism uses Socket.IO.
   * @type {Socket.IO}
   * @default null
   */
  lfr.WebSocketTransport.prototype.socket = null;

  /**
   * @inheritDoc
   */
  lfr.WebSocketTransport.prototype.close = function() {
    if (this.socket) {
      this.socket.close();
    }
    return this;
  };

  /**
   * Event handle for socket connect event. Fires transport open event.
   * @param {?Object} event
   * @protected
   */
  lfr.WebSocketTransport.prototype.onSocketConnect_ = function() {
    this.emit('open');
  };

  /**
   * Event handle for socket data event. Fires transport data event.
   * @param {*} data
   * @protected
   */
  lfr.WebSocketTransport.prototype.onSocketData_ = function(data) {
    this.emit('data', {
      data: this.decodeData(data)
    });
  };

  /**
   * Event handle for socket disconnect event. Fires transport close event.
   * @protected
   */
  lfr.WebSocketTransport.prototype.onSocketDisconnect_ = function() {
    this.emit('close');
  };

  /**
   * Event handle for socket error event. Fires transport error event.
   * @param {Object} event
   * @protected
   */
  lfr.WebSocketTransport.prototype.onSocketError_ = function(event) {
    var error = new Error('Transport request error');
    error.socket = this.socket;
    error.message = event;
    this.emit('error', {
      error: error
    });
  };

  /**
   * Event handle for socket message event. Fires transport message event.
   * @protected
   */
  lfr.WebSocketTransport.prototype.onSocketMessage_ = function(message) {
    this.emit('message', {
      data: message
    });
  };

  /**
   * @inheritDoc
   */
  lfr.WebSocketTransport.prototype.open = function() {
    if (this.isOpen()) {
      console.warn('Transport is already open');
      return;
    }

    this.emit('opening');

    /*global io*/
    if (!this.socket) {
      if (!io) {
        throw new Error('Socket.IO client not found');
      }
      this.socket = io(this.getUri());
      this.socket.on('connect', lfr.bind(this.onSocketConnect_, this));
      this.socket.on('disconnect', lfr.bind(this.onSocketDisconnect_, this));
      this.socket.on('error', lfr.bind(this.onSocketError_, this));
      this.socket.on('data', lfr.bind(this.onSocketData_, this));
      this.socket.on('message', lfr.bind(this.onSocketMessage_, this));
    }

    this.socket.open();

    return this;
  };

  /**
   * @inheritDoc
   */
  lfr.WebSocketTransport.prototype.write = function(message) {
    this.socket.send(message);
  };

}());
<|endoftext|>


<commit_before>'use strict'
var util = require('util')
var Transport = require('winston-transport')
var winston = require('winston')

const winstonCompat = require('winston-compat')
var _dirname = require('path').dirname
var LogseneJS = require('logsene-js')

var Logsene = function (options) {
  options = options || {}
  if (!options.hasOwnProperty('flushOnExit')) {
    options.flushOnExit = true
  }
  if (!options.levels) {
    options.levels = winston.config.npm.levels
  }
  Transport.call(this, options)
  this.logCount = 0
  this.setSource = options.setLogSource
  if (options.hasOwnProperty('setSource')) {
    this.setSource = options.setSource
  } else {
    this.setSource = false
  }
  this.logsene_debug = options.logsene_debug
  this.flatOptions = options.flatOptions || { safe: true, delimiter: '_' }
  this.json = options.json || false
  this.colorize = options.colorize || false
  this.prettyPrint = options.prettyPrint || false
  this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false
  this.label = options.label || null
  this.source = options.source || (process.mainModule ? _dirname(process.mainModule.filename) : null) || module.filename

  this.rewriter = options.rewriter || null
  if (this.json) {
    this.stringify = options.stringify || function (obj) {
      return JSON.stringify(obj, null, 2)
    }
  }
  this.logger = new LogseneJS(options.token,
    options.type || 'winston_logsene',
    options.url)
  var self = this
  this.logger.on('error', function (e) {
    const { err } = e

    if (err.code === 'EAI_AGAIN') {
      console.error(new Date().toISOString() + ` winston-logsene: cannot reach the receiver URL: ${err.url}, please check your network connection ...`)
      return
    }

    self.emit('warning', e)
    console.error(new Date().toISOString() + ` winston-logsene: cannot reach the receiver URL: ${err.url}, please check the error message ...`, err)
  })
  this.logger.on('log', function (data) {
    self.logCount = self.logCount - data.count
    self.emit('logged', data)
    self.emit('flush', data)
  })
  var flushLogs = function (callback) {
    var exitTimeout = 99000
    if (self.logCount < 1) {
      console.log(new Date().toISOString() + ' winston-logsene: flush: no logs in buffer')
      callback(null, exitTimeout)
    } else {
      console.log(new Date().toISOString() + ' winston-logsene: start flushing ' + self.logCount + ' logs before exit ...')
      self.logger.once('log', function (data) {
        console.log(new Date().toISOString() + ' winston-logsene: flush before exit: ' + data.count + ' logs send.')
        callback(null, exitTimeout)
      })
      self.logger.once('error', function (err) {
        console.log(new Date().toISOString() + ' winston-logsene: flush before exit error: ' + err)
        callback(err, exitTimeout)
      })
      process.nextTick(self.logger.send.bind(self.logger))
      // when no error or successful "log" event was received,
      // the process should terminate.
      // upstart waits max 10 seconds before kill -9
      callback(null, exitTimeout)
    }
  }
  var logseneExitHandler = function (code) {
    flushLogs(function (logseneErr, exitTime) {
      setTimeout(process.exit, exitTime)
    })
  }
  if (options.handleExceptions) {
    process.on('uncaughtException', function (err) {
      console.log(new Date().toISOString() + ' winston-logsene: uncaughtException: ' + err + ' ' + err.stack)
      self.logger.log('error', err.stack || err.toString(), err)
      flushLogs(function (flushErr, exitTime) {
        if (options.exitOnError) {
          setTimeout(function () {
            process.exit(-1)
          }, exitTime)
        }
      })
    })
  }

  if (options.handleErrors) {
    process.on('error', function (err) {
      console.log(new Date().toISOString() + ' winston-logsene: unhandledError: ' + err + ' ' + err.stack)
      self.logger.log('error', err.stack || err.toString(), err)
      flushLogs(function (flushErr, exitTime) {
        if (options.exitOnError) {
          setTimeout(function () {
            process.exit(-1)
          }, exitTime)
        }
      })
    })
  }

  process.on('unhandledRejection', function (err) {
    console.log(new Date().toISOString() + ' winston-logsene: unhandledRejection: ' + err + ' ' + err.stack)
    self.logger.log('warning', err.stack || err.toString(), err)
  })

  if (options.flushOnExit) {
    process.once('SIGTERM', logseneExitHandler)
    process.once('SIGINT', logseneExitHandler)
    process.once('SIGQUIT', logseneExitHandler)
    process.once('beforeExit', logseneExitHandler)
    process.once('exit', logseneExitHandler)
  }
  // Add toJSON to Error Class
  if (!('toJSON' in Error.prototype)) {
    Object.defineProperty(Error.prototype, 'toJSON', {
      value: function () {
        var alt = {}
        Object.getOwnPropertyNames(this).forEach(function (key) {
          alt[key] = this[key]
        }, this)
        return alt
      },
      configurable: true,
      writable: true
    })
  }
}

//
// Inherit from `winston.Transport`.
//
util.inherits(Logsene, Transport)

//
// Expose the name of this Transport on the prototype
//
Logsene.prototype.name = 'Logsene'

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
Logsene.prototype.log = function (meta, callback) {
  var level = meta.level
  var msg = meta.message
  this.logCount++
  var metaData = meta
  if (this.silent) {
    return callback(null, true)
  }
  if (this.setSource) {
    if (meta && (!meta.source)) {
      meta.source = this.source
    }
  }

  if (this.rewriter) {
    metaData = this.rewriter(level, msg, meta)
  }
  if (meta instanceof Error) {
    if (!msg) {
      msg = meta.stack || meta.message
    }
    metaData = { error_stack: meta.stack || meta.message }
  }
  if (this.logsene_debug) {
    var output = winstonCompat.log({
      colorize: this.colorize,
      json: this.json,
      level: level,
      message: msg,
      meta: metaData,
      stringify: this.stringify,
      timestamp: new Date(), // this.timestamp,
      prettyPrint: this.prettyPrint,
      raw: this.raw,
      label: this.label
    })
    console.log(output)
  }
  // this.logger.log(level, msg, flatten(metaData, this.flatOptions), callback)

  this.logger.log(level, msg, metaData, callback)
}

Logsene.prototype.clearLogs = function () {
  // not required ?
  process.nextTick(this.logger.send.bind(this.logger))
}

module.exports = Logsene
module.exports.Logsene = Logsene
<commit_msg>remove redundant code<commit_after>'use strict'
var util = require('util')
var Transport = require('winston-transport')
var winston = require('winston')

const winstonCompat = require('winston-compat')
var _dirname = require('path').dirname
var LogseneJS = require('logsene-js')

var Logsene = function (options) {
  options = options || {}
  if (!options.hasOwnProperty('flushOnExit')) {
    options.flushOnExit = true
  }
  if (!options.levels) {
    options.levels = winston.config.npm.levels
  }
  Transport.call(this, options)
  this.logCount = 0
  this.setSource = options.setLogSource
  if (options.hasOwnProperty('setSource')) {
    this.setSource = options.setSource
  } else {
    this.setSource = false
  }
  this.logsene_debug = options.logsene_debug
  this.json = options.json || false
  this.colorize = options.colorize || false
  this.prettyPrint = options.prettyPrint || false
  this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false
  this.label = options.label || null
  this.source = options.source || (process.mainModule ? _dirname(process.mainModule.filename) : null) || module.filename

  this.rewriter = options.rewriter || null
  if (this.json) {
    this.stringify = options.stringify || function (obj) {
      return JSON.stringify(obj, null, 2)
    }
  }
  this.logger = new LogseneJS(options.token,
    options.type || 'winston_logsene',
    options.url)
  var self = this
  this.logger.on('error', function (e) {
    const { err } = e

    if (err.code === 'EAI_AGAIN') {
      console.error(new Date().toISOString() + ` winston-logsene: cannot reach the receiver URL: ${err.url}, please check your network connection ...`)
      return
    }

    self.emit('warning', e)
    console.error(new Date().toISOString() + ` winston-logsene: cannot reach the receiver URL: ${err.url}, please check the error message ...`, err)
  })
  this.logger.on('log', function (data) {
    self.logCount = self.logCount - data.count
    self.emit('logged', data)
    self.emit('flush', data)
  })
  var flushLogs = function (callback) {
    var exitTimeout = 99000
    if (self.logCount < 1) {
      console.log(new Date().toISOString() + ' winston-logsene: flush: no logs in buffer')
      callback(null, exitTimeout)
    } else {
      console.log(new Date().toISOString() + ' winston-logsene: start flushing ' + self.logCount + ' logs before exit ...')
      self.logger.once('log', function (data) {
        console.log(new Date().toISOString() + ' winston-logsene: flush before exit: ' + data.count + ' logs send.')
        callback(null, exitTimeout)
      })
      self.logger.once('error', function (err) {
        console.log(new Date().toISOString() + ' winston-logsene: flush before exit error: ' + err)
        callback(err, exitTimeout)
      })
      process.nextTick(self.logger.send.bind(self.logger))
      // when no error or successful "log" event was received,
      // the process should terminate.
      // upstart waits max 10 seconds before kill -9
      callback(null, exitTimeout)
    }
  }
  var logseneExitHandler = function (code) {
    flushLogs(function (logseneErr, exitTime) {
      setTimeout(process.exit, exitTime)
    })
  }
  if (options.handleExceptions) {
    process.on('uncaughtException', function (err) {
      console.log(new Date().toISOString() + ' winston-logsene: uncaughtException: ' + err + ' ' + err.stack)
      self.logger.log('error', err.stack || err.toString(), err)
      flushLogs(function (flushErr, exitTime) {
        if (options.exitOnError) {
          setTimeout(function () {
            process.exit(-1)
          }, exitTime)
        }
      })
    })
  }

  if (options.handleErrors) {
    process.on('error', function (err) {
      console.log(new Date().toISOString() + ' winston-logsene: unhandledError: ' + err + ' ' + err.stack)
      self.logger.log('error', err.stack || err.toString(), err)
      flushLogs(function (flushErr, exitTime) {
        if (options.exitOnError) {
          setTimeout(function () {
            process.exit(-1)
          }, exitTime)
        }
      })
    })
  }

  process.on('unhandledRejection', function (err) {
    console.log(new Date().toISOString() + ' winston-logsene: unhandledRejection: ' + err + ' ' + err.stack)
    self.logger.log('warning', err.stack || err.toString(), err)
  })

  if (options.flushOnExit) {
    process.once('SIGTERM', logseneExitHandler)
    process.once('SIGINT', logseneExitHandler)
    process.once('SIGQUIT', logseneExitHandler)
    process.once('beforeExit', logseneExitHandler)
    process.once('exit', logseneExitHandler)
  }
  // Add toJSON to Error Class
  if (!('toJSON' in Error.prototype)) {
    Object.defineProperty(Error.prototype, 'toJSON', {
      value: function () {
        var alt = {}
        Object.getOwnPropertyNames(this).forEach(function (key) {
          alt[key] = this[key]
        }, this)
        return alt
      },
      configurable: true,
      writable: true
    })
  }
}

//
// Inherit from `winston.Transport`.
//
util.inherits(Logsene, Transport)

//
// Expose the name of this Transport on the prototype
//
Logsene.prototype.name = 'Logsene'

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
Logsene.prototype.log = function (meta, callback) {
  var level = meta.level
  var msg = meta.message
  this.logCount++
  var metaData = meta
  if (this.silent) {
    return callback(null, true)
  }
  if (this.setSource) {
    if (meta && (!meta.source)) {
      meta.source = this.source
    }
  }

  if (this.rewriter) {
    metaData = this.rewriter(level, msg, meta)
  }
  if (meta instanceof Error) {
    if (!msg) {
      msg = meta.stack || meta.message
    }
    metaData = { error_stack: meta.stack || meta.message }
  }
  if (this.logsene_debug) {
    var output = winstonCompat.log({
      colorize: this.colorize,
      json: this.json,
      level: level,
      message: msg,
      meta: metaData,
      stringify: this.stringify,
      timestamp: new Date(), // this.timestamp,
      prettyPrint: this.prettyPrint,
      raw: this.raw,
      label: this.label
    })
    console.log(output)
  }
  // this.logger.log(level, msg, flatten(metaData, this.flatOptions), callback)

  this.logger.log(level, msg, metaData, callback)
}

Logsene.prototype.clearLogs = function () {
  // not required ?
  process.nextTick(this.logger.send.bind(this.logger))
}

module.exports = Logsene
module.exports.Logsene = Logsene
<|endoftext|>


<commit_before>// Copyright 2012 The Obvious Corporation.

/*
 * Daemon Sauce: Just sprinkle it on your Node program, to make it a proper
 * *nix daemon.
 *
 * This assumes that the original script gets called with at least one
 * option of the form --daemon=<mode>, where mode is one of "parent"
 * "child" or "foreground". When running normally, it should be
 * "parent." When running in the foreground (e.g.  during
 * development), it should be "foreground." The "child" mode is used
 * internally (for the spawned child process).
 */

/*
 * Modules used
 */

"use strict";

var child_process = require("child_process");
var fs            = require("fs");
var path          = require("path");
var posix         = require("posix");
var util          = require("util");

var daemonsauceNative = require("../bin/daemonsauceNative");

/*
 * Module-local variables
 */

/** the "first-resort" error log file */
var ERROR_LOG_NAME = "error.log";

/** the "last-ditch" error log file */
var LAST_DITCH_ERROR_LOG_NAME = "dire-error.log";

/** the product name; used in logging */
var productName = "daemon";

/** what mode is this process in; one of: "child" "foreground" */
var mode = undefined;

/** directory for "run" files (notably, the pid lockfile) */
var runDir = undefined;

/** file to log to */
var logFile = undefined;

/** the full product info */
var theInfo = { name: productName };

/*
 * Helper functions
 */

/**
 * Heuristically sets the product name based on the given script name, by
 * extracting the base file name (excluding directories and dot-suffixes).
 */
function setProductNameFromScript(name) {
    var match = name.match(/^.*\/([^\/.]+)[^\/]*$/);

    if (!match || (match[1].length === 0)) {
	// The name isn't of the usual form. Just use the whole name.
	setProductName(name);
    } else {
	setProductName(match[1]);
    }
}

/**
 * Parses the given commandline arguments (process.argv if left
 * unspecified), determining what mode the process is to be in.  This
 * returns a map of the form { mode: <mode>, exec: <executable-name>,
 * script: <file-name>, argv: <cooked-argv> }, where mode is one of {
 * "parent", "child", "foreground" }, exec and script are the original
 * two arguments, and argv is an array of the arguments, excluding the
 * one that was used to determine parent-vs-child.
 *
 * This throws an exception if there is no mode argument present.
 */
function parseDaemonArguments(argv) {
    if (argv === undefined) {
	argv = process.argv;
    }

    if (argv.length < 3) {
	throw new Error("Too few arguments for daemon invocation");
    }

    var exec = argv[0];
    var script = argv[1];
    argv = argv.slice(2);

    // Scan for a --daemon argument, and note its index and value.

    var modeIndex = -1;
    var mode = undefined;

    for (var i = 0; i < argv.length; i++) {
	var arg = argv[i];
	if ((arg === "--") || (arg.length === 0) || (arg.charAt(0) !== "-")) {
	    break;
	}
	if (arg.search(/^--daemon=/) === 0) {
	    modeIndex = i;
	    mode = arg.slice(9);
	    break;
	}
    }

    // Validate.

    if (modeIndex < 0) {
        // Assume missing means "foreground".
        mode = "foreground";
    }

    switch (mode) {
        case "parent":
        case "child":
        case "foreground": {
	    // It's a valid value.
	    break;
	}
        default: {
	    throw new Error("Invalid --daemon option: " + mode);
	}
    }

    // Excise the --daemon argument from argv.
    if (modeIndex >= 0) {
        argv.splice(modeIndex, 1);
    }

    return {
	mode:   mode,
	exec:   exec,
	script: script,
	argv:   argv
    };
}

/**
 * Logs to the file indicated by logFile, or to stderr if logFile hasn't
 * yet been set.
 */
function logToFile(/*arg, ...*/) {
    var string = util.format.apply(this, arguments) + "\n";

    if (logFile === undefined) {
	process.stderr.write(string);
    } else {
	fs.write(logFile, string);
    }
}

/**
 * Logs to the the syslog.
 */
function logToSyslog(/*arg, ...*/) {
    posix.syslog("notice", util.format.apply(this, arguments));
}

/**
 * Make a directory (and its superdirectories) if it doesn't already exist.
 */
function mkdirsIfNeeded(dir) {
    try {
	var stat = fs.statSync(dir);
    } catch (ex) {
	if (ex.code == "ENOENT") {
	    var upDir = dir.match(/^(.*)\/[^\/]*$/);
	    if (upDir && upDir.length > 0) {
		mkdirsIfNeeded(upDir[1]);
	    }
	    fs.mkdirSync(dir);
	} else {
	    throw ex;
	}
    }
}

/*
 * Exported methods
 */

/**
 * Set the product name. This is used when logging.
 */
function setProductName(name) {
    productName = name;
    theInfo.name = name;
}

/**
 * Set the logging directory. This is (unsurprisingly) used when logging.
 */
function setLogDir(dir) {
    if (logFile !== undefined) {
	fs.closeSync(logFile);
    }

    mkdirsIfNeeded(dir);
    logFile = fs.openSync(path.join(dir, ERROR_LOG_NAME), "a");

    fs.writeSync(logFile, "\n\n[Restarting log at " + new Date() + ".]\n");

    // If there is anything in the "last ditch" error file (e.g. from
    // an earlier crash), copy it over here.
    var lastDitch = path.join(dir, LAST_DITCH_ERROR_LOG_NAME);
    if (path.existsSync(lastDitch)) {
        var buf = fs.readFileSync(lastDitch);
        if (buf.length !== 0) {
            fs.writeSync(
                logFile,
                "[The following was recovered from the last-ditch file.]\n");
            fs.writeSync(logFile, buf, 0, buf.length);
            fs.writeSync(logFile, "\n[End of recovered text.]\n\n");
        }
        fs.unlinkSync(lastDitch);
    }
}

/**
 * Set the run directory. This is notably used to hold a process pid
 * lockfile.
 */
function setRunDir(dir) {
    mkdirsIfNeeded(dir);
    runDir = dir;
}

/**
 * Take appropriate daemon setup action, based on the --daemon option
 * in the given commandline arguments (which default to process.argv
 * if left unspecified). This function should be called once, early on
 * in the life of a script.
 *
 * This function only returns in a child or foreground process. In a
 * parent process, this function is responsible for spawning the child
 * and then exiting.
 *
 * The return value is the given (or process) arguments, minus the one
 * that specified the daemon mode.
 */
function basicSetup(argv) {
    var parsedArgs = parseDaemonArguments(argv);
    mode = parsedArgs.mode; // Set the module-scope mode.
    setProductNameFromScript(parsedArgs.script);

    switch (mode) {
        case "parent": {
	    // We are the parent process. Spawn a child, telling it to
	    // run Node with the same script, but with the child daemon
	    // command.
	    var childArgs = [ "--daemon=child" ].concat(parsedArgs.argv);
	    var childProcess = child_process.fork(
		parsedArgs.script,
		childArgs,
		{ cwd: "/",
		  env: process.env, // TODO: Allow this to be passed in?
		  setsid: true
		});
	    process.exit(1);
	    throw new Error("Shouldn't happen");
	}
        case "child": {
	    // We are the child process. Reopen std* to /dev/null, and
	    // return the cooked argv.
	    daemonsauceNative.closeStdin();
	    daemonsauceNative.closeStdout();
	    daemonsauceNative.closeStderr();
	    return makeArgv();
	}
        case "foreground": {
	    // We are a foreground process. Just return the cooked argv.
	    return makeArgv();
	}
    }

    function makeArgv() {
	return [ parsedArgs.exec, parsedArgs.script ].concat(parsedArgs.argv);
    }
}

/**
 * Set up the logging environment. This only takes any action when
 * running in a daemon child process. This also needs to be done along
 * with a call to setLogDir().
 *
 * This replaces the logging methods of the global console
 * object. Most of the logging methods will write to an error log,
 * except for info(), which will emit syslog entries.
 */
function loggingSetup() {
    if (mode !== "child") {
	return;
    }

    // Set up for using syslog.
    posix.openlog(productName, {cons: true, pid: true}, "daemon");

    // What does "dir" mean? This is more or less copied from
    // console.js in the Node core.
    function dir(object) {
	console.log(util.inspect(object));
    }

    console.log = logToFile;
    console.info = logToSyslog;
    console.warn = logToFile;
    console.error = logToFile;
    console.dir = dir;
}

/**
 * Acquire the process lock. This will either succeed in locking or will
 * exit the process after logging the failure.
 *
 * This may only be called after setting the run directory.
 *
 * This method only takes action when running in a daemon child.
 */
function acquireLock() {
    if (mode !== "child") {
	return;
    }

    var lockFile = path.join(runDir, productName + ".pid");

    if (!daemonsauceNative.acquireLock(lockFile)) {
        console.info("Could not acquire lockfile: " + lockFile);
        process.exit(1);
    }
}

/**
 * Set user and group ids, based on the given info. It uses the
 * indicated `user` for the userid if supplied, defaulting to the
 * (product) `name` if not. `group` specifies the group id, which
 * defaults to the userid (which may itself have been defaulted to the
 * product name) if not specified.
 *
 * This function does nothing if it's not possible to set the ids
 * (e.g. id doesn't exist or not running as root).
 *
 * This method only takes action when running in a daemon child.
 */
function setUserAndGroup(info) {
    if (mode !== "child") {
	return;
    }

    var user = info.user || info.name;
    var group = info.group || user;

    try {
	process.setgid(group);
	process.setuid(user);
    } catch (ex) {
	// Ignore it.
    }
}

/**
 * Perform the "usual" daemon setup, based on the given info, which
 * must at least contain bindings for `{ name, logDir, runDir }`. Other
 * info is okay too, and is just returned directly by `getInfo()`.
 */
function usualSetup(info) {
    var name = info.name;
    var logDir = info.logDir;
    var runDir = info.runDir;

    if (!(name && logDir && runDir)) {
        throw new Error("Missing setup info");
    }

    theInfo = info;
    setProductName(name);
    setUserAndGroup(info);
    setRunDir(runDir);
    setLogDir(logDir);
    loggingSetup();
    acquireLock();
}

/**
 * Get the info previously passed to `usualSetup()`.
 */
function getInfo() {
    return theInfo;
}

module.exports = {
    acquireLock:     acquireLock,
    basicSetup:      basicSetup,
    getInfo:         getInfo,
    loggingSetup:    loggingSetup,
    setLogDir:       setLogDir,
    setRunDir:       setRunDir,
    setProductName:  setProductName,
    setUserAndGroup: setUserAndGroup,
    usualSetup:      usualSetup
};
<commit_msg>After spawning the child, exit should be normal, not erroneous.<commit_after>// Copyright 2012 The Obvious Corporation.

/*
 * Daemon Sauce: Just sprinkle it on your Node program, to make it a proper
 * *nix daemon.
 *
 * This assumes that the original script gets called with at least one
 * option of the form --daemon=<mode>, where mode is one of "parent"
 * "child" or "foreground". When running normally, it should be
 * "parent." When running in the foreground (e.g.  during
 * development), it should be "foreground." The "child" mode is used
 * internally (for the spawned child process).
 */

/*
 * Modules used
 */

"use strict";

var child_process = require("child_process");
var fs            = require("fs");
var path          = require("path");
var posix         = require("posix");
var util          = require("util");

var daemonsauceNative = require("../bin/daemonsauceNative");

/*
 * Module-local variables
 */

/** the "first-resort" error log file */
var ERROR_LOG_NAME = "error.log";

/** the "last-ditch" error log file */
var LAST_DITCH_ERROR_LOG_NAME = "dire-error.log";

/** the product name; used in logging */
var productName = "daemon";

/** what mode is this process in; one of: "child" "foreground" */
var mode = undefined;

/** directory for "run" files (notably, the pid lockfile) */
var runDir = undefined;

/** file to log to */
var logFile = undefined;

/** the full product info */
var theInfo = { name: productName };

/*
 * Helper functions
 */

/**
 * Heuristically sets the product name based on the given script name, by
 * extracting the base file name (excluding directories and dot-suffixes).
 */
function setProductNameFromScript(name) {
    var match = name.match(/^.*\/([^\/.]+)[^\/]*$/);

    if (!match || (match[1].length === 0)) {
	// The name isn't of the usual form. Just use the whole name.
	setProductName(name);
    } else {
	setProductName(match[1]);
    }
}

/**
 * Parses the given commandline arguments (process.argv if left
 * unspecified), determining what mode the process is to be in.  This
 * returns a map of the form { mode: <mode>, exec: <executable-name>,
 * script: <file-name>, argv: <cooked-argv> }, where mode is one of {
 * "parent", "child", "foreground" }, exec and script are the original
 * two arguments, and argv is an array of the arguments, excluding the
 * one that was used to determine parent-vs-child.
 *
 * This throws an exception if there is no mode argument present.
 */
function parseDaemonArguments(argv) {
    if (argv === undefined) {
	argv = process.argv;
    }

    if (argv.length < 3) {
	throw new Error("Too few arguments for daemon invocation");
    }

    var exec = argv[0];
    var script = argv[1];
    argv = argv.slice(2);

    // Scan for a --daemon argument, and note its index and value.

    var modeIndex = -1;
    var mode = undefined;

    for (var i = 0; i < argv.length; i++) {
	var arg = argv[i];
	if ((arg === "--") || (arg.length === 0) || (arg.charAt(0) !== "-")) {
	    break;
	}
	if (arg.search(/^--daemon=/) === 0) {
	    modeIndex = i;
	    mode = arg.slice(9);
	    break;
	}
    }

    // Validate.

    if (modeIndex < 0) {
        // Assume missing means "foreground".
        mode = "foreground";
    }

    switch (mode) {
        case "parent":
        case "child":
        case "foreground": {
	    // It's a valid value.
	    break;
	}
        default: {
	    throw new Error("Invalid --daemon option: " + mode);
	}
    }

    // Excise the --daemon argument from argv.
    if (modeIndex >= 0) {
        argv.splice(modeIndex, 1);
    }

    return {
	mode:   mode,
	exec:   exec,
	script: script,
	argv:   argv
    };
}

/**
 * Logs to the file indicated by logFile, or to stderr if logFile hasn't
 * yet been set.
 */
function logToFile(/*arg, ...*/) {
    var string = util.format.apply(this, arguments) + "\n";

    if (logFile === undefined) {
	process.stderr.write(string);
    } else {
	fs.write(logFile, string);
    }
}

/**
 * Logs to the the syslog.
 */
function logToSyslog(/*arg, ...*/) {
    posix.syslog("notice", util.format.apply(this, arguments));
}

/**
 * Make a directory (and its superdirectories) if it doesn't already exist.
 */
function mkdirsIfNeeded(dir) {
    try {
	var stat = fs.statSync(dir);
    } catch (ex) {
	if (ex.code == "ENOENT") {
	    var upDir = dir.match(/^(.*)\/[^\/]*$/);
	    if (upDir && upDir.length > 0) {
		mkdirsIfNeeded(upDir[1]);
	    }
	    fs.mkdirSync(dir);
	} else {
	    throw ex;
	}
    }
}

/*
 * Exported methods
 */

/**
 * Set the product name. This is used when logging.
 */
function setProductName(name) {
    productName = name;
    theInfo.name = name;
}

/**
 * Set the logging directory. This is (unsurprisingly) used when logging.
 */
function setLogDir(dir) {
    if (logFile !== undefined) {
	fs.closeSync(logFile);
    }

    mkdirsIfNeeded(dir);
    logFile = fs.openSync(path.join(dir, ERROR_LOG_NAME), "a");

    fs.writeSync(logFile, "\n\n[Restarting log at " + new Date() + ".]\n");

    // If there is anything in the "last ditch" error file (e.g. from
    // an earlier crash), copy it over here.
    var lastDitch = path.join(dir, LAST_DITCH_ERROR_LOG_NAME);
    if (path.existsSync(lastDitch)) {
        var buf = fs.readFileSync(lastDitch);
        if (buf.length !== 0) {
            fs.writeSync(
                logFile,
                "[The following was recovered from the last-ditch file.]\n");
            fs.writeSync(logFile, buf, 0, buf.length);
            fs.writeSync(logFile, "\n[End of recovered text.]\n\n");
        }
        fs.unlinkSync(lastDitch);
    }
}

/**
 * Set the run directory. This is notably used to hold a process pid
 * lockfile.
 */
function setRunDir(dir) {
    mkdirsIfNeeded(dir);
    runDir = dir;
}

/**
 * Take appropriate daemon setup action, based on the --daemon option
 * in the given commandline arguments (which default to process.argv
 * if left unspecified). This function should be called once, early on
 * in the life of a script.
 *
 * This function only returns in a child or foreground process. In a
 * parent process, this function is responsible for spawning the child
 * and then exiting.
 *
 * The return value is the given (or process) arguments, minus the one
 * that specified the daemon mode.
 */
function basicSetup(argv) {
    var parsedArgs = parseDaemonArguments(argv);
    mode = parsedArgs.mode; // Set the module-scope mode.
    setProductNameFromScript(parsedArgs.script);

    switch (mode) {
        case "parent": {
	    // We are the parent process. Spawn a child, telling it to
	    // run Node with the same script, but with the child daemon
	    // command.
	    var childArgs = [ "--daemon=child" ].concat(parsedArgs.argv);
	    var childProcess = child_process.fork(
		parsedArgs.script,
		childArgs,
		{ cwd: "/",
		  env: process.env, // TODO: Allow this to be passed in?
		  setsid: true
		});
	    process.exit(0);
	    throw new Error("Shouldn't happen");
	}
        case "child": {
	    // We are the child process. Reopen std* to /dev/null, and
	    // return the cooked argv.
	    daemonsauceNative.closeStdin();
	    daemonsauceNative.closeStdout();
	    daemonsauceNative.closeStderr();
	    return makeArgv();
	}
        case "foreground": {
	    // We are a foreground process. Just return the cooked argv.
	    return makeArgv();
	}
    }

    function makeArgv() {
	return [ parsedArgs.exec, parsedArgs.script ].concat(parsedArgs.argv);
    }
}

/**
 * Set up the logging environment. This only takes any action when
 * running in a daemon child process. This also needs to be done along
 * with a call to setLogDir().
 *
 * This replaces the logging methods of the global console
 * object. Most of the logging methods will write to an error log,
 * except for info(), which will emit syslog entries.
 */
function loggingSetup() {
    if (mode !== "child") {
	return;
    }

    // Set up for using syslog.
    posix.openlog(productName, {cons: true, pid: true}, "daemon");

    // What does "dir" mean? This is more or less copied from
    // console.js in the Node core.
    function dir(object) {
	console.log(util.inspect(object));
    }

    console.log = logToFile;
    console.info = logToSyslog;
    console.warn = logToFile;
    console.error = logToFile;
    console.dir = dir;
}

/**
 * Acquire the process lock. This will either succeed in locking or will
 * exit the process after logging the failure.
 *
 * This may only be called after setting the run directory.
 *
 * This method only takes action when running in a daemon child.
 */
function acquireLock() {
    if (mode !== "child") {
	return;
    }

    var lockFile = path.join(runDir, productName + ".pid");

    if (!daemonsauceNative.acquireLock(lockFile)) {
        console.info("Could not acquire lockfile: " + lockFile);
        process.exit(1);
    }
}

/**
 * Set user and group ids, based on the given info. It uses the
 * indicated `user` for the userid if supplied, defaulting to the
 * (product) `name` if not. `group` specifies the group id, which
 * defaults to the userid (which may itself have been defaulted to the
 * product name) if not specified.
 *
 * This function does nothing if it's not possible to set the ids
 * (e.g. id doesn't exist or not running as root).
 *
 * This method only takes action when running in a daemon child.
 */
function setUserAndGroup(info) {
    if (mode !== "child") {
	return;
    }

    var user = info.user || info.name;
    var group = info.group || user;

    try {
	process.setgid(group);
	process.setuid(user);
    } catch (ex) {
	// Ignore it.
    }
}

/**
 * Perform the "usual" daemon setup, based on the given info, which
 * must at least contain bindings for `{ name, logDir, runDir }`. Other
 * info is okay too, and is just returned directly by `getInfo()`.
 */
function usualSetup(info) {
    var name = info.name;
    var logDir = info.logDir;
    var runDir = info.runDir;

    if (!(name && logDir && runDir)) {
        throw new Error("Missing setup info");
    }

    theInfo = info;
    setProductName(name);
    setUserAndGroup(info);
    setRunDir(runDir);
    setLogDir(logDir);
    loggingSetup();
    acquireLock();
}

/**
 * Get the info previously passed to `usualSetup()`.
 */
function getInfo() {
    return theInfo;
}

module.exports = {
    acquireLock:     acquireLock,
    basicSetup:      basicSetup,
    getInfo:         getInfo,
    loggingSetup:    loggingSetup,
    setLogDir:       setLogDir,
    setRunDir:       setRunDir,
    setProductName:  setProductName,
    setUserAndGroup: setUserAndGroup,
    usualSetup:      usualSetup
};
<|endoftext|>


<commit_before>var pbkdf2 = {
    sha256: require("pbkdf2-sha256"),
    sha512: require("pbkdf2-sha512")
};

var PBKDF2 = {
    checkParams: function(format, algorithm) {
        return format === "raw" && algorithm.name === "PBKDF2";
    },

    usages: {'deriveBits': 'deriveBits'},

    formats: {
        raw: {
            types: [
                {
                    label: 'deriveBits',
                    usage: {
                        deriveBits: function(key, algorithm) {
                            return function(options, length) {
                                return PBKDF2.deriveBits(key, options, length);
                            };
                        }
                    }
                }
            ],

            import: function(key, algorithm) {
                return new Buffer(key);
            }
        }
    },

    createExporter(type, key) {
        throw "not implemented";
    },

    deriveBits(key, options, length) {
        var method = {"SHA-512": "sha512", "SHA-256": "sha256"}[options.hash.name];

        key = key.toString('utf8');
        var salt = new Buffer(options.salt).toString('utf8'); // TODO: make this work without string-encodings
        var result = pbkdf2[method](key, salt, options.iterations, length / 8);
        var nativeResult = new Uint8Array(result.length);
        for (var i = 0; i < result.length; i++) {
            nativeResult[i] = result[i];
        }
        return nativeResult;
    }
};

module.exports = PBKDF2;
<commit_msg>ie fix<commit_after>var pbkdf2 = {
    sha256: require("pbkdf2-sha256"),
    sha512: require("pbkdf2-sha512")
};

var PBKDF2 = {
    checkParams: function(format, algorithm) {
        return format === "raw" && algorithm.name === "PBKDF2";
    },

    usages: {'deriveBits': 'deriveBits'},

    formats: {
        raw: {
            types: [
                {
                    label: 'deriveBits',
                    usage: {
                        deriveBits: function(key, algorithm) {
                            return function(options, length) {
                                return PBKDF2.deriveBits(key, options, length);
                            };
                        }
                    }
                }
            ],

            import: function(key, algorithm) {
                return new Buffer(key);
            }
        }
    },

    createExporter: function(type, key) {
        throw "not implemented";
    },

    deriveBits: function(key, options, length) {
        var method = {"SHA-512": "sha512", "SHA-256": "sha256"}[options.hash.name];

        key = key.toString('utf8');
        var salt = new Buffer(options.salt).toString('utf8'); // TODO: make this work without string-encodings
        var result = pbkdf2[method](key, salt, options.iterations, length / 8);
        var nativeResult = new Uint8Array(result.length);
        for (var i = 0; i < result.length; i++) {
            nativeResult[i] = result[i];
        }
        return nativeResult;
    }
};

module.exports = PBKDF2;
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////
//
// Copyright 2016 Realm Inc.
//
// 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 require_method = require;

// Prevent React Native packager from seeing modules required with this
function nodeRequire(module) {
    return require_method(module);
}

function getContext() {
    // If process is an object, we're probably running in Node or Electron
    // From: http://stackoverflow.com/a/24279593/1417293
    if (typeof process === 'object' && process + '' === '[object process]') {

        // Visual Studio Code defines the global.__debug__ object.
        if (typeof global !== 'undefined' && global.__debug__) {
            return 'vscodedebugger';
        }

        return process.type === 'renderer' ? 'electron' : 'nodejs';
    }

    // When running via Jest, the jest object is defined.
    if (typeof jest === 'object') {
        return 'nodejs';
    }

    if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') { // eslint-disable-line no-undef
        // If the navigator.userAgent contains the string "Chrome", we're likely
        // running via the chrome debugger.
        if (typeof navigator !== 'undefined' &&
            /Chrome/.test(navigator.userAgent)) { // eslint-disable-line no-undef
            return 'chromedebugger';
        }

        // Otherwise, we must be in a "normal" react native situation.
        // In that case, the Realm type should have been injected by the native code.
        // If it hasn't, the user likely forgot to run link.
        if (typeof Realm === 'undefined'){
            throw new Error('Missing Realm constructor. Did you run "react-native link realm"? Please see https://realm.io/docs/react-native/latest/#missing-realm-constructor for troubleshooting');
        }
        return 'reactnative';
    }

    // If we're not running in React Native but we already injected the Realm class,
    // we are probably running in a pure jscore environment
    if (typeof Realm !== 'undefined') {
        return 'jscore';
    }

    // Visual Studio Code defines the global.__debug__ object.
    if (typeof global !== 'undefined' && global.__debug__) {
        return 'vscodedebugger';
    }

    // Finally, if the navigator.userAgent contains the string "Chrome", we're likely
    // running via the chrome debugger, even if navigator.product isn't set to "ReactNative"
    if (typeof navigator !== 'undefined' &&
        /Chrome/.test(navigator.userAgent)) { // eslint-disable-line no-undef
        return 'chromedebugger';
    }

    throw Error("Unknown execution context");
}

var realmConstructor;

switch(getContext()) {
    case 'nodejs':
    case 'electron':
        nodeRequire('./submit-analytics')('Run');

        var binary = nodeRequire('node-pre-gyp');
        var path = nodeRequire('path');
        var pkg = path.resolve(path.join(__dirname,'../package.json'));
        var binding_path = binary.find(pkg);

        realmConstructor = require_method(binding_path).Realm;
        break;

    case 'reactnative':
    case 'jscore':
        realmConstructor = Realm;  // eslint-disable-line no-undef
        break;

    case 'chromedebugger':
    case 'vscodedebugger':
        realmConstructor = require('./browser').default; // (exported as ES6 module)
        break;
}

if (!realmConstructor) {
    throw Error("Error trying to establish execution context");
}

require('./extensions')(realmConstructor);

module.exports = realmConstructor;
<commit_msg>Fix "realm constructor not defined" in JS remote debugging mode<commit_after>////////////////////////////////////////////////////////////////////////////
//
// Copyright 2016 Realm Inc.
//
// 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 require_method = require;

// Prevent React Native packager from seeing modules required with this
function nodeRequire(module) {
    return require_method(module);
}

function getContext() {
    // If process is an object, we're probably running in Node or Electron
    // From: http://stackoverflow.com/a/24279593/1417293
    if (typeof process === 'object' && process + '' === '[object process]') {

        // Visual Studio Code defines the global.__debug__ object.
        if (typeof global !== 'undefined' && global.__debug__) {
            return 'vscodedebugger';
        }

        return process.type === 'renderer' ? 'electron' : 'nodejs';
    }

    // When running via Jest, the jest object is defined.
    if (typeof jest === 'object') {
        return 'nodejs';
    }

    if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') { // eslint-disable-line no-undef
        // If the navigator.userAgent contains the string "Chrome", we're likely
        // running via the chrome debugger.
        if (typeof navigator !== 'undefined' &&
            /Chrome/.test(navigator.userAgent)) { // eslint-disable-line no-undef
            return 'chromedebugger';
        }

        // Check if its in remote js debugging mode
        // https://stackoverflow.com/a/42839384/3090989
        if (typeof atob !== 'undefined') {
            return 'chromedebugger';
        }

        // Otherwise, we must be in a "normal" react native situation.
        // In that case, the Realm type should have been injected by the native code.
        // If it hasn't, the user likely forgot to run link.
        if (typeof Realm === 'undefined'){
            throw new Error('Missing Realm constructor. Did you run "react-native link realm"? Please see https://realm.io/docs/react-native/latest/#missing-realm-constructor for troubleshooting');
        }
        return 'reactnative';
    }

    // If we're not running in React Native but we already injected the Realm class,
    // we are probably running in a pure jscore environment
    if (typeof Realm !== 'undefined') {
        return 'jscore';
    }

    // Visual Studio Code defines the global.__debug__ object.
    if (typeof global !== 'undefined' && global.__debug__) {
        return 'vscodedebugger';
    }

    // Finally, if the navigator.userAgent contains the string "Chrome", we're likely
    // running via the chrome debugger, even if navigator.product isn't set to "ReactNative"
    if (typeof navigator !== 'undefined' &&
        /Chrome/.test(navigator.userAgent)) { // eslint-disable-line no-undef
        return 'chromedebugger';
    }

    throw Error("Unknown execution context");
}

var realmConstructor;

switch(getContext()) {
    case 'nodejs':
    case 'electron':
        nodeRequire('./submit-analytics')('Run');

        var binary = nodeRequire('node-pre-gyp');
        var path = nodeRequire('path');
        var pkg = path.resolve(path.join(__dirname,'../package.json'));
        var binding_path = binary.find(pkg);

        realmConstructor = require_method(binding_path).Realm;
        break;

    case 'reactnative':
    case 'jscore':
        realmConstructor = Realm;  // eslint-disable-line no-undef
        break;

    case 'chromedebugger':
    case 'vscodedebugger':
        realmConstructor = require('./browser').default; // (exported as ES6 module)
        break;
}

if (!realmConstructor) {
    throw Error("Error trying to establish execution context");
}

require('./extensions')(realmConstructor);

module.exports = realmConstructor;
<|endoftext|>


<commit_before>import request from 'request';
import Clock from './clock.js';
import retry from './retry.js';
import {ByPassRetryError} from './retry.js';
import debug from 'debug';

const logger = debug('kadira-core:transport');

const DEFAULTS = {
  appId: '',
  appSecret: '',
  endpoint: 'https://enginex.kadira.io',
  hostname: 'localhost',
  clockSyncInterval: 1000 * 60,
  dataFlushInterval: 1000 * 10,
};

// exporting this for if we need to get this as a NPM module.
export class Kadira {
  constructor(_options) {
    this._options = Object.assign({}, DEFAULTS, _options);
    this._headers = {
      'content-type': 'application/json',
      'KADIRA-APP-ID': this._options.appId,
      'KADIRA-APP-SECRET': this._options.appSecret,
    };

    this._clock = new Clock({
      endpoint: this._options.endpoint + '/simplentp/sync',
    });

    this._clockSyncInterval = null;
  }

  connect() {
    logger('connecting with', this._options);
    return this._checkAuth()
      .then(() => this._clock.sync())
      .then(() => {
        this._clockSyncInterval = setInterval(
          () => this._clock.sync(),
          this._options.clockSyncInterval
        );
      });
  }

  disconnect() {
    logger('disconnect');
    clearInterval(this._clockSyncInterval);
  }

  updateJob(id, diff) {
    logger('update job', id);
    const data = {action: 'set', params: {}};
    Object.assign(data.params, diff, {id});

    const url = this._options.endpoint + '/jobs';
    const body = JSON.stringify(data);
    const params = {
      body,
      headers: this._headers,
    };

    return this._send(url, params);
  }

  // send the given payload to the server
  sendData(_payload) {
    const payload = {
      ..._payload,
      host: this._options.hostname
    };

    const url = this._options.endpoint;
    const body = JSON.stringify(payload);
    const params = {
      body,
      headers: this._headers,
      encoding: 'utf8'
    };

    logger(`send data - ${body.substr(0, 50)}...`);
    return this._send(url, params);
  }

  // ping the server to check whether appId and appSecret
  // are valid and correct. Data sent inside http headers.
  _checkAuth() {
    const uri = this._options.endpoint + '/ping';
    const params = {headers: this._headers};
    return this._send(uri, params);
  }

  // communicates with the server with http (using fetch)
  // Also handles response http status codes and  retries
  _send(url, params) {
    return retry(() => {
      return new Promise((resolve, reject) => {
        request.post(url, params, (err, res, body) => {
          if (res.statusCode === 200) {
            resolve(body);
          }

          if (res.statusCode === 401) {
            logger('Error: Unauthorized');
            reject(new ByPassRetryError('Unauthorized'));
          }

          if (res.statusCode >= 400 && res.statusCode < 500) {
            const message = `Agent Error: ${res.statusCode}`;
            logger(`Error: ${message}`);
            reject(new ByPassRetryError(message));
          }

          const message = `Request failed: ${res.statusCode}`;
          logger('Error: ${message}');
          reject(new Error(message));
        });
      });
    });
  }
}

export default Kadira;
<commit_msg>Fix some typos<commit_after>import request from 'request';
import Clock from './clock.js';
import retry from './retry.js';
import {ByPassRetryError} from './retry.js';
import debug from 'debug';

const logger = debug('kadira-core:transport');

const DEFAULTS = {
  appId: '',
  appSecret: '',
  endpoint: 'https://enginex.kadira.io',
  hostname: 'localhost',
  clockSyncInterval: 1000 * 60,
  dataFlushInterval: 1000 * 10,
};

// exporting this for if we need to get this as a NPM module.
export class Kadira {
  constructor(_options) {
    this._options = Object.assign({}, DEFAULTS, _options);
    this._headers = {
      'content-type': 'application/json',
      'KADIRA-APP-ID': this._options.appId,
      'KADIRA-APP-SECRET': this._options.appSecret,
    };

    this._clock = new Clock({
      endpoint: this._options.endpoint + '/simplentp/sync',
    });

    this._clockSyncInterval = null;
  }

  connect() {
    logger('connecting with', this._options);
    return this._checkAuth()
      .then(() => this._clock.sync())
      .then(() => {
        this._clockSyncInterval = setInterval(
          () => this._clock.sync(),
          this._options.clockSyncInterval
        );
      });
  }

  disconnect() {
    logger('disconnect');
    clearInterval(this._clockSyncInterval);
  }

  updateJob(id, diff) {
    const data = {action: 'set', params: {}};
    Object.assign(data.params, diff, {id});

    const url = this._options.endpoint + '/jobs';
    const body = JSON.stringify(data);
    const params = {
      body,
      headers: this._headers,
    };

    logger('update job', id);
    return this._send(url, params);
  }

  // send the given payload to the server
  sendData(_payload) {
    const payload = {
      ..._payload,
      host: this._options.hostname
    };

    const url = this._options.endpoint;
    const body = JSON.stringify(payload);
    const params = {
      body,
      headers: this._headers,
      encoding: 'utf8'
    };

    logger(`send data - ${body.substr(0, 50)}...`);
    return this._send(url, params);
  }

  // ping the server to check whether appId and appSecret
  // are valid and correct. Data sent inside http headers.
  _checkAuth() {
    const uri = this._options.endpoint + '/ping';
    const params = {headers: this._headers};
    return this._send(uri, params);
  }

  // communicates with the server with http (using fetch)
  // Also handles response http status codes and  retries
  _send(url, params) {
    return retry(() => {
      return new Promise((resolve, reject) => {
        request.post(url, params, (err, res, body) => {
          if (res.statusCode === 200) {
            return resolve(body);
          }

          if (res.statusCode === 401) {
            logger('Error: Unauthorized');
            return reject(new ByPassRetryError('Unauthorized'));
          }

          if (res.statusCode >= 400 && res.statusCode < 500) {
            const message = `Agent Error: ${res.statusCode}`;
            logger(`Error: ${message}`);
            return reject(new ByPassRetryError(message));
          }

          const message = `Request failed: ${res.statusCode}`;
          logger(`Error: ${message}`);
          reject(new Error(message));
        });
      });
    });
  }
}

export default Kadira;
<|endoftext|>